[ARM] Better OR's for MVE compares
[llvm-core.git] / test / Transforms / InstCombine / set-lowbits-mask-canonicalize.ll
blob99ec45098380bfa435a991d55ae0f3632528bd34
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 ; https://bugs.llvm.org/show_bug.cgi?id=37603
6 ; Pattern:
7 ;   (1 << NBits) - 1
8 ; Should be transformed into:
9 ;   ~(-(1 << NBits))
10 ; The `not` may end up being folded into `and`
12 ; ============================================================================ ;
13 ; Most basic positive tests
14 ; ============================================================================ ;
16 ; No no-wrap tags on shl
18 define i32 @shl_add(i32 %NBits) {
19 ; CHECK-LABEL: @shl_add(
20 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
21 ; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[NOTMASK]], -1
22 ; CHECK-NEXT:    ret i32 [[RET]]
24   %setbit = shl i32 1, %NBits
25   %ret = add i32 %setbit, -1
26   ret i32 %ret
29 define i32 @shl_add_nsw(i32 %NBits) {
30 ; CHECK-LABEL: @shl_add_nsw(
31 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
32 ; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[NOTMASK]], -1
33 ; CHECK-NEXT:    ret i32 [[RET]]
35   %setbit = shl i32 1, %NBits
36   %ret = add nsw i32 %setbit, -1
37   ret i32 %ret
40 define i32 @shl_add_nuw(i32 %NBits) {
41 ; CHECK-LABEL: @shl_add_nuw(
42 ; CHECK-NEXT:    ret i32 -1
44   %setbit = shl i32 1, %NBits
45   %ret = add nuw i32 %setbit, -1
46   ret i32 %ret
49 define i32 @shl_add_nsw_nuw(i32 %NBits) {
50 ; CHECK-LABEL: @shl_add_nsw_nuw(
51 ; CHECK-NEXT:    ret i32 -1
53   %setbit = shl i32 1, %NBits
54   %ret = add nuw nsw i32 %setbit, -1
55   ret i32 %ret
58 ; shl is nsw
60 define i32 @shl_nsw_add(i32 %NBits) {
61 ; CHECK-LABEL: @shl_nsw_add(
62 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
63 ; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[NOTMASK]], -1
64 ; CHECK-NEXT:    ret i32 [[RET]]
66   %setbit = shl nsw i32 1, %NBits
67   %ret = add i32 %setbit, -1
68   ret i32 %ret
71 define i32 @shl_nsw_add_nsw(i32 %NBits) {
72 ; CHECK-LABEL: @shl_nsw_add_nsw(
73 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
74 ; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[NOTMASK]], -1
75 ; CHECK-NEXT:    ret i32 [[RET]]
77   %setbit = shl nsw i32 1, %NBits
78   %ret = add nsw i32 %setbit, -1
79   ret i32 %ret
82 define i32 @shl_nsw_add_nuw(i32 %NBits) {
83 ; CHECK-LABEL: @shl_nsw_add_nuw(
84 ; CHECK-NEXT:    ret i32 -1
86   %setbit = shl nsw i32 1, %NBits
87   %ret = add nuw i32 %setbit, -1
88   ret i32 %ret
91 define i32 @shl_nsw_add_nsw_nuw(i32 %NBits) {
92 ; CHECK-LABEL: @shl_nsw_add_nsw_nuw(
93 ; CHECK-NEXT:    ret i32 -1
95   %setbit = shl nsw i32 1, %NBits
96   %ret = add nuw nsw i32 %setbit, -1
97   ret i32 %ret
100 ; shl is nuw
102 define i32 @shl_nuw_add(i32 %NBits) {
103 ; CHECK-LABEL: @shl_nuw_add(
104 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
105 ; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[NOTMASK]], -1
106 ; CHECK-NEXT:    ret i32 [[RET]]
108   %setbit = shl nuw i32 1, %NBits
109   %ret = add i32 %setbit, -1
110   ret i32 %ret
113 define i32 @shl_nuw_add_nsw(i32 %NBits) {
114 ; CHECK-LABEL: @shl_nuw_add_nsw(
115 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
116 ; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[NOTMASK]], -1
117 ; CHECK-NEXT:    ret i32 [[RET]]
119   %setbit = shl nuw i32 1, %NBits
120   %ret = add nsw i32 %setbit, -1
121   ret i32 %ret
124 define i32 @shl_nuw_add_nuw(i32 %NBits) {
125 ; CHECK-LABEL: @shl_nuw_add_nuw(
126 ; CHECK-NEXT:    ret i32 -1
128   %setbit = shl nuw i32 1, %NBits
129   %ret = add nuw i32 %setbit, -1
130   ret i32 %ret
133 define i32 @shl_nuw_add_nsw_nuw(i32 %NBits) {
134 ; CHECK-LABEL: @shl_nuw_add_nsw_nuw(
135 ; CHECK-NEXT:    ret i32 -1
137   %setbit = shl nuw i32 1, %NBits
138   %ret = add nuw nsw i32 %setbit, -1
139   ret i32 %ret
142 ; shl is nuw nsw
144 define i32 @shl_nsw_nuw_add(i32 %NBits) {
145 ; CHECK-LABEL: @shl_nsw_nuw_add(
146 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
147 ; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[NOTMASK]], -1
148 ; CHECK-NEXT:    ret i32 [[RET]]
150   %setbit = shl nuw nsw i32 1, %NBits
151   %ret = add i32 %setbit, -1
152   ret i32 %ret
155 define i32 @shl_nsw_nuw_add_nsw(i32 %NBits) {
156 ; CHECK-LABEL: @shl_nsw_nuw_add_nsw(
157 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[NBITS:%.*]]
158 ; CHECK-NEXT:    [[RET:%.*]] = xor i32 [[NOTMASK]], -1
159 ; CHECK-NEXT:    ret i32 [[RET]]
161   %setbit = shl nuw nsw i32 1, %NBits
162   %ret = add nsw i32 %setbit, -1
163   ret i32 %ret
166 define i32 @shl_nsw_nuw_add_nuw(i32 %NBits) {
167 ; CHECK-LABEL: @shl_nsw_nuw_add_nuw(
168 ; CHECK-NEXT:    ret i32 -1
170   %setbit = shl nuw nsw i32 1, %NBits
171   %ret = add nuw i32 %setbit, -1
172   ret i32 %ret
175 define i32 @shl_nsw_nuw_add_nsw_nuw(i32 %NBits) {
176 ; CHECK-LABEL: @shl_nsw_nuw_add_nsw_nuw(
177 ; CHECK-NEXT:    ret i32 -1
179   %setbit = shl nuw nsw i32 1, %NBits
180   %ret = add nuw nsw i32 %setbit, -1
181   ret i32 %ret
184 ; ============================================================================ ;
185 ; Vectors
186 ; ============================================================================ ;
188 define <2 x i32> @shl_add_vec(<2 x i32> %NBits) {
189 ; CHECK-LABEL: @shl_add_vec(
190 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw <2 x i32> <i32 -1, i32 -1>, [[NBITS:%.*]]
191 ; CHECK-NEXT:    [[RET:%.*]] = xor <2 x i32> [[NOTMASK]], <i32 -1, i32 -1>
192 ; CHECK-NEXT:    ret <2 x i32> [[RET]]
194   %setbit = shl <2 x i32> <i32 1, i32 1>, %NBits
195   %ret = add <2 x i32> %setbit, <i32 -1, i32 -1>
196   ret <2 x i32> %ret
199 define <3 x i32> @shl_add_vec_undef0(<3 x i32> %NBits) {
200 ; CHECK-LABEL: @shl_add_vec_undef0(
201 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
202 ; CHECK-NEXT:    [[RET:%.*]] = xor <3 x i32> [[NOTMASK]], <i32 -1, i32 -1, i32 -1>
203 ; CHECK-NEXT:    ret <3 x i32> [[RET]]
205   %setbit = shl <3 x i32> <i32 1, i32 undef, i32 1>, %NBits
206   %ret = add <3 x i32> %setbit, <i32 -1, i32 -1, i32 -1>
207   ret <3 x i32> %ret
210 define <3 x i32> @shl_add_vec_undef1(<3 x i32> %NBits) {
211 ; CHECK-LABEL: @shl_add_vec_undef1(
212 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
213 ; CHECK-NEXT:    [[RET:%.*]] = xor <3 x i32> [[NOTMASK]], <i32 -1, i32 -1, i32 -1>
214 ; CHECK-NEXT:    ret <3 x i32> [[RET]]
216   %setbit = shl <3 x i32> <i32 1, i32 1, i32 1>, %NBits
217   %ret = add <3 x i32> %setbit, <i32 -1, i32 undef, i32 -1>
218   ret <3 x i32> %ret
221 define <3 x i32> @shl_add_vec_undef2(<3 x i32> %NBits) {
222 ; CHECK-LABEL: @shl_add_vec_undef2(
223 ; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw <3 x i32> <i32 -1, i32 -1, i32 -1>, [[NBITS:%.*]]
224 ; CHECK-NEXT:    [[RET:%.*]] = xor <3 x i32> [[NOTMASK]], <i32 -1, i32 -1, i32 -1>
225 ; CHECK-NEXT:    ret <3 x i32> [[RET]]
227   %setbit = shl <3 x i32> <i32 1, i32 undef, i32 1>, %NBits
228   %ret = add <3 x i32> %setbit, <i32 -1, i32 undef, i32 -1>
229   ret <3 x i32> %ret
232 ; ============================================================================ ;
233 ; Negative tests. Should not be folded.
234 ; ============================================================================ ;
236 declare void @use32(i32)
238 ; One use only.
239 define i32 @bad_oneuse0(i32 %NBits) {
240 ; CHECK-LABEL: @bad_oneuse0(
241 ; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
242 ; CHECK-NEXT:    call void @use32(i32 [[SETBIT]])
243 ; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -1
244 ; CHECK-NEXT:    ret i32 [[RET]]
246   %setbit = shl i32 1, %NBits
247   call void @use32(i32 %setbit)
248   %ret = add i32 %setbit, -1
249   ret i32 %ret
252 ; shift base is not `1` constant
254 define i32 @bad_shl(i32 %base, i32 %NBits) {
255 ; CHECK-LABEL: @bad_shl(
256 ; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 [[BASE:%.*]], [[NBITS:%.*]]
257 ; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -1
258 ; CHECK-NEXT:    ret i32 [[RET]]
260   %setbit = shl i32 %base, %NBits ; %base instead of 1
261   %ret = add i32 %setbit, -1
262   ret i32 %ret
265 ; Second `add` operand is not `-1` constant
267 define i32 @bad_add0(i32 %NBits, i32 %addop2) {
268 ; CHECK-LABEL: @bad_add0(
269 ; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
270 ; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], [[ADDOP2:%.*]]
271 ; CHECK-NEXT:    ret i32 [[RET]]
273   %setbit = shl i32 1, %NBits
274   %ret = add i32 %setbit, %addop2
275   ret i32 %ret
278 ; Bad add constant
280 define i32 @bad_add1(i32 %NBits) {
281 ; CHECK-LABEL: @bad_add1(
282 ; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
283 ; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], 1
284 ; CHECK-NEXT:    ret i32 [[RET]]
286   %setbit = shl i32 1, %NBits
287   %ret = add i32 %setbit, 1 ; not -1
288   ret i32 %ret
291 define i32 @bad_add2(i32 %NBits) {
292 ; CHECK-LABEL: @bad_add2(
293 ; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
294 ; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -2
295 ; CHECK-NEXT:    ret i32 [[RET]]
297   %setbit = shl i32 1, %NBits
298   %ret = add i32 %setbit, -2 ; not -1
299   ret i32 %ret