[Transforms] Silence a warning in SROA.cpp (NFC)
[llvm-project.git] / llvm / test / Transforms / InstCombine / or-shifted-masks.ll
blob3d7ca9c1fb1239175733a3b73e11c9c9cd22e946
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 define i32 @or_and_shifts1(i32 %x) {
5 ; CHECK-LABEL: @or_and_shifts1(
6 ; CHECK-NEXT:    [[I:%.*]] = shl i32 [[X:%.*]], 3
7 ; CHECK-NEXT:    [[I1:%.*]] = and i32 [[I]], 8
8 ; CHECK-NEXT:    [[I2:%.*]] = shl i32 [[X]], 5
9 ; CHECK-NEXT:    [[I3:%.*]] = and i32 [[I2]], 32
10 ; CHECK-NEXT:    [[I4:%.*]] = or disjoint i32 [[I1]], [[I3]]
11 ; CHECK-NEXT:    ret i32 [[I4]]
13   %i = shl i32 %x, 3
14   %i1 = and i32 %i, 15
15   %i2 = shl i32 %x, 5
16   %i3 = and i32 %i2, 60
17   %i4 = or i32 %i1, %i3
18   ret i32 %i4
21 define i32 @or_and_shifts2(i32 %x) {
22 ; CHECK-LABEL: @or_and_shifts2(
23 ; CHECK-NEXT:    [[I:%.*]] = shl i32 [[X:%.*]], 3
24 ; CHECK-NEXT:    [[I1:%.*]] = and i32 [[I]], 896
25 ; CHECK-NEXT:    [[I2:%.*]] = lshr i32 [[X]], 4
26 ; CHECK-NEXT:    [[I3:%.*]] = and i32 [[I2]], 7
27 ; CHECK-NEXT:    [[I4:%.*]] = or disjoint i32 [[I1]], [[I3]]
28 ; CHECK-NEXT:    ret i32 [[I4]]
30   %i = shl i32 %x, 3
31   %i1 = and i32 %i, 896
32   %i2 = lshr i32 %x, 4
33   %i3 = and i32 %i2, 7
34   %i4 = or i32 %i1, %i3
35   ret i32 %i4
38 define i32 @or_and_shift_shift_and(i32 %x) {
39 ; CHECK-LABEL: @or_and_shift_shift_and(
40 ; CHECK-NEXT:    [[I:%.*]] = shl i32 [[X:%.*]], 3
41 ; CHECK-NEXT:    [[I1:%.*]] = and i32 [[I]], 56
42 ; CHECK-NEXT:    [[I2:%.*]] = shl i32 [[X]], 2
43 ; CHECK-NEXT:    [[I3:%.*]] = and i32 [[I2]], 28
44 ; CHECK-NEXT:    [[I4:%.*]] = or i32 [[I1]], [[I3]]
45 ; CHECK-NEXT:    ret i32 [[I4]]
47   %i = and i32 %x, 7
48   %i1 = shl i32 %i, 3
49   %i2 = shl i32 %x, 2
50   %i3 = and i32 %i2, 28
51   %i4 = or i32 %i1, %i3
52   ret i32 %i4
55 define i32 @multiuse1(i32 %x) {
56 ; CHECK-LABEL: @multiuse1(
57 ; CHECK-NEXT:    [[I:%.*]] = lshr i32 [[X:%.*]], 1
58 ; CHECK-NEXT:    [[I3:%.*]] = and i32 [[I]], 1
59 ; CHECK-NEXT:    [[I1:%.*]] = lshr i32 [[X]], 1
60 ; CHECK-NEXT:    [[I5:%.*]] = and i32 [[I1]], 2
61 ; CHECK-NEXT:    [[I21:%.*]] = shl i32 [[X]], 6
62 ; CHECK-NEXT:    [[I6:%.*]] = and i32 [[I21]], 384
63 ; CHECK-NEXT:    [[I7:%.*]] = or disjoint i32 [[I3]], [[I5]]
64 ; CHECK-NEXT:    [[I8:%.*]] = or disjoint i32 [[I7]], [[I6]]
65 ; CHECK-NEXT:    ret i32 [[I8]]
67   %i = and i32 %x, 2
68   %i1 = and i32 %x, 4
69   %i2 = shl nuw nsw i32 %i, 6
70   %i3 = lshr exact i32 %i, 1
71   %i4 = shl nuw nsw i32 %i1, 6
72   %i5 = lshr exact i32 %i1, 1
73   %i6 = or i32 %i2, %i4
74   %i7 = or i32 %i3, %i5
75   %i8 = or i32 %i7, %i6
76   ret i32 %i8
79 define i32 @multiuse2(i32 %x) {
80 ; CHECK-LABEL: @multiuse2(
81 ; CHECK-NEXT:    [[I:%.*]] = shl i32 [[X:%.*]], 1
82 ; CHECK-NEXT:    [[I2:%.*]] = and i32 [[I]], 12
83 ; CHECK-NEXT:    [[I3:%.*]] = shl i32 [[X]], 1
84 ; CHECK-NEXT:    [[I5:%.*]] = and i32 [[I3]], 48
85 ; CHECK-NEXT:    [[I6:%.*]] = shl i32 [[X]], 1
86 ; CHECK-NEXT:    [[I8:%.*]] = and i32 [[I6]], 192
87 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X]], 8
88 ; CHECK-NEXT:    [[I10:%.*]] = and i32 [[TMP1]], 32256
89 ; CHECK-NEXT:    [[I11:%.*]] = or disjoint i32 [[I8]], [[I5]]
90 ; CHECK-NEXT:    [[I12:%.*]] = or disjoint i32 [[I2]], [[I11]]
91 ; CHECK-NEXT:    [[I13:%.*]] = or disjoint i32 [[I10]], [[I12]]
92 ; CHECK-NEXT:    ret i32 [[I13]]
94   %i = and i32 %x, 6
95   %i1 = shl nuw nsw i32 %i, 8
96   %i2 = shl nuw nsw i32 %i, 1
97   %i3 = and i32 %x, 24
98   %i4 = shl nuw nsw i32 %i3, 8
99   %i5 = shl nuw nsw i32 %i3, 1
100   %i6 = and i32 %x, 96
101   %i7 = shl nuw nsw i32 %i6, 8
102   %i8 = shl nuw nsw i32 %i6, 1
103   %i9 = or i32 %i1, %i4
104   %i10 = or i32 %i7, %i9
105   %i11 = or i32 %i8, %i5
106   %i12 = or i32 %i2, %i11
107   %i13 = or i32 %i10, %i12
108   ret i32 %i13
111 define i32 @multiuse3(i32 %x) {
112 ; CHECK-LABEL: @multiuse3(
113 ; CHECK-NEXT:    [[I:%.*]] = lshr i32 [[X:%.*]], 1
114 ; CHECK-NEXT:    [[I2:%.*]] = and i32 [[I]], 48
115 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X]], 6
116 ; CHECK-NEXT:    [[I5:%.*]] = and i32 [[TMP1]], 8064
117 ; CHECK-NEXT:    [[I6:%.*]] = lshr i32 [[X]], 1
118 ; CHECK-NEXT:    [[I7:%.*]] = and i32 [[I6]], 15
119 ; CHECK-NEXT:    [[I8:%.*]] = or disjoint i32 [[I2]], [[I7]]
120 ; CHECK-NEXT:    [[I9:%.*]] = or disjoint i32 [[I8]], [[I5]]
121 ; CHECK-NEXT:    ret i32 [[I9]]
123   %i = and i32 %x, 96
124   %i1 = shl nuw nsw i32 %i, 6
125   %i2 = lshr exact i32 %i, 1
126   %i3 = shl i32 %x, 6
127   %i4 = and i32 %i3, 1920
128   %i5 = or i32 %i1, %i4
129   %i6 = lshr i32 %x, 1
130   %i7 = and i32 %i6, 15
131   %i8 = or i32 %i2, %i7
132   %i9 = or i32 %i8, %i5
133   ret i32 %i9
136 define i32 @multiuse4(i32 %x) local_unnamed_addr {
137 ; CHECK-LABEL: @multiuse4(
138 ; CHECK-NEXT:    [[I1:%.*]] = icmp sgt i32 [[X:%.*]], -1
139 ; CHECK-NEXT:    br i1 [[I1]], label [[IF:%.*]], label [[ELSE:%.*]]
140 ; CHECK:       if:
141 ; CHECK-NEXT:    [[I:%.*]] = lshr i32 [[X]], 22
142 ; CHECK-NEXT:    [[I2:%.*]] = and i32 [[I]], 24
143 ; CHECK-NEXT:    [[I3:%.*]] = lshr i32 [[X]], 22
144 ; CHECK-NEXT:    [[I4:%.*]] = and i32 [[I3]], 480
145 ; CHECK-NEXT:    [[I5:%.*]] = or disjoint i32 [[I4]], [[I2]]
146 ; CHECK-NEXT:    br label [[END:%.*]]
147 ; CHECK:       else:
148 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i32 [[X]], 17
149 ; CHECK-NEXT:    [[I9:%.*]] = and i32 [[TMP1]], 16128
150 ; CHECK-NEXT:    br label [[END]]
151 ; CHECK:       end:
152 ; CHECK-NEXT:    [[I10:%.*]] = phi i32 [ [[I5]], [[IF]] ], [ [[I9]], [[ELSE]] ]
153 ; CHECK-NEXT:    ret i32 [[I10]]
155   %i = and i32 %x, 100663296
156   %i1 = icmp sgt i32 %x, -1
157   br i1 %i1, label %if, label %else
160   %i2 = lshr exact i32 %i, 22
161   %i3 = lshr i32 %x, 22
162   %i4 = and i32 %i3, 480
163   %i5 = or i32 %i4, %i2
164   br label %end
166 else:
167   %i6 = lshr exact i32 %i, 17
168   %i7 = lshr i32 %x, 17
169   %i8 = and i32 %i7, 15360
170   %i9 = or i32 %i8, %i6
171   br label %end
173 end:
174   %i10 = phi i32 [ %i5, %if ], [ %i9, %else ]
175   ret i32 %i10
178 define i32 @multiuse5(i32 %x) local_unnamed_addr {
179 ; CHECK-LABEL: @multiuse5(
180 ; CHECK-NEXT:    [[I:%.*]] = shl i32 [[X:%.*]], 5
181 ; CHECK-NEXT:    [[I1:%.*]] = icmp sgt i32 [[X]], -1
182 ; CHECK-NEXT:    br i1 [[I1]], label [[IF:%.*]], label [[ELSE:%.*]]
183 ; CHECK:       if:
184 ; CHECK-NEXT:    [[I2:%.*]] = and i32 [[I]], 21760
185 ; CHECK-NEXT:    [[I3:%.*]] = shl i32 [[X]], 5
186 ; CHECK-NEXT:    [[I4:%.*]] = and i32 [[I3]], 43520
187 ; CHECK-NEXT:    [[I5:%.*]] = or disjoint i32 [[I4]], [[I2]]
188 ; CHECK-NEXT:    br label [[END:%.*]]
189 ; CHECK:       else:
190 ; CHECK-NEXT:    [[I6:%.*]] = and i32 [[I]], 5570560
191 ; CHECK-NEXT:    [[I7:%.*]] = shl i32 [[X]], 5
192 ; CHECK-NEXT:    [[I8:%.*]] = and i32 [[I7]], 11141120
193 ; CHECK-NEXT:    [[I9:%.*]] = or disjoint i32 [[I8]], [[I6]]
194 ; CHECK-NEXT:    br label [[END]]
195 ; CHECK:       end:
196 ; CHECK-NEXT:    [[I10:%.*]] = phi i32 [ [[I5]], [[IF]] ], [ [[I9]], [[ELSE]] ]
197 ; CHECK-NEXT:    ret i32 [[I10]]
199   %i = shl i32 %x, 5
200   %i1 = icmp sgt i32 %x, -1
201   br i1 %i1, label %if, label %else
204   %i2 = and i32 %i, 21760
205   %i3 = and i32 %x, 1360
206   %i4 = shl nuw nsw i32 %i3, 5
207   %i5 = or i32 %i4, %i2
208   br label %end
210 else:
211   %i6 = and i32 %i, 5570560
212   %i7 = and i32 %x, 348160
213   %i8 = shl nuw nsw i32 %i7, 5
214   %i9 = or i32 %i8, %i6
215   br label %end
217 end:
218   %i10 = phi i32 [ %i5, %if ], [ %i9, %else ]
219   ret i32 %i10
222 define i32 @shl_mask(i32 %x) {
223 ; CHECK-LABEL: @shl_mask(
224 ; CHECK-NEXT:    [[Z:%.*]] = and i32 [[X:%.*]], 255
225 ; CHECK-NEXT:    [[S:%.*]] = shl nuw nsw i32 [[Z]], 8
226 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i32 [[Z]], [[S]]
227 ; CHECK-NEXT:    ret i32 [[R]]
229   %z = and i32 %x, 255
230   %s = shl i32 %z, 8
231   %r = or i32 %z, %s
232   ret i32 %r
235 define i32 @shl_mask_wrong_shl_const(i32 %x) {
236 ; CHECK-LABEL: @shl_mask_wrong_shl_const(
237 ; CHECK-NEXT:    [[Z:%.*]] = and i32 [[X:%.*]], 255
238 ; CHECK-NEXT:    [[S:%.*]] = shl nuw nsw i32 [[Z]], 7
239 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[Z]], [[S]]
240 ; CHECK-NEXT:    ret i32 [[R]]
242   %z = and i32 %x, 255
243   %s = shl i32 %z, 7
244   %r = or i32 %z, %s
245   ret i32 %r
248 define i37 @shl_mask_weird_type(i37 %x) {
249 ; CHECK-LABEL: @shl_mask_weird_type(
250 ; CHECK-NEXT:    [[Z:%.*]] = and i37 [[X:%.*]], 255
251 ; CHECK-NEXT:    [[S:%.*]] = shl nuw nsw i37 [[Z]], 8
252 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i37 [[Z]], [[S]]
253 ; CHECK-NEXT:    ret i37 [[R]]
255   %z = and i37 %x, 255
256   %s = shl i37 %z, 8
257   %r = or i37 %z, %s
258   ret i37 %r
261 define i32 @shl_mask_extra_use(i32 %x, ptr %p) {
262 ; CHECK-LABEL: @shl_mask_extra_use(
263 ; CHECK-NEXT:    [[Z:%.*]] = and i32 [[X:%.*]], 255
264 ; CHECK-NEXT:    [[S:%.*]] = shl nuw nsw i32 [[Z]], 8
265 ; CHECK-NEXT:    store i32 [[S]], ptr [[P:%.*]], align 4
266 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i32 [[Z]], [[S]]
267 ; CHECK-NEXT:    ret i32 [[R]]
269   %z = and i32 %x, 255
270   %s = shl i32 %z, 8
271   store i32 %s, ptr %p, align 4
272   %r = or i32 %z, %s
273   ret i32 %r
276 ; This could be "Z * 65793".
278 define i32 @shl_mul_mask(i32 %x) {
279 ; CHECK-LABEL: @shl_mul_mask(
280 ; CHECK-NEXT:    [[Z:%.*]] = and i32 [[X:%.*]], 255
281 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[Z]], 65537
282 ; CHECK-NEXT:    [[S:%.*]] = shl nuw nsw i32 [[Z]], 8
283 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[S]]
284 ; CHECK-NEXT:    ret i32 [[R]]
286   %z = and i32 %x, 255
287   %m = mul i32 %z, 65537
288   %s = shl i32 %z, 8
289   %r = or i32 %m, %s
290   ret i32 %r
293 define i32 @shl_mul_mask_wrong_mul_const(i32 %x) {
294 ; CHECK-LABEL: @shl_mul_mask_wrong_mul_const(
295 ; CHECK-NEXT:    [[Z:%.*]] = and i32 [[X:%.*]], 255
296 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[Z]], 65535
297 ; CHECK-NEXT:    [[S:%.*]] = shl nuw nsw i32 [[Z]], 8
298 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[S]]
299 ; CHECK-NEXT:    ret i32 [[R]]
301   %z = and i32 %x, 255
302   %m = mul i32 %z, 65535
303   %s = shl i32 %z, 8
304   %r = or i32 %m, %s
305   ret i32 %r