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
8 ; Should be transformed into:
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
184 ; ============================================================================ ;
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>
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>
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>
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>
232 ; ============================================================================ ;
233 ; Negative tests. Should not be folded.
234 ; ============================================================================ ;
236 declare void @use32(i32)
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
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
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
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
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