1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
4 %overflow.result = type {i8, i1}
5 %ov.result.32 = type { i32, i1 }
8 declare %overflow.result @llvm.uadd.with.overflow.i8(i8, i8) nounwind readnone
9 declare %overflow.result @llvm.umul.with.overflow.i8(i8, i8) nounwind readnone
10 declare %ov.result.32 @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone
11 declare %ov.result.32 @llvm.uadd.with.overflow.i32(i32, i32) nounwind readnone
12 declare %ov.result.32 @llvm.ssub.with.overflow.i32(i32, i32) nounwind readnone
13 declare %ov.result.32 @llvm.usub.with.overflow.i32(i32, i32) nounwind readnone
14 declare %ov.result.32 @llvm.smul.with.overflow.i32(i32, i32) nounwind readnone
15 declare %ov.result.32 @llvm.umul.with.overflow.i32(i32, i32) nounwind readnone
16 declare double @llvm.powi.f64(double, i32) nounwind readonly
17 declare i32 @llvm.cttz.i32(i32, i1) nounwind readnone
18 declare i32 @llvm.ctlz.i32(i32, i1) nounwind readnone
19 declare i1 @llvm.cttz.i1(i1, i1) nounwind readnone
20 declare i1 @llvm.ctlz.i1(i1, i1) nounwind readnone
21 declare i32 @llvm.ctpop.i32(i32) nounwind readnone
22 declare <2 x i32> @llvm.cttz.v2i32(<2 x i32>, i1) nounwind readnone
23 declare <2 x i32> @llvm.ctlz.v2i32(<2 x i32>, i1) nounwind readnone
24 declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>) nounwind readnone
25 declare i8 @llvm.ctlz.i8(i8, i1) nounwind readnone
26 declare <2 x i8> @llvm.ctlz.v2i8(<2 x i8>, i1) nounwind readnone
27 declare double @llvm.cos.f64(double %Val) nounwind readonly
28 declare double @llvm.sin.f64(double %Val) nounwind readonly
29 declare double @llvm.floor.f64(double %Val) nounwind readonly
30 declare double @llvm.ceil.f64(double %Val) nounwind readonly
31 declare double @llvm.trunc.f64(double %Val) nounwind readonly
32 declare double @llvm.rint.f64(double %Val) nounwind readonly
33 declare double @llvm.nearbyint.f64(double %Val) nounwind readonly
35 define i8 @uaddtest1(i8 %A, i8 %B) {
36 %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B)
37 %y = extractvalue %overflow.result %x, 0
39 ; CHECK-LABEL: @uaddtest1(
40 ; CHECK-NEXT: %y = add i8 %A, %B
41 ; CHECK-NEXT: ret i8 %y
44 define i8 @uaddtest2(i8 %A, i8 %B, i1* %overflowPtr) {
45 %and.A = and i8 %A, 127
46 %and.B = and i8 %B, 127
47 %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %and.A, i8 %and.B)
48 %y = extractvalue %overflow.result %x, 0
49 %z = extractvalue %overflow.result %x, 1
50 store i1 %z, i1* %overflowPtr
52 ; CHECK-LABEL: @uaddtest2(
53 ; CHECK-NEXT: %and.A = and i8 %A, 127
54 ; CHECK-NEXT: %and.B = and i8 %B, 127
55 ; CHECK-NEXT: %x = add nuw i8 %and.A, %and.B
56 ; CHECK-NEXT: store i1 false, i1* %overflowPtr
57 ; CHECK-NEXT: ret i8 %x
60 define i8 @uaddtest3(i8 %A, i8 %B, i1* %overflowPtr) {
61 %or.A = or i8 %A, -128
62 %or.B = or i8 %B, -128
63 %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %or.A, i8 %or.B)
64 %y = extractvalue %overflow.result %x, 0
65 %z = extractvalue %overflow.result %x, 1
66 store i1 %z, i1* %overflowPtr
68 ; CHECK-LABEL: @uaddtest3(
69 ; CHECK-NEXT: %or.A = or i8 %A, -128
70 ; CHECK-NEXT: %or.B = or i8 %B, -128
71 ; CHECK-NEXT: %x = add i8 %or.A, %or.B
72 ; CHECK-NEXT: store i1 true, i1* %overflowPtr
73 ; CHECK-NEXT: ret i8 %x
76 define i8 @uaddtest4(i8 %A, i1* %overflowPtr) {
77 %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 undef, i8 %A)
78 %y = extractvalue %overflow.result %x, 0
79 %z = extractvalue %overflow.result %x, 1
80 store i1 %z, i1* %overflowPtr
82 ; CHECK-LABEL: @uaddtest4(
83 ; CHECK-NEXT: ret i8 undef
86 define i8 @uaddtest5(i8 %A, i1* %overflowPtr) {
87 %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 0, i8 %A)
88 %y = extractvalue %overflow.result %x, 0
89 %z = extractvalue %overflow.result %x, 1
90 store i1 %z, i1* %overflowPtr
92 ; CHECK-LABEL: @uaddtest5(
96 define i1 @uaddtest6(i8 %A, i8 %B) {
97 %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 -4)
98 %z = extractvalue %overflow.result %x, 1
100 ; CHECK-LABEL: @uaddtest6(
101 ; CHECK-NEXT: %z = icmp ugt i8 %A, 3
102 ; CHECK-NEXT: ret i1 %z
105 define i8 @uaddtest7(i8 %A, i8 %B) {
106 %x = call %overflow.result @llvm.uadd.with.overflow.i8(i8 %A, i8 %B)
107 %z = extractvalue %overflow.result %x, 0
109 ; CHECK-LABEL: @uaddtest7(
110 ; CHECK-NEXT: %z = add i8 %A, %B
111 ; CHECK-NEXT: ret i8 %z
115 define %ov.result.32 @saddtest_nsw(i8 %a, i8 %b) {
116 %A = sext i8 %a to i32
117 %B = sext i8 %b to i32
118 %x = call %ov.result.32 @llvm.sadd.with.overflow.i32(i32 %A, i32 %B)
120 ; CHECK-LABEL: @saddtest_nsw
121 ; CHECK: %x = add nsw i32 %A, %B
122 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
123 ; CHECK-NEXT: ret %ov.result.32 %1
126 define %ov.result.32 @uaddtest_nuw(i32 %a, i32 %b) {
127 %A = and i32 %a, 2147483647
128 %B = and i32 %b, 2147483647
129 %x = call %ov.result.32 @llvm.uadd.with.overflow.i32(i32 %A, i32 %B)
131 ; CHECK-LABEL: @uaddtest_nuw
132 ; CHECK: %x = add nuw i32 %A, %B
133 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
134 ; CHECK-NEXT: ret %ov.result.32 %1
137 define %ov.result.32 @ssubtest_nsw(i8 %a, i8 %b) {
138 %A = sext i8 %a to i32
139 %B = sext i8 %b to i32
140 %x = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 %A, i32 %B)
142 ; CHECK-LABEL: @ssubtest_nsw
143 ; CHECK: %x = sub nsw i32 %A, %B
144 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
145 ; CHECK-NEXT: ret %ov.result.32 %1
148 define %ov.result.32 @usubtest_nuw(i32 %a, i32 %b) {
149 %A = or i32 %a, 2147483648
150 %B = and i32 %b, 2147483647
151 %x = call %ov.result.32 @llvm.usub.with.overflow.i32(i32 %A, i32 %B)
153 ; CHECK-LABEL: @usubtest_nuw
154 ; CHECK: %x = sub nuw i32 %A, %B
155 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
156 ; CHECK-NEXT: ret %ov.result.32 %1
159 define %ov.result.32 @smultest1_nsw(i32 %a, i32 %b) {
160 %A = and i32 %a, 4095 ; 0xfff
161 %B = and i32 %b, 524287; 0x7ffff
162 %x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
164 ; CHECK-LABEL: @smultest1_nsw
165 ; CHECK: %x = mul nuw nsw i32 %A, %B
166 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
167 ; CHECK-NEXT: ret %ov.result.32 %1
170 define %ov.result.32 @smultest2_nsw(i32 %a, i32 %b) {
173 %x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
175 ; CHECK-LABEL: @smultest2_nsw
176 ; CHECK: %x = mul nsw i32 %A, %B
177 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
178 ; CHECK-NEXT: ret %ov.result.32 %1
181 define %ov.result.32 @smultest3_sw(i32 %a, i32 %b) {
184 %x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
186 ; CHECK-LABEL: @smultest3_sw
187 ; CHECK: %x = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %A, i32 %B)
188 ; CHECK-NEXT: ret %ov.result.32 %x
191 define %ov.result.32 @umultest_nuw(i32 %a, i32 %b) {
192 %A = and i32 %a, 65535 ; 0xffff
193 %B = and i32 %b, 65535 ; 0xffff
194 %x = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %A, i32 %B)
196 ; CHECK-LABEL: @umultest_nuw
197 ; CHECK: %x = mul nuw i32 %A, %B
198 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
199 ; CHECK-NEXT: ret %ov.result.32 %1
202 define i8 @umultest1(i8 %A, i1* %overflowPtr) {
203 %x = call %overflow.result @llvm.umul.with.overflow.i8(i8 0, i8 %A)
204 %y = extractvalue %overflow.result %x, 0
205 %z = extractvalue %overflow.result %x, 1
206 store i1 %z, i1* %overflowPtr
208 ; CHECK-LABEL: @umultest1(
209 ; CHECK-NEXT: store i1 false, i1* %overflowPtr
210 ; CHECK-NEXT: ret i8 0
213 define i8 @umultest2(i8 %A, i1* %overflowPtr) {
214 %x = call %overflow.result @llvm.umul.with.overflow.i8(i8 1, i8 %A)
215 %y = extractvalue %overflow.result %x, 0
216 %z = extractvalue %overflow.result %x, 1
217 store i1 %z, i1* %overflowPtr
219 ; CHECK-LABEL: @umultest2(
220 ; CHECK-NEXT: store i1 false, i1* %overflowPtr
221 ; CHECK-NEXT: ret i8 %A
224 define i32 @umultest3(i32 %n) nounwind {
225 %shr = lshr i32 %n, 2
226 %mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %shr, i32 3)
227 %ov = extractvalue %ov.result.32 %mul, 1
228 %res = extractvalue %ov.result.32 %mul, 0
229 %ret = select i1 %ov, i32 -1, i32 %res
231 ; CHECK-LABEL: @umultest3(
233 ; CHECK-NEXT: mul nuw
237 define i32 @umultest4(i32 %n) nounwind {
238 %shr = lshr i32 %n, 1
239 %mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %shr, i32 4)
240 %ov = extractvalue %ov.result.32 %mul, 1
241 %res = extractvalue %ov.result.32 %mul, 0
242 %ret = select i1 %ov, i32 -1, i32 %res
244 ; CHECK-LABEL: @umultest4(
245 ; CHECK: umul.with.overflow
248 define %ov.result.32 @umultest5(i32 %x, i32 %y) nounwind {
249 %or_x = or i32 %x, 2147483648
250 %or_y = or i32 %y, 2147483648
251 %mul = call %ov.result.32 @llvm.umul.with.overflow.i32(i32 %or_x, i32 %or_y)
252 ret %ov.result.32 %mul
253 ; CHECK-LABEL: @umultest5(
254 ; CHECK-NEXT: %[[or_x:.*]] = or i32 %x, -2147483648
255 ; CHECK-NEXT: %[[or_y:.*]] = or i32 %y, -2147483648
256 ; CHECK-NEXT: %[[mul:.*]] = mul i32 %[[or_x]], %[[or_y]]
257 ; CHECK-NEXT: %[[ret:.*]] = insertvalue %ov.result.32 { i32 undef, i1 true }, i32 %[[mul]], 0
258 ; CHECK-NEXT: ret %ov.result.32 %[[ret]]
261 define void @powi(double %V, double *%P) {
262 %A = tail call double @llvm.powi.f64(double %V, i32 -1) nounwind
263 store volatile double %A, double* %P
265 %D = tail call double @llvm.powi.f64(double %V, i32 2) nounwind
266 store volatile double %D, double* %P
268 ; CHECK-LABEL: @powi(
269 ; CHECK: %A = fdiv double 1.0{{.*}}, %V
270 ; CHECK: store volatile double %A,
271 ; CHECK: %D = fmul double %V, %V
272 ; CHECK: store volatile double %D
275 define i32 @cttz(i32 %a) {
276 ; CHECK-LABEL: @cttz(
277 ; CHECK-NEXT: ret i32 3
280 %and = and i32 %or, -8
281 %count = tail call i32 @llvm.cttz.i32(i32 %and, i1 true) nounwind readnone
285 define <2 x i32> @cttz_vec(<2 x i32> %a) {
286 ; CHECK-LABEL: @cttz_vec(
287 ; CHECK-NEXT: ret <2 x i32> <i32 3, i32 3>
289 %or = or <2 x i32> %a, <i32 8, i32 8>
290 %and = and <2 x i32> %or, <i32 -8, i32 -8>
291 %count = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %and, i1 true) nounwind readnone
295 ; Make sure we don't add range metadata to i1 cttz.
296 define i1 @cttz_i1(i1 %arg) {
297 ; CHECK-LABEL: @cttz_i1(
298 ; CHECK-NEXT: [[CNT:%.*]] = call i1 @llvm.cttz.i1(i1 [[ARG:%.*]], i1 false) #2
299 ; CHECK-NEXT: ret i1 [[CNT]]
301 %cnt = call i1 @llvm.cttz.i1(i1 %arg, i1 false) nounwind readnone
305 define i1 @cttz_knownbits(i32 %arg) {
306 ; CHECK-LABEL: @cttz_knownbits(
307 ; CHECK-NEXT: ret i1 false
310 %cnt = call i32 @llvm.cttz.i32(i32 %or, i1 true) nounwind readnone
311 %res = icmp eq i32 %cnt, 4
315 define <2 x i1> @cttz_knownbits_vec(<2 x i32> %arg) {
316 ; CHECK-LABEL: @cttz_knownbits_vec(
317 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
319 %or = or <2 x i32> %arg, <i32 4, i32 4>
320 %cnt = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %or, i1 true) nounwind readnone
321 %res = icmp eq <2 x i32> %cnt, <i32 4, i32 4>
325 define i32 @cttz_knownbits2(i32 %arg) {
326 ; CHECK-LABEL: @cttz_knownbits2(
327 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[ARG:%.*]], 4
328 ; CHECK-NEXT: [[CNT:%.*]] = call i32 @llvm.cttz.i32(i32 [[OR]], i1 true) #2, !range ![[$CTTZ_RANGE:[0-9]+]]
329 ; CHECK-NEXT: ret i32 [[CNT]]
332 %cnt = call i32 @llvm.cttz.i32(i32 %or, i1 true) nounwind readnone
336 define <2 x i32> @cttz_knownbits2_vec(<2 x i32> %arg) {
337 ; CHECK-LABEL: @cttz_knownbits2_vec(
338 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[ARG:%.*]], <i32 4, i32 4>
339 ; CHECK-NEXT: [[CNT:%.*]] = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[OR]], i1 true)
340 ; CHECK-NEXT: ret <2 x i32> [[CNT]]
342 %or = or <2 x i32> %arg, <i32 4, i32 4>
343 %cnt = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %or, i1 true) nounwind readnone
347 define i1 @cttz_knownbits3(i32 %arg) {
348 ; CHECK-LABEL: @cttz_knownbits3(
349 ; CHECK-NEXT: ret i1 false
352 %cnt = call i32 @llvm.cttz.i32(i32 %or, i1 true) nounwind readnone
353 %res = icmp eq i32 %cnt, 3
357 define <2 x i1> @cttz_knownbits3_vec(<2 x i32> %arg) {
358 ; CHECK-LABEL: @cttz_knownbits3_vec(
359 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
361 %or = or <2 x i32> %arg, <i32 4, i32 4>
362 %cnt = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %or, i1 true) nounwind readnone
363 %res = icmp eq <2 x i32> %cnt, <i32 3, i32 3>
367 define i8 @ctlz(i8 %a) {
368 ; CHECK-LABEL: @ctlz(
369 ; CHECK-NEXT: ret i8 2
372 %and = and i8 %or, 63
373 %count = tail call i8 @llvm.ctlz.i8(i8 %and, i1 true) nounwind readnone
377 define <2 x i8> @ctlz_vec(<2 x i8> %a) {
378 ; CHECK-LABEL: @ctlz_vec(
379 ; CHECK-NEXT: ret <2 x i8> <i8 2, i8 2>
381 %or = or <2 x i8> %a, <i8 32, i8 32>
382 %and = and <2 x i8> %or, <i8 63, i8 63>
383 %count = tail call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %and, i1 true) nounwind readnone
387 ; Make sure we don't add range metadata to i1 ctlz.
388 define i1 @ctlz_i1(i1 %arg) {
389 ; CHECK-LABEL: @ctlz_i1(
390 ; CHECK-NEXT: [[CNT:%.*]] = call i1 @llvm.ctlz.i1(i1 [[ARG:%.*]], i1 false) #2
391 ; CHECK-NEXT: ret i1 [[CNT]]
393 %cnt = call i1 @llvm.ctlz.i1(i1 %arg, i1 false) nounwind readnone
397 define i1 @ctlz_knownbits(i8 %arg) {
398 ; CHECK-LABEL: @ctlz_knownbits(
399 ; CHECK-NEXT: ret i1 false
402 %cnt = call i8 @llvm.ctlz.i8(i8 %or, i1 true) nounwind readnone
403 %res = icmp eq i8 %cnt, 4
407 define <2 x i1> @ctlz_knownbits_vec(<2 x i8> %arg) {
408 ; CHECK-LABEL: @ctlz_knownbits_vec(
409 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
411 %or = or <2 x i8> %arg, <i8 32, i8 32>
412 %cnt = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %or, i1 true) nounwind readnone
413 %res = icmp eq <2 x i8> %cnt, <i8 4, i8 4>
417 define i8 @ctlz_knownbits2(i8 %arg) {
418 ; CHECK-LABEL: @ctlz_knownbits2(
419 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[ARG:%.*]], 32
420 ; CHECK-NEXT: [[CNT:%.*]] = call i8 @llvm.ctlz.i8(i8 [[OR]], i1 true) #2, !range ![[$CTLZ_RANGE:[0-9]+]]
421 ; CHECK-NEXT: ret i8 [[CNT]]
424 %cnt = call i8 @llvm.ctlz.i8(i8 %or, i1 true) nounwind readnone
428 define <2 x i8> @ctlz_knownbits2_vec(<2 x i8> %arg) {
429 ; CHECK-LABEL: @ctlz_knownbits2_vec(
430 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i8> [[ARG:%.*]], <i8 32, i8 32>
431 ; CHECK-NEXT: [[CNT:%.*]] = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> [[OR]], i1 true)
432 ; CHECK-NEXT: ret <2 x i8> [[CNT]]
434 %or = or <2 x i8> %arg, <i8 32, i8 32>
435 %cnt = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %or, i1 true) nounwind readnone
439 define i1 @ctlz_knownbits3(i8 %arg) {
440 ; CHECK-LABEL: @ctlz_knownbits3(
441 ; CHECK-NEXT: ret i1 false
444 %cnt = call i8 @llvm.ctlz.i8(i8 %or, i1 true) nounwind readnone
445 %res = icmp eq i8 %cnt, 3
449 define <2 x i1> @ctlz_knownbits3_vec(<2 x i8> %arg) {
450 ; CHECK-LABEL: @ctlz_knownbits3_vec(
451 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
453 %or = or <2 x i8> %arg, <i8 32, i8 32>
454 %cnt = call <2 x i8> @llvm.ctlz.v2i8(<2 x i8> %or, i1 true) nounwind readnone
455 %res = icmp eq <2 x i8> %cnt, <i8 3, i8 3>
459 define i32 @ctlz_undef(i32 %Value) {
460 ; CHECK-LABEL: @ctlz_undef(
461 ; CHECK-NEXT: ret i32 undef
463 %ctlz = call i32 @llvm.ctlz.i32(i32 0, i1 true)
467 define <2 x i32> @ctlz_undef_vec(<2 x i32> %Value) {
468 ; CHECK-LABEL: @ctlz_undef_vec(
469 ; CHECK-NEXT: ret <2 x i32> undef
471 %ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> zeroinitializer, i1 true)
475 define i32 @ctlz_make_undef(i32 %a) {
477 %ctlz = tail call i32 @llvm.ctlz.i32(i32 %or, i1 false)
479 ; CHECK-LABEL: @ctlz_make_undef(
480 ; CHECK-NEXT: %or = or i32 %a, 8
481 ; CHECK-NEXT: %ctlz = tail call i32 @llvm.ctlz.i32(i32 %or, i1 true)
482 ; CHECK-NEXT: ret i32 %ctlz
485 define <2 x i32> @ctlz_make_undef_vec(<2 x i32> %a) {
486 ; CHECK-LABEL: @ctlz_make_undef_vec(
487 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
488 ; CHECK-NEXT: [[CTLZ:%.*]] = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[OR]], i1 true)
489 ; CHECK-NEXT: ret <2 x i32> [[CTLZ]]
491 %or = or <2 x i32> %a, <i32 8, i32 8>
492 %ctlz = tail call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %or, i1 false)
496 define i32 @cttz_undef(i32 %Value) nounwind {
497 ; CHECK-LABEL: @cttz_undef(
498 ; CHECK-NEXT: ret i32 undef
500 %cttz = call i32 @llvm.cttz.i32(i32 0, i1 true)
504 define <2 x i32> @cttz_undef_vec(<2 x i32> %Value) nounwind {
505 ; CHECK-LABEL: @cttz_undef_vec(
506 ; CHECK-NEXT: ret <2 x i32> undef
508 %cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> zeroinitializer, i1 true)
512 define i32 @cttz_make_undef(i32 %a) {
514 %cttz = tail call i32 @llvm.cttz.i32(i32 %or, i1 false)
516 ; CHECK-LABEL: @cttz_make_undef(
517 ; CHECK-NEXT: %or = or i32 %a, 8
518 ; CHECK-NEXT: %cttz = tail call i32 @llvm.cttz.i32(i32 %or, i1 true)
519 ; CHECK-NEXT: ret i32 %cttz
522 define <2 x i32> @cttz_make_undef_vec(<2 x i32> %a) {
523 ; CHECK-LABEL: @cttz_make_undef_vec(
524 ; CHECK-NEXT: [[OR:%.*]] = or <2 x i32> [[A:%.*]], <i32 8, i32 8>
525 ; CHECK-NEXT: [[CTTZ:%.*]] = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[OR]], i1 true)
526 ; CHECK-NEXT: ret <2 x i32> [[CTTZ]]
528 %or = or <2 x i32> %a, <i32 8, i32 8>
529 %cttz = tail call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %or, i1 false)
533 define i32 @ctlz_select(i32 %Value) nounwind {
534 ; CHECK-LABEL: @ctlz_select(
535 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.ctlz.i32(i32 %Value, i1 false)
536 ; CHECK-NEXT: ret i32 [[TMP1]]
538 %tobool = icmp ne i32 %Value, 0
539 %ctlz = call i32 @llvm.ctlz.i32(i32 %Value, i1 true)
540 %s = select i1 %tobool, i32 %ctlz, i32 32
544 define <2 x i32> @ctlz_select_vec(<2 x i32> %Value) nounwind {
545 ; CHECK-LABEL: @ctlz_select_vec(
546 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> [[VALUE:%.*]], i1 false)
547 ; CHECK-NEXT: ret <2 x i32> [[TMP1]]
549 %tobool = icmp ne <2 x i32> %Value, zeroinitializer
550 %ctlz = call <2 x i32> @llvm.ctlz.v2i32(<2 x i32> %Value, i1 true)
551 %s = select <2 x i1> %tobool, <2 x i32> %ctlz, <2 x i32> <i32 32, i32 32>
555 define i32 @cttz_select(i32 %Value) nounwind {
556 ; CHECK-LABEL: @cttz_select(
557 ; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.cttz.i32(i32 %Value, i1 false)
558 ; CHECK-NEXT: ret i32 [[TMP1]]
560 %tobool = icmp ne i32 %Value, 0
561 %cttz = call i32 @llvm.cttz.i32(i32 %Value, i1 true)
562 %s = select i1 %tobool, i32 %cttz, i32 32
566 define <2 x i32> @cttz_select_vec(<2 x i32> %Value) nounwind {
567 ; CHECK-LABEL: @cttz_select_vec(
568 ; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[VALUE:%.*]], i1 false)
569 ; CHECK-NEXT: ret <2 x i32> [[TMP1]]
571 %tobool = icmp ne <2 x i32> %Value, zeroinitializer
572 %cttz = call <2 x i32> @llvm.cttz.v2i32(<2 x i32> %Value, i1 true)
573 %s = select <2 x i1> %tobool, <2 x i32> %cttz, <2 x i32> <i32 32, i32 32>
577 define i1 @overflow_div_add(i32 %v1, i32 %v2) nounwind {
578 ; CHECK-LABEL: @overflow_div_add(
579 ; CHECK-NEXT: ret i1 false
581 %div = sdiv i32 %v1, 2
582 %t = call %ov.result.32 @llvm.sadd.with.overflow.i32(i32 %div, i32 1)
583 %obit = extractvalue %ov.result.32 %t, 1
587 define i1 @overflow_div_sub(i32 %v1, i32 %v2) nounwind {
588 ; Check cases where the known sign bits are larger than the word size.
589 ; CHECK-LABEL: @overflow_div_sub(
590 ; CHECK-NEXT: ret i1 false
592 %a = ashr i32 %v1, 18
593 %div = sdiv i32 %a, 65536
594 %t = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 %div, i32 1)
595 %obit = extractvalue %ov.result.32 %t, 1
599 define i1 @overflow_mod_mul(i32 %v1, i32 %v2) nounwind {
600 ; CHECK-LABEL: @overflow_mod_mul(
601 ; CHECK-NEXT: ret i1 false
603 %rem = srem i32 %v1, 1000
604 %t = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %rem, i32 %rem)
605 %obit = extractvalue %ov.result.32 %t, 1
609 define i1 @overflow_mod_overflow_mul(i32 %v1, i32 %v2) nounwind {
610 ; CHECK-LABEL: @overflow_mod_overflow_mul(
611 ; CHECK-NEXT: [[REM:%.*]] = srem i32 %v1, 65537
612 ; CHECK-NEXT: [[T:%.*]] = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 [[REM]], i32 [[REM]])
613 ; CHECK-NEXT: [[OBIT:%.*]] = extractvalue %ov.result.32 [[T]], 1
614 ; CHECK-NEXT: ret i1 [[OBIT]]
616 %rem = srem i32 %v1, 65537
617 ; This may overflow because the result of the mul operands may be greater than 16bits
618 ; and the result greater than 32.
619 %t = call %ov.result.32 @llvm.smul.with.overflow.i32(i32 %rem, i32 %rem)
620 %obit = extractvalue %ov.result.32 %t, 1
624 define %ov.result.32 @ssubtest_reorder(i8 %a) {
625 %A = sext i8 %a to i32
626 %x = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 0, i32 %A)
628 ; CHECK-LABEL: @ssubtest_reorder
629 ; CHECK: %x = sub nsw i32 0, %A
630 ; CHECK-NEXT: %1 = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %x, 0
631 ; CHECK-NEXT: ret %ov.result.32 %1
634 define %ov.result.32 @never_overflows_ssub_test0(i32 %a) {
635 %x = call %ov.result.32 @llvm.ssub.with.overflow.i32(i32 %a, i32 0)
637 ; CHECK-LABEL: @never_overflows_ssub_test0
638 ; CHECK-NEXT: %[[x:.*]] = insertvalue %ov.result.32 { i32 undef, i1 false }, i32 %a, 0
639 ; CHECK-NEXT: ret %ov.result.32 %[[x]]
642 define void @cos(double *%P) {
644 ; CHECK-NEXT: store volatile double 1.000000e+00, double* %P, align 8
645 ; CHECK-NEXT: ret void
647 %B = tail call double @llvm.cos.f64(double 0.0) nounwind
648 store volatile double %B, double* %P
653 define void @sin(double *%P) {
655 ; CHECK-NEXT: store volatile double 0.000000e+00, double* %P, align 8
656 ; CHECK-NEXT: ret void
658 %B = tail call double @llvm.sin.f64(double 0.0) nounwind
659 store volatile double %B, double* %P
664 define void @floor(double *%P) {
665 ; CHECK-LABEL: @floor(
666 ; CHECK-NEXT: store volatile double 1.000000e+00, double* %P, align 8
667 ; CHECK-NEXT: store volatile double -2.000000e+00, double* %P, align 8
668 ; CHECK-NEXT: ret void
670 %B = tail call double @llvm.floor.f64(double 1.5) nounwind
671 store volatile double %B, double* %P
672 %C = tail call double @llvm.floor.f64(double -1.5) nounwind
673 store volatile double %C, double* %P
677 define void @ceil(double *%P) {
678 ; CHECK-LABEL: @ceil(
679 ; CHECK-NEXT: store volatile double 2.000000e+00, double* %P, align 8
680 ; CHECK-NEXT: store volatile double -1.000000e+00, double* %P, align 8
681 ; CHECK-NEXT: ret void
683 %B = tail call double @llvm.ceil.f64(double 1.5) nounwind
684 store volatile double %B, double* %P
685 %C = tail call double @llvm.ceil.f64(double -1.5) nounwind
686 store volatile double %C, double* %P
690 define void @trunc(double *%P) {
691 ; CHECK-LABEL: @trunc(
692 ; CHECK-NEXT: store volatile double 1.000000e+00, double* %P, align 8
693 ; CHECK-NEXT: store volatile double -1.000000e+00, double* %P, align 8
694 ; CHECK-NEXT: ret void
696 %B = tail call double @llvm.trunc.f64(double 1.5) nounwind
697 store volatile double %B, double* %P
698 %C = tail call double @llvm.trunc.f64(double -1.5) nounwind
699 store volatile double %C, double* %P
703 define void @rint(double *%P) {
704 ; CHECK-LABEL: @rint(
705 ; CHECK-NEXT: store volatile double 2.000000e+00, double* %P, align 8
706 ; CHECK-NEXT: store volatile double -2.000000e+00, double* %P, align 8
707 ; CHECK-NEXT: ret void
709 %B = tail call double @llvm.rint.f64(double 1.5) nounwind
710 store volatile double %B, double* %P
711 %C = tail call double @llvm.rint.f64(double -1.5) nounwind
712 store volatile double %C, double* %P
716 define void @nearbyint(double *%P) {
717 ; CHECK-LABEL: @nearbyint(
718 ; CHECK-NEXT: store volatile double 2.000000e+00, double* %P, align 8
719 ; CHECK-NEXT: store volatile double -2.000000e+00, double* %P, align 8
720 ; CHECK-NEXT: ret void
722 %B = tail call double @llvm.nearbyint.f64(double 1.5) nounwind
723 store volatile double %B, double* %P
724 %C = tail call double @llvm.nearbyint.f64(double -1.5) nounwind
725 store volatile double %C, double* %P
729 ; CHECK: [[$CTTZ_RANGE]] = !{i32 0, i32 3}
730 ; CHECK: [[$CTLZ_RANGE]] = !{i8 0, i8 3}