1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; If the (shl x, C) preserved the sign and this is a sign test,
5 ; compare the LHS operand instead
7 define i1 @icmp_shl_nsw_sgt(i32 %x) {
8 ; CHECK-LABEL: @icmp_shl_nsw_sgt(
9 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 %x, 0
10 ; CHECK-NEXT: ret i1 [[CMP]]
12 %shl = shl nsw i32 %x, 21
13 %cmp = icmp sgt i32 %shl, 0
17 define i1 @icmp_shl_nsw_sge0(i32 %x) {
18 ; CHECK-LABEL: @icmp_shl_nsw_sge0(
19 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 %x, -1
20 ; CHECK-NEXT: ret i1 [[CMP]]
22 %shl = shl nsw i32 %x, 21
23 %cmp = icmp sge i32 %shl, 0
27 define i1 @icmp_shl_nsw_sge1(i32 %x) {
28 ; CHECK-LABEL: @icmp_shl_nsw_sge1(
29 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 %x, 0
30 ; CHECK-NEXT: ret i1 [[CMP]]
32 %shl = shl nsw i32 %x, 21
33 %cmp = icmp sge i32 %shl, 1
37 define <2 x i1> @icmp_shl_nsw_sge1_vec(<2 x i32> %x) {
38 ; CHECK-LABEL: @icmp_shl_nsw_sge1_vec(
39 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> %x, zeroinitializer
40 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
42 %shl = shl nsw <2 x i32> %x, <i32 21, i32 21>
43 %cmp = icmp sge <2 x i32> %shl, <i32 1, i32 1>
47 ; Checks for icmp (eq|ne) (shl x, C), 0
49 define i1 @icmp_shl_nsw_eq(i32 %x) {
50 ; CHECK-LABEL: @icmp_shl_nsw_eq(
51 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %x, 0
52 ; CHECK-NEXT: ret i1 [[CMP]]
54 %mul = shl nsw i32 %x, 5
55 %cmp = icmp eq i32 %mul, 0
59 define <2 x i1> @icmp_shl_nsw_eq_vec(<2 x i32> %x) {
60 ; CHECK-LABEL: @icmp_shl_nsw_eq_vec(
61 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> %x, zeroinitializer
62 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
64 %mul = shl nsw <2 x i32> %x, <i32 5, i32 5>
65 %cmp = icmp eq <2 x i32> %mul, zeroinitializer
69 ; icmp sgt with shl nsw with a constant compare operand and constant
70 ; shift amount can always be reduced to icmp sgt alone.
72 ; Known bits analysis turns this into an equality predicate.
74 define i1 @icmp_sgt1(i8 %x) {
75 ; CHECK-LABEL: @icmp_sgt1(
76 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, -64
77 ; CHECK-NEXT: ret i1 [[CMP]]
79 %shl = shl nsw i8 %x, 1
80 %cmp = icmp sgt i8 %shl, -128
84 define i1 @icmp_sgt2(i8 %x) {
85 ; CHECK-LABEL: @icmp_sgt2(
86 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -64
87 ; CHECK-NEXT: ret i1 [[CMP]]
89 %shl = shl nsw i8 %x, 1
90 %cmp = icmp sgt i8 %shl, -127
94 define i1 @icmp_sgt3(i8 %x) {
95 ; CHECK-LABEL: @icmp_sgt3(
96 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -8
97 ; CHECK-NEXT: ret i1 [[CMP]]
99 %shl = shl nsw i8 %x, 1
100 %cmp = icmp sgt i8 %shl, -16
104 define i1 @icmp_sgt4(i8 %x) {
105 ; CHECK-LABEL: @icmp_sgt4(
106 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1
107 ; CHECK-NEXT: ret i1 [[CMP]]
109 %shl = shl nsw i8 %x, 1
110 %cmp = icmp sgt i8 %shl, -2
114 ; x >s -1 is a sign bit test.
115 ; x >s 0 is a sign bit test.
117 define i1 @icmp_sgt5(i8 %x) {
118 ; CHECK-LABEL: @icmp_sgt5(
119 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 0
120 ; CHECK-NEXT: ret i1 [[CMP]]
122 %shl = shl nsw i8 %x, 1
123 %cmp = icmp sgt i8 %shl, 1
127 define i1 @icmp_sgt6(i8 %x) {
128 ; CHECK-LABEL: @icmp_sgt6(
129 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 8
130 ; CHECK-NEXT: ret i1 [[CMP]]
132 %shl = shl nsw i8 %x, 1
133 %cmp = icmp sgt i8 %shl, 16
137 define i1 @icmp_sgt7(i8 %x) {
138 ; CHECK-LABEL: @icmp_sgt7(
139 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, 62
140 ; CHECK-NEXT: ret i1 [[CMP]]
142 %shl = shl nsw i8 %x, 1
143 %cmp = icmp sgt i8 %shl, 124
147 ; Known bits analysis turns this into an equality predicate.
149 define i1 @icmp_sgt8(i8 %x) {
150 ; CHECK-LABEL: @icmp_sgt8(
151 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, 63
152 ; CHECK-NEXT: ret i1 [[CMP]]
154 %shl = shl nsw i8 %x, 1
155 %cmp = icmp sgt i8 %shl, 125
159 ; Compares with 126 and 127 are recognized as always false.
161 ; Known bits analysis turns this into an equality predicate.
163 define i1 @icmp_sgt9(i8 %x) {
164 ; CHECK-LABEL: @icmp_sgt9(
165 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, -1
166 ; CHECK-NEXT: ret i1 [[CMP]]
168 %shl = shl nsw i8 %x, 7
169 %cmp = icmp sgt i8 %shl, -128
173 define i1 @icmp_sgt10(i8 %x) {
174 ; CHECK-LABEL: @icmp_sgt10(
175 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1
176 ; CHECK-NEXT: ret i1 [[CMP]]
178 %shl = shl nsw i8 %x, 7
179 %cmp = icmp sgt i8 %shl, -127
183 define i1 @icmp_sgt11(i8 %x) {
184 ; CHECK-LABEL: @icmp_sgt11(
185 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 %x, -1
186 ; CHECK-NEXT: ret i1 [[CMP]]
188 %shl = shl nsw i8 %x, 7
189 %cmp = icmp sgt i8 %shl, -2
193 ; Splat vector version should fold the same way.
195 define <2 x i1> @icmp_sgt11_vec(<2 x i8> %x) {
196 ; CHECK-LABEL: @icmp_sgt11_vec(
197 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>
198 ; CHECK-NEXT: ret <2 x i1> [[CMP]]
200 %shl = shl nsw <2 x i8> %x, <i8 7, i8 7>
201 %cmp = icmp sgt <2 x i8> %shl, <i8 -2, i8 -2>
205 ; Known bits analysis returns false for compares with >=0.
207 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
209 ; Repeat the shl nsw + sgt tests with predicate changed to 'sle'.
211 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
213 ; Known bits analysis turns this into an equality predicate.
215 define i1 @icmp_sle1(i8 %x) {
216 ; CHECK-LABEL: @icmp_sle1(
217 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, -64
218 ; CHECK-NEXT: ret i1 [[CMP]]
220 %shl = shl nsw i8 %x, 1
221 %cmp = icmp sle i8 %shl, -128
225 define i1 @icmp_sle2(i8 %x) {
226 ; CHECK-LABEL: @icmp_sle2(
227 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, -63
228 ; CHECK-NEXT: ret i1 [[CMP]]
230 %shl = shl nsw i8 %x, 1
231 %cmp = icmp sle i8 %shl, -127
235 define i1 @icmp_sle3(i8 %x) {
236 ; CHECK-LABEL: @icmp_sle3(
237 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, -7
238 ; CHECK-NEXT: ret i1 [[CMP]]
240 %shl = shl nsw i8 %x, 1
241 %cmp = icmp sle i8 %shl, -16
245 define i1 @icmp_sle4(i8 %x) {
246 ; CHECK-LABEL: @icmp_sle4(
247 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 0
248 ; CHECK-NEXT: ret i1 [[CMP]]
250 %shl = shl nsw i8 %x, 1
251 %cmp = icmp sle i8 %shl, -2
255 ; x <=s -1 is a sign bit test.
256 ; x <=s 0 is a sign bit test.
258 define i1 @icmp_sle5(i8 %x) {
259 ; CHECK-LABEL: @icmp_sle5(
260 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 1
261 ; CHECK-NEXT: ret i1 [[CMP]]
263 %shl = shl nsw i8 %x, 1
264 %cmp = icmp sle i8 %shl, 1
268 define i1 @icmp_sle6(i8 %x) {
269 ; CHECK-LABEL: @icmp_sle6(
270 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 9
271 ; CHECK-NEXT: ret i1 [[CMP]]
273 %shl = shl nsw i8 %x, 1
274 %cmp = icmp sle i8 %shl, 16
278 define i1 @icmp_sle7(i8 %x) {
279 ; CHECK-LABEL: @icmp_sle7(
280 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 63
281 ; CHECK-NEXT: ret i1 [[CMP]]
283 %shl = shl nsw i8 %x, 1
284 %cmp = icmp sle i8 %shl, 124
288 ; Known bits analysis turns this into an equality predicate.
290 define i1 @icmp_sle8(i8 %x) {
291 ; CHECK-LABEL: @icmp_sle8(
292 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, 63
293 ; CHECK-NEXT: ret i1 [[CMP]]
295 %shl = shl nsw i8 %x, 1
296 %cmp = icmp sle i8 %shl, 125
300 ; Compares with 126 and 127 are recognized as always true.
302 ; Known bits analysis turns this into an equality predicate.
304 define i1 @icmp_sle9(i8 %x) {
305 ; CHECK-LABEL: @icmp_sle9(
306 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, -1
307 ; CHECK-NEXT: ret i1 [[CMP]]
309 %shl = shl nsw i8 %x, 7
310 %cmp = icmp sle i8 %shl, -128
314 define i1 @icmp_sle10(i8 %x) {
315 ; CHECK-LABEL: @icmp_sle10(
316 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 0
317 ; CHECK-NEXT: ret i1 [[CMP]]
319 %shl = shl nsw i8 %x, 7
320 %cmp = icmp sle i8 %shl, -127
324 define i1 @icmp_sle11(i8 %x) {
325 ; CHECK-LABEL: @icmp_sle11(
326 ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 0
327 ; CHECK-NEXT: ret i1 [[CMP]]
329 %shl = shl nsw i8 %x, 7
330 %cmp = icmp sle i8 %shl, -2
334 ; Some of the earlier sgt/sle tests are transformed to eq/ne, but try a couple
335 ; of those explicitly, so we know no intermediate transforms are necessary.
337 define i1 @icmp_eq1(i8 %x) {
338 ; CHECK-LABEL: @icmp_eq1(
339 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 %x, 6
340 ; CHECK-NEXT: ret i1 [[CMP]]
342 %shl = shl nsw i8 %x, 1
343 %cmp = icmp eq i8 %shl, 12
347 define i1 @icmp_ne1(i8 %x) {
348 ; CHECK-LABEL: @icmp_ne1(
349 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 %x, -2
350 ; CHECK-NEXT: ret i1 [[CMP]]
352 %shl = shl nsw i8 %x, 6
353 %cmp = icmp ne i8 %shl, -128