Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / icmp-uge-of-add-of-shl-one-by-bits-to-allones-and-val-to-icmp-eq-of-lshr-val-by-bits-and-0.ll
blob5adf476f7a79fde155de79ccbdfc4dc9bed9b55b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=38708
6 ; Pattern:
7 ;   ((1 << bits)+(-1)) u>= val
8 ; Should be transformed into:
9 ;   (val l>> bits) == 0
11 ; NOTE: the innermost shl is not one-use. Else canonicalization happens.
13 declare void @use8(i8)
14 declare void @use2i8(<2 x i8>)
15 declare void @use3i8(<3 x i8>)
17 ; ============================================================================ ;
18 ; Basic positive tests
19 ; ============================================================================ ;
21 define i1 @p0(i8 %val, i8 %bits) {
22 ; CHECK-LABEL: @p0(
23 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
24 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
25 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL:%.*]], [[BITS]]
26 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[VAL_HIGHBITS]], 0
27 ; CHECK-NEXT:    ret i1 [[R]]
29   %t0 = shl i8 1, %bits
30   call void @use8(i8 %t0)
31   %t1 = add i8 %t0, -1
32   %r = icmp uge i8 %t1, %val
33   ret i1 %r
36 ; ============================================================================ ;
37 ; Vector tests
38 ; ============================================================================ ;
40 define <2 x i1> @p1_vec(<2 x i8> %val, <2 x i8> %bits) {
41 ; CHECK-LABEL: @p1_vec(
42 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
43 ; CHECK-NEXT:    call void @use2i8(<2 x i8> [[T0]])
44 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <2 x i8> [[VAL:%.*]], [[BITS]]
45 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[VAL_HIGHBITS]], zeroinitializer
46 ; CHECK-NEXT:    ret <2 x i1> [[R]]
48   %t0 = shl <2 x i8> <i8 1, i8 1>, %bits
49   call void @use2i8(<2 x i8> %t0)
50   %t1 = add <2 x i8> %t0, <i8 -1, i8 -1>
51   %r = icmp uge <2 x i8> %t1, %val
52   ret <2 x i1> %r
55 define <3 x i1> @p2_vec_undef0(<3 x i8> %val, <3 x i8> %bits) {
56 ; CHECK-LABEL: @p2_vec_undef0(
57 ; CHECK-NEXT:    [[T0:%.*]] = shl <3 x i8> <i8 1, i8 undef, i8 1>, [[BITS:%.*]]
58 ; CHECK-NEXT:    call void @use3i8(<3 x i8> [[T0]])
59 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
60 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
61 ; CHECK-NEXT:    ret <3 x i1> [[R]]
63   %t0 = shl <3 x i8> <i8 1, i8 undef, i8 1>, %bits
64   call void @use3i8(<3 x i8> %t0)
65   %t1 = add <3 x i8> %t0, <i8 -1, i8 -1, i8 -1>
66   %r = icmp uge <3 x i8> %t1, %val
67   ret <3 x i1> %r
70 define <3 x i1> @p2_vec_poison0(<3 x i8> %val, <3 x i8> %bits) {
71 ; CHECK-LABEL: @p2_vec_poison0(
72 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 poison, i8 1>, [[BITS:%.*]]
73 ; CHECK-NEXT:    call void @use3i8(<3 x i8> [[T0]])
74 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
75 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
76 ; CHECK-NEXT:    ret <3 x i1> [[R]]
78   %t0 = shl <3 x i8> <i8 1, i8 poison, i8 1>, %bits
79   call void @use3i8(<3 x i8> %t0)
80   %t1 = add <3 x i8> %t0, <i8 -1, i8 -1, i8 -1>
81   %r = icmp uge <3 x i8> %t1, %val
82   ret <3 x i1> %r
85 define <3 x i1> @p2_vec_poison1(<3 x i8> %val, <3 x i8> %bits) {
86 ; CHECK-LABEL: @p2_vec_poison1(
87 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 1, i8 1>, [[BITS:%.*]]
88 ; CHECK-NEXT:    call void @use3i8(<3 x i8> [[T0]])
89 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
90 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
91 ; CHECK-NEXT:    ret <3 x i1> [[R]]
93   %t0 = shl <3 x i8> <i8 1, i8 1, i8 1>, %bits
94   call void @use3i8(<3 x i8> %t0)
95   %t1 = add <3 x i8> %t0, <i8 -1, i8 poison, i8 -1>
96   %r = icmp uge <3 x i8> %t1, %val
97   ret <3 x i1> %r
100 define <3 x i1> @p2_vec_poison2(<3 x i8> %val, <3 x i8> %bits) {
101 ; CHECK-LABEL: @p2_vec_poison2(
102 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw <3 x i8> <i8 1, i8 poison, i8 1>, [[BITS:%.*]]
103 ; CHECK-NEXT:    call void @use3i8(<3 x i8> [[T0]])
104 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr <3 x i8> [[VAL:%.*]], [[BITS]]
105 ; CHECK-NEXT:    [[R:%.*]] = icmp eq <3 x i8> [[VAL_HIGHBITS]], zeroinitializer
106 ; CHECK-NEXT:    ret <3 x i1> [[R]]
108   %t0 = shl <3 x i8> <i8 1, i8 poison, i8 1>, %bits
109   call void @use3i8(<3 x i8> %t0)
110   %t1 = add <3 x i8> %t0, <i8 -1, i8 poison, i8 -1>
111   %r = icmp uge <3 x i8> %t1, %val
112   ret <3 x i1> %r
115 ; ============================================================================ ;
116 ; Commutativity tests.
117 ; ============================================================================ ;
119 declare i8 @gen8()
121 define i1 @c0(i8 %bits) {
122 ; CHECK-LABEL: @c0(
123 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
124 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
125 ; CHECK-NEXT:    [[VAL:%.*]] = call i8 @gen8()
126 ; CHECK-NEXT:    [[VAL_HIGHBITS:%.*]] = lshr i8 [[VAL]], [[BITS]]
127 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[VAL_HIGHBITS]], 0
128 ; CHECK-NEXT:    ret i1 [[R]]
130   %t0 = shl i8 1, %bits
131   call void @use8(i8 %t0)
132   %t1 = add i8 %t0, -1
133   %val = call i8 @gen8()
134   %r = icmp ule i8 %val, %t1 ; swapped order and predicate
135   ret i1 %r
138 ; What if we have the same pattern on both sides?
139 define i1 @both(i8 %bits0, i8 %bits1) {
140 ; CHECK-LABEL: @both(
141 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS0:%.*]]
142 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
143 ; CHECK-NEXT:    [[T2:%.*]] = shl nuw i8 1, [[BITS1:%.*]]
144 ; CHECK-NEXT:    call void @use8(i8 [[T2]])
145 ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[T2]], -1
146 ; CHECK-NEXT:    [[T3_HIGHBITS:%.*]] = lshr i8 [[T3]], [[BITS0]]
147 ; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[T3_HIGHBITS]], 0
148 ; CHECK-NEXT:    ret i1 [[R]]
150   %t0 = shl i8 1, %bits0
151   call void @use8(i8 %t0)
152   %t1 = add i8 %t0, -1
153   %t2 = shl i8 1, %bits1
154   call void @use8(i8 %t2)
155   %t3 = add i8 %t2, -1
156   %r = icmp uge i8 %t1, %t3
157   ret i1 %r
160 ; ============================================================================ ;
161 ; One-use tests.
162 ; ============================================================================ ;
164 define i1 @oneuse(i8 %val, i8 %bits) {
165 ; CHECK-LABEL: @oneuse(
166 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
167 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
168 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1
169 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
170 ; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]
171 ; CHECK-NEXT:    ret i1 [[R]]
173   %t0 = shl i8 1, %bits
174   call void @use8(i8 %t0) ; this is needed anyway
175   %t1 = add i8 %t0, -1
176   call void @use8(i8 %t1)
177   %r = icmp uge i8 %t1, %val
178   ret i1 %r
181 ; ============================================================================ ;
182 ; Negative tests
183 ; ============================================================================ ;
185 define i1 @n0(i8 %val, i8 %bits) {
186 ; CHECK-LABEL: @n0(
187 ; CHECK-NEXT:    [[T0:%.*]] = shl nsw i8 -1, [[BITS:%.*]]
188 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
189 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1
190 ; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]
191 ; CHECK-NEXT:    ret i1 [[R]]
193   %t0 = shl i8 -1, %bits ; constant is not 1
194   call void @use8(i8 %t0)
195   %t1 = add i8 %t0, -1
196   %r = icmp uge i8 %t1, %val
197   ret i1 %r
200 define i1 @n1(i8 %val, i8 %bits) {
201 ; CHECK-LABEL: @n1(
202 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
203 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
204 ; CHECK-NEXT:    [[T1:%.*]] = add nuw i8 [[T0]], 1
205 ; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[T1]], [[VAL:%.*]]
206 ; CHECK-NEXT:    ret i1 [[R]]
208   %t0 = shl i8 1, %bits
209   call void @use8(i8 %t0)
210   %t1 = add i8 %t0, 1 ; constant is not -1
211   %r = icmp uge i8 %t1, %val
212   ret i1 %r
215 define <2 x i1> @n2_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
216 ; CHECK-LABEL: @n2_vec_nonsplat(
217 ; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i8> <i8 1, i8 -1>, [[BITS:%.*]]
218 ; CHECK-NEXT:    call void @use2i8(<2 x i8> [[T0]])
219 ; CHECK-NEXT:    [[T1:%.*]] = add <2 x i8> [[T0]], <i8 -1, i8 -1>
220 ; CHECK-NEXT:    [[R:%.*]] = icmp uge <2 x i8> [[T1]], [[VAL:%.*]]
221 ; CHECK-NEXT:    ret <2 x i1> [[R]]
223   %t0 = shl <2 x i8> <i8 1, i8 -1>, %bits ; again, wrong constant
224   call void @use2i8(<2 x i8> %t0)
225   %t1 = add <2 x i8> %t0, <i8 -1, i8 -1>
226   %r = icmp uge <2 x i8> %t1, %val
227   ret <2 x i1> %r
230 define <2 x i1> @n3_vec_nonsplat(<2 x i8> %val, <2 x i8> %bits) {
231 ; CHECK-LABEL: @n3_vec_nonsplat(
232 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw <2 x i8> <i8 1, i8 1>, [[BITS:%.*]]
233 ; CHECK-NEXT:    call void @use2i8(<2 x i8> [[T0]])
234 ; CHECK-NEXT:    [[T1:%.*]] = add <2 x i8> [[T0]], <i8 -1, i8 1>
235 ; CHECK-NEXT:    [[R:%.*]] = icmp uge <2 x i8> [[T1]], [[VAL:%.*]]
236 ; CHECK-NEXT:    ret <2 x i1> [[R]]
238   %t0 = shl <2 x i8> <i8 1, i8 1>, %bits
239   call void @use2i8(<2 x i8> %t0)
240   %t1 = add <2 x i8> %t0, <i8 -1, i8 1> ; again, wrong constant
241   %r = icmp uge <2 x i8> %t1, %val
242   ret <2 x i1> %r
245 define i1 @n3(i8 %val, i8 %bits) {
246 ; CHECK-LABEL: @n3(
247 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
248 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
249 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1
250 ; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[T1]], [[VAL:%.*]]
251 ; CHECK-NEXT:    ret i1 [[R]]
253   %t0 = shl i8 1, %bits
254   call void @use8(i8 %t0)
255   %t1 = add i8 %t0, -1
256   %r = icmp ugt i8 %t1, %val ; wrong predicate
257   ret i1 %r
260 define i1 @n4(i8 %bits) {
261 ; CHECK-LABEL: @n4(
262 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[BITS:%.*]]
263 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
264 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0]], -1
265 ; CHECK-NEXT:    [[VAL:%.*]] = call i8 @gen8()
266 ; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[VAL]], [[T1]]
267 ; CHECK-NEXT:    ret i1 [[R]]
269   %t0 = shl i8 1, %bits
270   call void @use8(i8 %t0)
271   %t1 = add i8 %t0, -1
272   %val = call i8 @gen8()
273   %r = icmp ult i8 %val, %t1 ; swapped order and [wrong] predicate
274   ret i1 %r