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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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>
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
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>
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
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>
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]]
226 %b = call i32 @llvm.abs.i32(i32 %a, i1 false)
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)
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]]
246 %sel = select i1 %b, i32 %neg, i32 %x
247 %abs = call i32 @llvm.abs.i32(i32 %sel, i1 true)
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)
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:%.*]]
267 ; CHECK-NEXT: ret i32 [[X]]
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
276 %a1 = call i32 @llvm.abs.i32(i32 %x, i1 false)
280 %a2 = call i32 @llvm.abs.i32(i32 %x, i1 false)
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:%.*]]
289 ; CHECK-NEXT: ret i32 [[X]]
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
298 %a1 = call i32 @llvm.abs.i32(i32 %x, i1 true)
302 %a2 = call i32 @llvm.abs.i32(i32 %x, i1 true)
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)
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)
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)
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)
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)
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)
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)
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
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
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
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
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)
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)
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
456 %a = call i32 @llvm.abs.i32(i32 %s, i1 0)
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
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>
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)
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>
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)
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]]
527 %r = call i32 @llvm.abs.i32(i32 %s, i1 true)
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)
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]]
553 %r = call i32 @llvm.abs.i32(i32 %s, i1 true)
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(
561 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
562 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
564 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
565 ; CHECK-NEXT: br label [[COND_END]]
567 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
568 ; CHECK-NEXT: ret i32 [[R]]
571 %cmp = icmp sgt i32 %x, %y
572 br i1 %cmp, label %cond.true, label %cond.end
575 %sub = sub nsw i32 %x, %y
576 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
580 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
584 ; https://alive2.llvm.org/ce/z/VSumU5
585 define i32 @sub_abs_sgeT(i32 %x, i32 %y) {
586 ; CHECK-LABEL: @sub_abs_sgeT(
588 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
589 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
591 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]
592 ; CHECK-NEXT: br label [[COND_END]]
594 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
595 ; CHECK-NEXT: ret i32 [[R]]
598 %cmp = icmp sge i32 %x, %y
599 br i1 %cmp, label %cond.true, label %cond.end
602 %sub = sub nsw i32 %x, %y
603 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
607 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
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(
615 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]
616 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
618 ; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]
619 ; CHECK-NEXT: br label [[COND_END]]
621 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
622 ; CHECK-NEXT: ret i32 [[R]]
625 %cmp = icmp sge i32 %y, %x ; swap the operands
626 br i1 %cmp, label %cond.true, label %cond.end
629 %sub = sub nsw i32 %x, %y
630 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
634 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
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(
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:%.*]]
645 ; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]
646 ; CHECK-NEXT: br label [[COND_END]]
648 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_FALSE]] ], [ 0, [[ENTRY:%.*]] ]
649 ; CHECK-NEXT: ret i32 [[R]]
652 %cmp.not = icmp sge i32 %x, %y
653 br i1 %cmp.not, label %cond.end, label %cond.false
656 %sub = sub nsw i32 %x, %y
657 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true) ; abs in false case
661 %r = phi i32 [ %0, %cond.false ], [ 0, %entry ]
665 define i32 @sub_abs_lt(i32 %x, i32 %y) {
666 ; CHECK-LABEL: @sub_abs_lt(
668 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
669 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
671 ; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]
672 ; CHECK-NEXT: br label [[COND_END]]
674 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
675 ; CHECK-NEXT: ret i32 [[R]]
678 %cmp = icmp slt i32 %x, %y
679 br i1 %cmp, label %cond.true, label %cond.end
682 %sub = sub nsw i32 %x, %y
683 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
687 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
691 ; https://alive2.llvm.org/ce/z/9wQo6G
692 define i32 @sub_abs_sle(i32 %x, i32 %y) {
693 ; CHECK-LABEL: @sub_abs_sle(
695 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
696 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
698 ; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]
699 ; CHECK-NEXT: br label [[COND_END]]
701 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
702 ; CHECK-NEXT: ret i32 [[R]]
705 %cmp = icmp sle i32 %x, %y
706 br i1 %cmp, label %cond.true, label %cond.end
709 %sub = sub nsw i32 %x, %y
710 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
714 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
718 ; https://alive2.llvm.org/ce/z/xlpSO0
719 define i8 @sub_abs_sleF(i8 %x, i8 %y) {
720 ; CHECK-LABEL: @sub_abs_sleF(
722 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
723 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
725 ; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i8 [[Y]], [[X]]
726 ; CHECK-NEXT: br label [[COND_END]]
728 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
729 ; CHECK-NEXT: ret i8 [[R]]
732 %cmp = icmp sle i8 %x, %y
733 br i1 %cmp, label %cond.true, label %cond.end
736 %sub = sub nsw i8 %x, %y
737 %0 = call i8 @llvm.abs.i8(i8 %sub, i1 false)
741 %r = phi i8 [ %0, %cond.true ], [ 0, %entry ]
745 define i8 @sub_abs_sleT(i8 %x, i8 %y) {
746 ; CHECK-LABEL: @sub_abs_sleT(
748 ; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]
749 ; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]
751 ; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i8 [[Y]], [[X]]
752 ; CHECK-NEXT: br label [[COND_END]]
754 ; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
755 ; CHECK-NEXT: ret i8 [[R]]
758 %cmp = icmp sle i8 %x, %y
759 br i1 %cmp, label %cond.true, label %cond.end
762 %sub = sub nsw i8 %x, %y
763 %0 = call i8 @llvm.abs.i8(i8 %sub, i1 true)
767 %r = phi i8 [ %0, %cond.true ], [ 0, %entry ]
771 define i32 @sub_abs_lt_min_not_poison(i32 %x, i32 %y) {
772 ; CHECK-LABEL: @sub_abs_lt_min_not_poison(
774 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
775 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
777 ; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i32 [[Y]], [[X]]
778 ; CHECK-NEXT: br label [[COND_END]]
780 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
781 ; CHECK-NEXT: ret i32 [[R]]
784 %cmp = icmp slt i32 %x, %y
785 br i1 %cmp, label %cond.true, label %cond.end
788 %sub = sub nsw i32 %x, %y
789 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 false)
793 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
797 define i32 @sub_abs_wrong_pred(i32 %x, i32 %y) {
798 ; CHECK-LABEL: @sub_abs_wrong_pred(
800 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]
801 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
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]]
807 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[TMP0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
808 ; CHECK-NEXT: ret i32 [[R]]
811 %cmp = icmp ugt i32 %x, %y
812 br i1 %cmp, label %cond.true, label %cond.end
815 %sub = sub nsw i32 %x, %y
816 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
820 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]
824 define i32 @sub_abs_no_nsw(i32 %x, i32 %y) {
825 ; CHECK-LABEL: @sub_abs_no_nsw(
827 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]
828 ; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]
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]]
834 ; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[TMP0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]
835 ; CHECK-NEXT: ret i32 [[R]]
838 %cmp = icmp sgt i32 %x, %y
839 br i1 %cmp, label %cond.true, label %cond.end
842 %sub = sub i32 %x, %y
843 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)
847 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]