[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-sub.ll
blob40447559bbb80a9bbf450252deab2c61b60d88e6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare void @use(i32)
5 declare void @use_vec(<2 x i8>)
7 define i1 @test_nuw_and_unsigned_pred(i64 %x) {
8 ; CHECK-LABEL: @test_nuw_and_unsigned_pred(
9 ; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i64 [[X:%.*]], 7
10 ; CHECK-NEXT:    ret i1 [[Z]]
12   %y = sub nuw i64 10, %x
13   %z = icmp ult i64 %y, 3
14   ret i1 %z
17 define i1 @test_nsw_and_signed_pred(i64 %x) {
18 ; CHECK-LABEL: @test_nsw_and_signed_pred(
19 ; CHECK-NEXT:    [[Z:%.*]] = icmp slt i64 [[X:%.*]], -7
20 ; CHECK-NEXT:    ret i1 [[Z]]
22   %y = sub nsw i64 3, %x
23   %z = icmp sgt i64 %y, 10
24   ret i1 %z
27 define i1 @test_nuw_nsw_and_unsigned_pred(i64 %x) {
28 ; CHECK-LABEL: @test_nuw_nsw_and_unsigned_pred(
29 ; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i64 [[X:%.*]], 6
30 ; CHECK-NEXT:    ret i1 [[Z]]
32   %y = sub nuw nsw i64 10, %x
33   %z = icmp ule i64 %y, 3
34   ret i1 %z
37 define i1 @test_nuw_nsw_and_signed_pred(i64 %x) {
38 ; CHECK-LABEL: @test_nuw_nsw_and_signed_pred(
39 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i64 [[X:%.*]], 7
40 ; CHECK-NEXT:    ret i1 [[Z]]
42   %y = sub nuw nsw i64 10, %x
43   %z = icmp slt i64 %y, 3
44   ret i1 %z
47 define i1 @test_negative_nuw_and_signed_pred(i64 %x) {
48 ; CHECK-LABEL: @test_negative_nuw_and_signed_pred(
49 ; CHECK-NEXT:    [[NOTSUB:%.*]] = add nuw i64 [[X:%.*]], -11
50 ; CHECK-NEXT:    [[Z:%.*]] = icmp sgt i64 [[NOTSUB]], -4
51 ; CHECK-NEXT:    ret i1 [[Z]]
53   %y = sub nuw i64 10, %x
54   %z = icmp slt i64 %y, 3
55   ret i1 %z
58 define i1 @test_negative_nsw_and_unsigned_pred(i64 %x) {
59 ; CHECK-LABEL: @test_negative_nsw_and_unsigned_pred(
60 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[X:%.*]], -8
61 ; CHECK-NEXT:    [[Z:%.*]] = icmp ult i64 [[TMP1]], 3
62 ; CHECK-NEXT:    ret i1 [[Z]]
64   %y = sub nsw i64 10, %x
65   %z = icmp ult i64 %y, 3
66   ret i1 %z
69 define i1 @test_negative_combined_sub_unsigned_overflow(i64 %x) {
70 ; CHECK-LABEL: @test_negative_combined_sub_unsigned_overflow(
71 ; CHECK-NEXT:    ret i1 true
73   %y = sub nuw i64 10, %x
74   %z = icmp ult i64 %y, 11
75   ret i1 %z
78 define i1 @test_negative_combined_sub_signed_overflow(i8 %x) {
79 ; CHECK-LABEL: @test_negative_combined_sub_signed_overflow(
80 ; CHECK-NEXT:    ret i1 false
82   %y = sub nsw i8 127, %x
83   %z = icmp slt i8 %y, -1
84   ret i1 %z
87 define i1 @test_sub_0_Y_eq_0(i8 %y) {
88 ; CHECK-LABEL: @test_sub_0_Y_eq_0(
89 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i8 [[Y:%.*]], 0
90 ; CHECK-NEXT:    ret i1 [[Z]]
92   %s = sub i8 0, %y
93   %z = icmp eq i8 %s, 0
94   ret i1 %z
97 define i1 @test_sub_0_Y_ne_0(i8 %y) {
98 ; CHECK-LABEL: @test_sub_0_Y_ne_0(
99 ; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[Y:%.*]], 0
100 ; CHECK-NEXT:    ret i1 [[Z]]
102   %s = sub i8 0, %y
103   %z = icmp ne i8 %s, 0
104   ret i1 %z
107 define i1 @test_sub_4_Y_ne_4(i8 %y) {
108 ; CHECK-LABEL: @test_sub_4_Y_ne_4(
109 ; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[Y:%.*]], 0
110 ; CHECK-NEXT:    ret i1 [[Z]]
112   %s = sub i8 4, %y
113   %z = icmp ne i8 %s, 4
114   ret i1 %z
117 define i1 @test_sub_127_Y_eq_127(i8 %y) {
118 ; CHECK-LABEL: @test_sub_127_Y_eq_127(
119 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i8 [[Y:%.*]], 0
120 ; CHECK-NEXT:    ret i1 [[Z]]
122   %s = sub i8 127, %y
123   %z = icmp eq i8 %s, 127
124   ret i1 %z
127 define i1 @test_sub_255_Y_eq_255(i8 %y) {
128 ; CHECK-LABEL: @test_sub_255_Y_eq_255(
129 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq i8 [[Y:%.*]], 0
130 ; CHECK-NEXT:    ret i1 [[Z]]
132   %s = sub i8 255, %y
133   %z = icmp eq i8 %s, 255
134   ret i1 %z
136 define <2 x i1> @test_sub_255_Y_eq_255_vec(<2 x i8> %y) {
137 ; CHECK-LABEL: @test_sub_255_Y_eq_255_vec(
138 ; CHECK-NEXT:    [[Z:%.*]] = icmp eq <2 x i8> [[Y:%.*]], zeroinitializer
139 ; CHECK-NEXT:    ret <2 x i1> [[Z]]
141   %s = sub <2 x i8> <i8 255, i8 255>, %y
142   %z = icmp eq <2 x i8> %s, <i8 255, i8 255>
143   ret <2 x i1> %z
146 define <2 x i1> @icmp_eq_sub_undef(<2 x i32> %a) {
147 ; CHECK-LABEL: @icmp_eq_sub_undef(
148 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 undef>
149 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
151   %sub = sub <2 x i32> <i32 15, i32 undef>, %a
152   %cmp = icmp eq <2 x i32> %sub, <i32 10, i32 10>
153   ret <2 x i1> %cmp
156 define <2 x i1> @icmp_eq_sub_non_splat(<2 x i32> %a) {
157 ; CHECK-LABEL: @icmp_eq_sub_non_splat(
158 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[A:%.*]], <i32 5, i32 6>
159 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
161   %sub = sub <2 x i32> <i32 15, i32 16>, %a
162   %cmp = icmp eq <2 x i32> %sub, <i32 10, i32 10>
163   ret <2 x i1> %cmp
166 define <2 x i1> @icmp_eq_sub_undef2(<2 x i32> %a) {
167 ; CHECK-LABEL: @icmp_eq_sub_undef2(
168 ; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i32> <i32 15, i32 15>, [[A:%.*]]
169 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[SUB]], <i32 10, i32 undef>
170 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
172   %sub = sub <2 x i32> <i32 15, i32 15>, %a
173   %cmp = icmp eq <2 x i32> %sub, <i32 10, i32 undef>
174   ret <2 x i1> %cmp
177 define <2 x i1> @icmp_eq_sub_non_splat2(<2 x i32> %a) {
178 ; CHECK-LABEL: @icmp_eq_sub_non_splat2(
179 ; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i32> <i32 15, i32 15>, [[A:%.*]]
180 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i32> [[SUB]], <i32 10, i32 11>
181 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
183   %sub = sub <2 x i32> <i32 15, i32 15>, %a
184   %cmp = icmp eq <2 x i32> %sub, <i32 10, i32 11>
185   ret <2 x i1> %cmp
188 define i1 @neg_sgt_42(i32 %x) {
189 ; CHECK-LABEL: @neg_sgt_42(
190 ; CHECK-NEXT:    [[NOTSUB:%.*]] = add i32 [[X:%.*]], -1
191 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[NOTSUB]], -43
192 ; CHECK-NEXT:    ret i1 [[R]]
194   %negx = sub i32 0, %x
195   %r = icmp sgt i32 %negx, 42
196   ret i1 %r
199 define i1 @neg_eq_43(i32 %x) {
200 ; CHECK-LABEL: @neg_eq_43(
201 ; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
202 ; CHECK-NEXT:    call void @use(i32 [[NEGX]])
203 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[X]], -43
204 ; CHECK-NEXT:    ret i1 [[R]]
206   %negx = sub i32 0, %x
207   call void @use(i32 %negx)
208   %r = icmp eq i32 %negx, 43
209   ret i1 %r
212 define i1 @neg_ne_44(i32 %x) {
213 ; CHECK-LABEL: @neg_ne_44(
214 ; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
215 ; CHECK-NEXT:    call void @use(i32 [[NEGX]])
216 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[X]], -44
217 ; CHECK-NEXT:    ret i1 [[R]]
219   %negx = sub i32 0, %x
220   call void @use(i32 %negx)
221   %r = icmp ne i32 %negx, 44
222   ret i1 %r
225 define i1 @neg_nsw_eq_45(i32 %x) {
226 ; CHECK-LABEL: @neg_nsw_eq_45(
227 ; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw i32 0, [[X:%.*]]
228 ; CHECK-NEXT:    call void @use(i32 [[NEGX]])
229 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[X]], -45
230 ; CHECK-NEXT:    ret i1 [[R]]
232   %negx = sub nsw i32 0, %x
233   call void @use(i32 %negx)
234   %r = icmp eq i32 %negx, 45
235   ret i1 %r
238 define i1 @neg_nsw_ne_46(i32 %x) {
239 ; CHECK-LABEL: @neg_nsw_ne_46(
240 ; CHECK-NEXT:    [[NEGX:%.*]] = sub nsw i32 0, [[X:%.*]]
241 ; CHECK-NEXT:    call void @use(i32 [[NEGX]])
242 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[X]], -46
243 ; CHECK-NEXT:    ret i1 [[R]]
245   %negx = sub nsw i32 0, %x
246   call void @use(i32 %negx)
247   %r = icmp ne i32 %negx, 46
248   ret i1 %r
251 define i1 @subC_eq(i32 %x) {
252 ; CHECK-LABEL: @subC_eq(
253 ; CHECK-NEXT:    [[SUBX:%.*]] = sub i32 -2147483648, [[X:%.*]]
254 ; CHECK-NEXT:    call void @use(i32 [[SUBX]])
255 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[X]], 2147483605
256 ; CHECK-NEXT:    ret i1 [[R]]
258   %subx = sub i32 -2147483648, %x
259   call void @use(i32 %subx)
260   %r = icmp eq i32 %subx, 43
261   ret i1 %r
264 define <2 x i1> @subC_ne(<2 x i8> %x) {
265 ; CHECK-LABEL: @subC_ne(
266 ; CHECK-NEXT:    [[SUBX:%.*]] = sub <2 x i8> <i8 -6, i8 -128>, [[X:%.*]]
267 ; CHECK-NEXT:    call void @use_vec(<2 x i8> [[SUBX]])
268 ; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[X]], <i8 38, i8 -84>
269 ; CHECK-NEXT:    ret <2 x i1> [[R]]
271   %subx = sub <2 x i8> <i8 -6, i8 -128>, %x
272   call void @use_vec(<2 x i8> %subx)
273   %r = icmp ne <2 x i8> %subx, <i8 -44, i8 -44>
274   ret <2 x i1> %r
277 define i1 @subC_nsw_eq(i32 %x) {
278 ; CHECK-LABEL: @subC_nsw_eq(
279 ; CHECK-NEXT:    [[SUBX:%.*]] = sub nsw i32 -100, [[X:%.*]]
280 ; CHECK-NEXT:    call void @use(i32 [[SUBX]])
281 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[X]], 2147483548
282 ; CHECK-NEXT:    ret i1 [[R]]
284   %subx = sub nsw i32 -100, %x
285   call void @use(i32 %subx)
286   %r = icmp eq i32 %subx, -2147483648
287   ret i1 %r
290 define i1 @subC_nsw_ne(i32 %x) {
291 ; CHECK-LABEL: @subC_nsw_ne(
292 ; CHECK-NEXT:    [[SUBX:%.*]] = sub nsw i32 -2147483647, [[X:%.*]]
293 ; CHECK-NEXT:    call void @use(i32 [[SUBX]])
294 ; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[X]], 2147483603
295 ; CHECK-NEXT:    ret i1 [[R]]
297   %subx = sub nsw i32 -2147483647, %x
298   call void @use(i32 %subx)
299   %r = icmp ne i32 %subx, 46
300   ret i1 %r
303 define i1 @neg_slt_42(i128 %x) {
304 ; CHECK-LABEL: @neg_slt_42(
305 ; CHECK-NEXT:    [[NOTSUB:%.*]] = add i128 [[X:%.*]], -1
306 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i128 [[NOTSUB]], -43
307 ; CHECK-NEXT:    ret i1 [[R]]
309   %negx = sub i128 0, %x
310   %r = icmp slt i128 %negx, 42
311   ret i1 %r
314 define <2 x i1> @neg_ugt_42_splat(<2 x i7> %x) {
315 ; CHECK-LABEL: @neg_ugt_42_splat(
316 ; CHECK-NEXT:    [[NOTSUB:%.*]] = add <2 x i7> [[X:%.*]], <i7 -1, i7 -1>
317 ; CHECK-NEXT:    [[R:%.*]] = icmp ult <2 x i7> [[NOTSUB]], <i7 -43, i7 -43>
318 ; CHECK-NEXT:    ret <2 x i1> [[R]]
320   %negx = sub <2 x i7> zeroinitializer, %x
321   %r = icmp ugt <2 x i7> %negx, <i7 42, i7 42>
322   ret <2 x i1> %r
325 define i1 @neg_sgt_42_use(i32 %x) {
326 ; CHECK-LABEL: @neg_sgt_42_use(
327 ; CHECK-NEXT:    [[NEGX:%.*]] = sub i32 0, [[X:%.*]]
328 ; CHECK-NEXT:    call void @use(i32 [[NEGX]])
329 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i32 [[NEGX]], 42
330 ; CHECK-NEXT:    ret i1 [[R]]
332   %negx = sub i32 0, %x
333   call void @use(i32 %negx)
334   %r = icmp sgt i32 %negx, 42
335   ret i1 %r
338 ; Test common/edge cases with signed pred.
340 define i1 @neg_slt_n1(i8 %x) {
341 ; CHECK-LABEL: @neg_slt_n1(
342 ; CHECK-NEXT:    [[NOTSUB:%.*]] = add i8 [[X:%.*]], -1
343 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[NOTSUB]], 0
344 ; CHECK-NEXT:    ret i1 [[R]]
346   %negx = sub i8 0, %x
347   %r = icmp slt i8 %negx, -1
348   ret i1 %r
351 define i1 @neg_slt_0(i8 %x) {
352 ; CHECK-LABEL: @neg_slt_0(
353 ; CHECK-NEXT:    [[NOTSUB:%.*]] = add i8 [[X:%.*]], -1
354 ; CHECK-NEXT:    [[ISNEGNEG:%.*]] = icmp sgt i8 [[NOTSUB]], -1
355 ; CHECK-NEXT:    ret i1 [[ISNEGNEG]]
357   %negx = sub i8 0, %x
358   %isnegneg = icmp slt i8 %negx, 0
359   ret i1 %isnegneg
362 define i1 @neg_slt_1(i8 %x) {
363 ; CHECK-LABEL: @neg_slt_1(
364 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X:%.*]], -127
365 ; CHECK-NEXT:    ret i1 [[R]]
367   %negx = sub i8 0, %x
368   %r = icmp slt i8 %negx, 1
369   ret i1 %r
372 define i1 @neg_sgt_n1(i8 %x) {
373 ; CHECK-LABEL: @neg_sgt_n1(
374 ; CHECK-NEXT:    [[NOTSUB:%.*]] = add i8 [[X:%.*]], -1
375 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[NOTSUB]], 0
376 ; CHECK-NEXT:    ret i1 [[R]]
378   %negx = sub i8 0, %x
379   %r = icmp sgt i8 %negx, -1
380   ret i1 %r
383 define i1 @neg_sgt_0(i8 %x) {
384 ; CHECK-LABEL: @neg_sgt_0(
385 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[X:%.*]], -128
386 ; CHECK-NEXT:    ret i1 [[R]]
388   %negx = sub i8 0, %x
389   %r = icmp sgt i8 %negx, 0
390   ret i1 %r
393 define i1 @neg_sgt_1(i8 %x) {
394 ; CHECK-LABEL: @neg_sgt_1(
395 ; CHECK-NEXT:    [[NOTSUB:%.*]] = add i8 [[X:%.*]], -1
396 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[NOTSUB]], -2
397 ; CHECK-NEXT:    ret i1 [[R]]
399   %negx = sub i8 0, %x
400   %r = icmp sgt i8 %negx, 1
401   ret i1 %r
404 ; Test common/edge cases with signed pred and nsw.
406 define i1 @neg_nsw_slt_n1(i8 %x) {
407 ; CHECK-LABEL: @neg_nsw_slt_n1(
408 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[X:%.*]], 1
409 ; CHECK-NEXT:    ret i1 [[R]]
411   %negx = sub nsw i8 0, %x
412   %r = icmp slt i8 %negx, -1
413   ret i1 %r
416 define i1 @neg_nsw_slt_0(i8 %x) {
417 ; CHECK-LABEL: @neg_nsw_slt_0(
418 ; CHECK-NEXT:    [[ISNEGNEG:%.*]] = icmp sgt i8 [[X:%.*]], 0
419 ; CHECK-NEXT:    ret i1 [[ISNEGNEG]]
421   %negx = sub nsw i8 0, %x
422   %isnegneg = icmp slt i8 %negx, 0
423   ret i1 %isnegneg
426 define i1 @neg_nsw_slt_1(i8 %x) {
427 ; CHECK-LABEL: @neg_nsw_slt_1(
428 ; CHECK-NEXT:    [[R:%.*]] = icmp sgt i8 [[X:%.*]], -1
429 ; CHECK-NEXT:    ret i1 [[R]]
431   %negx = sub nsw i8 0, %x
432   %r = icmp slt i8 %negx, 1
433   ret i1 %r
436 define i1 @neg_nsw_sgt_n1(i8 %x) {
437 ; CHECK-LABEL: @neg_nsw_sgt_n1(
438 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[X:%.*]], 1
439 ; CHECK-NEXT:    ret i1 [[R]]
441   %negx = sub nsw i8 0, %x
442   %r = icmp sgt i8 %negx, -1
443   ret i1 %r
446 define i1 @neg_nsw_sgt_0(i8 %x) {
447 ; CHECK-LABEL: @neg_nsw_sgt_0(
448 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[X:%.*]], 0
449 ; CHECK-NEXT:    ret i1 [[R]]
451   %negx = sub nsw i8 0, %x
452   %r = icmp sgt i8 %negx, 0
453   ret i1 %r
456 define i1 @neg_nsw_sgt_1(i8 %x) {
457 ; CHECK-LABEL: @neg_nsw_sgt_1(
458 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i8 [[X:%.*]], -1
459 ; CHECK-NEXT:    ret i1 [[R]]
461   %negx = sub nsw i8 0, %x
462   %r = icmp sgt i8 %negx, 1
463   ret i1 %r
466 define i1 @sub_eq_zero_use(i32 %x, i32 %y) {
467 ; CHECK-LABEL: @sub_eq_zero_use(
468 ; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
469 ; CHECK-NEXT:    call void @use(i32 [[SUB]])
470 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[SUB]], 0
471 ; CHECK-NEXT:    ret i1 [[R]]
473   %sub = sub i32 %x, %y
474   call void @use(i32 %sub)
475   %r = icmp eq i32 %sub, 0
476   ret i1 %r
479 define <2 x i1> @sub_ne_zero_use(<2 x i8> %x, <2 x i8> %y) {
480 ; CHECK-LABEL: @sub_ne_zero_use(
481 ; CHECK-NEXT:    [[SUB:%.*]] = sub <2 x i8> [[X:%.*]], [[Y:%.*]]
482 ; CHECK-NEXT:    call void @use_vec(<2 x i8> [[SUB]])
483 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[SUB]], zeroinitializer
484 ; CHECK-NEXT:    ret <2 x i1> [[R]]
486   %sub = sub <2 x i8> %x, %y
487   call void @use_vec(<2 x i8> %sub)
488   %r = icmp eq <2 x i8> %sub, zeroinitializer
489   ret <2 x i1> %r