1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -instcombine < %s | FileCheck %s
4 define i32 @or_and_shifts1(i32 %x) {
5 ; CHECK-LABEL: @or_and_shifts1(
6 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 3
7 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 8
8 ; CHECK-NEXT: [[TMP3:%.*]] = shl i32 [[X]], 5
9 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 32
10 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]]
11 ; CHECK-NEXT: ret i32 [[TMP5]]
21 define i32 @or_and_shifts2(i32 %x) {
22 ; CHECK-LABEL: @or_and_shifts2(
23 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 3
24 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 896
25 ; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[X]], 4
26 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 7
27 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]]
28 ; CHECK-NEXT: ret i32 [[TMP5]]
38 define i32 @or_and_shift_shift_and(i32 %x) {
39 ; CHECK-LABEL: @or_and_shift_shift_and(
40 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 3
41 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 56
42 ; CHECK-NEXT: [[TMP3:%.*]] = shl i32 [[X]], 2
43 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 28
44 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP2]], [[TMP4]]
45 ; CHECK-NEXT: ret i32 [[TMP5]]
55 define i32 @multiuse1(i32 %x) {
56 ; CHECK-LABEL: @multiuse1(
57 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 6
58 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 384
59 ; CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[X]], 1
60 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 3
61 ; CHECK-NEXT: [[TMP5:%.*]] = or i32 [[TMP4]], [[TMP2]]
62 ; CHECK-NEXT: ret i32 [[TMP5]]
66 %3 = shl nuw nsw i32 %1, 6
67 %4 = lshr exact i32 %1, 1
68 %5 = shl nuw nsw i32 %2, 6
69 %6 = lshr exact i32 %2, 1
76 define i32 @multiuse2(i32 %x) {
77 ; CHECK-LABEL: @multiuse2(
78 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 1
79 ; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], 12
80 ; CHECK-NEXT: [[TMP3:%.*]] = shl i32 [[X]], 8
81 ; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], 24576
82 ; CHECK-NEXT: [[TMP5:%.*]] = shl i32 [[X]], 8
83 ; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 7680
84 ; CHECK-NEXT: [[TMP7:%.*]] = or i32 [[TMP4]], [[TMP6]]
85 ; CHECK-NEXT: [[TMP8:%.*]] = shl i32 [[X]], 1
86 ; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 240
87 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP2]], [[TMP9]]
88 ; CHECK-NEXT: [[TMP11:%.*]] = or i32 [[TMP7]], [[TMP10]]
89 ; CHECK-NEXT: ret i32 [[TMP11]]
92 %2 = shl nuw nsw i32 %1, 8
93 %3 = shl nuw nsw i32 %1, 1
95 %5 = shl nuw nsw i32 %4, 8
96 %6 = shl nuw nsw i32 %4, 1
98 %8 = shl nuw nsw i32 %7, 8
99 %9 = shl nuw nsw i32 %7, 1
104 %14 = or i32 %11, %13
108 define i32 @multiuse3(i32 %x) {
109 ; CHECK-LABEL: @multiuse3(
110 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 96
111 ; CHECK-NEXT: [[TMP2:%.*]] = shl nuw nsw i32 [[TMP1]], 6
112 ; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i32 [[TMP1]], 1
113 ; CHECK-NEXT: [[TMP4:%.*]] = shl i32 [[X]], 6
114 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 1920
115 ; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP2]], [[TMP5]]
116 ; CHECK-NEXT: [[TMP7:%.*]] = lshr i32 [[X]], 1
117 ; CHECK-NEXT: [[TMP8:%.*]] = and i32 [[TMP7]], 15
118 ; CHECK-NEXT: [[TMP9:%.*]] = or i32 [[TMP3]], [[TMP8]]
119 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP6]]
120 ; CHECK-NEXT: ret i32 [[TMP10]]
123 %2 = shl nuw nsw i32 %1, 6
124 %3 = lshr exact i32 %1, 1
126 %5 = and i32 %4, 1920
135 define i32 @multiuse4(i32 %x) local_unnamed_addr #0 {
136 ; CHECK-LABEL: @multiuse4(
137 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 100663296
138 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -1
139 ; CHECK-NEXT: br i1 [[TMP2]], label [[IF:%.*]], label [[ELSE:%.*]]
141 ; CHECK-NEXT: [[TMP3:%.*]] = lshr exact i32 [[TMP1]], 22
142 ; CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[X]], 22
143 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 480
144 ; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP5]], [[TMP3]]
145 ; CHECK-NEXT: br label [[END:%.*]]
147 ; CHECK-NEXT: [[TMP7:%.*]] = lshr exact i32 [[TMP1]], 17
148 ; CHECK-NEXT: [[TMP8:%.*]] = lshr i32 [[X]], 17
149 ; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 15360
150 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP7]]
151 ; CHECK-NEXT: br label [[END]]
153 ; CHECK-NEXT: [[TMP11:%.*]] = phi i32 [ [[TMP6]], [[IF]] ], [ [[TMP10]], [[ELSE]] ]
154 ; CHECK-NEXT: ret i32 [[TMP11]]
156 %1 = and i32 %x, 100663296
157 %2 = icmp sgt i32 %x, -1
158 br i1 %2, label %if, label %else
161 %3 = lshr exact i32 %1, 22
168 %7 = lshr exact i32 %1, 17
170 %9 = and i32 %8, 15360
175 %11 = phi i32 [ %6, %if ], [ %10, %else ]
179 define i32 @multiuse5(i32 %x) local_unnamed_addr #0 {
180 ; CHECK-LABEL: @multiuse5(
181 ; CHECK-NEXT: [[TMP1:%.*]] = shl i32 [[X:%.*]], 5
182 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[X]], -1
183 ; CHECK-NEXT: br i1 [[TMP2]], label [[IF:%.*]], label [[ELSE:%.*]]
185 ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP1]], 21760
186 ; CHECK-NEXT: [[TMP4:%.*]] = shl i32 [[X]], 5
187 ; CHECK-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 43520
188 ; CHECK-NEXT: [[TMP6:%.*]] = or i32 [[TMP5]], [[TMP3]]
189 ; CHECK-NEXT: br label [[END:%.*]]
191 ; CHECK-NEXT: [[TMP7:%.*]] = and i32 [[TMP1]], 5570560
192 ; CHECK-NEXT: [[TMP8:%.*]] = shl i32 [[X]], 5
193 ; CHECK-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 11141120
194 ; CHECK-NEXT: [[TMP10:%.*]] = or i32 [[TMP9]], [[TMP7]]
195 ; CHECK-NEXT: br label [[END]]
197 ; CHECK-NEXT: [[TMP11:%.*]] = phi i32 [ [[TMP6]], [[IF]] ], [ [[TMP10]], [[ELSE]] ]
198 ; CHECK-NEXT: ret i32 [[TMP11]]
201 %2 = icmp sgt i32 %x, -1
202 br i1 %2, label %if, label %else
205 %3 = and i32 %1, 21760
206 %4 = and i32 %x, 1360
207 %5 = shl nuw nsw i32 %4, 5
212 %7 = and i32 %1, 5570560
213 %8 = and i32 %x, 348160
214 %9 = shl nuw nsw i32 %8, 5
219 %11 = phi i32 [ %6, %if ], [ %10, %else ]
223 define i32 @shl_mask(i32 %x) {
224 ; CHECK-LABEL: @shl_mask(
225 ; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255
226 ; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8
227 ; CHECK-NEXT: [[R:%.*]] = or i32 [[Z]], [[S]]
228 ; CHECK-NEXT: ret i32 [[R]]
236 define i32 @shl_mask_wrong_shl_const(i32 %x) {
237 ; CHECK-LABEL: @shl_mask_wrong_shl_const(
238 ; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255
239 ; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 7
240 ; CHECK-NEXT: [[R:%.*]] = or i32 [[Z]], [[S]]
241 ; CHECK-NEXT: ret i32 [[R]]
249 define i37 @shl_mask_weird_type(i37 %x) {
250 ; CHECK-LABEL: @shl_mask_weird_type(
251 ; CHECK-NEXT: [[Z:%.*]] = and i37 [[X:%.*]], 255
252 ; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i37 [[Z]], 8
253 ; CHECK-NEXT: [[R:%.*]] = or i37 [[Z]], [[S]]
254 ; CHECK-NEXT: ret i37 [[R]]
262 define i32 @shl_mask_extra_use(i32 %x, i32* %p) {
263 ; CHECK-LABEL: @shl_mask_extra_use(
264 ; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255
265 ; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8
266 ; CHECK-NEXT: store i32 [[S]], i32* [[P:%.*]], align 4
267 ; CHECK-NEXT: [[R:%.*]] = or i32 [[Z]], [[S]]
268 ; CHECK-NEXT: ret i32 [[R]]
272 store i32 %s, i32* %p
277 ; This could be "Z * 65793".
279 define i32 @shl_mul_mask(i32 %x) {
280 ; CHECK-LABEL: @shl_mul_mask(
281 ; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255
282 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Z]], 65537
283 ; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8
284 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[S]]
285 ; CHECK-NEXT: ret i32 [[R]]
288 %m = mul i32 %z, 65537
294 define i32 @shl_mul_mask_wrong_mul_const(i32 %x) {
295 ; CHECK-LABEL: @shl_mul_mask_wrong_mul_const(
296 ; CHECK-NEXT: [[Z:%.*]] = and i32 [[X:%.*]], 255
297 ; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[Z]], 65535
298 ; CHECK-NEXT: [[S:%.*]] = shl nuw nsw i32 [[Z]], 8
299 ; CHECK-NEXT: [[R:%.*]] = or i32 [[M]], [[S]]
300 ; CHECK-NEXT: ret i32 [[R]]
303 %m = mul i32 %z, 65535