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 ; Test that a sequence of allocas with less than stack alignment get fused. | 7 ; Test that a sequence of allocas with less than stack alignment get fused. |
8 define internal void @fused_small_align(i32 %arg) { | 8 define internal void @fused_small_align(i32 %arg) { |
9 entry: | 9 entry: |
10 %a1 = alloca i8, i32 8, align 4 | 10 %a1 = alloca i8, i32 8, align 4 |
11 %a2 = alloca i8, i32 12, align 4 | 11 %a2 = alloca i8, i32 12, align 4 |
12 %a3 = alloca i8, i32 16, align 8 | 12 %a3 = alloca i8, i32 16, align 8 |
13 %p1 = bitcast i8* %a1 to i32* | 13 %p1 = bitcast i8* %a1 to i32* |
14 %p2 = bitcast i8* %a2 to i32* | 14 %p2 = bitcast i8* %a2 to i32* |
15 %p3 = bitcast i8* %a3 to i32* | 15 %p3 = bitcast i8* %a3 to i32* |
16 store i32 %arg, i32* %p1, align 1 | 16 store i32 %arg, i32* %p1, align 1 |
17 store i32 %arg, i32* %p2, align 1 | 17 store i32 %arg, i32* %p2, align 1 |
18 store i32 %arg, i32* %p3, align 1 | 18 store i32 %arg, i32* %p3, align 1 |
19 ret void | 19 ret void |
20 } | 20 } |
21 ; CHECK-LABEL: fused_small_align | 21 ; CHECK-LABEL: fused_small_align |
22 ; CHECK-NEXT: sub esp,0xc | |
23 ; CHECK-NEXT: mov eax,DWORD PTR [esp+0x10] | |
24 ; CHECK-NEXT: sub esp,0x30 | 22 ; CHECK-NEXT: sub esp,0x30 |
25 ; CHECK-NEXT: mov {{.*}},esp | 23 ; CHECK-NEXT: mov eax,DWORD PTR [esp+0x34] |
26 ; CHECK-NEXT: mov DWORD PTR [esp+0x10],eax | 24 ; CHECK-NEXT: mov DWORD PTR [esp+0x10],eax |
27 ; CHECK-NEXT: mov DWORD PTR [esp+0x18],eax | 25 ; CHECK-NEXT: mov DWORD PTR [esp+0x18],eax |
28 ; CHECK-NEXT: mov DWORD PTR [esp],eax | 26 ; CHECK-NEXT: mov DWORD PTR [esp],eax |
29 ; CHECK-NEXT: add esp,0x3c | 27 ; CHECK-NEXT: add esp,0x30 |
30 | 28 |
31 ; Test that a sequence of allocas with greater than stack alignment get fused. | 29 ; Test that a sequence of allocas with greater than stack alignment get fused. |
32 define internal void @fused_large_align(i32 %arg) { | 30 define internal void @fused_large_align(i32 %arg) { |
33 entry: | 31 entry: |
34 %a1 = alloca i8, i32 8, align 32 | 32 %a1 = alloca i8, i32 8, align 32 |
35 %a2 = alloca i8, i32 12, align 64 | 33 %a2 = alloca i8, i32 12, align 64 |
36 %a3 = alloca i8, i32 16, align 32 | 34 %a3 = alloca i8, i32 16, align 32 |
37 %p1 = bitcast i8* %a1 to i32* | 35 %p1 = bitcast i8* %a1 to i32* |
38 %p2 = bitcast i8* %a2 to i32* | 36 %p2 = bitcast i8* %a2 to i32* |
39 %p3 = bitcast i8* %a3 to i32* | 37 %p3 = bitcast i8* %a3 to i32* |
40 store i32 %arg, i32* %p1, align 1 | 38 store i32 %arg, i32* %p1, align 1 |
41 store i32 %arg, i32* %p2, align 1 | 39 store i32 %arg, i32* %p2, align 1 |
42 store i32 %arg, i32* %p3, align 1 | 40 store i32 %arg, i32* %p3, align 1 |
43 ret void | 41 ret void |
44 } | 42 } |
45 ; CHECK-LABEL: fused_large_align | 43 ; CHECK-LABEL: fused_large_align |
46 ; CHECK-NEXT: push ebp | 44 ; CHECK-NEXT: push ebp |
47 ; CHECK-NEXT: mov ebp,esp | 45 ; CHECK-NEXT: mov ebp,esp |
48 ; CHECK-NEXT: sub esp,0x8 | 46 ; CHECK-NEXT: sub esp,0x80 |
| 47 ; CHECK-NEXT: and esp,0xffffffc0 |
49 ; CHECK-NEXT: mov eax,DWORD PTR [ebp+0x8] | 48 ; CHECK-NEXT: mov eax,DWORD PTR [ebp+0x8] |
50 ; CHECK-NEXT: and esp,0xffffffc0 | |
51 ; CHECK-NEXT: sub esp,0x80 | |
52 ; CHECK-NEXT: mov ecx,esp | |
53 ; CHECK-NEXT: mov DWORD PTR [esp+0x40],eax | 49 ; CHECK-NEXT: mov DWORD PTR [esp+0x40],eax |
54 ; CHECK-NEXT: mov DWORD PTR [esp],eax | 50 ; CHECK-NEXT: mov DWORD PTR [esp],eax |
55 ; CHECK-NEXT: mov DWORD PTR [esp+0x60],eax | 51 ; CHECK-NEXT: mov DWORD PTR [esp+0x60],eax |
56 ; CHECK-NEXT: mov esp,ebp | 52 ; CHECK-NEXT: mov esp,ebp |
57 ; CHECK-NEXT: pop ebp | 53 ; CHECK-NEXT: pop ebp |
58 | 54 |
59 ; Test that an interior pointer into a rematerializable variable is also | 55 ; Test that an interior pointer into a rematerializable variable is also |
60 ; rematerializable, and test that it is detected even when the use appears | 56 ; rematerializable, and test that it is detected even when the use appears |
61 ; syntactically before the definition. Test that it is folded into mem | 57 ; syntactically before the definition. Test that it is folded into mem |
62 ; operands, and also rematerializable through an lea instruction for direct use. | 58 ; operands, and also rematerializable through an lea instruction for direct use. |
(...skipping 10 matching lines...) Expand all Loading... |
73 ret i32 %retval | 69 ret i32 %retval |
74 block2: | 70 block2: |
75 ; The following are all rematerializable variables deriving from %a2. | 71 ; The following are all rematerializable variables deriving from %a2. |
76 %p2 = ptrtoint i8* %a2 to i32 | 72 %p2 = ptrtoint i8* %a2 to i32 |
77 %d = add i32 %p2, 12 | 73 %d = add i32 %p2, 12 |
78 %retval = add i32 %p2, 1 | 74 %retval = add i32 %p2, 1 |
79 %derived = inttoptr i32 %d to i32* | 75 %derived = inttoptr i32 %d to i32* |
80 br label %block1 | 76 br label %block1 |
81 } | 77 } |
82 ; CHECK-LABEL: fused_derived | 78 ; CHECK-LABEL: fused_derived |
83 ; CHECK-NEXT: sub esp,0xc | |
84 ; CHECK-NEXT: mov [[ARG:e..]],DWORD PTR [esp+0x10] | |
85 ; CHECK-NEXT: sub esp,0x180 | 79 ; CHECK-NEXT: sub esp,0x180 |
86 ; CHECK-NEXT: mov {{.*}},esp | 80 ; CHECK-NEXT: mov [[ARG:e..]],DWORD PTR [esp+0x184] |
87 ; CHECK-NEXT: jmp | 81 ; CHECK-NEXT: jmp |
88 ; CHECK-NEXT: mov DWORD PTR [esp+0x80],[[ARG]] | 82 ; CHECK-NEXT: mov DWORD PTR [esp+0x80],[[ARG]] |
89 ; CHECK-NEXT: mov DWORD PTR [esp+0x8c],[[ARG]] | 83 ; CHECK-NEXT: mov DWORD PTR [esp+0x8c],[[ARG]] |
90 ; CHECK-NEXT: lea eax,[esp+0x81] | 84 ; CHECK-NEXT: lea eax,[esp+0x81] |
91 ; CHECK-NEXT: add esp,0x18c | 85 ; CHECK-NEXT: add esp,0x180 |
92 ; CHECK-NEXT: ret | 86 ; CHECK-NEXT: ret |
| 87 |
| 88 ; Test that a fixed alloca gets referenced by the frame pointer. |
| 89 define internal void @fused_small_align_with_dynamic(i32 %arg) { |
| 90 entry: |
| 91 %a1 = alloca i8, i32 8, align 16 |
| 92 br label %next |
| 93 next: |
| 94 %a2 = alloca i8, i32 12, align 1 |
| 95 %a3 = alloca i8, i32 16, align 1 |
| 96 %p1 = bitcast i8* %a1 to i32* |
| 97 %p2 = bitcast i8* %a2 to i32* |
| 98 %p3 = bitcast i8* %a3 to i32* |
| 99 store i32 %arg, i32* %p1, align 1 |
| 100 store i32 %arg, i32* %p2, align 1 |
| 101 store i32 %arg, i32* %p3, align 1 |
| 102 ret void |
| 103 } |
| 104 ; CHECK-LABEL: fused_small_align_with_dynamic |
| 105 ; CHECK-NEXT: push ebp |
| 106 ; CHECK-NEXT: mov ebp,esp |
| 107 ; CHECK-NEXT: sub esp,0x18 |
| 108 ; CHECK-NEXT: mov eax,DWORD PTR [ebp+0x8] |
| 109 ; CHECK-NEXT: sub esp,0x10 |
| 110 ; CHECK-NEXT: mov ecx,esp |
| 111 ; CHECK-NEXT: sub esp,0x10 |
| 112 ; CHECK-NEXT: mov edx,esp |
| 113 ; CHECK-NEXT: mov DWORD PTR [ebp-0x18],eax |
| 114 ; CHECK-NEXT: mov DWORD PTR [ecx],eax |
| 115 ; CHECK-NEXT: mov DWORD PTR [edx],eax |
| 116 ; CHECK-NEXT: mov esp,ebp |
| 117 ; CHECK-NEXT: pop ebp |
| 118 |
| 119 ; Test that a sequence with greater than stack alignment and dynamic size |
| 120 ; get folded and referenced correctly; |
| 121 |
| 122 define internal void @fused_large_align_with_dynamic(i32 %arg) { |
| 123 entry: |
| 124 %a1 = alloca i8, i32 8, align 32 |
| 125 %a2 = alloca i8, i32 12, align 32 |
| 126 %a3 = alloca i8, i32 16, align 1 |
| 127 %a4 = alloca i8, i32 16, align 1 |
| 128 br label %next |
| 129 next: |
| 130 %a5 = alloca i8, i32 16, align 1 |
| 131 %p1 = bitcast i8* %a1 to i32* |
| 132 %p2 = bitcast i8* %a2 to i32* |
| 133 %p3 = bitcast i8* %a3 to i32* |
| 134 %p4 = bitcast i8* %a4 to i32* |
| 135 %p5 = bitcast i8* %a5 to i32* |
| 136 store i32 %arg, i32* %p1, align 1 |
| 137 store i32 %arg, i32* %p2, align 1 |
| 138 store i32 %arg, i32* %p3, align 1 |
| 139 store i32 %arg, i32* %p4, align 1 |
| 140 store i32 %arg, i32* %p5, align 1 |
| 141 ret void |
| 142 } |
| 143 ; CHECK-LABEL: fused_large_align_with_dynamic |
| 144 ; CHECK-NEXT: push ebx |
| 145 ; CHECK-NEXT: push ebp |
| 146 ; CHECK-NEXT: mov ebp,esp |
| 147 ; CHECK-NEXT: sub esp,0x64 |
| 148 ; CHECK-NEXT: mov eax,DWORD PTR [ebp+0xc] |
| 149 ; CHECK-NEXT: and esp,0xffffffe0 |
| 150 ; CHECK-NEXT: sub esp,0x40 |
| 151 ; CHECK-NEXT: mov ecx,esp |
| 152 ; CHECK-NEXT: mov edx,ecx |
| 153 ; CHECK-NEXT: add edx,0x20 |
| 154 ; CHECK-NEXT: add ecx,0x0 |
| 155 ; CHECK-NEXT: sub esp,0x10 |
| 156 ; CHECK-NEXT: mov ebx,esp |
| 157 ; CHECK-NEXT: mov DWORD PTR [ecx],eax |
| 158 ; CHECK-NEXT: mov DWORD PTR [edx],eax |
| 159 ; CHECK-NEXT: mov DWORD PTR [ebp-0x14],eax |
| 160 ; CHECK-NEXT: mov DWORD PTR [ebp-0x24],eax |
| 161 ; CHECK-NEXT: mov DWORD PTR [ebx],eax |
| 162 ; CHECK-NEXT: mov esp,ebp |
| 163 ; CHECK-NEXT: pop ebp |
OLD | NEW |