xref: /llvm-project/llvm/test/Transforms/InstCombine/or-shifted-masks.ll (revision 7ec4f6094e54911794c142b5d88496a220d807d6)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4define 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]]
12;
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
19}
20
21define 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]]
29;
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
36}
37
38define 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]]
46;
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
53}
54
55define 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]]
66;
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
77}
78
79define 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]]
93;
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
109}
110
111define 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]]
122;
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
134}
135
136define 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]]
154;
155  %i = and i32 %x, 100663296
156  %i1 = icmp sgt i32 %x, -1
157  br i1 %i1, label %if, label %else
158
159if:
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
165
166else:
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
172
173end:
174  %i10 = phi i32 [ %i5, %if ], [ %i9, %else ]
175  ret i32 %i10
176}
177
178define 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]]
198;
199  %i = shl i32 %x, 5
200  %i1 = icmp sgt i32 %x, -1
201  br i1 %i1, label %if, label %else
202
203if:
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
209
210else:
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
216
217end:
218  %i10 = phi i32 [ %i5, %if ], [ %i9, %else ]
219  ret i32 %i10
220}
221
222define 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]]
228;
229  %z = and i32 %x, 255
230  %s = shl i32 %z, 8
231  %r = or i32 %z, %s
232  ret i32 %r
233}
234
235define 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]]
241;
242  %z = and i32 %x, 255
243  %s = shl i32 %z, 7
244  %r = or i32 %z, %s
245  ret i32 %r
246}
247
248define 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]]
254;
255  %z = and i37 %x, 255
256  %s = shl i37 %z, 8
257  %r = or i37 %z, %s
258  ret i37 %r
259}
260
261define 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]]
268;
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
274}
275
276; This could be "Z * 65793".
277
278define 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]]
285;
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
291}
292
293define 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]]
300;
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
306}
307