OLD | NEW |
---|---|
1 ; This tests the advanced lowering of switch statements. The advanced lowering | 1 ; This tests the advanced lowering of switch statements. The advanced lowering |
2 ; uses jump tables, range tests and binary search. | 2 ; uses jump tables, range tests and binary search. |
3 | 3 |
4 ; RUN: %p2i -i %s --filetype=obj --disassemble --args -O2 | FileCheck %s | 4 ; RUN: %p2i -i %s --target=x8632 --filetype=obj --disassemble --args -O2 \ |
John
2016/02/29 15:34:09
enable the other lit tests, too?
Jim Stichnoth
2016/02/29 17:53:18
Clarified offline. Most of the tests are run for
| |
5 ; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X8632 | |
6 ; RUN: %p2i -i %s --target=x8664 --filetype=obj --disassemble --args -O2 \ | |
7 ; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=X8664 | |
5 | 8 |
6 ; Dense but non-continuous ranges should be converted into a jump table. | 9 ; Dense but non-continuous ranges should be converted into a jump table. |
7 define internal i32 @testJumpTable(i32 %a) { | 10 define internal i32 @testJumpTable(i32 %a) { |
8 entry: | 11 entry: |
9 switch i32 %a, label %sw.default [ | 12 switch i32 %a, label %sw.default [ |
10 i32 91, label %sw.default | 13 i32 91, label %sw.default |
11 i32 92, label %sw.bb1 | 14 i32 92, label %sw.bb1 |
12 i32 93, label %sw.default | 15 i32 93, label %sw.default |
13 i32 99, label %sw.bb1 | 16 i32 99, label %sw.bb1 |
14 i32 98, label %sw.default | 17 i32 98, label %sw.default |
(...skipping 10 matching lines...) Expand all Loading... | |
25 br label %sw.epilog | 28 br label %sw.epilog |
26 | 29 |
27 sw.epilog: | 30 sw.epilog: |
28 %result.1 = phi i32 [ %add, %sw.default ], [ %tmp, %sw.bb1 ], [ 17, %entry ] | 31 %result.1 = phi i32 [ %add, %sw.default ], [ %tmp, %sw.bb1 ], [ 17, %entry ] |
29 ret i32 %result.1 | 32 ret i32 %result.1 |
30 } | 33 } |
31 ; CHECK-LABEL: testJumpTable | 34 ; CHECK-LABEL: testJumpTable |
32 ; CHECK: sub [[IND:[^,]+]],0x5b | 35 ; CHECK: sub [[IND:[^,]+]],0x5b |
33 ; CHECK-NEXT: cmp [[IND]],0x8 | 36 ; CHECK-NEXT: cmp [[IND]],0x8 |
34 ; CHECK-NEXT: ja | 37 ; CHECK-NEXT: ja |
35 ; CHECK-NEXT: mov [[TARGET:.*]],DWORD PTR {{\[}}[[IND]]*4+0x0] {{[0-9a-f]+}}: R_ 386_32 .{{.*}}testJumpTable$jumptable | 38 ; X8632-NEXT: mov [[TARGET:.*]],DWORD PTR {{\[}}[[IND]]*4+0x0] {{[0-9a-f]+}}: R_ 386_32 .{{.*}}testJumpTable$jumptable |
36 ; CHECK-NEXT: jmp [[TARGET]] | 39 ; X8632-NEXT: jmp [[TARGET]] |
40 ; X8664-NEXT: mov {{.}}[[TARGET:.*]],DWORD PTR {{\[}}[[IND]]*4+0x0] {{[0-9a-f]+} }: R_X86_64_32S .{{.*}}testJumpTable$jumptable | |
41 ; X8664-NEXT: jmp {{.}}[[TARGET]] | |
42 ; Note: x86-32 may do "mov eax, [...]; jmp eax", whereas x86-64 may do | |
43 ; "mov eax, [...]; jmp rax", so we assume the all characters except the first | |
44 ; one in the register name will match. | |
37 | 45 |
38 ; Continuous ranges which map to the same target should be grouped and | 46 ; Continuous ranges which map to the same target should be grouped and |
39 ; efficiently tested. | 47 ; efficiently tested. |
40 define internal i32 @testRangeTest() { | 48 define internal i32 @testRangeTest() { |
41 entry: | 49 entry: |
42 switch i32 10, label %sw.default [ | 50 switch i32 10, label %sw.default [ |
43 i32 0, label %sw.epilog | 51 i32 0, label %sw.epilog |
44 i32 1, label %sw.epilog | 52 i32 1, label %sw.epilog |
45 i32 2, label %sw.epilog | 53 i32 2, label %sw.epilog |
46 i32 3, label %sw.epilog | 54 i32 3, label %sw.epilog |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 br label %return | 130 br label %return |
123 | 131 |
124 sw.default: | 132 sw.default: |
125 br label %return | 133 br label %return |
126 | 134 |
127 return: | 135 return: |
128 %retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, % sw.bb1 ], [ 1, %entry ] | 136 %retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, % sw.bb1 ], [ 1, %entry ] |
129 ret i32 %retval.0 | 137 ret i32 %retval.0 |
130 } | 138 } |
131 ; CHECK-LABEL: testSwitchSmall64 | 139 ; CHECK-LABEL: testSwitchSmall64 |
132 ; CHECK: cmp {{.*}},0x0 | 140 ; X8632: cmp {{.*}},0x0 |
133 ; CHECK-NEXT: jne | 141 ; X8632-NEXT: jne |
134 ; CHECK-NEXT: cmp {{.*}},0x159 | 142 ; X8632-NEXT: cmp {{.*}},0x159 |
135 ; CHECK-NEXT: jb | 143 ; X8632-NEXT: jb |
136 ; CHECK-NEXT: je | 144 ; X8632-NEXT: je |
137 ; CHECK-NEXT: cmp {{.*}},0x1c8 | 145 ; X8632-NEXT: cmp {{.*}},0x1c8 |
138 ; CHECK-NEXT: je | 146 ; X8632-NEXT: je |
139 ; CHECK-NEXT: jmp | 147 ; X8632-NEXT: jmp |
140 ; CHECK-NEXT: cmp {{.*}},0x7b | 148 ; X8632-NEXT: cmp {{.*}},0x7b |
141 ; CHECK-NEXT: je | 149 ; X8632-NEXT: je |
142 ; CHECK-NEXT: cmp {{.*}},0xea | 150 ; X8632-NEXT: cmp {{.*}},0xea |
143 ; CHECK-NEXT: je | 151 ; X8632-NEXT: je |
144 | 152 |
145 ; Test for correct 64-bit lowering. | 153 ; Test for correct 64-bit lowering. |
146 ; TODO(ascull): this should generate better code like the 32-bit version | 154 ; TODO(ascull): this should generate better code like the 32-bit version |
147 define internal i32 @testSwitch64(i64 %a) { | 155 define internal i32 @testSwitch64(i64 %a) { |
148 entry: | 156 entry: |
149 switch i64 %a, label %sw.default [ | 157 switch i64 %a, label %sw.default [ |
150 i64 123, label %return | 158 i64 123, label %return |
151 i64 234, label %sw.bb1 | 159 i64 234, label %sw.bb1 |
152 i64 345, label %sw.bb2 | 160 i64 345, label %sw.bb2 |
153 i64 78187493520, label %sw.bb3 | 161 i64 78187493520, label %sw.bb3 |
154 ] | 162 ] |
155 | 163 |
156 sw.bb1: | 164 sw.bb1: |
157 br label %return | 165 br label %return |
158 | 166 |
159 sw.bb2: | 167 sw.bb2: |
160 br label %return | 168 br label %return |
161 | 169 |
162 sw.bb3: | 170 sw.bb3: |
163 br label %return | 171 br label %return |
164 | 172 |
165 sw.default: | 173 sw.default: |
166 br label %return | 174 br label %return |
167 | 175 |
168 return: | 176 return: |
169 %retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, % sw.bb1 ], [ 1, %entry ] | 177 %retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, % sw.bb1 ], [ 1, %entry ] |
170 ret i32 %retval.0 | 178 ret i32 %retval.0 |
171 } | 179 } |
172 ; CHECK-LABEL: testSwitch64 | 180 ; CHECK-LABEL: testSwitch64 |
173 ; CHECK: cmp {{.*}},0x7b | 181 ; X8632: cmp {{.*}},0x7b |
174 ; CHECK-NEXT: jne | 182 ; X8632-NEXT: jne |
175 ; CHECK-NEXT: cmp {{.*}},0x0 | 183 ; X8632-NEXT: cmp {{.*}},0x0 |
176 ; CHECK-NEXT: je | 184 ; X8632-NEXT: je |
177 ; CHECK: cmp {{.*}},0xea | 185 ; X8632: cmp {{.*}},0xea |
178 ; CHECK-NEXT: jne | 186 ; X8632-NEXT: jne |
179 ; CHECK-NEXT: cmp {{.*}},0x0 | 187 ; X8632-NEXT: cmp {{.*}},0x0 |
180 ; CHECK-NEXT: je | 188 ; X8632-NEXT: je |
181 ; CHECK: cmp {{.*}},0x159 | 189 ; X8632: cmp {{.*}},0x159 |
182 ; CHECK-NEXT: jne | 190 ; X8632-NEXT: jne |
183 ; CHECK-NEXT: cmp {{.*}},0x0 | 191 ; X8632-NEXT: cmp {{.*}},0x0 |
184 ; CHECK-NEXT: je | 192 ; X8632-NEXT: je |
185 ; CHECK: cmp {{.*}},0x34567890 | 193 ; X8632: cmp {{.*}},0x34567890 |
186 ; CHECK-NEXT: jne | 194 ; X8632-NEXT: jne |
187 ; CHECK-NEXT: cmp {{.*}},0x12 | 195 ; X8632-NEXT: cmp {{.*}},0x12 |
188 ; CHECK-NEXT: je | 196 ; X8632-NEXT: je |
189 | 197 |
190 ; Test for correct 64-bit jump table with UINT64_MAX as one of the values. | 198 ; Test for correct 64-bit jump table with UINT64_MAX as one of the values. |
191 define internal i32 @testJumpTable64(i64 %a) { | 199 define internal i32 @testJumpTable64(i64 %a) { |
192 entry: | 200 entry: |
193 switch i64 %a, label %sw.default [ | 201 switch i64 %a, label %sw.default [ |
194 i64 -6, label %return | 202 i64 -6, label %return |
195 i64 -4, label %sw.bb1 | 203 i64 -4, label %sw.bb1 |
196 i64 -3, label %sw.bb2 | 204 i64 -3, label %sw.bb2 |
197 i64 -1, label %sw.bb3 | 205 i64 -1, label %sw.bb3 |
198 ] | 206 ] |
(...skipping 10 matching lines...) Expand all Loading... | |
209 sw.default: | 217 sw.default: |
210 br label %return | 218 br label %return |
211 | 219 |
212 return: | 220 return: |
213 %retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, % sw.bb1 ], [ 1, %entry ] | 221 %retval.0 = phi i32 [ 5, %sw.default ], [ 4, %sw.bb3 ], [ 3, %sw.bb2 ], [ 2, % sw.bb1 ], [ 1, %entry ] |
214 ret i32 %retval.0 | 222 ret i32 %retval.0 |
215 } | 223 } |
216 | 224 |
217 ; TODO(ascull): this should generate a jump table. For now, just make sure it | 225 ; TODO(ascull): this should generate a jump table. For now, just make sure it |
218 ; doesn't crash the compiler. | 226 ; doesn't crash the compiler. |
227 ; CHECK-LABEL: testJumpTable64 | |
OLD | NEW |