1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instcombine -S < %s | FileCheck %s
3
4declare double @llvm.powi.f64(double, i32) nounwind readonly
5declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
6declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone
7declare i1 @llvm.cttz.i1(i1, i1) nounwind readnone
8declare i1 @llvm.ctlz.i1(i1, i1) nounwind readnone
9declare i32 @llvm.ctpop.i32(i32) nounwind readnone
10declare <2 x i32> @llvm.cttz.v2i32(<2 x i32>, i1) nounwind readnone
11declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1) nounwind readnone
12declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>) nounwind readnone
13declare i8 @llvm.ctlz.i8(i8, i1) nounwind readnone
14declare <2 x i8> @llvm.ctlz.v2i8(<2 x i8>, i1) nounwind readnone
15declare double @llvm.cos.f64(double %Val) nounwind readonly
16declare double @llvm.sin.f64(double %Val) nounwind readonly
17declare double @llvm.floor.f64(double %Val) nounwind readonly
18declare double @llvm.ceil.f64(double %Val) nounwind readonly
19declare double @llvm.trunc.f64(double %Val) nounwind readonly
20declare double @llvm.rint.f64(double %Val) nounwind readonly
21declare double @llvm.nearbyint.f64(double %Val) nounwind readonly
22
23define void @powi(double %V, double *%P) {
24  %A = tail call double @llvm.powi.f64(double %V, i32 -1) nounwind
25  store volatile double %A, double* %P
26
27  %D = tail call double @llvm.powi.f64(double %V, i32 2) nounwind
28  store volatile double %D, double* %P
29  ret void
30; CHECK-LABEL: @powi(
31; CHECK: %A = fdiv double 1.0{{.*}}, %V
32; CHECK: store volatile double %A,
33; CHECK: %D = fmul double %V, %V
34; CHECK: store volatile double %D
35}
36
37define i32 @cttz(i32 %a) {
38; CHECK-LABEL: @cttz(
39; CHECK-NEXT:    ret i32 3
40;
41  %or = or i32 %a, 8
42  %and = and i32 %or, -8
43  %count = tail call i32 @llvm.cttz.i32(i32 %and, i1 true) nounwind readnone
44  ret i32 %count
45}
46
47define <2 x i32> @cttz_vec(<2 x i32> %a) {
48; CHECK-LABEL: @cttz_vec(
49; CHECK-NEXT:    ret <2 x i32> <i32 3, i32 3>
50;
51  %or = or <2 x i32> %a, <i32 8, i32 8>
52  %and = and <2 x i32> %or, <i32 -8, i32 -8>
53  %count = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %and, i1 true) nounwind readnone
54  ret <2 x i32> %count
55}
56
57; Make sure we don't add range metadata to i1 cttz.
58define i1 @cttz_i1(i1 %arg) {
59; CHECK-LABEL: @cttz_i1(
60; CHECK-NEXT:    [[CNT:%.*]] = call i1 @llvm.cttz.i1(i1 [[ARG:%.*]], i1 false) #2
61; CHECK-NEXT:    ret i1 [[CNT]]
62;
63  %cnt = call i1 @llvm.cttz.i1(i1 %arg, i1 false) nounwind readnone
64  ret i1 %cnt
65}
66
67define i1 @cttz_knownbits(i32 %arg) {
68; CHECK-LABEL: @cttz_knownbits(
69; CHECK-NEXT:    ret i1 false
70;
71  %or = or i32 %arg, 4
72  %cnt = call i32 @llvm.cttz.i32(i32 %or, i1 true) nounwind readnone
73  %res = icmp eq i32 %cnt, 4
74  ret i1 %res
75}
76
77define <2 x i1> @cttz_knownbits_vec(<2 x i32> %arg) {
78; CHECK-LABEL: @cttz_knownbits_vec(
79; CHECK-NEXT:    ret <2 x i1> zeroinitializer
80;
81  %or = or <2 x i32> %arg, <i32 4, i32 4>
82  %cnt = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %or, i1 true) nounwind readnone
83  %res = icmp eq <2 x i32> %cnt, <i32 4, i32 4>
84  ret <2 x i1> %res
85}
86
87define i32 @cttz_knownbits2(i32 %arg) {
88; CHECK-LABEL: @cttz_knownbits2(
89; CHECK-NEXT:    [[OR:%.*]] = or i32 [[ARG:%.*]], 4
90; CHECK-NEXT:    [[CNT:%.*]] = call i32 @llvm.cttz.i32(i32 [[OR]], i1 true) #2, !range ![[$CTTZ_RANGE:[0-9]+]]
91; CHECK-NEXT:    ret i32 [[CNT]]
92;
93  %or = or i32 %arg, 4
94  %cnt = call i32 @llvm.cttz.i32(i32 %or, i1 true) nounwind readnone
95  ret i32 %cnt
96}
97
98define <2 x i32> @cttz_knownbits2_vec(<2 x i32> %arg) {
99; CHECK-LABEL: @cttz_knownbits2_vec(
100; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[ARG:%.*]], <i32 4, i32 4>
101; CHECK-NEXT:    [[CNT:%.*]] = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[OR]], i1 true)
102; CHECK-NEXT:    ret <2 x i32> [[CNT]]
103;
104  %or = or <2 x i32> %arg, <i32 4, i32 4>
105  %cnt = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %or, i1 true) nounwind readnone
106  ret <2 x i32> %cnt
107}
108
109define i1 @cttz_knownbits3(i32 %arg) {
110; CHECK-LABEL: @cttz_knownbits3(
111; CHECK-NEXT:    ret i1 false
112;
113  %or = or i32 %arg, 4
114  %cnt = call i32 @llvm.cttz.i32(i32 %or, i1 true) nounwind readnone
115  %res = icmp eq i32 %cnt, 3
116  ret i1 %res
117}
118
119define <2 x i1> @cttz_knownbits3_vec(<2 x i32> %arg) {
120; CHECK-LABEL: @cttz_knownbits3_vec(
121; CHECK-NEXT:    ret <2 x i1> zeroinitializer
122;
123  %or = or <2 x i32> %arg, <i32 4, i32 4>
124  %cnt = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %or, i1 true) nounwind readnone
125  %res = icmp eq <2 x i32> %cnt, <i32 3, i32 3>
126  ret <2 x i1> %res
127}
128
129define i8 @ctlz(i8 %a) {
130; CHECK-LABEL: @ctlz(
131; CHECK-NEXT:    ret i8 2
132;
133  %or = or i8 %a, 32
134  %and = and i8 %or, 63
135  %count = tail call i8 @llvm.ctlz.i8(i8 %and, i1 true) nounwind readnone
136  ret i8 %count
137}
138
139define <2 x i8> @ctlz_vec(<2 x i8> %a) {
140; CHECK-LABEL: @ctlz_vec(
141; CHECK-NEXT:    ret <2 x i8> <i8 2, i8 2>
142;
143  %or = or <2 x i8> %a, <i8 32, i8 32>
144  %and = and <2 x i8> %or, <i8 63, i8 63>
145  %count = tail call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %and, i1 true) nounwind readnone
146  ret <2 x i8> %count
147}
148
149; Make sure we don't add range metadata to i1 ctlz.
150define i1 @ctlz_i1(i1 %arg) {
151; CHECK-LABEL: @ctlz_i1(
152; CHECK-NEXT:    [[CNT:%.*]] = call i1 @llvm.ctlz.i1(i1 [[ARG:%.*]], i1 false) #2
153; CHECK-NEXT:    ret i1 [[CNT]]
154;
155  %cnt = call i1 @llvm.ctlz.i1(i1 %arg, i1 false) nounwind readnone
156  ret i1 %cnt
157}
158
159define i1 @ctlz_knownbits(i8 %arg) {
160; CHECK-LABEL: @ctlz_knownbits(
161; CHECK-NEXT:    ret i1 false
162;
163  %or = or i8 %arg, 32
164  %cnt = call i8 @llvm.ctlz.i8(i8 %or, i1 true) nounwind readnone
165  %res = icmp eq i8 %cnt, 4
166  ret i1 %res
167}
168
169define <2 x i1> @ctlz_knownbits_vec(<2 x i8> %arg) {
170; CHECK-LABEL: @ctlz_knownbits_vec(
171; CHECK-NEXT:    ret <2 x i1> zeroinitializer
172;
173  %or = or <2 x i8> %arg, <i8 32, i8 32>
174  %cnt = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %or, i1 true) nounwind readnone
175  %res = icmp eq <2 x i8> %cnt, <i8 4, i8 4>
176  ret <2 x i1> %res
177}
178
179define i8 @ctlz_knownbits2(i8 %arg) {
180; CHECK-LABEL: @ctlz_knownbits2(
181; CHECK-NEXT:    [[OR:%.*]] = or i8 [[ARG:%.*]], 32
182; CHECK-NEXT:    [[CNT:%.*]] = call i8 @llvm.ctlz.i8(i8 [[OR]], i1 true) #2, !range ![[$CTLZ_RANGE:[0-9]+]]
183; CHECK-NEXT:    ret i8 [[CNT]]
184;
185  %or = or i8 %arg, 32
186  %cnt = call i8 @llvm.ctlz.i8(i8 %or, i1 true) nounwind readnone
187  ret i8 %cnt
188}
189
190define <2 x i8> @ctlz_knownbits2_vec(<2 x i8> %arg) {
191; CHECK-LABEL: @ctlz_knownbits2_vec(
192; CHECK-NEXT:    [[OR:%.*]] = or <2 x i8> [[ARG:%.*]], <i8 32, i8 32>
193; CHECK-NEXT:    [[CNT:%.*]] = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> [[OR]], i1 true)
194; CHECK-NEXT:    ret <2 x i8> [[CNT]]
195;
196  %or = or <2 x i8> %arg, <i8 32, i8 32>
197  %cnt = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %or, i1 true) nounwind readnone
198  ret <2 x i8> %cnt
199}
200
201define i1 @ctlz_knownbits3(i8 %arg) {
202; CHECK-LABEL: @ctlz_knownbits3(
203; CHECK-NEXT:    ret i1 false
204;
205  %or = or i8 %arg, 32
206  %cnt = call i8 @llvm.ctlz.i8(i8 %or, i1 true) nounwind readnone
207  %res = icmp eq i8 %cnt, 3
208  ret i1 %res
209}
210
211define <2 x i1> @ctlz_knownbits3_vec(<2 x i8> %arg) {
212; CHECK-LABEL: @ctlz_knownbits3_vec(
213; CHECK-NEXT:    ret <2 x i1> zeroinitializer
214;
215  %or = or <2 x i8> %arg, <i8 32, i8 32>
216  %cnt = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %or, i1 true) nounwind readnone
217  %res = icmp eq <2 x i8> %cnt, <i8 3, i8 3>
218  ret <2 x i1> %res
219}
220
221define i32 @ctlz_undef(i32 %Value) {
222; CHECK-LABEL: @ctlz_undef(
223; CHECK-NEXT:    ret i32 undef
224;
225  %ctlz = call i32 @llvm.ctlz.i32(i32 0, i1 true)
226  ret i32 %ctlz
227}
228
229define <2 x i32> @ctlz_undef_vec(<2 x i32> %Value) {
230; CHECK-LABEL: @ctlz_undef_vec(
231; CHECK-NEXT:    ret <2 x i32> undef
232;
233  %ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> zeroinitializer, i1 true)
234  ret <2 x i32> %ctlz
235}
236
237define i32 @ctlz_make_undef(i32 %a) {
238  %or = or i32 %a, 8
239  %ctlz = tail call i32 @llvm.ctlz.i32(i32 %or, i1 false)
240  ret i32 %ctlz
241; CHECK-LABEL: @ctlz_make_undef(
242; CHECK-NEXT: %or = or i32 %a, 8
243; CHECK-NEXT: %ctlz = tail call i32 @llvm.ctlz.i32(i32 %or, i1 true)
244; CHECK-NEXT: ret i32 %ctlz
245}
246
247define <2 x i32> @ctlz_make_undef_vec(<2 x i32> %a) {
248; CHECK-LABEL: @ctlz_make_undef_vec(
249; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
250; CHECK-NEXT:    [[CTLZ:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[OR]], i1 true)
251; CHECK-NEXT:    ret <2 x i32> [[CTLZ]]
252;
253  %or = or <2 x i32> %a, <i32 8, i32 8>
254  %ctlz = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %or, i1 false)
255  ret <2 x i32> %ctlz
256}
257
258define i32 @cttz_undef(i32 %Value) nounwind {
259; CHECK-LABEL: @cttz_undef(
260; CHECK-NEXT:    ret i32 undef
261;
262  %cttz = call i32 @llvm.cttz.i32(i32 0, i1 true)
263  ret i32 %cttz
264}
265
266define <2 x i32> @cttz_undef_vec(<2 x i32> %Value) nounwind {
267; CHECK-LABEL: @cttz_undef_vec(
268; CHECK-NEXT:    ret <2 x i32> undef
269;
270  %cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> zeroinitializer, i1 true)
271  ret <2 x i32> %cttz
272}
273
274define i32 @cttz_make_undef(i32 %a) {
275  %or = or i32 %a, 8
276  %cttz = tail call i32 @llvm.cttz.i32(i32 %or, i1 false)
277  ret i32 %cttz
278; CHECK-LABEL: @cttz_make_undef(
279; CHECK-NEXT: %or = or i32 %a, 8
280; CHECK-NEXT: %cttz = tail call i32 @llvm.cttz.i32(i32 %or, i1 true)
281; CHECK-NEXT: ret i32 %cttz
282}
283
284define <2 x i32> @cttz_make_undef_vec(<2 x i32> %a) {
285; CHECK-LABEL: @cttz_make_undef_vec(
286; CHECK-NEXT:    [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
287; CHECK-NEXT:    [[CTTZ:%.*]] = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[OR]], i1 true)
288; CHECK-NEXT:    ret <2 x i32> [[CTTZ]]
289;
290  %or = or <2 x i32> %a, <i32 8, i32 8>
291  %cttz = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %or, i1 false)
292  ret <2 x i32> %cttz
293}
294
295define i32 @ctlz_select(i32 %Value) nounwind {
296; CHECK-LABEL: @ctlz_select(
297; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.ctlz.i32(i32 %Value, i1 false)
298; CHECK-NEXT:    ret i32 [[TMP1]]
299;
300  %tobool = icmp ne i32 %Value, 0
301  %ctlz = call i32 @llvm.ctlz.i32(i32 %Value, i1 true)
302  %s = select i1 %tobool, i32 %ctlz, i32 32
303  ret i32 %s
304}
305
306define <2 x i32> @ctlz_select_vec(<2 x i32> %Value) nounwind {
307; CHECK-LABEL: @ctlz_select_vec(
308; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[VALUE:%.*]], i1 false)
309; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
310;
311  %tobool = icmp ne <2 x i32> %Value, zeroinitializer
312  %ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %Value, i1 true)
313  %s = select <2 x i1> %tobool, <2 x i32> %ctlz, <2 x i32> <i32 32, i32 32>
314  ret <2 x i32> %s
315}
316
317define i32 @cttz_select(i32 %Value) nounwind {
318; CHECK-LABEL: @cttz_select(
319; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.cttz.i32(i32 %Value, i1 false)
320; CHECK-NEXT:    ret i32 [[TMP1]]
321;
322  %tobool = icmp ne i32 %Value, 0
323  %cttz = call i32 @llvm.cttz.i32(i32 %Value, i1 true)
324  %s = select i1 %tobool, i32 %cttz, i32 32
325  ret i32 %s
326}
327
328define <2 x i32> @cttz_select_vec(<2 x i32> %Value) nounwind {
329; CHECK-LABEL: @cttz_select_vec(
330; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[VALUE:%.*]], i1 false)
331; CHECK-NEXT:    ret <2 x i32> [[TMP1]]
332;
333  %tobool = icmp ne <2 x i32> %Value, zeroinitializer
334  %cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %Value, i1 true)
335  %s = select <2 x i1> %tobool, <2 x i32> %cttz, <2 x i32> <i32 32, i32 32>
336  ret <2 x i32> %s
337}
338
339define void @cos(double *%P) {
340; CHECK-LABEL: @cos(
341; CHECK-NEXT:    store volatile double 1.000000e+00, double* %P, align 8
342; CHECK-NEXT:    ret void
343;
344  %B = tail call double @llvm.cos.f64(double 0.0) nounwind
345  store volatile double %B, double* %P
346
347  ret void
348}
349
350define void @sin(double *%P) {
351; CHECK-LABEL: @sin(
352; CHECK-NEXT:    store volatile double 0.000000e+00, double* %P, align 8
353; CHECK-NEXT:    ret void
354;
355  %B = tail call double @llvm.sin.f64(double 0.0) nounwind
356  store volatile double %B, double* %P
357
358  ret void
359}
360
361define void @floor(double *%P) {
362; CHECK-LABEL: @floor(
363; CHECK-NEXT:    store volatile double 1.000000e+00, double* %P, align 8
364; CHECK-NEXT:    store volatile double -2.000000e+00, double* %P, align 8
365; CHECK-NEXT:    ret void
366;
367  %B = tail call double @llvm.floor.f64(double 1.5) nounwind
368  store volatile double %B, double* %P
369  %C = tail call double @llvm.floor.f64(double -1.5) nounwind
370  store volatile double %C, double* %P
371  ret void
372}
373
374define void @ceil(double *%P) {
375; CHECK-LABEL: @ceil(
376; CHECK-NEXT:    store volatile double 2.000000e+00, double* %P, align 8
377; CHECK-NEXT:    store volatile double -1.000000e+00, double* %P, align 8
378; CHECK-NEXT:    ret void
379;
380  %B = tail call double @llvm.ceil.f64(double 1.5) nounwind
381  store volatile double %B, double* %P
382  %C = tail call double @llvm.ceil.f64(double -1.5) nounwind
383  store volatile double %C, double* %P
384  ret void
385}
386
387define void @trunc(double *%P) {
388; CHECK-LABEL: @trunc(
389; CHECK-NEXT:    store volatile double 1.000000e+00, double* %P, align 8
390; CHECK-NEXT:    store volatile double -1.000000e+00, double* %P, align 8
391; CHECK-NEXT:    ret void
392;
393  %B = tail call double @llvm.trunc.f64(double 1.5) nounwind
394  store volatile double %B, double* %P
395  %C = tail call double @llvm.trunc.f64(double -1.5) nounwind
396  store volatile double %C, double* %P
397  ret void
398}
399
400define void @rint(double *%P) {
401; CHECK-LABEL: @rint(
402; CHECK-NEXT:    store volatile double 2.000000e+00, double* %P, align 8
403; CHECK-NEXT:    store volatile double -2.000000e+00, double* %P, align 8
404; CHECK-NEXT:    ret void
405;
406  %B = tail call double @llvm.rint.f64(double 1.5) nounwind
407  store volatile double %B, double* %P
408  %C = tail call double @llvm.rint.f64(double -1.5) nounwind
409  store volatile double %C, double* %P
410  ret void
411}
412
413define void @nearbyint(double *%P) {
414; CHECK-LABEL: @nearbyint(
415; CHECK-NEXT:    store volatile double 2.000000e+00, double* %P, align 8
416; CHECK-NEXT:    store volatile double -2.000000e+00, double* %P, align 8
417; CHECK-NEXT:    ret void
418;
419  %B = tail call double @llvm.nearbyint.f64(double 1.5) nounwind
420  store volatile double %B, double* %P
421  %C = tail call double @llvm.nearbyint.f64(double -1.5) nounwind
422  store volatile double %C, double* %P
423  ret void
424}
425
426; CHECK: [[$CTTZ_RANGE]] = !{i32 0, i32 3}
427; CHECK: [[$CTLZ_RANGE]] = !{i8 0, i8 3}
428