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]]
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]]
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]]
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]]
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
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]]
95 %i1 = shl nuw nsw i32 %i, 8
96 %i2 = shl nuw nsw i32 %i, 1
98 %i4 = shl nuw nsw i32 %i3, 8
99 %i5 = shl nuw nsw i32 %i3, 1
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
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]]
124 %i1 = shl nuw nsw i32 %i, 6
125 %i2 = lshr exact i32 %i, 1
127 %i4 = and i32 %i3, 1920
128 %i5 = or i32 %i1, %i4
130 %i7 = and i32 %i6, 15
131 %i8 = or i32 %i2, %i7
132 %i9 = or i32 %i8, %i5
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:%.*]]
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:%.*]]
148 ; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X]], 17
149 ; CHECK-NEXT: [[I9:%.*]] = and i32 [[TMP1]], 16128
150 ; CHECK-NEXT: br label [[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
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
174 %i10 = phi i32 [ %i5, %if ], [ %i9, %else ]
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:%.*]]
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:%.*]]
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]]
196 ; CHECK-NEXT: [[I10:%.*]] = phi i32 [ [[I5]], [[IF]] ], [ [[I9]], [[ELSE]] ]
197 ; CHECK-NEXT: ret i32 [[I10]]
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
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
218 %i10 = phi i32 [ %i5, %if ], [ %i9, %else ]
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]]
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]]
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]]
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]]
271 store i32 %s, ptr %p, align 4
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]]
287 %m = mul i32 %z, 65537
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]]
302 %m = mul i32 %z, 65535