1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s
4 declare i1 @llvm.abs.i1(i1, i1)
5 declare i8 @llvm.abs.i8(i8, i1)
6 declare i32 @llvm.abs.i32(i32, i1)
7 declare <3 x i82> @llvm.abs.v3i82(<3 x i82>, i1)
8 declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)
10 define i32 @test_abs_abs_0(i32 %x) {
11 ; CHECK-LABEL: @test_abs_abs_0(
12 ; CHECK-NEXT: [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
13 ; CHECK-NEXT: ret i32 [[A]]
15 %a = call i32 @llvm.abs.i32(i32 %x, i1 false)
16 %b = call i32 @llvm.abs.i32(i32 %a, i1 false)
20 define i32 @test_abs_abs_1(i32 %x) {
21 ; CHECK-LABEL: @test_abs_abs_1(
22 ; CHECK-NEXT: [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
23 ; CHECK-NEXT: ret i32 [[A]]
25 %a = call i32 @llvm.abs.i32(i32 %x, i1 true)
26 %b = call i32 @llvm.abs.i32(i32 %a, i1 false)
30 define i32 @test_abs_abs_2(i32 %x) {
31 ; CHECK-LABEL: @test_abs_abs_2(
32 ; CHECK-NEXT: [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
33 ; CHECK-NEXT: ret i32 [[A]]
35 %a = call i32 @llvm.abs.i32(i32 %x, i1 false)
36 %b = call i32 @llvm.abs.i32(i32 %a, i1 true)
40 define i32 @test_abs_abs_3(i32 %x) {
41 ; CHECK-LABEL: @test_abs_abs_3(
42 ; CHECK-NEXT: [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
43 ; CHECK-NEXT: ret i32 [[A]]
45 %a = call i32 @llvm.abs.i32(i32 %x, i1 true)
46 %b = call i32 @llvm.abs.i32(i32 %a, i1 true)
50 ; If the sign bit is known zero, the abs is not needed.
51 ; These cases are only folded by InstCombine, to avoid computing known bits
52 ; twice, for the non-negative and the negative case.
54 define i32 @zext_abs(i31 %x) {
55 ; CHECK-LABEL: @zext_abs(
56 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i31 [[X:%.*]] to i32
57 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[ZEXT]], i1 false)
58 ; CHECK-NEXT: ret i32 [[ABS]]
60 %zext = zext i31 %x to i32
61 %abs = call i32 @llvm.abs.i32(i32 %zext, i1 false)
65 define <3 x i82> @lshr_abs(<3 x i82> %x) {
66 ; CHECK-LABEL: @lshr_abs(
67 ; CHECK-NEXT: [[LSHR:%.*]] = lshr <3 x i82> [[X:%.*]], <i82 1, i82 1, i82 1>
68 ; CHECK-NEXT: [[ABS:%.*]] = call <3 x i82> @llvm.abs.v3i82(<3 x i82> [[LSHR]], i1 true)
69 ; CHECK-NEXT: ret <3 x i82> [[ABS]]
71 %lshr = lshr <3 x i82> %x, <i82 1, i82 1, i82 1>
72 %abs = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %lshr, i1 true)
76 define i32 @and_abs(i32 %x) {
77 ; CHECK-LABEL: @and_abs(
78 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 2147483644
79 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[AND]], i1 true)
80 ; CHECK-NEXT: ret i32 [[ABS]]
82 %and = and i32 %x, 2147483644
83 %abs = call i32 @llvm.abs.i32(i32 %and, i1 true)
87 define <3 x i82> @select_abs(<3 x i1> %cond) {
88 ; CHECK-LABEL: @select_abs(
89 ; CHECK-NEXT: [[SEL:%.*]] = select <3 x i1> [[COND:%.*]], <3 x i82> zeroinitializer, <3 x i82> <i82 2147483647, i82 42, i82 1>
90 ; CHECK-NEXT: [[ABS:%.*]] = call <3 x i82> @llvm.abs.v3i82(<3 x i82> [[SEL]], i1 false)
91 ; CHECK-NEXT: ret <3 x i82> [[ABS]]
93 %sel = select <3 x i1> %cond, <3 x i82> zeroinitializer, <3 x i82> <i82 2147483647, i82 42, i82 1>
94 %abs = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %sel, i1 false)
98 declare void @llvm.assume(i1)
100 define i32 @assume_abs(i32 %x) {
101 ; CHECK-LABEL: @assume_abs(
102 ; CHECK-NEXT: [[ASSUME:%.*]] = icmp sge i32 [[X:%.*]], 0
103 ; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
104 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 true)
105 ; CHECK-NEXT: ret i32 [[ABS]]
107 %assume = icmp sge i32 %x, 0
108 call void @llvm.assume(i1 %assume)
109 %abs = call i32 @llvm.abs.i32(i32 %x, i1 true)
113 define i1 @abs_nsw_must_be_positive(i32 %x) {
114 ; CHECK-LABEL: @abs_nsw_must_be_positive(
115 ; CHECK-NEXT: ret i1 true
117 %abs = call i32 @llvm.abs.i32(i32 %x, i1 true)
118 %c2 = icmp sge i32 %abs, 0
122 define <4 x i1> @abs_nsw_must_be_positive_vec(<4 x i32> %x) {
123 ; CHECK-LABEL: @abs_nsw_must_be_positive_vec(
124 ; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
126 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %x, i1 true)
127 %c2 = icmp sge <4 x i32> %abs, zeroinitializer
131 ; Negative test, no nsw provides no information about the sign bit of the result.
132 define i1 @abs_nonsw(i32 %x) {
133 ; CHECK-LABEL: @abs_nonsw(
134 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
135 ; CHECK-NEXT: [[C2:%.*]] = icmp sge i32 [[ABS]], 0
136 ; CHECK-NEXT: ret i1 [[C2]]
138 %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
139 %c2 = icmp sge i32 %abs, 0
143 define <4 x i1> @abs_nonsw_vec(<4 x i32> %x) {
144 ; CHECK-LABEL: @abs_nonsw_vec(
145 ; CHECK-NEXT: [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 false)
146 ; CHECK-NEXT: [[C2:%.*]] = icmp sge <4 x i32> [[ABS]], zeroinitializer
147 ; CHECK-NEXT: ret <4 x i1> [[C2]]
149 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %x, i1 false)
150 %c2 = icmp sge <4 x i32> %abs, zeroinitializer
154 define i1 @abs_known_positive_input_compare(i31 %x) {
155 ; CHECK-LABEL: @abs_known_positive_input_compare(
156 ; CHECK-NEXT: ret i1 true
158 %zext = zext i31 %x to i32
159 %abs = call i32 @llvm.abs.i32(i32 %zext, i1 false)
160 %c2 = icmp sge i32 %abs, 0
164 define <4 x i1> @abs_known_positive_input_compare_vec(<4 x i31> %x) {
165 ; CHECK-LABEL: @abs_known_positive_input_compare_vec(
166 ; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
168 %zext = zext <4 x i31> %x to <4 x i32>
169 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %zext, i1 false)
170 %c2 = icmp sge <4 x i32> %abs, zeroinitializer
174 define i1 @abs_known_not_int_min(i32 %x) {
175 ; CHECK-LABEL: @abs_known_not_int_min(
176 ; CHECK-NEXT: ret i1 true
179 %abs = call i32 @llvm.abs.i32(i32 %or, i1 false)
180 %c2 = icmp sge i32 %abs, 0
184 define <4 x i1> @abs_known_not_int_min_vec(<4 x i32> %x) {
185 ; CHECK-LABEL: @abs_known_not_int_min_vec(
186 ; CHECK-NEXT: ret <4 x i1> <i1 true, i1 true, i1 true, i1 true>
188 %or = or <4 x i32> %x, <i32 1, i32 1, i32 1, i32 1>
189 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %or, i1 false)
190 %c2 = icmp sge <4 x i32> %abs, zeroinitializer
194 ; If it's >= 0 it should be >= -1 as well.
195 define i1 @abs_nsw_sge_neg(i32 %x) {
196 ; CHECK-LABEL: @abs_nsw_sge_neg(
197 ; CHECK-NEXT: ret i1 true
199 %abs = call i32 @llvm.abs.i32(i32 %x, i1 true)
200 %c = icmp sge i32 %abs, -1
204 define i1 @abs_ule_int_min(i8 %x) {
205 ; CHECK-LABEL: @abs_ule_int_min(
206 ; CHECK-NEXT: ret i1 true
208 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)
209 %c = icmp ule i8 %abs, 128
213 define i32 @select_abs_of_abs_eq(i32 %x) {
214 ; CHECK-LABEL: @select_abs_of_abs_eq(
215 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
216 ; CHECK-NEXT: ret i32 [[ABS]]
218 %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
219 %neg = sub i32 0, %abs
220 %cmp = icmp eq i32 %x, 0
221 %sel = select i1 %cmp, i32 %neg, i32 %abs
225 ; The comparison is not with the same value we take abs() of, so this isn't the pattern.
226 define i32 @select_abs_of_abs_eq_wrong(i32 %x, i32 %y) {
227 ; CHECK-LABEL: @select_abs_of_abs_eq_wrong(
228 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
229 ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[ABS]]
230 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[Y:%.*]], 0
231 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[NEG]], i32 [[ABS]]
232 ; CHECK-NEXT: ret i32 [[SEL]]
234 %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
235 %neg = sub i32 0, %abs
236 %cmp = icmp eq i32 %y, 0 ; not %x
237 %sel = select i1 %cmp, i32 %neg, i32 %abs
241 define i32 @select_abs_of_abs_ne(i32 %x) {
242 ; CHECK-LABEL: @select_abs_of_abs_ne(
243 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
244 ; CHECK-NEXT: ret i32 [[ABS]]
246 %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
247 %neg = sub i32 0, %abs
248 %cmp = icmp ne i32 %x, 0
249 %sel = select i1 %cmp, i32 %abs, i32 %neg
253 define i32 @select_nabs_of_abs_eq(i32 %x) {
254 ; CHECK-LABEL: @select_nabs_of_abs_eq(
255 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
256 ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[ABS]]
257 ; CHECK-NEXT: ret i32 [[NEG]]
259 %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
260 %neg = sub i32 0, %abs
261 %cmp = icmp eq i32 %x, 0
262 %sel = select i1 %cmp, i32 %abs, i32 %neg
266 ; The comparison is not with the same value we take abs() of, so this isn't the pattern.
267 define i32 @select_nabs_of_abs_eq_wrong(i32 %x, i32 %y) {
268 ; CHECK-LABEL: @select_nabs_of_abs_eq_wrong(
269 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
270 ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[ABS]]
271 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[Y:%.*]], 0
272 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[ABS]], i32 [[NEG]]
273 ; CHECK-NEXT: ret i32 [[SEL]]
275 %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
276 %neg = sub i32 0, %abs
277 %cmp = icmp eq i32 %y, 0
278 %sel = select i1 %cmp, i32 %abs, i32 %neg
282 define i32 @select_nabs_of_abs_ne(i32 %x) {
283 ; CHECK-LABEL: @select_nabs_of_abs_ne(
284 ; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
285 ; CHECK-NEXT: [[NEG:%.*]] = sub i32 0, [[ABS]]
286 ; CHECK-NEXT: ret i32 [[NEG]]
288 %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
289 %neg = sub i32 0, %abs
290 %cmp = icmp ne i32 %x, 0
291 %sel = select i1 %cmp, i32 %neg, i32 %abs
295 define i1 @abs_i1_non_poison_eq_false(i1 %x) {
296 ; CHECK-LABEL: @abs_i1_non_poison_eq_false(
297 ; CHECK-NEXT: [[ABS:%.*]] = call i1 @llvm.abs.i1(i1 [[X:%.*]], i1 false)
298 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[ABS]], false
299 ; CHECK-NEXT: ret i1 [[CMP]]
301 %abs = call i1 @llvm.abs.i1(i1 %x, i1 false)
302 %cmp = icmp eq i1 %abs, false
306 define i1 @abs_i1_non_poison_eq_true(i1 %x) {
307 ; CHECK-LABEL: @abs_i1_non_poison_eq_true(
308 ; CHECK-NEXT: [[ABS:%.*]] = call i1 @llvm.abs.i1(i1 [[X:%.*]], i1 false)
309 ; CHECK-NEXT: ret i1 [[ABS]]
311 %abs = call i1 @llvm.abs.i1(i1 %x, i1 false)
312 %cmp = icmp eq i1 %abs, true
316 define i1 @abs_i1_poison_eq_false(i1 %x) {
317 ; CHECK-LABEL: @abs_i1_poison_eq_false(
318 ; CHECK-NEXT: ret i1 true
320 %abs = call i1 @llvm.abs.i1(i1 %x, i1 true)
321 %cmp = icmp eq i1 %abs, false
325 define i1 @abs_i1_poison_eq_true(i1 %x) {
326 ; CHECK-LABEL: @abs_i1_poison_eq_true(
327 ; CHECK-NEXT: [[ABS:%.*]] = call i1 @llvm.abs.i1(i1 [[X:%.*]], i1 true)
328 ; CHECK-NEXT: ret i1 [[ABS]]
330 %abs = call i1 @llvm.abs.i1(i1 %x, i1 true)
331 %cmp = icmp eq i1 %abs, true