[MIParser] Set RegClassOrRegBank during instruction parsing
[llvm-complete.git] / test / Transforms / SimplifyCFG / X86 / speculate-cttz-ctlz.ll
blob3a2f067a2ee32a18e79e1c4aae9c54012d81cb6b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+bmi < %s | FileCheck %s --check-prefix=ALL --check-prefix=BMI
3 ; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown -mattr=+lzcnt < %s | FileCheck %s --check-prefix=ALL --check-prefix=LZCNT
4 ; RUN: opt -S -simplifycfg -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=GENERIC
7 define i64 @test1(i64 %A) {
8 ; BMI-LABEL: @test1(
9 ; BMI-NEXT:  entry:
10 ; BMI-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
11 ; BMI-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[A]], i1 true)
12 ; BMI-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
13 ; BMI-NEXT:    ret i64 [[COND]]
15 ; LZCNT-LABEL: @test1(
16 ; LZCNT-NEXT:  entry:
17 ; LZCNT-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
18 ; LZCNT-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[A]], i1 true)
19 ; LZCNT-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
20 ; LZCNT-NEXT:    ret i64 [[SPEC_SELECT]]
22 ; GENERIC-LABEL: @test1(
23 ; GENERIC-NEXT:  entry:
24 ; GENERIC-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
25 ; GENERIC-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[A]], i1 true)
26 ; GENERIC-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
27 ; GENERIC-NEXT:    ret i64 [[COND]]
29 entry:
30   %tobool = icmp eq i64 %A, 0
31   br i1 %tobool, label %cond.end, label %cond.true
33 cond.true:                                        ; preds = %entry
34   %0 = tail call i64 @llvm.ctlz.i64(i64 %A, i1 true)
35   br label %cond.end
37 cond.end:                                         ; preds = %entry, %cond.true
38   %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
39   ret i64 %cond
42 define i32 @test2(i32 %A) {
43 ; BMI-LABEL: @test2(
44 ; BMI-NEXT:  entry:
45 ; BMI-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
46 ; BMI-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[A]], i1 true)
47 ; BMI-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
48 ; BMI-NEXT:    ret i32 [[COND]]
50 ; LZCNT-LABEL: @test2(
51 ; LZCNT-NEXT:  entry:
52 ; LZCNT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
53 ; LZCNT-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[A]], i1 true)
54 ; LZCNT-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
55 ; LZCNT-NEXT:    ret i32 [[SPEC_SELECT]]
57 ; GENERIC-LABEL: @test2(
58 ; GENERIC-NEXT:  entry:
59 ; GENERIC-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
60 ; GENERIC-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[A]], i1 true)
61 ; GENERIC-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
62 ; GENERIC-NEXT:    ret i32 [[COND]]
64 entry:
65   %tobool = icmp eq i32 %A, 0
66   br i1 %tobool, label %cond.end, label %cond.true
68 cond.true:                                        ; preds = %entry
69   %0 = tail call i32 @llvm.ctlz.i32(i32 %A, i1 true)
70   br label %cond.end
72 cond.end:                                         ; preds = %entry, %cond.true
73   %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
74   ret i32 %cond
78 define signext i16 @test3(i16 signext %A) {
79 ; BMI-LABEL: @test3(
80 ; BMI-NEXT:  entry:
81 ; BMI-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
82 ; BMI-NEXT:    [[TMP0:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[A]], i1 true)
83 ; BMI-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
84 ; BMI-NEXT:    ret i16 [[COND]]
86 ; LZCNT-LABEL: @test3(
87 ; LZCNT-NEXT:  entry:
88 ; LZCNT-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
89 ; LZCNT-NEXT:    [[TMP0:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[A]], i1 true)
90 ; LZCNT-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
91 ; LZCNT-NEXT:    ret i16 [[SPEC_SELECT]]
93 ; GENERIC-LABEL: @test3(
94 ; GENERIC-NEXT:  entry:
95 ; GENERIC-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
96 ; GENERIC-NEXT:    [[TMP0:%.*]] = tail call i16 @llvm.ctlz.i16(i16 [[A]], i1 true)
97 ; GENERIC-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
98 ; GENERIC-NEXT:    ret i16 [[COND]]
100 entry:
101   %tobool = icmp eq i16 %A, 0
102   br i1 %tobool, label %cond.end, label %cond.true
104 cond.true:                                        ; preds = %entry
105   %0 = tail call i16 @llvm.ctlz.i16(i16 %A, i1 true)
106   br label %cond.end
108 cond.end:                                         ; preds = %entry, %cond.true
109   %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
110   ret i16 %cond
114 define i64 @test1b(i64 %A) {
115 ; BMI-LABEL: @test1b(
116 ; BMI-NEXT:  entry:
117 ; BMI-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
118 ; BMI-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[A]], i1 true)
119 ; BMI-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
120 ; BMI-NEXT:    ret i64 [[SPEC_SELECT]]
122 ; LZCNT-LABEL: @test1b(
123 ; LZCNT-NEXT:  entry:
124 ; LZCNT-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
125 ; LZCNT-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[A]], i1 true)
126 ; LZCNT-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
127 ; LZCNT-NEXT:    ret i64 [[COND]]
129 ; GENERIC-LABEL: @test1b(
130 ; GENERIC-NEXT:  entry:
131 ; GENERIC-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[A:%.*]], 0
132 ; GENERIC-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[A]], i1 true)
133 ; GENERIC-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 64, i64 [[TMP0]]
134 ; GENERIC-NEXT:    ret i64 [[COND]]
136 entry:
137   %tobool = icmp eq i64 %A, 0
138   br i1 %tobool, label %cond.end, label %cond.true
140 cond.true:                                        ; preds = %entry
141   %0 = tail call i64 @llvm.cttz.i64(i64 %A, i1 true)
142   br label %cond.end
144 cond.end:                                         ; preds = %entry, %cond.true
145   %cond = phi i64 [ %0, %cond.true ], [ 64, %entry ]
146   ret i64 %cond
150 define i32 @test2b(i32 %A) {
151 ; BMI-LABEL: @test2b(
152 ; BMI-NEXT:  entry:
153 ; BMI-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
154 ; BMI-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[A]], i1 true)
155 ; BMI-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
156 ; BMI-NEXT:    ret i32 [[SPEC_SELECT]]
158 ; LZCNT-LABEL: @test2b(
159 ; LZCNT-NEXT:  entry:
160 ; LZCNT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
161 ; LZCNT-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[A]], i1 true)
162 ; LZCNT-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
163 ; LZCNT-NEXT:    ret i32 [[COND]]
165 ; GENERIC-LABEL: @test2b(
166 ; GENERIC-NEXT:  entry:
167 ; GENERIC-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
168 ; GENERIC-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[A]], i1 true)
169 ; GENERIC-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 32, i32 [[TMP0]]
170 ; GENERIC-NEXT:    ret i32 [[COND]]
172 entry:
173   %tobool = icmp eq i32 %A, 0
174   br i1 %tobool, label %cond.end, label %cond.true
176 cond.true:                                        ; preds = %entry
177   %0 = tail call i32 @llvm.cttz.i32(i32 %A, i1 true)
178   br label %cond.end
180 cond.end:                                         ; preds = %entry, %cond.true
181   %cond = phi i32 [ %0, %cond.true ], [ 32, %entry ]
182   ret i32 %cond
186 define signext i16 @test3b(i16 signext %A) {
187 ; BMI-LABEL: @test3b(
188 ; BMI-NEXT:  entry:
189 ; BMI-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
190 ; BMI-NEXT:    [[TMP0:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[A]], i1 true)
191 ; BMI-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
192 ; BMI-NEXT:    ret i16 [[SPEC_SELECT]]
194 ; LZCNT-LABEL: @test3b(
195 ; LZCNT-NEXT:  entry:
196 ; LZCNT-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
197 ; LZCNT-NEXT:    [[TMP0:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[A]], i1 true)
198 ; LZCNT-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
199 ; LZCNT-NEXT:    ret i16 [[COND]]
201 ; GENERIC-LABEL: @test3b(
202 ; GENERIC-NEXT:  entry:
203 ; GENERIC-NEXT:    [[TOBOOL:%.*]] = icmp eq i16 [[A:%.*]], 0
204 ; GENERIC-NEXT:    [[TMP0:%.*]] = tail call i16 @llvm.cttz.i16(i16 [[A]], i1 true)
205 ; GENERIC-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i16 16, i16 [[TMP0]]
206 ; GENERIC-NEXT:    ret i16 [[COND]]
208 entry:
209   %tobool = icmp eq i16 %A, 0
210   br i1 %tobool, label %cond.end, label %cond.true
212 cond.true:                                        ; preds = %entry
213   %0 = tail call i16 @llvm.cttz.i16(i16 %A, i1 true)
214   br label %cond.end
216 cond.end:                                         ; preds = %entry, %cond.true
217   %cond = phi i16 [ %0, %cond.true ], [ 16, %entry ]
218   ret i16 %cond
221 ; The following tests verify that calls to cttz/ctlz are speculated even if
222 ; basic block %cond.true has an extra zero extend/truncate which is "free"
223 ; for the target.
225 define i64 @test1e(i32 %x) {
226 ; ALL-LABEL: @test1e(
227 ; ALL-NEXT:  entry:
228 ; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
229 ; ALL-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true)
230 ; ALL-NEXT:    [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64
231 ; ALL-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 32, i64 [[PHITMP2]]
232 ; ALL-NEXT:    ret i64 [[COND]]
234 entry:
235   %tobool = icmp eq i32 %x, 0
236   br i1 %tobool, label %cond.end, label %cond.true
238 cond.true:                                        ; preds = %entry
239   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
240   %phitmp2 = zext i32 %0 to i64
241   br label %cond.end
243 cond.end:                                         ; preds = %entry, %cond.true
244   %cond = phi i64 [ %phitmp2, %cond.true ], [ 32, %entry ]
245   ret i64 %cond
248 define i32 @test2e(i64 %x) {
249 ; ALL-LABEL: @test2e(
250 ; ALL-NEXT:  entry:
251 ; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
252 ; ALL-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true)
253 ; ALL-NEXT:    [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
254 ; ALL-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]
255 ; ALL-NEXT:    ret i32 [[COND]]
257 entry:
258   %tobool = icmp eq i64 %x, 0
259   br i1 %tobool, label %cond.end, label %cond.true
261 cond.true:                                        ; preds = %entry
262   %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
263   %cast = trunc i64 %0 to i32
264   br label %cond.end
266 cond.end:                                         ; preds = %entry, %cond.true
267   %cond = phi i32 [ %cast, %cond.true ], [ 64, %entry ]
268   ret i32 %cond
271 define i64 @test3e(i32 %x) {
272 ; ALL-LABEL: @test3e(
273 ; ALL-NEXT:  entry:
274 ; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
275 ; ALL-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
276 ; ALL-NEXT:    [[PHITMP2:%.*]] = zext i32 [[TMP0]] to i64
277 ; ALL-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i64 32, i64 [[PHITMP2]]
278 ; ALL-NEXT:    ret i64 [[COND]]
280 entry:
281   %tobool = icmp eq i32 %x, 0
282   br i1 %tobool, label %cond.end, label %cond.true
284 cond.true:                                        ; preds = %entry
285   %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
286   %phitmp2 = zext i32 %0 to i64
287   br label %cond.end
289 cond.end:                                         ; preds = %entry, %cond.true
290   %cond = phi i64 [ %phitmp2, %cond.true ], [ 32, %entry ]
291   ret i64 %cond
294 define i32 @test4e(i64 %x) {
295 ; ALL-LABEL: @test4e(
296 ; ALL-NEXT:  entry:
297 ; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
298 ; ALL-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
299 ; ALL-NEXT:    [[CAST:%.*]] = trunc i64 [[TMP0]] to i32
300 ; ALL-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i32 64, i32 [[CAST]]
301 ; ALL-NEXT:    ret i32 [[COND]]
303 entry:
304   %tobool = icmp eq i64 %x, 0
305   br i1 %tobool, label %cond.end, label %cond.true
307 cond.true:                                        ; preds = %entry
308   %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
309   %cast = trunc i64 %0 to i32
310   br label %cond.end
312 cond.end:                                         ; preds = %entry, %cond.true
313   %cond = phi i32 [ %cast, %cond.true ], [ 64, %entry ]
314   ret i32 %cond
317 define i16 @test5e(i64 %x) {
318 ; ALL-LABEL: @test5e(
319 ; ALL-NEXT:  entry:
320 ; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
321 ; ALL-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.ctlz.i64(i64 [[X]], i1 true)
322 ; ALL-NEXT:    [[CAST:%.*]] = trunc i64 [[TMP0]] to i16
323 ; ALL-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i16 64, i16 [[CAST]]
324 ; ALL-NEXT:    ret i16 [[COND]]
326 entry:
327   %tobool = icmp eq i64 %x, 0
328   br i1 %tobool, label %cond.end, label %cond.true
330 cond.true:                                        ; preds = %entry
331   %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
332   %cast = trunc i64 %0 to i16
333   br label %cond.end
335 cond.end:                                         ; preds = %entry, %cond.true
336   %cond = phi i16 [ %cast, %cond.true ], [ 64, %entry ]
337   ret i16 %cond
340 define i16 @test6e(i32 %x) {
341 ; ALL-LABEL: @test6e(
342 ; ALL-NEXT:  entry:
343 ; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
344 ; ALL-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.ctlz.i32(i32 [[X]], i1 true)
345 ; ALL-NEXT:    [[CAST:%.*]] = trunc i32 [[TMP0]] to i16
346 ; ALL-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i16 32, i16 [[CAST]]
347 ; ALL-NEXT:    ret i16 [[COND]]
349 entry:
350   %tobool = icmp eq i32 %x, 0
351   br i1 %tobool, label %cond.end, label %cond.true
353 cond.true:                                        ; preds = %entry
354   %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
355   %cast = trunc i32 %0 to i16
356   br label %cond.end
358 cond.end:                                         ; preds = %entry, %cond.true
359   %cond = phi i16 [ %cast, %cond.true ], [ 32, %entry ]
360   ret i16 %cond
363 define i16 @test7e(i64 %x) {
364 ; ALL-LABEL: @test7e(
365 ; ALL-NEXT:  entry:
366 ; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i64 [[X:%.*]], 0
367 ; ALL-NEXT:    [[TMP0:%.*]] = tail call i64 @llvm.cttz.i64(i64 [[X]], i1 true)
368 ; ALL-NEXT:    [[CAST:%.*]] = trunc i64 [[TMP0]] to i16
369 ; ALL-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i16 64, i16 [[CAST]]
370 ; ALL-NEXT:    ret i16 [[COND]]
372 entry:
373   %tobool = icmp eq i64 %x, 0
374   br i1 %tobool, label %cond.end, label %cond.true
376 cond.true:                                        ; preds = %entry
377   %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
378   %cast = trunc i64 %0 to i16
379   br label %cond.end
381 cond.end:                                         ; preds = %entry, %cond.true
382   %cond = phi i16 [ %cast, %cond.true ], [ 64, %entry ]
383   ret i16 %cond
386 define i16 @test8e(i32 %x) {
387 ; ALL-LABEL: @test8e(
388 ; ALL-NEXT:  entry:
389 ; ALL-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[X:%.*]], 0
390 ; ALL-NEXT:    [[TMP0:%.*]] = tail call i32 @llvm.cttz.i32(i32 [[X]], i1 true)
391 ; ALL-NEXT:    [[CAST:%.*]] = trunc i32 [[TMP0]] to i16
392 ; ALL-NEXT:    [[COND:%.*]] = select i1 [[TOBOOL]], i16 32, i16 [[CAST]]
393 ; ALL-NEXT:    ret i16 [[COND]]
395 entry:
396   %tobool = icmp eq i32 %x, 0
397   br i1 %tobool, label %cond.end, label %cond.true
399 cond.true:                                        ; preds = %entry
400   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
401   %cast = trunc i32 %0 to i16
402   br label %cond.end
404 cond.end:                                         ; preds = %entry, %cond.true
405   %cond = phi i16 [ %cast, %cond.true ], [ 32, %entry ]
406   ret i16 %cond
410 declare i64 @llvm.ctlz.i64(i64, i1)
411 declare i32 @llvm.ctlz.i32(i32, i1)
412 declare i16 @llvm.ctlz.i16(i16, i1)
413 declare i64 @llvm.cttz.i64(i64, i1)
414 declare i32 @llvm.cttz.i32(i32, i1)
415 declare i16 @llvm.cttz.i16(i16, i1)