OLD | NEW |
1 ; This is a basic test of the alloca instruction. | 1 ; This is a basic test of the alloca instruction. |
2 | 2 |
3 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \ | 3 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \ |
4 ; RUN: --target x8632 -i %s --args -O2 -allow-externally-defined-symbols \ | 4 ; RUN: --target x8632 -i %s --args -O2 -allow-externally-defined-symbols \ |
5 ; RUN: | %if --need=target_X8632 --command FileCheck %s | 5 ; RUN: | %if --need=target_X8632 --command FileCheck %s |
6 | 6 |
| 7 ; RUN: %if --need=target_MIPS32 --need=allow_dump \ |
| 8 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target \ |
| 9 ; RUN: mips32 -i %s --args -O2 -allow-externally-defined-symbols \ |
| 10 ; RUN: | %if --need=target_MIPS32 --need=allow_dump \ |
| 11 ; RUN: --command FileCheck --check-prefix MIPS32 %s |
| 12 |
7 ; Test that a sequence of allocas with less than stack alignment get fused. | 13 ; Test that a sequence of allocas with less than stack alignment get fused. |
8 define internal void @fused_small_align(i32 %arg) { | 14 define internal void @fused_small_align(i32 %arg) { |
9 entry: | 15 entry: |
10 %a1 = alloca i8, i32 8, align 4 | 16 %a1 = alloca i8, i32 8, align 4 |
11 %a2 = alloca i8, i32 12, align 4 | 17 %a2 = alloca i8, i32 12, align 4 |
12 %a3 = alloca i8, i32 16, align 8 | 18 %a3 = alloca i8, i32 16, align 8 |
13 %p1 = bitcast i8* %a1 to i32* | 19 %p1 = bitcast i8* %a1 to i32* |
14 %p2 = bitcast i8* %a2 to i32* | 20 %p2 = bitcast i8* %a2 to i32* |
15 %p3 = bitcast i8* %a3 to i32* | 21 %p3 = bitcast i8* %a3 to i32* |
16 store i32 %arg, i32* %p1, align 1 | 22 store i32 %arg, i32* %p1, align 1 |
17 store i32 %arg, i32* %p2, align 1 | 23 store i32 %arg, i32* %p2, align 1 |
18 store i32 %arg, i32* %p3, align 1 | 24 store i32 %arg, i32* %p3, align 1 |
19 ret void | 25 ret void |
20 } | 26 } |
21 ; CHECK-LABEL: fused_small_align | 27 ; CHECK-LABEL: fused_small_align |
22 ; CHECK-NEXT: sub esp,0x30 | 28 ; CHECK-NEXT: sub esp,0x30 |
23 ; CHECK-NEXT: mov eax,DWORD PTR [esp+0x34] | 29 ; CHECK-NEXT: mov eax,DWORD PTR [esp+0x34] |
24 ; CHECK-NEXT: mov DWORD PTR [esp+0x10],eax | 30 ; CHECK-NEXT: mov DWORD PTR [esp+0x10],eax |
25 ; CHECK-NEXT: mov DWORD PTR [esp+0x18],eax | 31 ; CHECK-NEXT: mov DWORD PTR [esp+0x18],eax |
26 ; CHECK-NEXT: mov DWORD PTR [esp],eax | 32 ; CHECK-NEXT: mov DWORD PTR [esp],eax |
27 ; CHECK-NEXT: add esp,0x30 | 33 ; CHECK-NEXT: add esp,0x30 |
| 34 ; MIPS32-LABEL: fused_small_align |
| 35 ; MIPS32: addiu sp,sp,{{.*}} |
| 36 ; MIPS32: move v0,a0 |
| 37 ; MIPS32: sw v0,{{.*}}(sp) |
| 38 ; MIPS32: move v0,a0 |
| 39 ; MIPS32: sw v0,{{.*}}(sp) |
| 40 ; MIPS32: sw a0,{{.*}}(sp) |
| 41 ; MIPS32: addiu sp,sp,{{.*}} |
28 | 42 |
29 ; Test that a sequence of allocas with greater than stack alignment get fused. | 43 ; Test that a sequence of allocas with greater than stack alignment get fused. |
30 define internal void @fused_large_align(i32 %arg) { | 44 define internal void @fused_large_align(i32 %arg) { |
31 entry: | 45 entry: |
32 %a1 = alloca i8, i32 8, align 32 | 46 %a1 = alloca i8, i32 8, align 32 |
33 %a2 = alloca i8, i32 12, align 64 | 47 %a2 = alloca i8, i32 12, align 64 |
34 %a3 = alloca i8, i32 16, align 32 | 48 %a3 = alloca i8, i32 16, align 32 |
35 %p1 = bitcast i8* %a1 to i32* | 49 %p1 = bitcast i8* %a1 to i32* |
36 %p2 = bitcast i8* %a2 to i32* | 50 %p2 = bitcast i8* %a2 to i32* |
37 %p3 = bitcast i8* %a3 to i32* | 51 %p3 = bitcast i8* %a3 to i32* |
38 store i32 %arg, i32* %p1, align 1 | 52 store i32 %arg, i32* %p1, align 1 |
39 store i32 %arg, i32* %p2, align 1 | 53 store i32 %arg, i32* %p2, align 1 |
40 store i32 %arg, i32* %p3, align 1 | 54 store i32 %arg, i32* %p3, align 1 |
41 ret void | 55 ret void |
42 } | 56 } |
43 ; CHECK-LABEL: fused_large_align | 57 ; CHECK-LABEL: fused_large_align |
44 ; CHECK-NEXT: push ebp | 58 ; CHECK-NEXT: push ebp |
45 ; CHECK-NEXT: mov ebp,esp | 59 ; CHECK-NEXT: mov ebp,esp |
46 ; CHECK-NEXT: sub esp,0x80 | 60 ; CHECK-NEXT: sub esp,0x80 |
47 ; CHECK-NEXT: and esp,0xffffffc0 | 61 ; CHECK-NEXT: and esp,0xffffffc0 |
48 ; CHECK-NEXT: mov eax,DWORD PTR [ebp+0x8] | 62 ; CHECK-NEXT: mov eax,DWORD PTR [ebp+0x8] |
49 ; CHECK-NEXT: mov DWORD PTR [esp+0x40],eax | 63 ; CHECK-NEXT: mov DWORD PTR [esp+0x40],eax |
50 ; CHECK-NEXT: mov DWORD PTR [esp],eax | 64 ; CHECK-NEXT: mov DWORD PTR [esp],eax |
51 ; CHECK-NEXT: mov DWORD PTR [esp+0x60],eax | 65 ; CHECK-NEXT: mov DWORD PTR [esp+0x60],eax |
52 ; CHECK-NEXT: mov esp,ebp | 66 ; CHECK-NEXT: mov esp,ebp |
53 ; CHECK-NEXT: pop ebp | 67 ; CHECK-NEXT: pop ebp |
| 68 ; MIPS32-LABEL: fused_large_align |
| 69 ; MIPS32: addiu sp,sp,{{.*}} |
| 70 ; MIPS32: sw s8,{{.*}}(sp) |
| 71 ; MIPS32: move s8,sp |
| 72 ; MIPS32: move v0,a0 |
| 73 ; MIPS32: sw v0,{{.*}}(sp) |
| 74 ; MIPS32: move v0,a0 |
| 75 ; MIPS32: sw v0,{{.*}}(sp) |
| 76 ; MIPS32: sw a0,{{.*}}(sp) |
| 77 ; MIPS32: move sp,s8 |
| 78 ; MIPS32: lw s8,{{.*}}(sp) |
| 79 ; MIPS32: addiu sp,sp,{{.*}} |
54 | 80 |
55 ; Test that an interior pointer into a rematerializable variable is also | 81 ; Test that an interior pointer into a rematerializable variable is also |
56 ; rematerializable, and test that it is detected even when the use appears | 82 ; rematerializable, and test that it is detected even when the use appears |
57 ; syntactically before the definition. Test that it is folded into mem | 83 ; syntactically before the definition. Test that it is folded into mem |
58 ; operands, and also rematerializable through an lea instruction for direct use. | 84 ; operands, and also rematerializable through an lea instruction for direct use. |
59 define internal i32 @fused_derived(i32 %arg) { | 85 define internal i32 @fused_derived(i32 %arg) { |
60 entry: | 86 entry: |
61 %a1 = alloca i8, i32 128, align 4 | 87 %a1 = alloca i8, i32 128, align 4 |
62 %a2 = alloca i8, i32 128, align 4 | 88 %a2 = alloca i8, i32 128, align 4 |
63 %a3 = alloca i8, i32 128, align 4 | 89 %a3 = alloca i8, i32 128, align 4 |
(...skipping 13 matching lines...) Expand all Loading... |
77 } | 103 } |
78 ; CHECK-LABEL: fused_derived | 104 ; CHECK-LABEL: fused_derived |
79 ; CHECK-NEXT: sub esp,0x180 | 105 ; CHECK-NEXT: sub esp,0x180 |
80 ; CHECK-NEXT: mov [[ARG:e..]],DWORD PTR [esp+0x184] | 106 ; CHECK-NEXT: mov [[ARG:e..]],DWORD PTR [esp+0x184] |
81 ; CHECK-NEXT: jmp | 107 ; CHECK-NEXT: jmp |
82 ; CHECK-NEXT: mov DWORD PTR [esp+0x80],[[ARG]] | 108 ; CHECK-NEXT: mov DWORD PTR [esp+0x80],[[ARG]] |
83 ; CHECK-NEXT: mov DWORD PTR [esp+0x8c],[[ARG]] | 109 ; CHECK-NEXT: mov DWORD PTR [esp+0x8c],[[ARG]] |
84 ; CHECK-NEXT: lea eax,[esp+0x81] | 110 ; CHECK-NEXT: lea eax,[esp+0x81] |
85 ; CHECK-NEXT: add esp,0x180 | 111 ; CHECK-NEXT: add esp,0x180 |
86 ; CHECK-NEXT: ret | 112 ; CHECK-NEXT: ret |
| 113 ; MIPS32-LABEL: fused_derived |
| 114 ; MIPS32: addiu sp,sp,{{.*}} |
| 115 ; MIPS32: b |
| 116 ; MIPS32: move v0,a0 |
| 117 ; MIPS32: sw v0,{{.*}}(sp) |
| 118 ; MIPS32: sw a0,{{.*}}(sp) |
| 119 ; MIPS32: addiu v0,sp,129 |
| 120 ; MIPS32: addiu sp,sp,{{.*}} |
87 | 121 |
88 ; Test that a fixed alloca gets referenced by the frame pointer. | 122 ; Test that a fixed alloca gets referenced by the frame pointer. |
89 define internal void @fused_small_align_with_dynamic(i32 %arg) { | 123 define internal void @fused_small_align_with_dynamic(i32 %arg) { |
90 entry: | 124 entry: |
91 %a1 = alloca i8, i32 8, align 16 | 125 %a1 = alloca i8, i32 8, align 16 |
92 br label %next | 126 br label %next |
93 next: | 127 next: |
94 %a2 = alloca i8, i32 12, align 1 | 128 %a2 = alloca i8, i32 12, align 1 |
95 %a3 = alloca i8, i32 16, align 1 | 129 %a3 = alloca i8, i32 16, align 1 |
96 %p1 = bitcast i8* %a1 to i32* | 130 %p1 = bitcast i8* %a1 to i32* |
(...skipping 11 matching lines...) Expand all Loading... |
108 ; CHECK-NEXT: mov eax,DWORD PTR [ebp+0x8] | 142 ; CHECK-NEXT: mov eax,DWORD PTR [ebp+0x8] |
109 ; CHECK-NEXT: sub esp,0x10 | 143 ; CHECK-NEXT: sub esp,0x10 |
110 ; CHECK-NEXT: mov ecx,esp | 144 ; CHECK-NEXT: mov ecx,esp |
111 ; CHECK-NEXT: sub esp,0x10 | 145 ; CHECK-NEXT: sub esp,0x10 |
112 ; CHECK-NEXT: mov edx,esp | 146 ; CHECK-NEXT: mov edx,esp |
113 ; CHECK-NEXT: mov DWORD PTR [ebp-0x18],eax | 147 ; CHECK-NEXT: mov DWORD PTR [ebp-0x18],eax |
114 ; CHECK-NEXT: mov DWORD PTR [ecx],eax | 148 ; CHECK-NEXT: mov DWORD PTR [ecx],eax |
115 ; CHECK-NEXT: mov DWORD PTR [edx],eax | 149 ; CHECK-NEXT: mov DWORD PTR [edx],eax |
116 ; CHECK-NEXT: mov esp,ebp | 150 ; CHECK-NEXT: mov esp,ebp |
117 ; CHECK-NEXT: pop ebp | 151 ; CHECK-NEXT: pop ebp |
| 152 ; MIPS32-LABEL: fused_small_align_with_dynamic |
| 153 ; MIPS32: addiu sp,sp,{{.*}} |
| 154 ; MIPS32: sw s8,{{.*}}(sp) |
| 155 ; MIPS32: move s8,sp |
| 156 ; MIPS32: addiu v0,sp,0 |
| 157 ; MIPS32: addiu v1,sp,16 |
| 158 ; MIPS32: move a1,a0 |
| 159 ; MIPS32: sw a1,16(s8) |
| 160 ; MIPS32: move a1,a0 |
| 161 ; MIPS32: sw a1,0(v0) |
| 162 ; MIPS32: sw a0,0(v1) |
| 163 ; MIPS32: move sp,s8 |
| 164 ; MIPS32: lw s8,{{.*}}(sp) |
| 165 ; MIPS32: addiu sp,sp,{{.*}} |
118 | 166 |
119 ; Test that a sequence with greater than stack alignment and dynamic size | 167 ; Test that a sequence with greater than stack alignment and dynamic size |
120 ; get folded and referenced correctly; | 168 ; get folded and referenced correctly; |
121 | 169 |
122 define internal void @fused_large_align_with_dynamic(i32 %arg) { | 170 define internal void @fused_large_align_with_dynamic(i32 %arg) { |
123 entry: | 171 entry: |
124 %a1 = alloca i8, i32 8, align 32 | 172 %a1 = alloca i8, i32 8, align 32 |
125 %a2 = alloca i8, i32 12, align 32 | 173 %a2 = alloca i8, i32 12, align 32 |
126 %a3 = alloca i8, i32 16, align 1 | 174 %a3 = alloca i8, i32 16, align 1 |
127 %a4 = alloca i8, i32 16, align 1 | 175 %a4 = alloca i8, i32 16, align 1 |
(...skipping 26 matching lines...) Expand all Loading... |
154 ; CHECK-NEXT: add edx,0x0 | 202 ; CHECK-NEXT: add edx,0x0 |
155 ; CHECK-NEXT: sub esp,0x10 | 203 ; CHECK-NEXT: sub esp,0x10 |
156 ; CHECK-NEXT: mov ebx,esp | 204 ; CHECK-NEXT: mov ebx,esp |
157 ; CHECK-NEXT: mov DWORD PTR [edx],eax | 205 ; CHECK-NEXT: mov DWORD PTR [edx],eax |
158 ; CHECK-NEXT: mov DWORD PTR [ecx],eax | 206 ; CHECK-NEXT: mov DWORD PTR [ecx],eax |
159 ; CHECK-NEXT: mov DWORD PTR [ebp-0x14],eax | 207 ; CHECK-NEXT: mov DWORD PTR [ebp-0x14],eax |
160 ; CHECK-NEXT: mov DWORD PTR [ebp-0x24],eax | 208 ; CHECK-NEXT: mov DWORD PTR [ebp-0x24],eax |
161 ; CHECK-NEXT: mov DWORD PTR [ebx],eax | 209 ; CHECK-NEXT: mov DWORD PTR [ebx],eax |
162 ; CHECK-NEXT: mov esp,ebp | 210 ; CHECK-NEXT: mov esp,ebp |
163 ; CHECK-NEXT: pop ebp | 211 ; CHECK-NEXT: pop ebp |
| 212 ; MIPS32-LABEL: fused_large_align_with_dynamic |
| 213 ; MIPS32: addiu sp,sp,{{.*}} |
| 214 ; MIPS32: sw s8,{{.*}}(sp) |
| 215 ; MIPS32: move s8,sp |
| 216 ; MIPS32: addiu v0,sp,0 |
| 217 ; MIPS32: addiu v1,sp,64 |
| 218 ; MIPS32: move a1,v0 |
| 219 ; MIPS32: move a2,a0 |
| 220 ; MIPS32: sw a2,0(a1) |
| 221 ; MIPS32: move a1,a0 |
| 222 ; MIPS32: sw a1,32(v0) |
| 223 ; MIPS32: move v0,a0 |
| 224 ; MIPS32: sw v0,64(s8) |
| 225 ; MIPS32: move v0,a0 |
| 226 ; MIPS32: sw v0,48(s8) |
| 227 ; MIPS32: sw a0,0(v1) |
| 228 ; MIPS32: move sp,s8 |
| 229 ; MIPS32: lw s8,{{.*}}(sp) |
| 230 ; MIPS32: addiu sp,sp,{{.*}} |
OLD | NEW |