[Transforms] Silence a warning in SROA.cpp (NFC)
[llvm-project.git] / llvm / test / Transforms / InstCombine / abs-intrinsic.ll
blob022d60d2f501bf69578c81b2719d9b97c6d68ac5
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare i8 @llvm.abs.i8(i8, i1)
5 declare i32 @llvm.abs.i32(i32, i1)
6 declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)
7 declare <3 x i82> @llvm.abs.v3i82(<3 x i82>, i1)
8 declare <2 x i8> @llvm.abs.v2i8(<2 x i8>, i1)
9 declare void @llvm.assume(i1)
10 declare void @use(i32)
12 define i8 @test_abs_abs_a_mul_b_i8(i8 %a, i8 %b) {
13 ; CHECK-LABEL: @test_abs_abs_a_mul_b_i8(
14 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[B:%.*]], [[A:%.*]]
15 ; CHECK-NEXT:    [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 true)
16 ; CHECK-NEXT:    ret i8 [[ABS2]]
18   %abs1 = call i8 @llvm.abs.i8(i8 %a, i1 true)
19   %mul = mul i8 %abs1, %b
20   %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 true)
21   ret i8 %abs2
24 define i8 @test_abs_a_mul_abs_b_i8(i8 %a, i8 %b) {
25 ; CHECK-LABEL: @test_abs_a_mul_abs_b_i8(
26 ; CHECK-NEXT:    [[A1:%.*]] = urem i8 123, [[A:%.*]]
27 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[A1]], [[B:%.*]]
28 ; CHECK-NEXT:    [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 true)
29 ; CHECK-NEXT:    ret i8 [[ABS2]]
31   %a1 = urem i8 123, %a  ; thwart complexity-based canonicalization
32   %abs1 = call i8 @llvm.abs.i8(i8 %b, i1 true)
33   %mul = mul i8 %a1, %abs1
34   %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 true)
35   ret i8 %abs2
38 define i32 @test_abs_abs_a_mul_b_i32(i32 %a, i32 %b) {
39 ; CHECK-LABEL: @test_abs_abs_a_mul_b_i32(
40 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]
41 ; CHECK-NEXT:    [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 true)
42 ; CHECK-NEXT:    ret i32 [[ABS2]]
44   %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 true)
45   %mul = mul i32 %abs1, %b
46   %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 true)
47   ret i32 %abs2
50 define i32 @test_abs_abs_a_mul_b_i32_abs_false_true(i32 %a, i32 %b) {
51 ; CHECK-LABEL: @test_abs_abs_a_mul_b_i32_abs_false_true(
52 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]
53 ; CHECK-NEXT:    [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 true)
54 ; CHECK-NEXT:    ret i32 [[ABS2]]
56   %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 false)
57   %mul = mul i32 %abs1, %b
58   %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 true)
59   ret i32 %abs2
62 define i32 @test_abs_abs_a_mul_b_i32_abs_true_false(i32 %a, i32 %b) {
63 ; CHECK-LABEL: @test_abs_abs_a_mul_b_i32_abs_true_false(
64 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]
65 ; CHECK-NEXT:    [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 false)
66 ; CHECK-NEXT:    ret i32 [[ABS2]]
68   %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 true)
69   %mul = mul i32 %abs1, %b
70   %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 false)
71   ret i32 %abs2
74 define i32 @test_abs_abs_a_mul_b_i32_abs_false_false(i32 %a, i32 %b) {
75 ; CHECK-LABEL: @test_abs_abs_a_mul_b_i32_abs_false_false(
76 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]
77 ; CHECK-NEXT:    [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 false)
78 ; CHECK-NEXT:    ret i32 [[ABS2]]
80   %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 false)
81   %mul = mul i32 %abs1, %b
82   %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 false)
83   ret i32 %abs2
86 ; this should work
87 define i8 @test_nsw_with_true(i8 %a, i8 %b) {
88 ; CHECK-LABEL: @test_nsw_with_true(
89 ; CHECK-NEXT:    [[TMP1:%.*]] = mul nsw i8 [[B:%.*]], [[A:%.*]]
90 ; CHECK-NEXT:    [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 true)
91 ; CHECK-NEXT:    ret i8 [[ABS2]]
93   %abs1 = call i8 @llvm.abs.i8(i8 %a, i1 false)
94   %mul = mul nsw i8 %abs1, %b
95   %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 true)
96   ret i8 %abs2
99 ; this should't propagate the nsw
100 define i8 @test_nsw_with_false(i8 %a, i8 %b) {
101 ; CHECK-LABEL: @test_nsw_with_false(
102 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[B:%.*]], [[A:%.*]]
103 ; CHECK-NEXT:    [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 false)
104 ; CHECK-NEXT:    ret i8 [[ABS2]]
106   %abs1 = call i8 @llvm.abs.i8(i8 %a, i1 false)
107   %mul = mul nsw i8 %abs1, %b
108   %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 false)
109   ret i8 %abs2
112 define i32 @test_abs_abs_a_mul_b_more_one_use(i32 %a, i32 %b) {
113 ; CHECK-LABEL: @test_abs_abs_a_mul_b_more_one_use(
114 ; CHECK-NEXT:    [[ABS1:%.*]] = call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)
115 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[ABS1]], [[B:%.*]]
116 ; CHECK-NEXT:    [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[MUL]], i1 false)
117 ; CHECK-NEXT:    call void @use(i32 [[MUL]])
118 ; CHECK-NEXT:    ret i32 [[ABS2]]
120   %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 true)
121   %mul = mul i32 %abs1, %b
122   %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 false)
123   call void @use(i32 %mul)
124   ret i32 %abs2
127 define <2 x i8> @test_abs_abs_a_mul_b_vector_i8(<2 x i8> %a, <2 x i8> %b) {
128 ; CHECK-LABEL: @test_abs_abs_a_mul_b_vector_i8(
129 ; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i8> [[B:%.*]], [[A:%.*]]
130 ; CHECK-NEXT:    [[ABS2:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[TMP1]], i1 true)
131 ; CHECK-NEXT:    ret <2 x i8> [[ABS2]]
133   %abs = call <2 x i8> @llvm.abs.v2i8(<2 x i8> %a, i1 true)
134   %mul = mul <2 x i8> %abs, %b
135   %abs2 = call <2 x i8> @llvm.abs.v2i8(<2 x i8> %mul, i1 true)
136   ret <2 x i8> %abs2
139 ; abs preserves trailing zeros so the second and is unneeded
140 define i32 @abs_trailing_zeros(i32 %x) {
141 ; CHECK-LABEL: @abs_trailing_zeros(
142 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], -4
143 ; CHECK-NEXT:    [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[AND]], i1 false)
144 ; CHECK-NEXT:    ret i32 [[ABS]]
146   %and = and i32 %x, -4
147   %abs = call i32 @llvm.abs.i32(i32 %and, i1 false)
148   %and2 = and i32 %abs, -2
149   ret i32 %and2
152 define <4 x i32> @abs_trailing_zeros_vec(<4 x i32> %x) {
153 ; CHECK-LABEL: @abs_trailing_zeros_vec(
154 ; CHECK-NEXT:    [[AND:%.*]] = and <4 x i32> [[X:%.*]], <i32 -4, i32 -8, i32 -16, i32 -32>
155 ; CHECK-NEXT:    [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[AND]], i1 false)
156 ; CHECK-NEXT:    ret <4 x i32> [[ABS]]
158   %and = and <4 x i32> %x, <i32 -4, i32 -8, i32 -16, i32 -32>
159   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %and, i1 false)
160   %and2 = and <4 x i32> %abs, <i32 -2, i32 -2, i32 -2, i32 -2>
161   ret <4 x i32> %and2
164 ; negative test, can't remove the second and based on trailing zeroes.
165 ; FIXME: Could remove the first and using demanded bits.
166 define i32 @abs_trailing_zeros_negative(i32 %x) {
167 ; CHECK-LABEL: @abs_trailing_zeros_negative(
168 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], -2
169 ; CHECK-NEXT:    [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[AND]], i1 false)
170 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[ABS]], -4
171 ; CHECK-NEXT:    ret i32 [[AND2]]
173   %and = and i32 %x, -2
174   %abs = call i32 @llvm.abs.i32(i32 %and, i1 false)
175   %and2 = and i32 %abs, -4
176   ret i32 %and2
179 define <4 x i32> @abs_trailing_zeros_negative_vec(<4 x i32> %x) {
180 ; CHECK-LABEL: @abs_trailing_zeros_negative_vec(
181 ; CHECK-NEXT:    [[AND:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 -2)
182 ; CHECK-NEXT:    [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[AND]], i1 false)
183 ; CHECK-NEXT:    [[AND2:%.*]] = and <4 x i32> [[ABS]], splat (i32 -4)
184 ; CHECK-NEXT:    ret <4 x i32> [[AND2]]
186   %and = and <4 x i32> %x, <i32 -2, i32 -2, i32 -2, i32 -2>
187   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %and, i1 false)
188   %and2 = and <4 x i32> %abs, <i32 -4, i32 -4, i32 -4, i32 -4>
189   ret <4 x i32> %and2
192 ; Make sure we infer this add doesn't overflow. The input to the abs has 3
193 ; sign bits, the abs reduces this to 2 sign bits.
194 define i32 @abs_signbits(i30 %x) {
195 ; CHECK-LABEL: @abs_signbits(
196 ; CHECK-NEXT:    [[TMP1:%.*]] = call i30 @llvm.abs.i30(i30 [[X:%.*]], i1 false)
197 ; CHECK-NEXT:    [[NARROW:%.*]] = add nuw i30 [[TMP1]], 1
198 ; CHECK-NEXT:    [[ADD:%.*]] = zext i30 [[NARROW]] to i32
199 ; CHECK-NEXT:    ret i32 [[ADD]]
201   %ext = sext i30 %x to i32
202   %abs = call i32 @llvm.abs.i32(i32 %ext, i1 false)
203   %add = add i32 %abs, 1
204   ret i32 %add
207 define <4 x i32> @abs_signbits_vec(<4 x i30> %x) {
208 ; CHECK-LABEL: @abs_signbits_vec(
209 ; CHECK-NEXT:    [[TMP1:%.*]] = call <4 x i30> @llvm.abs.v4i30(<4 x i30> [[X:%.*]], i1 false)
210 ; CHECK-NEXT:    [[NARROW:%.*]] = add nuw <4 x i30> [[TMP1]], splat (i30 1)
211 ; CHECK-NEXT:    [[ADD:%.*]] = zext <4 x i30> [[NARROW]] to <4 x i32>
212 ; CHECK-NEXT:    ret <4 x i32> [[ADD]]
214   %ext = sext <4 x i30> %x to <4 x i32>
215   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %ext, i1 false)
216   %add = add <4 x i32> %abs, <i32 1, i32 1, i32 1, i32 1>
217   ret <4 x i32> %add
220 define i32 @abs_of_neg(i32 %x) {
221 ; CHECK-LABEL: @abs_of_neg(
222 ; CHECK-NEXT:    [[B:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
223 ; CHECK-NEXT:    ret i32 [[B]]
225   %a = sub i32 0, %x
226   %b = call i32 @llvm.abs.i32(i32 %a, i1 false)
227   ret i32 %b
230 define <4 x i32> @abs_of_neg_vec(<4 x i32> %x) {
231 ; CHECK-LABEL: @abs_of_neg_vec(
232 ; CHECK-NEXT:    [[B:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 false)
233 ; CHECK-NEXT:    ret <4 x i32> [[B]]
235   %a = sub nsw <4 x i32> zeroinitializer, %x
236   %b = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %a, i1 false)
237   ret <4 x i32> %b
240 define i32 @abs_of_select_neg_true_val(i1 %b, i32 %x) {
241 ; CHECK-LABEL: @abs_of_select_neg_true_val(
242 ; CHECK-NEXT:    [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
243 ; CHECK-NEXT:    ret i32 [[ABS]]
245   %neg = sub i32 0, %x
246   %sel = select i1 %b, i32 %neg, i32 %x
247   %abs = call i32 @llvm.abs.i32(i32 %sel, i1 true)
248   ret i32 %abs
251 define <4 x i32> @abs_of_select_neg_false_val(<4 x i1> %b, <4 x i32> %x) {
252 ; CHECK-LABEL: @abs_of_select_neg_false_val(
253 ; CHECK-NEXT:    [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 false)
254 ; CHECK-NEXT:    ret <4 x i32> [[ABS]]
256   %neg = sub <4 x i32> zeroinitializer, %x
257   %sel = select <4 x i1> %b, <4 x i32> %x, <4 x i32> %neg
258   %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sel, i1 false)
259   ret <4 x i32> %abs
262 define i32 @abs_dom_cond_nopoison(i32 %x) {
263 ; CHECK-LABEL: @abs_dom_cond_nopoison(
264 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
265 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
266 ; CHECK:       true:
267 ; CHECK-NEXT:    ret i32 [[X]]
268 ; CHECK:       false:
269 ; CHECK-NEXT:    [[A2:%.*]] = sub i32 0, [[X]]
270 ; CHECK-NEXT:    ret i32 [[A2]]
272   %cmp = icmp sge i32 %x, 0
273   br i1 %cmp, label %true, label %false
275 true:
276   %a1 = call i32 @llvm.abs.i32(i32 %x, i1 false)
277   ret i32 %a1
279 false:
280   %a2 = call i32 @llvm.abs.i32(i32 %x, i1 false)
281   ret i32 %a2
284 define i32 @abs_dom_cond_poison(i32 %x) {
285 ; CHECK-LABEL: @abs_dom_cond_poison(
286 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1
287 ; CHECK-NEXT:    br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]
288 ; CHECK:       true:
289 ; CHECK-NEXT:    ret i32 [[X]]
290 ; CHECK:       false:
291 ; CHECK-NEXT:    [[A2:%.*]] = sub nsw i32 0, [[X]]
292 ; CHECK-NEXT:    ret i32 [[A2]]
294   %cmp = icmp sge i32 %x, 0
295   br i1 %cmp, label %true, label %false
297 true:
298   %a1 = call i32 @llvm.abs.i32(i32 %x, i1 true)
299   ret i32 %a1
301 false:
302   %a2 = call i32 @llvm.abs.i32(i32 %x, i1 true)
303   ret i32 %a2
306 ; Abs argument non-neg based on known bits.
308 define i32 @zext_abs(i31 %x) {
309 ; CHECK-LABEL: @zext_abs(
310 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i31 [[X:%.*]] to i32
311 ; CHECK-NEXT:    ret i32 [[ZEXT]]
313   %zext = zext i31 %x to i32
314   %abs = call i32 @llvm.abs.i32(i32 %zext, i1 false)
315   ret i32 %abs
318 define <3 x i82> @lshr_abs(<3 x i82> %x) {
319 ; CHECK-LABEL: @lshr_abs(
320 ; CHECK-NEXT:    [[LSHR:%.*]] = lshr <3 x i82> [[X:%.*]], splat (i82 1)
321 ; CHECK-NEXT:    ret <3 x i82> [[LSHR]]
323   %lshr = lshr <3 x i82> %x, <i82 1, i82 1, i82 1>
324   %abs = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %lshr, i1 true)
325   ret <3 x i82> %abs
328 define i32 @and_abs(i32 %x) {
329 ; CHECK-LABEL: @and_abs(
330 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], 2147483644
331 ; CHECK-NEXT:    ret i32 [[AND]]
333   %and = and i32 %x, 2147483644
334   %abs = call i32 @llvm.abs.i32(i32 %and, i1 true)
335   ret i32 %abs
338 define <3 x i82> @select_abs(<3 x i1> %cond) {
339 ; CHECK-LABEL: @select_abs(
340 ; CHECK-NEXT:    [[SEL:%.*]] = select <3 x i1> [[COND:%.*]], <3 x i82> zeroinitializer, <3 x i82> <i82 2147483647, i82 42, i82 1>
341 ; CHECK-NEXT:    ret <3 x i82> [[SEL]]
343   %sel = select <3 x i1> %cond, <3 x i82> zeroinitializer, <3 x i82> <i82 2147483647, i82 42, i82 1>
344   %abs = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %sel, i1 false)
345   ret <3 x i82> %abs
348 define i32 @assume_abs(i32 %x) {
349 ; CHECK-LABEL: @assume_abs(
350 ; CHECK-NEXT:    [[ASSUME:%.*]] = icmp sgt i32 [[X:%.*]], -1
351 ; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUME]])
352 ; CHECK-NEXT:    ret i32 [[X]]
354   %assume = icmp sge i32 %x, 0
355   call void @llvm.assume(i1 %assume)
356   %abs = call i32 @llvm.abs.i32(i32 %x, i1 true)
357   ret i32 %abs
360 ; Abs argument negative based on known bits.
362 define i32 @abs_assume_neg(i32 %x) {
363 ; CHECK-LABEL: @abs_assume_neg(
364 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
365 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
366 ; CHECK-NEXT:    [[ABS:%.*]] = sub i32 0, [[X]]
367 ; CHECK-NEXT:    ret i32 [[ABS]]
369   %cmp = icmp slt i32 %x, 0
370   call void @llvm.assume(i1 %cmp)
371   %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
372   ret i32 %abs
375 define i32 @abs_known_neg(i16 %x) {
376 ; CHECK-LABEL: @abs_known_neg(
377 ; CHECK-NEXT:    [[EXT:%.*]] = zext i16 [[X:%.*]] to i32
378 ; CHECK-NEXT:    [[NEG_NEG:%.*]] = add nuw nsw i32 [[EXT]], 1
379 ; CHECK-NEXT:    ret i32 [[NEG_NEG]]
381   %ext = zext i16 %x to i32
382   %neg = sub nsw i32 -1, %ext
383   %abs = call i32 @llvm.abs.i32(i32 %neg, i1 false)
384   ret i32 %abs
387 define i1 @abs_eq_int_min_poison(i8 %x) {
388 ; CHECK-LABEL: @abs_eq_int_min_poison(
389 ; CHECK-NEXT:    ret i1 false
391   %abs = call i8 @llvm.abs.i8(i8 %x, i1 true)
392   %cmp = icmp eq i8 %abs, -128
393   ret i1 %cmp
396 define i1 @abs_ne_int_min_poison(i8 %x) {
397 ; CHECK-LABEL: @abs_ne_int_min_poison(
398 ; CHECK-NEXT:    ret i1 true
400   %abs = call i8 @llvm.abs.i8(i8 %x, i1 true)
401   %cmp = icmp ne i8 %abs, -128
402   ret i1 %cmp
405 define i1 @abs_eq_int_min_nopoison(i8 %x) {
406 ; CHECK-LABEL: @abs_eq_int_min_nopoison(
407 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128
408 ; CHECK-NEXT:    ret i1 [[CMP]]
410   %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
411   %cmp = icmp eq i8 %abs, -128
412   ret i1 %cmp
415 define i1 @abs_ne_int_min_nopoison(i8 %x) {
416 ; CHECK-LABEL: @abs_ne_int_min_nopoison(
417 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[X:%.*]], -128
418 ; CHECK-NEXT:    ret i1 [[CMP]]
420   %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
421   %cmp = icmp ne i8 %abs, -128
422   ret i1 %cmp
425 define i32 @abs_sext(i8 %x) {
426 ; CHECK-LABEL: @abs_sext(
427 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)
428 ; CHECK-NEXT:    [[A:%.*]] = zext i8 [[TMP1]] to i32
429 ; CHECK-NEXT:    ret i32 [[A]]
431   %s = sext i8 %x to i32
432   %a = call i32 @llvm.abs.i32(i32 %s, i1 0)
433   ret i32 %a
436 define <3 x i82> @abs_nsw_sext(<3 x i7> %x) {
437 ; CHECK-LABEL: @abs_nsw_sext(
438 ; CHECK-NEXT:    [[TMP1:%.*]] = call <3 x i7> @llvm.abs.v3i7(<3 x i7> [[X:%.*]], i1 false)
439 ; CHECK-NEXT:    [[A:%.*]] = zext <3 x i7> [[TMP1]] to <3 x i82>
440 ; CHECK-NEXT:    ret <3 x i82> [[A]]
442   %s = sext <3 x i7> %x to <3 x i82>
443   %a = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %s, i1 1)
444   ret <3 x i82> %a
447 define i32 @abs_sext_extra_use(i8 %x, ptr %p) {
448 ; CHECK-LABEL: @abs_sext_extra_use(
449 ; CHECK-NEXT:    [[S:%.*]] = sext i8 [[X:%.*]] to i32
450 ; CHECK-NEXT:    store i32 [[S]], ptr [[P:%.*]], align 4
451 ; CHECK-NEXT:    [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[S]], i1 false)
452 ; CHECK-NEXT:    ret i32 [[A]]
454   %s = sext i8 %x to i32
455   store i32 %s, ptr %p
456   %a = call i32 @llvm.abs.i32(i32 %s, i1 0)
457   ret i32 %a
460 ; PR48816
462 define i8 @trunc_abs_sext(i8 %x) {
463 ; CHECK-LABEL: @trunc_abs_sext(
464 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)
465 ; CHECK-NEXT:    ret i8 [[TMP1]]
467   %s = sext i8 %x to i32
468   %a = tail call i32 @llvm.abs.i32(i32 %s, i1 true)
469   %t = trunc i32 %a to i8
470   ret i8 %t
473 define <4 x i8> @trunc_abs_sext_vec(<4 x i8> %x) {
474 ; CHECK-LABEL: @trunc_abs_sext_vec(
475 ; CHECK-NEXT:    [[TMP1:%.*]] = call <4 x i8> @llvm.abs.v4i8(<4 x i8> [[X:%.*]], i1 false)
476 ; CHECK-NEXT:    ret <4 x i8> [[TMP1]]
478   %s = sext <4 x i8> %x to <4 x i32>
479   %a = tail call <4 x i32> @llvm.abs.v4i32(<4 x i32> %s, i1 true)
480   %t = trunc <4 x i32> %a to <4 x i8>
481   ret <4 x i8> %t
484 ; abs() doesn't change the low bit.
486 define i32 @demand_low_bit(i32 %x) {
487 ; CHECK-LABEL: @demand_low_bit(
488 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[X:%.*]], 1
489 ; CHECK-NEXT:    ret i32 [[R]]
491   %a = call i32 @llvm.abs.i32(i32 %x, i1 false)
492   %r = and i32 %a, 1
493   ret i32 %r
496 ; Int min behavior doesn't affect the transform.
498 define <3 x i82> @demand_low_bit_int_min_is_poison(<3 x i82> %x) {
499 ; CHECK-LABEL: @demand_low_bit_int_min_is_poison(
500 ; CHECK-NEXT:    [[R:%.*]] = shl <3 x i82> [[X:%.*]], splat (i82 81)
501 ; CHECK-NEXT:    ret <3 x i82> [[R]]
503   %a = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %x, i1 true)
504   %r = shl <3 x i82> %a, <i82 81, i82 81, i82 81>
505   ret <3 x i82> %r
508 ; Negative test - only low bit is allowed.
510 define i32 @demand_low_bits(i32 %x) {
511 ; CHECK-LABEL: @demand_low_bits(
512 ; CHECK-NEXT:    [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
513 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], 3
514 ; CHECK-NEXT:    ret i32 [[R]]
516   %a = call i32 @llvm.abs.i32(i32 %x, i1 false)
517   %r = and i32 %a, 3
518   ret i32 %r
521 define i32 @srem_by_2_int_min_is_poison(i32 %x) {
522 ; CHECK-LABEL: @srem_by_2_int_min_is_poison(
523 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[X:%.*]], 1
524 ; CHECK-NEXT:    ret i32 [[R]]
526   %s = srem i32 %x, 2
527   %r = call i32 @llvm.abs.i32(i32 %s, i1 true)
528   ret i32 %r
531 define <3 x i82> @srem_by_2(<3 x i82> %x, ptr %p) {
532 ; CHECK-LABEL: @srem_by_2(
533 ; CHECK-NEXT:    [[S:%.*]] = srem <3 x i82> [[X:%.*]], splat (i82 2)
534 ; CHECK-NEXT:    store <3 x i82> [[S]], ptr [[P:%.*]], align 32
535 ; CHECK-NEXT:    [[R:%.*]] = and <3 x i82> [[X]], splat (i82 1)
536 ; CHECK-NEXT:    ret <3 x i82> [[R]]
538   %s = srem <3 x i82> %x, <i82 2, i82 2, i82 2>
539   store <3 x i82> %s, ptr %p
540   %r = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %s, i1 false)
541   ret <3 x i82> %r
544 ; TODO: A more general transform could sink the srem and turn it into urem.
546 define i32 @srem_by_3(i32 %x) {
547 ; CHECK-LABEL: @srem_by_3(
548 ; CHECK-NEXT:    [[S:%.*]] = srem i32 [[X:%.*]], 3
549 ; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.abs.i32(i32 [[S]], i1 true)
550 ; CHECK-NEXT:    ret i32 [[R]]
552   %s = srem i32 %x, 3
553   %r = call i32 @llvm.abs.i32(i32 %s, i1 true)
554   ret i32 %r
557 ; Test from https://github.com/llvm/llvm-project/issues/54132.
558 define i32 @sub_abs_gt(i32 %x, i32 %y) {
559 ; CHECK-LABEL: @sub_abs_gt(
560 ; CHECK-NEXT:  entry:
561 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
562 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
563 ; CHECK:       cond.true:
564 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
565 ; CHECK-NEXT:    br label [[COND_END]]
566 ; CHECK:       cond.end:
567 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[SUB]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
568 ; CHECK-NEXT:    ret i32 [[R]]
570 entry:
571   %cmp = icmp sgt i32 %x, %y
572   br i1 %cmp, label %cond.true, label %cond.end
574 cond.true:
575   %sub = sub nsw i32 %x, %y
576   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
577   br label %cond.end
579 cond.end:
580   %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
581   ret i32 %r
584 ; https://alive2.llvm.org/ce/z/VSumU5
585 define i32 @sub_abs_sgeT(i32 %x, i32 %y) {
586 ; CHECK-LABEL: @sub_abs_sgeT(
587 ; CHECK-NEXT:  entry:
588 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
589 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
590 ; CHECK:       cond.true:
591 ; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
592 ; CHECK-NEXT:    br label [[COND_END]]
593 ; CHECK:       cond.end:
594 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[SUB]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
595 ; CHECK-NEXT:    ret i32 [[R]]
597 entry:
598   %cmp = icmp sge i32 %x, %y
599   br i1 %cmp, label %cond.true, label %cond.end
601 cond.true:
602   %sub = sub nsw i32 %x, %y
603   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
604   br label %cond.end
606 cond.end:
607   %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
608   ret i32 %r
611 ; https://alive2.llvm.org/ce/z/BSM6UR
612 define i32 @sub_abs_sgeT_swap(i32 %x, i32 %y) {
613 ; CHECK-LABEL: @sub_abs_sgeT_swap(
614 ; CHECK-NEXT:  entry:
615 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
616 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
617 ; CHECK:       cond.true:
618 ; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]
619 ; CHECK-NEXT:    br label [[COND_END]]
620 ; CHECK:       cond.end:
621 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
622 ; CHECK-NEXT:    ret i32 [[R]]
624 entry:
625   %cmp = icmp sge i32 %y, %x   ; swap the operands
626   br i1 %cmp, label %cond.true, label %cond.end
628 cond.true:
629   %sub = sub nsw i32 %x, %y
630   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
631   br label %cond.end
633 cond.end:
634   %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
635   ret i32 %r
638 ; https://alive2.llvm.org/ce/z/BSM6UR
639 define i32 @sub_abs_sgeT_false(i32 %x, i32 %y) {
640 ; CHECK-LABEL: @sub_abs_sgeT_false(
641 ; CHECK-NEXT:  entry:
642 ; CHECK-NEXT:    [[CMP_NOT_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
643 ; CHECK-NEXT:    br i1 [[CMP_NOT_NOT]], label [[COND_FALSE:%.*]], label [[COND_END:%.*]]
644 ; CHECK:       cond.false:
645 ; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]
646 ; CHECK-NEXT:    br label [[COND_END]]
647 ; CHECK:       cond.end:
648 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_FALSE]] ], [ 0, [[ENTRY:%.*]] ]
649 ; CHECK-NEXT:    ret i32 [[R]]
651 entry:
652   %cmp.not = icmp sge i32 %x, %y
653   br i1 %cmp.not, label %cond.end, label %cond.false
655 cond.false:
656   %sub = sub nsw i32 %x, %y
657   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true) ; abs in false case
658   br label %cond.end
660 cond.end:
661   %r = phi i32 [ %0, %cond.false ], [ 0, %entry ]
662   ret i32 %r
665 define i32 @sub_abs_lt(i32 %x, i32 %y) {
666 ; CHECK-LABEL: @sub_abs_lt(
667 ; CHECK-NEXT:  entry:
668 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
669 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
670 ; CHECK:       cond.true:
671 ; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]
672 ; CHECK-NEXT:    br label [[COND_END]]
673 ; CHECK:       cond.end:
674 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
675 ; CHECK-NEXT:    ret i32 [[R]]
677 entry:
678   %cmp = icmp slt i32 %x, %y
679   br i1 %cmp, label %cond.true, label %cond.end
681 cond.true:
682   %sub = sub nsw i32 %x, %y
683   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
684   br label %cond.end
686 cond.end:
687   %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
688   ret i32 %r
691 ; https://alive2.llvm.org/ce/z/9wQo6G
692 define i32 @sub_abs_sle(i32 %x, i32 %y) {
693 ; CHECK-LABEL: @sub_abs_sle(
694 ; CHECK-NEXT:  entry:
695 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
696 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
697 ; CHECK:       cond.true:
698 ; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]
699 ; CHECK-NEXT:    br label [[COND_END]]
700 ; CHECK:       cond.end:
701 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
702 ; CHECK-NEXT:    ret i32 [[R]]
704 entry:
705   %cmp = icmp sle i32 %x, %y
706   br i1 %cmp, label %cond.true, label %cond.end
708 cond.true:
709   %sub = sub nsw i32 %x, %y
710   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
711   br label %cond.end
713 cond.end:
714   %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
715   ret i32 %r
718 ; https://alive2.llvm.org/ce/z/xlpSO0
719 define i8 @sub_abs_sleF(i8 %x, i8 %y) {
720 ; CHECK-LABEL: @sub_abs_sleF(
721 ; CHECK-NEXT:  entry:
722 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
723 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
724 ; CHECK:       cond.true:
725 ; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub i8 [[Y]], [[X]]
726 ; CHECK-NEXT:    br label [[COND_END]]
727 ; CHECK:       cond.end:
728 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
729 ; CHECK-NEXT:    ret i8 [[R]]
731 entry:
732   %cmp = icmp sle i8 %x, %y
733   br i1 %cmp, label %cond.true, label %cond.end
735 cond.true:
736   %sub = sub nsw i8 %x, %y
737   %0 = call i8 @llvm.abs.i8(i8 %sub, i1 false)
738   br label %cond.end
740 cond.end:
741   %r = phi i8 [ %0, %cond.true ], [ 0, %entry ]
742   ret i8 %r
745 define i8 @sub_abs_sleT(i8 %x, i8 %y) {
746 ; CHECK-LABEL: @sub_abs_sleT(
747 ; CHECK-NEXT:  entry:
748 ; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
749 ; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
750 ; CHECK:       cond.true:
751 ; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub nsw i8 [[Y]], [[X]]
752 ; CHECK-NEXT:    br label [[COND_END]]
753 ; CHECK:       cond.end:
754 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
755 ; CHECK-NEXT:    ret i8 [[R]]
757 entry:
758   %cmp = icmp sle i8 %x, %y
759   br i1 %cmp, label %cond.true, label %cond.end
761 cond.true:
762   %sub = sub nsw i8 %x, %y
763   %0 = call i8 @llvm.abs.i8(i8 %sub, i1 true)
764   br label %cond.end
766 cond.end:
767   %r = phi i8 [ %0, %cond.true ], [ 0, %entry ]
768   ret i8 %r
771 define i32 @sub_abs_lt_min_not_poison(i32 %x, i32 %y) {
772 ; CHECK-LABEL: @sub_abs_lt_min_not_poison(
773 ; CHECK-NEXT:  entry:
774 ; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
775 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
776 ; CHECK:       cond.true:
777 ; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub i32 [[Y]], [[X]]
778 ; CHECK-NEXT:    br label [[COND_END]]
779 ; CHECK:       cond.end:
780 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
781 ; CHECK-NEXT:    ret i32 [[R]]
783 entry:
784   %cmp = icmp slt i32 %x, %y
785   br i1 %cmp, label %cond.true, label %cond.end
787 cond.true:
788   %sub = sub nsw i32 %x, %y
789   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 false)
790   br label %cond.end
792 cond.end:
793   %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
794   ret i32 %r
797 define i32 @sub_abs_wrong_pred(i32 %x, i32 %y) {
798 ; CHECK-LABEL: @sub_abs_wrong_pred(
799 ; CHECK-NEXT:  entry:
800 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
801 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
802 ; CHECK:       cond.true:
803 ; CHECK-NEXT:    [[SUB:%.*]] = sub nuw nsw i32 [[X]], [[Y]]
804 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)
805 ; CHECK-NEXT:    br label [[COND_END]]
806 ; CHECK:       cond.end:
807 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[TMP0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
808 ; CHECK-NEXT:    ret i32 [[R]]
810 entry:
811   %cmp = icmp ugt i32 %x, %y
812   br i1 %cmp, label %cond.true, label %cond.end
814 cond.true:
815   %sub = sub nsw i32 %x, %y
816   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
817   br label %cond.end
819 cond.end:
820   %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
821   ret i32 %r
824 define i32 @sub_abs_no_nsw(i32 %x, i32 %y) {
825 ; CHECK-LABEL: @sub_abs_no_nsw(
826 ; CHECK-NEXT:  entry:
827 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
828 ; CHECK-NEXT:    br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
829 ; CHECK:       cond.true:
830 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X]], [[Y]]
831 ; CHECK-NEXT:    [[TMP0:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)
832 ; CHECK-NEXT:    br label [[COND_END]]
833 ; CHECK:       cond.end:
834 ; CHECK-NEXT:    [[R:%.*]] = phi i32 [ [[TMP0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
835 ; CHECK-NEXT:    ret i32 [[R]]
837 entry:
838   %cmp = icmp sgt i32 %x, %y
839   br i1 %cmp, label %cond.true, label %cond.end
841 cond.true:
842   %sub = sub i32 %x, %y
843   %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
844   br label %cond.end
846 cond.end:
847   %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
848   ret i32 %r