[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / icmp-shl-nsw.ll
blobba05302897e9e781d67f6147039fb51121400376
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
14   ret i1 %cmp
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
24   ret i1 %cmp
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
34   ret i1 %cmp
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>
44   ret <2 x i1> %cmp
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
56   ret i1 %cmp
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
66   ret <2 x i1> %cmp
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
81   ret i1 %cmp
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
91   ret i1 %cmp
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
101   ret i1 %cmp
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
111   ret i1 %cmp
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
124   ret i1 %cmp
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
134   ret i1 %cmp
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
144   ret i1 %cmp
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
156   ret i1 %cmp
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
170   ret i1 %cmp
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
180   ret i1 %cmp
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
190   ret i1 %cmp
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>
202   ret <2 x i1> %cmp
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
222   ret i1 %cmp
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
232   ret i1 %cmp
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
242   ret i1 %cmp
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
252   ret i1 %cmp
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
265   ret i1 %cmp
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
275   ret i1 %cmp
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
285   ret i1 %cmp
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
297   ret i1 %cmp
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
311   ret i1 %cmp
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
321   ret i1 %cmp
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
331   ret i1 %cmp
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
344   ret i1 %cmp
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
354   ret i1 %cmp