1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instsimplify -S | FileCheck %s
4 ; This is canonical form for this IR.
6 define i1 @abs_nsw_is_positive(i32 %x) {
7 ; CHECK-LABEL: @abs_nsw_is_positive(
8 ; CHECK-NEXT: ret i1 true
10 %cmp = icmp slt i32 %x, 0
11 %negx = sub nsw i32 0, %x
12 %abs = select i1 %cmp, i32 %negx, i32 %x
13 %r = icmp sgt i32 %abs, -1
17 ; Test non-canonical predicate and non-canonical form of abs().
19 define i1 @abs_nsw_is_positive_sge(i32 %x) {
20 ; CHECK-LABEL: @abs_nsw_is_positive_sge(
21 ; CHECK-NEXT: ret i1 true
23 %cmp = icmp slt i32 %x, 1
24 %negx = sub nsw i32 0, %x
25 %abs = select i1 %cmp, i32 %negx, i32 %x
26 %r = icmp sge i32 %abs, 0
30 ; This is a range-based analysis. Any negative constant works.
32 define i1 @abs_nsw_is_positive_reduced_range(i32 %x) {
33 ; CHECK-LABEL: @abs_nsw_is_positive_reduced_range(
34 ; CHECK-NEXT: ret i1 true
36 %cmp = icmp slt i32 %x, 0
37 %negx = sub nsw i32 0, %x
38 %abs = select i1 %cmp, i32 %negx, i32 %x
39 %r = icmp sgt i32 %abs, -42
43 ; Negative test - we need 'nsw' in the abs().
45 define i1 @abs_is_positive_reduced_range(i32 %x) {
46 ; CHECK-LABEL: @abs_is_positive_reduced_range(
47 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
48 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
49 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
50 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[ABS]], 42
51 ; CHECK-NEXT: ret i1 [[R]]
53 %cmp = icmp slt i32 %x, 0
55 %abs = select i1 %cmp, i32 %negx, i32 %x
56 %r = icmp sgt i32 %abs, 42
60 ; Negative test - range intersection is not subset.
62 define i1 @abs_nsw_is_positive_wrong_range(i32 %x) {
63 ; CHECK-LABEL: @abs_nsw_is_positive_wrong_range(
64 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
65 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X]]
66 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
67 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[ABS]], 0
68 ; CHECK-NEXT: ret i1 [[R]]
70 %cmp = icmp slt i32 %x, 0
71 %negx = sub nsw i32 0, %x
72 %abs = select i1 %cmp, i32 %negx, i32 %x
73 %r = icmp sgt i32 %abs, 0
77 ; This is canonical form for this IR.
79 define i1 @abs_nsw_is_not_negative(i32 %x) {
80 ; CHECK-LABEL: @abs_nsw_is_not_negative(
81 ; CHECK-NEXT: ret i1 false
83 %cmp = icmp slt i32 %x, 0
84 %negx = sub nsw i32 0, %x
85 %abs = select i1 %cmp, i32 %negx, i32 %x
86 %r = icmp slt i32 %abs, 0
90 ; Test non-canonical predicate and non-canonical form of abs().
92 define i1 @abs_nsw_is_not_negative_sle(i32 %x) {
93 ; CHECK-LABEL: @abs_nsw_is_not_negative_sle(
94 ; CHECK-NEXT: ret i1 false
96 %cmp = icmp slt i32 %x, 1
97 %negx = sub nsw i32 0, %x
98 %abs = select i1 %cmp, i32 %negx, i32 %x
99 %r = icmp sle i32 %abs, -1
103 ; This is a range-based analysis. Any negative constant works.
105 define i1 @abs_nsw_is_not_negative_reduced_range(i32 %x) {
106 ; CHECK-LABEL: @abs_nsw_is_not_negative_reduced_range(
107 ; CHECK-NEXT: ret i1 false
109 %cmp = icmp slt i32 %x, 0
110 %negx = sub nsw i32 0, %x
111 %abs = select i1 %cmp, i32 %negx, i32 %x
112 %r = icmp slt i32 %abs, -24
116 ; Negative test - we need 'nsw' in the abs().
118 define i1 @abs_is_not_negative_reduced_range(i32 %x) {
119 ; CHECK-LABEL: @abs_is_not_negative_reduced_range(
120 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
121 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
122 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
123 ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[ABS]], 42
124 ; CHECK-NEXT: ret i1 [[R]]
126 %cmp = icmp slt i32 %x, 0
127 %negx = sub i32 0, %x
128 %abs = select i1 %cmp, i32 %negx, i32 %x
129 %r = icmp slt i32 %abs, 42
133 ; Negative test - range intersection is not empty.
135 define i1 @abs_nsw_is_not_negative_wrong_range(i32 %x) {
136 ; CHECK-LABEL: @abs_nsw_is_not_negative_wrong_range(
137 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
138 ; CHECK-NEXT: [[NEGX:%.*]] = sub nsw i32 0, [[X]]
139 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
140 ; CHECK-NEXT: [[R:%.*]] = icmp sle i32 [[ABS]], 0
141 ; CHECK-NEXT: ret i1 [[R]]
143 %cmp = icmp slt i32 %x, 0
144 %negx = sub nsw i32 0, %x
145 %abs = select i1 %cmp, i32 %negx, i32 %x
146 %r = icmp sle i32 %abs, 0
150 ; Even if we don't have nsw, the range is still limited in the unsigned domain.
151 define i1 @abs_positive_or_signed_min(i32 %x) {
152 ; CHECK-LABEL: @abs_positive_or_signed_min(
153 ; CHECK-NEXT: ret i1 true
155 %cmp = icmp slt i32 %x, 0
156 %negx = sub i32 0, %x
157 %abs = select i1 %cmp, i32 %negx, i32 %x
158 %r = icmp ult i32 %abs, 2147483649
162 define i1 @abs_positive_or_signed_min_reduced_range(i32 %x) {
163 ; CHECK-LABEL: @abs_positive_or_signed_min_reduced_range(
164 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0
165 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
166 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[NEGX]], i32 [[X]]
167 ; CHECK-NEXT: [[R:%.*]] = icmp ult i32 [[ABS]], -2147483648
168 ; CHECK-NEXT: ret i1 [[R]]
170 %cmp = icmp slt i32 %x, 0
171 %negx = sub i32 0, %x
172 %abs = select i1 %cmp, i32 %negx, i32 %x
173 %r = icmp ult i32 %abs, 2147483648
177 ; This is canonical form for this IR. For nabs(), we don't require 'nsw'
179 define i1 @nabs_is_negative_or_0(i32 %x) {
180 ; CHECK-LABEL: @nabs_is_negative_or_0(
181 ; CHECK-NEXT: ret i1 true
183 %cmp = icmp slt i32 %x, 0
184 %negx = sub i32 0, %x
185 %nabs = select i1 %cmp, i32 %x, i32 %negx
186 %r = icmp slt i32 %nabs, 1
190 ; Test non-canonical predicate and non-canonical form of nabs().
192 define i1 @nabs_is_negative_or_0_sle(i32 %x) {
193 ; CHECK-LABEL: @nabs_is_negative_or_0_sle(
194 ; CHECK-NEXT: ret i1 true
196 %cmp = icmp slt i32 %x, 1
197 %negx = sub i32 0, %x
198 %nabs = select i1 %cmp, i32 %x, i32 %negx
199 %r = icmp sle i32 %nabs, 0
203 ; This is a range-based analysis. Any positive constant works.
205 define i1 @nabs_is_negative_or_0_reduced_range(i32 %x) {
206 ; CHECK-LABEL: @nabs_is_negative_or_0_reduced_range(
207 ; CHECK-NEXT: ret i1 true
209 %cmp = icmp slt i32 %x, 1
210 %negx = sub i32 0, %x
211 %nabs = select i1 %cmp, i32 %x, i32 %negx
212 %r = icmp slt i32 %nabs, 421
216 ; Negative test - range intersection is not subset.
218 define i1 @nabs_is_negative_or_0_wrong_range(i32 %x) {
219 ; CHECK-LABEL: @nabs_is_negative_or_0_wrong_range(
220 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
221 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
222 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
223 ; CHECK-NEXT: [[R:%.*]] = icmp slt i32 [[NABS]], 0
224 ; CHECK-NEXT: ret i1 [[R]]
226 %cmp = icmp slt i32 %x, 1
227 %negx = sub i32 0, %x
228 %nabs = select i1 %cmp, i32 %x, i32 %negx
229 %r = icmp slt i32 %nabs, 0
233 ; This is canonical form for this IR. For nabs(), we don't require 'nsw'
235 define i1 @nabs_is_not_over_0(i32 %x) {
236 ; CHECK-LABEL: @nabs_is_not_over_0(
237 ; CHECK-NEXT: ret i1 false
239 %cmp = icmp slt i32 %x, 0
240 %negx = sub i32 0, %x
241 %nabs = select i1 %cmp, i32 %x, i32 %negx
242 %r = icmp sgt i32 %nabs, 0
246 ; Test non-canonical predicate and non-canonical form of nabs().
248 define i1 @nabs_is_not_over_0_sle(i32 %x) {
249 ; CHECK-LABEL: @nabs_is_not_over_0_sle(
250 ; CHECK-NEXT: ret i1 false
252 %cmp = icmp slt i32 %x, 1
253 %negx = sub i32 0, %x
254 %nabs = select i1 %cmp, i32 %x, i32 %negx
255 %r = icmp sge i32 %nabs, 1
259 ; This is a range-based analysis. Any positive constant works.
261 define i1 @nabs_is_not_over_0_reduced_range(i32 %x) {
262 ; CHECK-LABEL: @nabs_is_not_over_0_reduced_range(
263 ; CHECK-NEXT: ret i1 false
265 %cmp = icmp slt i32 %x, 1
266 %negx = sub i32 0, %x
267 %nabs = select i1 %cmp, i32 %x, i32 %negx
268 %r = icmp sgt i32 %nabs, 4223
272 ; Negative test - range intersection is not subset.
274 define i1 @nabs_is_not_over_0_wrong_range(i32 %x) {
275 ; CHECK-LABEL: @nabs_is_not_over_0_wrong_range(
276 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 1
277 ; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, [[X]]
278 ; CHECK-NEXT: [[NABS:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[NEGX]]
279 ; CHECK-NEXT: [[R:%.*]] = icmp sgt i32 [[NABS]], -1
280 ; CHECK-NEXT: ret i1 [[R]]
282 %cmp = icmp slt i32 %x, 1
283 %negx = sub i32 0, %x
284 %nabs = select i1 %cmp, i32 %x, i32 %negx
285 %r = icmp sgt i32 %nabs, -1
289 ; More miscellaneous tests for predicates/types.
291 ; Equality predicates are ok.
293 define i1 @abs_nsw_is_positive_eq(i32 %x) {
294 ; CHECK-LABEL: @abs_nsw_is_positive_eq(
295 ; CHECK-NEXT: ret i1 false
297 %cmp = icmp slt i32 %x, 1
298 %negx = sub nsw i32 0, %x
299 %abs = select i1 %cmp, i32 %negx, i32 %x
300 %r = icmp eq i32 %abs, -8
304 ; An unsigned compare may work.
306 define i1 @abs_nsw_is_positive_ult(i8 %x) {
307 ; CHECK-LABEL: @abs_nsw_is_positive_ult(
308 ; CHECK-NEXT: ret i1 true
310 %cmp = icmp slt i8 %x, 0
311 %negx = sub nsw i8 0, %x
312 %abs = select i1 %cmp, i8 %negx, i8 %x
313 %r = icmp ult i8 %abs, 139
317 ; An unsigned compare may work.
319 define i1 @abs_nsw_is_not_negative_ugt(i8 %x) {
320 ; CHECK-LABEL: @abs_nsw_is_not_negative_ugt(
321 ; CHECK-NEXT: ret i1 false
323 %cmp = icmp slt i8 %x, 0
324 %negx = sub nsw i8 0, %x
325 %abs = select i1 %cmp, i8 %negx, i8 %x
326 %r = icmp ugt i8 %abs, 127
330 ; Vector types are ok.
332 define <2 x i1> @abs_nsw_is_not_negative_vec_splat(<2 x i32> %x) {
333 ; CHECK-LABEL: @abs_nsw_is_not_negative_vec_splat(
334 ; CHECK-NEXT: ret <2 x i1> zeroinitializer
336 %cmp = icmp slt <2 x i32> %x, zeroinitializer
337 %negx = sub nsw <2 x i32> zeroinitializer, %x
338 %abs = select <2 x i1> %cmp, <2 x i32> %negx, <2 x i32> %x
339 %r = icmp slt <2 x i32> %abs, <i32 -8, i32 -8>
343 ; Equality predicates are ok.
345 define i1 @nabs_is_negative_or_0_ne(i8 %x) {
346 ; CHECK-LABEL: @nabs_is_negative_or_0_ne(
347 ; CHECK-NEXT: ret i1 true
349 %cmp = icmp slt i8 %x, 0
351 %nabs = select i1 %cmp, i8 %x, i8 %negx
352 %r = icmp ne i8 %nabs, 12
356 ; Vector types are ok.
358 define <3 x i1> @nabs_is_not_over_0_sle_vec_splat(<3 x i33> %x) {
359 ; CHECK-LABEL: @nabs_is_not_over_0_sle_vec_splat(
360 ; CHECK-NEXT: ret <3 x i1> zeroinitializer
362 %cmp = icmp slt <3 x i33> %x, <i33 1, i33 1, i33 1>
363 %negx = sub <3 x i33> zeroinitializer, %x
364 %nabs = select <3 x i1> %cmp, <3 x i33> %x, <3 x i33> %negx
365 %r = icmp sge <3 x i33> %nabs, <i33 1, i33 1, i33 1>
369 ; Negative test - intersection does not equal absolute value range.
370 ; PR39510 - https://bugs.llvm.org/show_bug.cgi?id=39510
372 define i1 @abs_no_intersection(i32 %a) {
373 ; CHECK-LABEL: @abs_no_intersection(
374 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], 0
375 ; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 0, [[A]]
376 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
377 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[COND]], 2
378 ; CHECK-NEXT: ret i1 [[R]]
380 %cmp = icmp slt i32 %a, 0
381 %sub = sub nsw i32 0, %a
382 %cond = select i1 %cmp, i32 %sub, i32 %a
383 %r = icmp ne i32 %cond, 2
387 ; Negative test - intersection does not equal absolute value range.
389 define i1 @nabs_no_intersection(i32 %a) {
390 ; CHECK-LABEL: @nabs_no_intersection(
391 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 0
392 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[A]]
393 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
394 ; CHECK-NEXT: [[R:%.*]] = icmp ne i32 [[COND]], -2
395 ; CHECK-NEXT: ret i1 [[R]]
397 %cmp = icmp sgt i32 %a, 0
399 %cond = select i1 %cmp, i32 %sub, i32 %a
400 %r = icmp ne i32 %cond, -2
404 ; We can't fold this to false unless both subs have nsw.
405 define i1 @abs_sub_sub_missing_nsw(i32 %x, i32 %y) {
406 ; CHECK-LABEL: @abs_sub_sub_missing_nsw(
407 ; CHECK-NEXT: [[A:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
408 ; CHECK-NEXT: [[B:%.*]] = sub nsw i32 [[Y]], [[X]]
409 ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], -1
410 ; CHECK-NEXT: [[D:%.*]] = select i1 [[C]], i32 [[A]], i32 [[B]]
411 ; CHECK-NEXT: [[E:%.*]] = icmp slt i32 [[D]], 0
412 ; CHECK-NEXT: ret i1 [[E]]
415 %b = sub nsw i32 %y, %x
416 %c = icmp sgt i32 %a, -1
417 %d = select i1 %c, i32 %a, i32 %b
418 %e = icmp slt i32 %d, 0