1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; ((ashr X, 31) | 1 ) * X --> abs(X)
5 ; X * ((ashr X, 31) | 1 ) --> abs(X)
7 define i32 @ashr_or_mul_to_abs(i32 %X) {
8 ; CHECK-LABEL: @ashr_or_mul_to_abs(
9 ; CHECK-NEXT: [[I2:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
10 ; CHECK-NEXT: ret i32 [[I2]]
14 %i2 = mul nsw i32 %i1, %X
18 define i32 @ashr_or_mul_to_abs2(i32 %X) {
19 ; CHECK-LABEL: @ashr_or_mul_to_abs2(
20 ; CHECK-NEXT: [[I2:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
21 ; CHECK-NEXT: ret i32 [[I2]]
29 define i32 @ashr_or_mul_to_abs3(i32 %PX) {
30 ; CHECK-LABEL: @ashr_or_mul_to_abs3(
31 ; CHECK-NEXT: [[X:%.*]] = sdiv i32 42, [[PX:%.*]]
32 ; CHECK-NEXT: [[I2:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false)
33 ; CHECK-NEXT: ret i32 [[I2]]
35 %X = sdiv i32 42, %PX ; thwart complexity-based canonicalization
43 define <4 x i32> @ashr_or_mul_to_abs_vec(<4 x i32> %X) {
44 ; CHECK-LABEL: @ashr_or_mul_to_abs_vec(
45 ; CHECK-NEXT: [[I2:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 false)
46 ; CHECK-NEXT: ret <4 x i32> [[I2]]
48 %i = ashr <4 x i32> %X, <i32 31, i32 31, i32 31, i32 31>
49 %i1 = or <4 x i32> %i, <i32 1, i32 1, i32 1, i32 1>
50 %i2 = mul <4 x i32> %i1, %X
54 define <4 x i32> @ashr_or_mul_to_abs_vec2(<4 x i32> %X) {
55 ; CHECK-LABEL: @ashr_or_mul_to_abs_vec2(
56 ; CHECK-NEXT: [[I2:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 true)
57 ; CHECK-NEXT: ret <4 x i32> [[I2]]
59 %i = ashr <4 x i32> %X, <i32 31, i32 31, i32 31, i32 31>
60 %i1 = or <4 x i32> %i, <i32 1, i32 1, i32 1, i32 1>
61 %i2 = mul nsw <4 x i32> %i1, %X
65 define <4 x i32> @ashr_or_mul_to_abs_vec3_undef(<4 x i32> %X) {
66 ; CHECK-LABEL: @ashr_or_mul_to_abs_vec3_undef(
67 ; CHECK-NEXT: [[I2:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 false)
68 ; CHECK-NEXT: ret <4 x i32> [[I2]]
70 %i = ashr <4 x i32> %X, <i32 31, i32 undef, i32 31, i32 31>
71 %i1 = or <4 x i32> %i, <i32 1, i32 1, i32 1, i32 undef>
72 %i2 = mul <4 x i32> %i1, %X
78 define i32 @ashr_or_mul_to_abs_neg(i32 %X) {
79 ; CHECK-LABEL: @ashr_or_mul_to_abs_neg(
80 ; CHECK-NEXT: [[I:%.*]] = ashr i32 [[X:%.*]], 30
81 ; CHECK-NEXT: [[I1:%.*]] = or i32 [[I]], 1
82 ; CHECK-NEXT: [[I2:%.*]] = mul nsw i32 [[I1]], [[X]]
83 ; CHECK-NEXT: ret i32 [[I2]]
87 %i2 = mul nsw i32 %i1, %X
91 define i32 @ashr_or_mul_to_abs_neg2(i32 %X) {
92 ; CHECK-LABEL: @ashr_or_mul_to_abs_neg2(
93 ; CHECK-NEXT: [[I:%.*]] = ashr i32 [[X:%.*]], 31
94 ; CHECK-NEXT: [[I1:%.*]] = or i32 [[I]], 2
95 ; CHECK-NEXT: [[I2:%.*]] = mul nsw i32 [[I1]], [[X]]
96 ; CHECK-NEXT: ret i32 [[I2]]
100 %i2 = mul nsw i32 %i1, %X
104 define i32 @ashr_or_mul_to_abs_neg3(i32 %X, i32 %Y) {
105 ; CHECK-LABEL: @ashr_or_mul_to_abs_neg3(
106 ; CHECK-NEXT: [[I:%.*]] = ashr i32 [[X:%.*]], 31
107 ; CHECK-NEXT: [[I1:%.*]] = or i32 [[I]], 1
108 ; CHECK-NEXT: [[I2:%.*]] = mul nsw i32 [[I1]], [[Y:%.*]]
109 ; CHECK-NEXT: ret i32 [[I2]]
113 %i2 = mul nsw i32 %i1, %Y