• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4; PR1949
5
6define i1 @test1(i32 %a) {
7; CHECK-LABEL: @test1(
8; CHECK-NEXT:    [[C:%.*]] = icmp ugt i32 %a, -5
9; CHECK-NEXT:    ret i1 [[C]]
10;
11  %b = add i32 %a, 4
12  %c = icmp ult i32 %b, 4
13  ret i1 %c
14}
15
16define <2 x i1> @test1vec(<2 x i32> %a) {
17; CHECK-LABEL: @test1vec(
18; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i32> %a, <i32 -5, i32 -5>
19; CHECK-NEXT:    ret <2 x i1> [[C]]
20;
21  %b = add <2 x i32> %a, <i32 4, i32 4>
22  %c = icmp ult <2 x i32> %b, <i32 4, i32 4>
23  ret <2 x i1> %c
24}
25
26define i1 @test2(i32 %a) {
27; CHECK-LABEL: @test2(
28; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 %a, 4
29; CHECK-NEXT:    ret i1 [[C]]
30;
31  %b = sub i32 %a, 4
32  %c = icmp ugt i32 %b, -5
33  ret i1 %c
34}
35
36define <2 x i1> @test2vec(<2 x i32> %a) {
37; CHECK-LABEL: @test2vec(
38; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> %a, <i32 4, i32 4>
39; CHECK-NEXT:    ret <2 x i1> [[C]]
40;
41  %b = sub <2 x i32> %a, <i32 4, i32 4>
42  %c = icmp ugt <2 x i32> %b, <i32 -5, i32 -5>
43  ret <2 x i1> %c
44}
45
46define i1 @test3(i32 %a) {
47; CHECK-LABEL: @test3(
48; CHECK-NEXT:    [[C:%.*]] = icmp sgt i32 %a, 2147483643
49; CHECK-NEXT:    ret i1 [[C]]
50;
51  %b = add i32 %a, 4
52  %c = icmp slt i32 %b, 2147483652
53  ret i1 %c
54}
55
56define <2 x i1> @test3vec(<2 x i32> %a) {
57; CHECK-LABEL: @test3vec(
58; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i32> %a, <i32 2147483643, i32 2147483643>
59; CHECK-NEXT:    ret <2 x i1> [[C]]
60;
61  %b = add <2 x i32> %a, <i32 4, i32 4>
62  %c = icmp slt <2 x i32> %b, <i32 2147483652, i32 2147483652>
63  ret <2 x i1> %c
64}
65
66define i1 @test4(i32 %a) {
67; CHECK-LABEL: @test4(
68; CHECK-NEXT:    [[C:%.*]] = icmp slt i32 %a, -4
69; CHECK-NEXT:    ret i1 [[C]]
70;
71  %b = add i32 %a, 2147483652
72  %c = icmp sge i32 %b, 4
73  ret i1 %c
74}
75
76define <2 x i1> @test4vec(<2 x i32> %a) {
77; CHECK-LABEL: @test4vec(
78; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i32> %a, <i32 -4, i32 -4>
79; CHECK-NEXT:    ret <2 x i1> [[C]]
80;
81  %b = add <2 x i32> %a, <i32 2147483652, i32 2147483652>
82  %c = icmp sge <2 x i32> %b, <i32 4, i32 4>
83  ret <2 x i1> %c
84}
85
86; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
87; This becomes equality because it's at the limit.
88
89define i1 @nsw_slt1(i8 %a) {
90; CHECK-LABEL: @nsw_slt1(
91; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 %a, -128
92; CHECK-NEXT:    ret i1 [[C]]
93;
94  %b = add nsw i8 %a, 100
95  %c = icmp slt i8 %b, -27
96  ret i1 %c
97}
98
99define <2 x i1> @nsw_slt1_splat_vec(<2 x i8> %a) {
100; CHECK-LABEL: @nsw_slt1_splat_vec(
101; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], <i8 -128, i8 -128>
102; CHECK-NEXT:    ret <2 x i1> [[C]]
103;
104  %b = add nsw <2 x i8> %a, <i8 100, i8 100>
105  %c = icmp slt <2 x i8> %b, <i8 -27, i8 -27>
106  ret <2 x i1> %c
107}
108
109; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
110; This becomes equality because it's at the limit.
111
112define i1 @nsw_slt2(i8 %a) {
113; CHECK-LABEL: @nsw_slt2(
114; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 %a, 127
115; CHECK-NEXT:    ret i1 [[C]]
116;
117  %b = add nsw i8 %a, -100
118  %c = icmp slt i8 %b, 27
119  ret i1 %c
120}
121
122define <2 x i1> @nsw_slt2_splat_vec(<2 x i8> %a) {
123; CHECK-LABEL: @nsw_slt2_splat_vec(
124; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], <i8 127, i8 127>
125; CHECK-NEXT:    ret <2 x i1> [[C]]
126;
127  %b = add nsw <2 x i8> %a, <i8 -100, i8 -100>
128  %c = icmp slt <2 x i8> %b, <i8 27, i8 27>
129  ret <2 x i1> %c
130}
131
132; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
133; Less than the limit, so the predicate doesn't change.
134
135define i1 @nsw_slt3(i8 %a) {
136; CHECK-LABEL: @nsw_slt3(
137; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %a, -126
138; CHECK-NEXT:    ret i1 [[C]]
139;
140  %b = add nsw i8 %a, 100
141  %c = icmp slt i8 %b, -26
142  ret i1 %c
143}
144
145; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
146; Less than the limit, so the predicate doesn't change.
147
148define i1 @nsw_slt4(i8 %a) {
149; CHECK-LABEL: @nsw_slt4(
150; CHECK-NEXT:    [[C:%.*]] = icmp slt i8 %a, 126
151; CHECK-NEXT:    ret i1 [[C]]
152;
153  %b = add nsw i8 %a, -100
154  %c = icmp slt i8 %b, 26
155  ret i1 %c
156}
157
158; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
159; Try sgt to make sure that works too.
160
161define i1 @nsw_sgt1(i8 %a) {
162; CHECK-LABEL: @nsw_sgt1(
163; CHECK-NEXT:    [[C:%.*]] = icmp eq i8 %a, 127
164; CHECK-NEXT:    ret i1 [[C]]
165;
166  %b = add nsw i8 %a, -100
167  %c = icmp sgt i8 %b, 26
168  ret i1 %c
169}
170
171define <2 x i1> @nsw_sgt1_splat_vec(<2 x i8> %a) {
172; CHECK-LABEL: @nsw_sgt1_splat_vec(
173; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i8> [[A:%.*]], <i8 127, i8 127>
174; CHECK-NEXT:    ret <2 x i1> [[C]]
175;
176  %b = add nsw <2 x i8> %a, <i8 -100, i8 -100>
177  %c = icmp sgt <2 x i8> %b, <i8 26, i8 26>
178  ret <2 x i1> %c
179}
180
181define i1 @nsw_sgt2(i8 %a) {
182; CHECK-LABEL: @nsw_sgt2(
183; CHECK-NEXT:    [[C:%.*]] = icmp sgt i8 [[A:%.*]], -126
184; CHECK-NEXT:    ret i1 [[C]]
185;
186  %b = add nsw i8 %a, 100
187  %c = icmp sgt i8 %b, -26
188  ret i1 %c
189}
190
191define <2 x i1> @nsw_sgt2_splat_vec(<2 x i8> %a) {
192; CHECK-LABEL: @nsw_sgt2_splat_vec(
193; CHECK-NEXT:    [[C:%.*]] = icmp sgt <2 x i8> %a, <i8 -126, i8 -126>
194; CHECK-NEXT:    ret <2 x i1> [[C]]
195;
196  %b = add nsw <2 x i8> %a, <i8 100, i8 100>
197  %c = icmp sgt <2 x i8> %b, <i8 -26, i8 -26>
198  ret <2 x i1> %c
199}
200
201; icmp Pred (add nsw X, C2), C --> icmp Pred X, (C - C2), when C - C2 does not overflow.
202; Comparison with 0 doesn't need special-casing.
203
204define i1 @slt_zero_add_nsw(i32 %a) {
205; CHECK-LABEL: @slt_zero_add_nsw(
206; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 %a, -1
207; CHECK-NEXT:    ret i1 [[CMP]]
208;
209  %add = add nsw i32 %a, 1
210  %cmp = icmp slt i32 %add, 0
211  ret i1 %cmp
212}
213
214; The same fold should work with vectors.
215
216define <2 x i1> @slt_zero_add_nsw_splat_vec(<2 x i8> %a) {
217; CHECK-LABEL: @slt_zero_add_nsw_splat_vec(
218; CHECK-NEXT:    [[CMP:%.*]] = icmp slt <2 x i8> %a, <i8 -1, i8 -1>
219; CHECK-NEXT:    ret <2 x i1> [[CMP]]
220;
221  %add = add nsw <2 x i8> %a, <i8 1, i8 1>
222  %cmp = icmp slt <2 x i8> %add, zeroinitializer
223  ret <2 x i1> %cmp
224}
225
226; Test the edges - instcombine should not interfere with simplification to constants.
227; Constant subtraction does not overflow, but this is false.
228
229define i1 @nsw_slt3_ov_no(i8 %a) {
230; CHECK-LABEL: @nsw_slt3_ov_no(
231; CHECK-NEXT:    ret i1 false
232;
233  %b = add nsw i8 %a, 100
234  %c = icmp slt i8 %b, -28
235  ret i1 %c
236}
237
238; Test the edges - instcombine should not interfere with simplification to constants.
239; Constant subtraction overflows. This is false.
240
241define i1 @nsw_slt4_ov(i8 %a) {
242; CHECK-LABEL: @nsw_slt4_ov(
243; CHECK-NEXT:    ret i1 false
244;
245  %b = add nsw i8 %a, 100
246  %c = icmp slt i8 %b, -29
247  ret i1 %c
248}
249
250; Test the edges - instcombine should not interfere with simplification to constants.
251; Constant subtraction overflows. This is true.
252
253define i1 @nsw_slt5_ov(i8 %a) {
254; CHECK-LABEL: @nsw_slt5_ov(
255; CHECK-NEXT:    ret i1 true
256;
257  %b = add nsw i8 %a, -100
258  %c = icmp slt i8 %b, 28
259  ret i1 %c
260}
261
262; InstCombine should not thwart this opportunity to simplify completely.
263
264define i1 @slt_zero_add_nsw_signbit(i8 %x) {
265; CHECK-LABEL: @slt_zero_add_nsw_signbit(
266; CHECK-NEXT:    ret i1 true
267;
268  %y = add nsw i8 %x, -128
269  %z = icmp slt i8 %y, 0
270  ret i1 %z
271}
272
273; InstCombine should not thwart this opportunity to simplify completely.
274
275define i1 @slt_zero_add_nuw_signbit(i8 %x) {
276; CHECK-LABEL: @slt_zero_add_nuw_signbit(
277; CHECK-NEXT:    ret i1 true
278;
279  %y = add nuw i8 %x, 128
280  %z = icmp slt i8 %y, 0
281  ret i1 %z
282}
283
284