[InstCombine] Fix regression introduced at r227197.
[oota-llvm.git] / test / Transforms / InstCombine / select-cmp-cttz-ctlz.ll
1 ; RUN: opt -instcombine -S < %s | FileCheck %s
2
3 ; This test is to verify that the instruction combiner is able to fold
4 ; a cttz/ctlz followed by a icmp + select into a single cttz/ctlz with
5 ; the 'is_zero_undef' flag cleared.
6
7 define i16 @test1(i16 %x) {
8 ; CHECK-LABEL: @test1(
9 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
10 ; CHECK-NEXT: ret i16 [[VAR]]
11 entry:
12   %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
13   %tobool = icmp ne i16 %x, 0
14   %cond = select i1 %tobool, i16 %0, i16 16
15   ret i16 %cond
16 }
17
18 define i32 @test2(i32 %x) {
19 ; CHECK-LABEL: @test2(
20 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
21 ; CHECK-NEXT: ret i32 [[VAR]]
22 entry:
23   %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
24   %tobool = icmp ne i32 %x, 0
25   %cond = select i1 %tobool, i32 %0, i32 32
26   ret i32 %cond
27 }
28
29 define i64 @test3(i64 %x) {
30 ; CHECK-LABEL: @test3(
31 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
32 ; CHECK-NEXT: ret i64 [[VAR]]
33 entry:
34   %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
35   %tobool = icmp ne i64 %x, 0
36   %cond = select i1 %tobool, i64 %0, i64 64
37   ret i64 %cond
38 }
39
40 define i16 @test4(i16 %x) {
41 ; CHECK-LABEL: @test4(
42 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
43 ; CHECK-NEXT: ret i16 [[VAR]]
44 entry:
45   %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
46   %tobool = icmp eq i16 %x, 0
47   %cond = select i1 %tobool, i16 16, i16 %0
48   ret i16 %cond
49 }
50
51 define i32 @test5(i32 %x) {
52 ; CHECK-LABEL: @test5(
53 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
54 ; CHECK-NEXT: ret i32 [[VAR]]
55 entry:
56   %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
57   %tobool = icmp eq i32 %x, 0
58   %cond = select i1 %tobool, i32 32, i32 %0
59   ret i32 %cond
60 }
61
62 define i64 @test6(i64 %x) {
63 ; CHECK-LABEL: @test6(
64 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
65 ; CHECK-NEXT: ret i64 [[VAR]]
66 entry:
67   %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
68   %tobool = icmp eq i64 %x, 0
69   %cond = select i1 %tobool, i64 64, i64 %0
70   ret i64 %cond
71 }
72
73 define i16 @test1b(i16 %x) {
74 ; CHECK-LABEL: @test1b(
75 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
76 ; CHECK-NEXT: ret i16 [[VAR]]
77 entry:
78   %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
79   %tobool = icmp ne i16 %x, 0
80   %cond = select i1 %tobool, i16 %0, i16 16
81   ret i16 %cond
82 }
83
84 define i32 @test2b(i32 %x) {
85 ; CHECK-LABEL: @test2b(
86 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
87 ; CHECK-NEXT: ret i32 [[VAR]]
88 entry:
89   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
90   %tobool = icmp ne i32 %x, 0
91   %cond = select i1 %tobool, i32 %0, i32 32
92   ret i32 %cond
93 }
94
95 define i64 @test3b(i64 %x) {
96 ; CHECK-LABEL: @test3b(
97 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
98 ; CHECK-NEXT: ret i64 [[VAR]]
99 entry:
100   %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
101   %tobool = icmp ne i64 %x, 0
102   %cond = select i1 %tobool, i64 %0, i64 64
103   ret i64 %cond
104 }
105
106 define i16 @test4b(i16 %x) {
107 ; CHECK-LABEL: @test4b(
108 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
109 ; CHECK-NEXT: ret i16 [[VAR]]
110 entry:
111   %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
112   %tobool = icmp eq i16 %x, 0
113   %cond = select i1 %tobool, i16 16, i16 %0
114   ret i16 %cond
115 }
116
117 define i32 @test5b(i32 %x) {
118 ; CHECK-LABEL: @test5b(
119 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
120 ; CHECK-NEXT: ret i32 [[VAR]]
121 entry:
122   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
123   %tobool = icmp eq i32 %x, 0
124   %cond = select i1 %tobool, i32 32, i32 %0
125   ret i32 %cond
126 }
127
128 define i64 @test6b(i64 %x) {
129 ; CHECK-LABEL: @test6b(
130 ; CHECK: [[VAR:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
131 ; CHECK-NEXT: ret i64 [[VAR]]
132 entry:
133   %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
134   %tobool = icmp eq i64 %x, 0
135   %cond = select i1 %tobool, i64 64, i64 %0
136   ret i64 %cond
137 }
138
139 define i32 @test1c(i16 %x) {
140 ; CHECK-LABEL: @test1c(
141 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
142 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i32
143 ; CHECK-NEXT: ret i32 [[VAR2]]
144 entry:
145   %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
146   %cast2 = zext i16 %0 to i32
147   %tobool = icmp ne i16 %x, 0
148   %cond = select i1 %tobool, i32 %cast2, i32 16
149   ret i32 %cond
150 }
151
152 define i64 @test2c(i16 %x) {
153 ; CHECK-LABEL: @test2c(
154 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.cttz.i16(i16 %x, i1 false)
155 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i64
156 ; CHECK-NEXT: ret i64 [[VAR2]]
157 entry:
158   %0 = tail call i16 @llvm.cttz.i16(i16 %x, i1 true)
159   %conv = zext i16 %0 to i64
160   %tobool = icmp ne i16 %x, 0
161   %cond = select i1 %tobool, i64 %conv, i64 16
162   ret i64 %cond
163 }
164
165 define i64 @test3c(i32 %x) {
166 ; CHECK-LABEL: @test3c(
167 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
168 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
169 ; CHECK-NEXT: ret i64 [[VAR2]]
170 entry:
171   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
172   %conv = zext i32 %0 to i64
173   %tobool = icmp ne i32 %x, 0
174   %cond = select i1 %tobool, i64 %conv, i64 32
175   ret i64 %cond
176 }
177
178 define i32 @test4c(i16 %x) {
179 ; CHECK-LABEL: @test4c(
180 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
181 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i32
182 ; CHECK-NEXT: ret i32 [[VAR2]]
183 entry:
184   %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
185   %cast = zext i16 %0 to i32
186   %tobool = icmp ne i16 %x, 0
187   %cond = select i1 %tobool, i32 %cast, i32 16
188   ret i32 %cond
189 }
190
191 define i64 @test5c(i16 %x) {
192 ; CHECK-LABEL: @test5c(
193 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i16 @llvm.ctlz.i16(i16 %x, i1 false)
194 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i16 [[VAR1]] to i64
195 ; CHECK-NEXT: ret i64 [[VAR2]]
196 entry:
197   %0 = tail call i16 @llvm.ctlz.i16(i16 %x, i1 true)
198   %cast = zext i16 %0 to i64
199   %tobool = icmp ne i16 %x, 0
200   %cond = select i1 %tobool, i64 %cast, i64 16
201   ret i64 %cond
202 }
203
204 define i64 @test6c(i32 %x) {
205 ; CHECK-LABEL: @test6c(
206 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
207 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
208 ; CHECK-NEXT: ret i64 [[VAR2]]
209 entry:
210   %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
211   %cast = zext i32 %0 to i64
212   %tobool = icmp ne i32 %x, 0
213   %cond = select i1 %tobool, i64 %cast, i64 32
214   ret i64 %cond
215 }
216
217 define i16 @test1d(i64 %x) {
218 ; CHECK-LABEL: @test1d(
219 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
220 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i16
221 ; CHECK-NEXT: ret i16 [[VAR2]]
222 entry:
223   %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
224   %conv = trunc i64 %0 to i16
225   %tobool = icmp ne i64 %x, 0
226   %cond = select i1 %tobool, i16 %conv, i16 64
227   ret i16 %cond
228 }
229
230 define i32 @test2d(i64 %x) {
231 ; CHECK-LABEL: @test2d(
232 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %x, i1 false)
233 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i32
234 ; CHECK-NEXT: ret i32 [[VAR2]]
235 entry:
236   %0 = tail call i64 @llvm.cttz.i64(i64 %x, i1 true)
237   %cast = trunc i64 %0 to i32
238   %tobool = icmp ne i64 %x, 0
239   %cond = select i1 %tobool, i32 %cast, i32 64
240   ret i32 %cond
241 }
242
243 define i16 @test3d(i32 %x) {
244 ; CHECK-LABEL: @test3d(
245 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
246 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
247 ; CHECK-NEXT: ret i16 [[VAR2]]
248 entry:
249   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
250   %cast = trunc i32 %0 to i16
251   %tobool = icmp ne i32 %x, 0
252   %cond = select i1 %tobool, i16 %cast, i16 32
253   ret i16 %cond
254 }
255
256 define i16 @test4d(i64 %x) {
257 ; CHECK-LABEL: @test4d(
258 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
259 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i16
260 ; CHECK-NEXT: ret i16 [[VAR2]]
261 entry:
262   %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
263   %cast = trunc i64 %0 to i16
264   %tobool = icmp ne i64 %x, 0
265   %cond = select i1 %tobool, i16 %cast, i16 64
266   ret i16 %cond
267 }
268
269 define i32 @test5d(i64 %x) {
270 ; CHECK-LABEL: @test5d(
271 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %x, i1 false)
272 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i64 [[VAR1]] to i32
273 ; CHECK-NEXT: ret i32 [[VAR2]]
274 entry:
275   %0 = tail call i64 @llvm.ctlz.i64(i64 %x, i1 true)
276   %cast = trunc i64 %0 to i32
277   %tobool = icmp ne i64 %x, 0
278   %cond = select i1 %tobool, i32 %cast, i32 64
279   ret i32 %cond
280 }
281
282 define i16 @test6d(i32 %x) {
283 ; CHECK-LABEL: @test6d(
284 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %x, i1 false)
285 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
286 ; CHECK-NEXT: ret i16 [[VAR2]]
287 entry:
288   %0 = tail call i32 @llvm.ctlz.i32(i32 %x, i1 true)
289   %cast = trunc i32 %0 to i16
290   %tobool = icmp ne i32 %x, 0
291   %cond = select i1 %tobool, i16 %cast, i16 32
292   ret i16 %cond
293 }
294
295 define i64 @select_bug1(i32 %x) {
296 ; CHECK-LABEL: @select_bug1(
297 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
298 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = zext i32 [[VAR1]] to i64
299 ; CHECK-NEXT: ret i64 [[VAR2]]
300 entry:
301   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
302   %conv = zext i32 %0 to i64
303   %tobool = icmp ne i32 %x, 0
304   %cond = select i1 %tobool, i64 %conv, i64 32
305   ret i64 %cond
306 }
307
308 define i16 @select_bug2(i32 %x) {
309 ; CHECK-LABEL: @select_bug2(
310 ; CHECK: [[VAR1:%[a-zA-Z0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
311 ; CHECK-NEXT: [[VAR2:%[a-zA-Z0-9]+]] = trunc i32 [[VAR1]] to i16
312 ; CHECK-NEXT: ret i16 [[VAR2]]
313 entry:
314   %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
315   %conv = trunc i32 %0 to i16
316   %tobool = icmp ne i32 %x, 0
317   %cond = select i1 %tobool, i16 %conv, i16 32
318   ret i16 %cond
319 }
320
321
322 declare i16 @llvm.ctlz.i16(i16, i1)
323 declare i32 @llvm.ctlz.i32(i32, i1)
324 declare i64 @llvm.ctlz.i64(i64, i1)
325 declare i16 @llvm.cttz.i16(i16, i1)
326 declare i32 @llvm.cttz.i32(i32, i1)
327 declare i64 @llvm.cttz.i64(i64, i1)