xref: /llvm-project/llvm/test/Transforms/InstCombine/rem-mul-shl.ll (revision 24c2ba07ce65a5bf7d1113e05c517169d950b663)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3declare void @use8(i8)
4declare i64 @llvm.vscale.i64()
5declare i32 @llvm.vscale.i32()
6
7define i8 @srem_non_matching(i8 %X, i8 %Y) {
8; CHECK-LABEL: @srem_non_matching(
9; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 15
10; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Y:%.*]], 5
11; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
12; CHECK-NEXT:    ret i8 [[R]]
13;
14  %BO0 = mul nsw nuw i8 %X, 15
15  %BO1 = mul nsw nuw i8 %Y, 5
16  %r = srem i8 %BO0, %BO1
17  ret i8 %r
18}
19
20define i8 @urem_1_shl(i8 %X, i8 %Y) {
21; CHECK-LABEL: @urem_1_shl(
22; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 1, [[X:%.*]]
23; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i8 -1, [[Y:%.*]]
24; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[NOTMASK]], -1
25; CHECK-NEXT:    [[R:%.*]] = and i8 [[BO0]], [[TMP1]]
26; CHECK-NEXT:    ret i8 [[R]]
27;
28  %BO0 = shl nsw nuw i8 1, %X
29  %BO1 = shl nsw nuw i8 1, %Y
30  %r = urem i8 %BO0, %BO1
31  ret i8 %r
32}
33
34define <vscale x 16 x i8> @urem_XY_XZ_with_CY_rem_CZ_eq_0_scalable(<vscale x 16 x i8> %X) {
35; CHECK-LABEL: @urem_XY_XZ_with_CY_rem_CZ_eq_0_scalable(
36; CHECK-NEXT:    ret <vscale x 16 x i8> zeroinitializer
37;
38  %BO0 = mul nuw <vscale x 16 x i8> %X, splat (i8 15)
39  %BO1 = mul <vscale x 16 x i8> %X, splat (i8 5)
40  %r = urem <vscale x 16 x i8> %BO0, %BO1
41  ret <vscale x 16 x i8> %r
42}
43
44define i8 @urem_XY_XZ_with_CY_rem_CZ_eq_0(i8 %X) {
45; CHECK-LABEL: @urem_XY_XZ_with_CY_rem_CZ_eq_0(
46; CHECK-NEXT:    ret i8 0
47;
48  %BO0 = mul nuw i8 %X, 15
49  %BO1 = mul i8 %X, 5
50  %r = urem i8 %BO0, %BO1
51  ret i8 %r
52}
53
54define i8 @urem_XY_XZ_with_CY_rem_CZ_eq_0_with_shl(i8 %X) {
55; CHECK-LABEL: @urem_XY_XZ_with_CY_rem_CZ_eq_0_with_shl(
56; CHECK-NEXT:    ret i8 0
57;
58  %BO0 = shl nuw i8 15, %X
59  %BO1 = shl i8 5, %X
60  %r = urem i8 %BO0, %BO1
61  ret i8 %r
62}
63
64define i8 @urem_XY_XZ_with_CY_rem_CZ_eq_0_fail_missing_flag(i8 %X) {
65; CHECK-LABEL: @urem_XY_XZ_with_CY_rem_CZ_eq_0_fail_missing_flag(
66; CHECK-NEXT:    [[BO0:%.*]] = mul nsw i8 [[X:%.*]], 15
67; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], 5
68; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
69; CHECK-NEXT:    ret i8 [[R]]
70;
71  %BO0 = mul nsw i8 %X, 15
72  %BO1 = mul nsw nuw i8 %X, 5
73  %r = urem i8 %BO0, %BO1
74  ret i8 %r
75}
76
77define i8 @urem_XY_XZ_with_CY_lt_CZ(i8 %X) {
78; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ(
79; CHECK-NEXT:    [[R:%.*]] = mul nuw i8 [[X:%.*]], 3
80; CHECK-NEXT:    ret i8 [[R]]
81;
82  %BO0 = mul i8 %X, 3
83  %BO1 = mul nuw i8 %X, 12
84  %r = urem i8 %BO0, %BO1
85  ret i8 %r
86}
87
88define i8 @urem_XY_XZ_with_CY_lt_CZ_with_shl(i8 %X) {
89; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ_with_shl(
90; CHECK-NEXT:    [[R:%.*]] = shl nuw i8 3, [[X:%.*]]
91; CHECK-NEXT:    ret i8 [[R]]
92;
93  %BO0 = shl i8 3, %X
94  %BO1 = shl nuw i8 12, %X
95  %r = urem i8 %BO0, %BO1
96  ret i8 %r
97}
98
99define <2 x i8> @urem_XY_XZ_with_CY_lt_CZ_with_nsw_out(<2 x i8> %X) {
100; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ_with_nsw_out(
101; CHECK-NEXT:    [[R:%.*]] = shl nuw nsw <2 x i8> [[X:%.*]], splat (i8 2)
102; CHECK-NEXT:    ret <2 x i8> [[R]]
103;
104  %BO0 = shl nsw <2 x i8> %X, <i8 2, i8 2>
105  %BO1 = mul nuw <2 x i8> %X, <i8 12, i8 12>
106  %r = urem <2 x i8> %BO0, %BO1
107  ret <2 x i8> %r
108}
109
110define i8 @urem_XY_XZ_with_CY_lt_CZ_no_nsw_out(i8 %X) {
111; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ_no_nsw_out(
112; CHECK-NEXT:    [[R:%.*]] = mul nuw i8 [[X:%.*]], 3
113; CHECK-NEXT:    ret i8 [[R]]
114;
115  %BO0 = mul nuw i8 %X, 3
116  %BO1 = shl nsw nuw i8 %X, 3
117  %r = urem i8 %BO0, %BO1
118  ret i8 %r
119}
120
121define i8 @urem_XY_XZ_with_CY_lt_CZ_fail_missing_flag(i8 %X) {
122; CHECK-LABEL: @urem_XY_XZ_with_CY_lt_CZ_fail_missing_flag(
123; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 3
124; CHECK-NEXT:    [[BO1:%.*]] = mul nsw i8 [[X]], 12
125; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
126; CHECK-NEXT:    ret i8 [[R]]
127;
128  %BO0 = mul nuw nsw i8 %X, 3
129  %BO1 = mul nsw i8 %X, 12
130  %r = urem i8 %BO0, %BO1
131  ret i8 %r
132}
133
134define i8 @urem_XY_XZ_with_CY_gt_CZ(i8 %X) {
135; CHECK-LABEL: @urem_XY_XZ_with_CY_gt_CZ(
136; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i8 [[X:%.*]], 3
137; CHECK-NEXT:    ret i8 [[R]]
138;
139  %BO0 = mul nuw i8 %X, 21
140  %BO1 = mul i8 %X, 6
141  %r = urem i8 %BO0, %BO1
142  ret i8 %r
143}
144
145define i8 @urem_XY_XZ_with_CY_gt_CZ_fail_missing_flag(i8 %X) {
146; CHECK-LABEL: @urem_XY_XZ_with_CY_gt_CZ_fail_missing_flag(
147; CHECK-NEXT:    [[BO0:%.*]] = mul nsw i8 [[X:%.*]], 21
148; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], 6
149; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
150; CHECK-NEXT:    ret i8 [[R]]
151;
152  %BO0 = mul nsw i8 %X, 21
153  %BO1 = mul nsw nuw i8 %X, 6
154  %r = urem i8 %BO0, %BO1
155  ret i8 %r
156}
157
158define i8 @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ(i8 %X, i8 %Y, i8 %Z) {
159; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ(
160; CHECK-NEXT:    [[BO0:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
161; CHECK-NEXT:    [[BO1:%.*]] = mul nuw i8 [[Z:%.*]], [[X]]
162; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
163; CHECK-NEXT:    ret i8 [[R]]
164;
165  %BO0 = mul nuw i8 %X, %Y
166  %BO1 = mul nuw i8 %Z, %X
167  %r = urem i8 %BO0, %BO1
168  ret i8 %r
169}
170
171define i8 @urem_XY_XZ_with_CX_Y_Z_is_mul_X_RemYZ(i8 %Y, i8 %Z) {
172; CHECK-LABEL: @urem_XY_XZ_with_CX_Y_Z_is_mul_X_RemYZ(
173; CHECK-NEXT:    [[BO0:%.*]] = mul nuw i8 [[Y:%.*]], 10
174; CHECK-NEXT:    [[BO1:%.*]] = shl nuw i8 10, [[Z:%.*]]
175; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
176; CHECK-NEXT:    ret i8 [[R]]
177;
178  %BO0 = mul nuw i8 10, %Y
179  %BO1 = shl nuw i8 10, %Z
180  %r = urem i8 %BO0, %BO1
181  ret i8 %r
182}
183
184define i8 @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nsw_out1(i8 %X, i8 %Y, i8 %Z) {
185; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nsw_out1(
186; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
187; CHECK-NEXT:    [[BO1:%.*]] = shl nuw i8 [[X]], [[Z:%.*]]
188; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
189; CHECK-NEXT:    ret i8 [[R]]
190;
191  %BO0 = mul nuw nsw i8 %X, %Y
192  %BO1 = shl nuw i8 %X, %Z
193  %r = urem i8 %BO0, %BO1
194  ret i8 %r
195}
196
197define <2 x i8> @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nsw_out2(<2 x i8> %X, <2 x i8> %Y, <2 x i8> %Z) {
198; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nsw_out2(
199; CHECK-NEXT:    [[BO0:%.*]] = shl nuw <2 x i8> [[Y:%.*]], [[X:%.*]]
200; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw <2 x i8> [[Z:%.*]], [[X]]
201; CHECK-NEXT:    [[R:%.*]] = urem <2 x i8> [[BO0]], [[BO1]]
202; CHECK-NEXT:    ret <2 x i8> [[R]]
203;
204  %BO0 = shl nuw <2 x i8> %Y, %X
205  %BO1 = shl nuw nsw <2 x i8> %Z, %X
206  %r = urem <2 x i8> %BO0, %BO1
207  ret <2 x i8> %r
208}
209
210define i8 @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_reused1(i8 %X, i8 %Y, i8 %Z) {
211; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_reused1(
212; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
213; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
214; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
215; CHECK-NEXT:    call void @use8(i8 [[BO0]])
216; CHECK-NEXT:    ret i8 [[R]]
217;
218  %BO0 = mul nsw nuw i8 %X, %Y
219  %BO1 = mul nsw nuw i8 %X, %Z
220  %r = urem i8 %BO0, %BO1
221  call void @use8(i8 %BO0)
222  ret i8 %r
223}
224
225define <2 x i8> @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1(<2 x i8> %X, <2 x i8> %Y, <2 x i8> %Z) {
226; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1(
227; CHECK-NEXT:    [[BO0:%.*]] = mul nsw <2 x i8> [[X:%.*]], [[Y:%.*]]
228; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw <2 x i8> [[X]], [[Z:%.*]]
229; CHECK-NEXT:    [[R:%.*]] = urem <2 x i8> [[BO0]], [[BO1]]
230; CHECK-NEXT:    ret <2 x i8> [[R]]
231;
232  %BO0 = mul nsw <2 x i8> %X, %Y
233  %BO1 = mul nsw nuw <2 x i8> %X, %Z
234  %r = urem <2 x i8> %BO0, %BO1
235  ret <2 x i8> %r
236}
237
238define i8 @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2(i8 %X, i8 %Y, i8 %Z) {
239; CHECK-LABEL: @urem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2(
240; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
241; CHECK-NEXT:    [[BO1:%.*]] = shl nsw i8 [[X]], [[Z:%.*]]
242; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
243; CHECK-NEXT:    ret i8 [[R]]
244;
245  %BO0 = mul nsw nuw i8 %X, %Y
246  %BO1 = shl nsw i8 %X, %Z
247  %r = urem i8 %BO0, %BO1
248  ret i8 %r
249}
250
251;; Signed Verions
252define <vscale x 16 x i8> @srem_XY_XZ_with_CY_rem_CZ_eq_0_scalable(<vscale x 16 x i8> %X) {
253; CHECK-LABEL: @srem_XY_XZ_with_CY_rem_CZ_eq_0_scalable(
254; CHECK-NEXT:    ret <vscale x 16 x i8> zeroinitializer
255;
256  %BO0 = mul nsw <vscale x 16 x i8> %X, splat (i8 15)
257  %BO1 = mul <vscale x 16 x i8> %X, splat (i8 5)
258  %r = srem <vscale x 16 x i8> %BO0, %BO1
259  ret <vscale x 16 x i8> %r
260}
261
262define i8 @srem_XY_XZ_with_CY_rem_CZ_eq_0(i8 %X) {
263; CHECK-LABEL: @srem_XY_XZ_with_CY_rem_CZ_eq_0(
264; CHECK-NEXT:    ret i8 0
265;
266  %BO0 = mul nsw i8 %X, 9
267  %BO1 = mul i8 %X, 3
268  %r = srem i8 %BO0, %BO1
269  ret i8 %r
270}
271
272define i8 @srem_XY_XZ_with_CY_rem_CZ_eq_0_fail_missing_flag(i8 %X) {
273; CHECK-LABEL: @srem_XY_XZ_with_CY_rem_CZ_eq_0_fail_missing_flag(
274; CHECK-NEXT:    [[BO0:%.*]] = mul nuw i8 [[X:%.*]], 9
275; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], 3
276; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
277; CHECK-NEXT:    ret i8 [[R]]
278;
279  %BO0 = mul nuw i8 %X, 9
280  %BO1 = mul nsw nuw i8 %X, 3
281  %r = srem i8 %BO0, %BO1
282  ret i8 %r
283}
284
285define <2 x i8> @srem_XY_XZ_with_CY_lt_CZ(<2 x i8> %X) {
286; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ(
287; CHECK-NEXT:    [[R:%.*]] = shl nsw <2 x i8> [[X:%.*]], splat (i8 3)
288; CHECK-NEXT:    ret <2 x i8> [[R]]
289;
290  %BO0 = shl <2 x i8> %X, <i8 3, i8 3>
291  %BO1 = mul nsw <2 x i8> %X, <i8 15, i8 15>
292  %r = srem <2 x i8> %BO0, %BO1
293  ret <2 x i8> %r
294}
295
296define i8 @srem_XY_XZ_with_CY_lt_CZ_with_nuw_out(i8 %X) {
297; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ_with_nuw_out(
298; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i8 [[X:%.*]], 5
299; CHECK-NEXT:    ret i8 [[R]]
300;
301  %BO0 = mul nuw i8 %X, 5
302  %BO1 = mul nsw i8 %X, 15
303  %r = srem i8 %BO0, %BO1
304  ret i8 %r
305}
306
307define <2 x i8> @srem_XY_XZ_with_CY_lt_CZ_with_nuw_out_with_shl(<2 x i8> %X) {
308; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ_with_nuw_out_with_shl(
309; CHECK-NEXT:    [[R:%.*]] = shl nuw nsw <2 x i8> splat (i8 3), [[X:%.*]]
310; CHECK-NEXT:    ret <2 x i8> [[R]]
311;
312  %BO0 = shl nuw <2 x i8> <i8 3, i8 3>, %X
313  %BO1 = shl nsw <2 x i8> <i8 15, i8 15>, %X
314  %r = srem <2 x i8> %BO0, %BO1
315  ret <2 x i8> %r
316}
317
318define i8 @srem_XY_XZ_with_CY_lt_CZ_no_nsw_out(i8 %X) {
319; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ_no_nsw_out(
320; CHECK-NEXT:    [[R:%.*]] = mul nsw i8 [[X:%.*]], 5
321; CHECK-NEXT:    ret i8 [[R]]
322;
323  %BO0 = mul nsw i8 %X, 5
324  %BO1 = shl nsw nuw i8 %X, 4
325  %r = srem i8 %BO0, %BO1
326  ret i8 %r
327}
328
329define i8 @srem_XY_XZ_with_CY_lt_CZ_fail_missing_flag(i8 %X) {
330; CHECK-LABEL: @srem_XY_XZ_with_CY_lt_CZ_fail_missing_flag(
331; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 5
332; CHECK-NEXT:    [[BO1:%.*]] = shl nuw i8 [[X]], 4
333; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
334; CHECK-NEXT:    ret i8 [[R]]
335;
336  %BO0 = mul nuw nsw i8 %X, 5
337  %BO1 = shl nuw i8 %X, 4
338  %r = srem i8 %BO0, %BO1
339  ret i8 %r
340}
341
342define i8 @srem_XY_XZ_with_CY_gt_CZ(i8 %X) {
343; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ(
344; CHECK-NEXT:    [[R:%.*]] = shl nsw i8 [[X:%.*]], 1
345; CHECK-NEXT:    ret i8 [[R]]
346;
347  %BO0 = shl nsw i8 %X, 3
348  %BO1 = mul nsw i8 %X, 6
349  %r = srem i8 %BO0, %BO1
350  ret i8 %r
351}
352
353define i8 @srem_XY_XZ_with_CY_gt_CZ_with_nuw_out(i8 %X) {
354; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_with_nuw_out(
355; CHECK-NEXT:    [[R:%.*]] = shl nuw nsw i8 [[X:%.*]], 2
356; CHECK-NEXT:    ret i8 [[R]]
357;
358  %BO0 = mul nsw nuw i8 %X, 10
359  %BO1 = mul nsw i8 %X, 6
360  %r = srem i8 %BO0, %BO1
361  ret i8 %r
362}
363
364define <2 x i8> @srem_XY_XZ_with_CY_gt_CZ_no_nuw_out(<2 x i8> %X) {
365; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_no_nuw_out(
366; CHECK-NEXT:    [[R:%.*]] = shl nsw <2 x i8> [[X:%.*]], splat (i8 1)
367; CHECK-NEXT:    ret <2 x i8> [[R]]
368;
369  %BO0 = mul nsw <2 x i8> %X, <i8 10, i8 10>
370  %BO1 = shl nsw nuw <2 x i8> %X, <i8 3, i8 3>
371  %r = srem <2 x i8> %BO0, %BO1
372  ret <2 x i8> %r
373}
374
375define i8 @srem_XY_XZ_with_CY_gt_CZ_drop_nsw(i8 noundef %X) {
376; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_drop_nsw(
377; CHECK-NEXT:    [[BO0:%.*]] = mul nsw i8 [[X:%.*]], 127
378; CHECK-NEXT:    [[BO1:%.*]] = shl nsw i8 [[X]], 7
379; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO1]], [[BO0]]
380; CHECK-NEXT:    ret i8 [[R]]
381;
382  %BO0 = mul nsw i8 %X, 127
383  %BO1 = shl nsw i8 %X, 7
384  %r = srem i8 %BO1, %BO0
385  ret i8 %r
386}
387
388define i8 @srem_XY_XZ_with_CY_gt_CZ_drop_nsw_commuted(i8 noundef %X) {
389; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_drop_nsw_commuted(
390; CHECK-NEXT:    [[BO0:%.*]] = mul nsw i8 [[X:%.*]], 127
391; CHECK-NEXT:    [[BO1:%.*]] = shl nsw i8 [[X]], 7
392; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
393; CHECK-NEXT:    ret i8 [[R]]
394;
395  %BO0 = mul nsw i8 %X, 127
396  %BO1 = shl nsw i8 %X, 7
397  %r = srem i8 %BO0, %BO1
398  ret i8 %r
399}
400
401define i8 @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag1(i8 %X) {
402; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag1(
403; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 10
404; CHECK-NEXT:    [[BO1:%.*]] = mul nuw i8 [[X]], 6
405; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
406; CHECK-NEXT:    ret i8 [[R]]
407;
408  %BO0 = mul nsw nuw i8 %X, 10
409  %BO1 = mul nuw i8 %X, 6
410  %r = srem i8 %BO0, %BO1
411  ret i8 %r
412}
413
414define i8 @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag2(i8 %X) {
415; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag2(
416; CHECK-NEXT:    [[BO0:%.*]] = shl nuw i8 [[X:%.*]], 4
417; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], 5
418; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
419; CHECK-NEXT:    ret i8 [[R]]
420;
421  %BO0 = shl nuw i8 %X, 4
422  %BO1 = mul nsw nuw i8 %X, 5
423  %r = srem i8 %BO0, %BO1
424  ret i8 %r
425}
426
427define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ(i8 %X, i8 %Y, i8 %Z) {
428; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ(
429; CHECK-NEXT:    [[BO0:%.*]] = mul nsw i8 [[Y:%.*]], [[X:%.*]]
430; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
431; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
432; CHECK-NEXT:    ret i8 [[R]]
433;
434  %BO0 = mul nsw i8 %Y, %X
435  %BO1 = mul nsw nuw i8 %X, %Z
436  %r = srem i8 %BO0, %BO1
437  ret i8 %r
438}
439
440define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nuw_out(i8 %X, i8 %Y, i8 %Z) {
441; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nuw_out(
442; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]]
443; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]]
444; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
445; CHECK-NEXT:    ret i8 [[R]]
446;
447  %BO0 = mul nsw nuw i8 %Y, %X
448  %BO1 = mul nsw nuw i8 %Z, %X
449  %r = srem i8 %BO0, %BO1
450  ret i8 %r
451}
452
453define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_shl(i8 %X, i8 %Y, i8 %Z) {
454; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_shl(
455; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
456; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]]
457; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
458; CHECK-NEXT:    ret i8 [[R]]
459;
460  %BO0 = shl nsw nuw i8 %X, %Y
461  %BO1 = shl nsw nuw i8 %X, %Z
462  %r = srem i8 %BO0, %BO1
463  ret i8 %r
464}
465
466
467define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1(i8 %X, i8 %Y, i8 %Z) {
468; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1(
469; CHECK-NEXT:    [[BO0:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
470; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
471; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
472; CHECK-NEXT:    ret i8 [[R]]
473;
474  %BO0 = mul nuw i8 %X, %Y
475  %BO1 = mul nsw nuw i8 %X, %Z
476  %r = srem i8 %BO0, %BO1
477  ret i8 %r
478}
479
480define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2(i8 %X, i8 %Y, i8 %Z) {
481; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2(
482; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
483; CHECK-NEXT:    [[BO1:%.*]] = mul nuw i8 [[X]], [[Z:%.*]]
484; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
485; CHECK-NEXT:    ret i8 [[R]]
486;
487  %BO0 = mul nsw nuw i8 %X, %Y
488  %BO1 = mul nuw i8 %X, %Z
489  %r = srem i8 %BO0, %BO1
490  ret i8 %r
491}
492
493define i8 @urem_shl_XY_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) {
494; CHECK-LABEL: @urem_shl_XY_shl_ZX_fail(
495; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
496; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
497; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
498; CHECK-NEXT:    ret i8 [[R]]
499;
500  %BO0 = shl nuw nsw i8 %X, %Y
501  %BO1 = shl nuw nsw i8 %Z, %X
502  %r = urem i8 %BO0, %BO1
503  ret i8 %r
504}
505
506define i8 @urem_mul_XY_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) {
507; CHECK-LABEL: @urem_mul_XY_shl_ZX_fail(
508; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
509; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
510; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
511; CHECK-NEXT:    ret i8 [[R]]
512;
513  %BO0 = mul nuw nsw i8 %X, %Y
514  %BO1 = shl nuw nsw i8 %Z, %X
515  %r = urem i8 %BO0, %BO1
516  ret i8 %r
517}
518
519define i8 @urem_shl_YX_shl_XZ_fail(i8 %X, i8 %Z, i8 %Y) {
520; CHECK-LABEL: @urem_shl_YX_shl_XZ_fail(
521; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
522; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]]
523; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
524; CHECK-NEXT:    ret i8 [[R]]
525;
526  %BO0 = shl nuw nsw i8 %Y, %X
527  %BO1 = shl nuw nsw i8 %X, %Z
528  %r = urem i8 %BO0, %BO1
529  ret i8 %r
530}
531
532define i8 @urem_shl_YX_mul_XZ_fail(i8 %X, i8 %Z, i8 %Y) {
533; CHECK-LABEL: @urem_shl_YX_mul_XZ_fail(
534; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
535; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
536; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
537; CHECK-NEXT:    ret i8 [[R]]
538;
539  %BO0 = shl nuw nsw i8 %Y, %X
540  %BO1 = mul nuw nsw i8 %X, %Z
541  %r = urem i8 %BO0, %BO1
542  ret i8 %r
543}
544
545define i8 @urem_shl_YX_mul_ZX_fail(i8 %X, i8 %Z, i8 %Y) {
546; CHECK-LABEL: @urem_shl_YX_mul_ZX_fail(
547; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
548; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]]
549; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
550; CHECK-NEXT:    ret i8 [[R]]
551;
552  %BO0 = shl nuw nsw i8 %Y, %X
553  %BO1 = mul nuw nsw i8 %Z, %X
554  %r = urem i8 %BO0, %BO1
555  ret i8 %r
556}
557
558define i8 @urem_mul_YX_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) {
559; CHECK-LABEL: @urem_mul_YX_shl_ZX_fail(
560; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]]
561; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
562; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
563; CHECK-NEXT:    ret i8 [[R]]
564;
565  %BO0 = mul nuw nsw i8 %Y, %X
566  %BO1 = shl nuw nsw i8 %Z, %X
567  %r = urem i8 %BO0, %BO1
568  ret i8 %r
569}
570
571define i8 @urem_shl_CXY_shl_ZCX_fail(i8 %Z, i8 %Y) {
572; CHECK-LABEL: @urem_shl_CXY_shl_ZCX_fail(
573; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 3, [[Y:%.*]]
574; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], 3
575; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
576; CHECK-NEXT:    ret i8 [[R]]
577;
578  %BO0 = shl nuw nsw i8 3, %Y
579  %BO1 = shl nuw nsw i8 %Z, 3
580  %r = urem i8 %BO0, %BO1
581  ret i8 %r
582}
583
584define i8 @urem_shl_YCX_shl_CXZ_fail(i8 %Z, i8 %Y) {
585; CHECK-LABEL: @urem_shl_YCX_shl_CXZ_fail(
586; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], 3
587; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 3, [[Z:%.*]]
588; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
589; CHECK-NEXT:    ret i8 [[R]]
590;
591  %BO0 = shl nuw nsw i8 %Y, 3
592  %BO1 = shl nuw nsw i8 3, %Z
593  %r = urem i8 %BO0, %BO1
594  ret i8 %r
595}
596
597define i8 @urem_shl_YCX_mul_ZCX_fail(i8 %Z, i8 %Y) {
598; CHECK-LABEL: @urem_shl_YCX_mul_ZCX_fail(
599; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], 3
600; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], 10
601; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
602; CHECK-NEXT:    ret i8 [[R]]
603;
604  %BO0 = shl nuw nsw i8 %Y, 3
605  %BO1 = mul nuw nsw i8 %Z, 10
606  %r = urem i8 %BO0, %BO1
607  ret i8 %r
608}
609
610define i8 @urem_mul_YCX_shl_ZCX_fail(i8 %Z, i8 %Y) {
611; CHECK-LABEL: @urem_mul_YCX_shl_ZCX_fail(
612; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], 3
613; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], 3
614; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
615; CHECK-NEXT:    ret i8 [[R]]
616;
617  %BO0 = mul nuw nsw i8 %Y, 3
618  %BO1 = shl nuw nsw i8 %Z, 3
619  %r = urem i8 %BO0, %BO1
620  ret i8 %r
621}
622
623define i8 @urem_shl_XCY_shl_CZX_fail(i8 %X) {
624; CHECK-LABEL: @urem_shl_XCY_shl_CZX_fail(
625; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], 3
626; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 6, [[X]]
627; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
628; CHECK-NEXT:    ret i8 [[R]]
629;
630  %BO0 = shl nuw nsw i8 %X, 3
631  %BO1 = shl nuw nsw i8 6, %X
632  %r = urem i8 %BO0, %BO1
633  ret i8 %r
634}
635
636define i8 @urem_mul_XCY_shl_CZX_fail(i8 %X) {
637; CHECK-LABEL: @urem_mul_XCY_shl_CZX_fail(
638; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 6
639; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 3, [[X]]
640; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
641; CHECK-NEXT:    ret i8 [[R]]
642;
643  %BO0 = mul nuw nsw i8 %X, 6
644  %BO1 = shl nuw nsw i8 3, %X
645  %r = urem i8 %BO0, %BO1
646  ret i8 %r
647}
648
649define i8 @urem_shl_CYX_shl_XCZ_fail(i8 %X) {
650; CHECK-LABEL: @urem_shl_CYX_shl_XCZ_fail(
651; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 3, [[X:%.*]]
652; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], 6
653; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
654; CHECK-NEXT:    ret i8 [[R]]
655;
656  %BO0 = shl nuw nsw i8 3, %X
657  %BO1 = shl nuw nsw i8 %X, 6
658  %r = urem i8 %BO0, %BO1
659  ret i8 %r
660}
661
662define i8 @urem_shl_CYX_mul_XCZ_fail(i8 %X) {
663; CHECK-LABEL: @urem_shl_CYX_mul_XCZ_fail(
664; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 3, [[X:%.*]]
665; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], 10
666; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
667; CHECK-NEXT:    ret i8 [[R]]
668;
669  %BO0 = shl nuw nsw i8 3, %X
670  %BO1 = mul nuw nsw i8 %X, 10
671  %r = urem i8 %BO0, %BO1
672  ret i8 %r
673}
674
675define i8 @urem_shl_XX_shl_ZX(i8 %X, i8 %Z) {
676; CHECK-LABEL: @urem_shl_XX_shl_ZX(
677; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
678; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
679; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
680; CHECK-NEXT:    ret i8 [[R]]
681;
682  %BO0 = shl nuw nsw i8 %X, %X
683  %BO1 = shl nuw nsw i8 %Z, %X
684  %r = urem i8 %BO0, %BO1
685  ret i8 %r
686}
687
688define i8 @urem_shl_YX_shl_XX(i8 %X, i8 %Y) {
689; CHECK-LABEL: @urem_shl_YX_shl_XX(
690; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
691; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
692; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
693; CHECK-NEXT:    ret i8 [[R]]
694;
695  %BO0 = shl nuw nsw i8 %Y, %X
696  %BO1 = shl nuw nsw i8 %X, %X
697  %r = urem i8 %BO0, %BO1
698  ret i8 %r
699}
700
701define i8 @urem_shl_XX_shl_XZ(i8 %X, i8 %Z) {
702; CHECK-LABEL: @urem_shl_XX_shl_XZ(
703; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
704; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]]
705; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
706; CHECK-NEXT:    ret i8 [[R]]
707;
708  %BO0 = shl nuw nsw i8 %X, %X
709  %BO1 = shl nuw nsw i8 %X, %Z
710  %r = urem i8 %BO0, %BO1
711  ret i8 %r
712}
713
714define i8 @urem_shl_XY_shl_XX(i8 %X, i8 %Y) {
715; CHECK-LABEL: @urem_shl_XY_shl_XX(
716; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
717; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
718; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
719; CHECK-NEXT:    ret i8 [[R]]
720;
721  %BO0 = shl nuw nsw i8 %X, %Y
722  %BO1 = shl nuw nsw i8 %X, %X
723  %r = urem i8 %BO0, %BO1
724  ret i8 %r
725}
726
727define i8 @urem_mul_XX_shl_ZX(i8 %X, i8 %Z) {
728; CHECK-LABEL: @urem_mul_XX_shl_ZX(
729; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]]
730; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
731; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
732; CHECK-NEXT:    ret i8 [[R]]
733;
734  %BO0 = mul nuw nsw i8 %X, %X
735  %BO1 = shl nuw nsw i8 %Z, %X
736  %r = urem i8 %BO0, %BO1
737  ret i8 %r
738}
739
740define i8 @urem_mul_YX_shl_XX(i8 %X, i8 %Y) {
741; CHECK-LABEL: @urem_mul_YX_shl_XX(
742; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]]
743; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
744; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
745; CHECK-NEXT:    ret i8 [[R]]
746;
747  %BO0 = mul nuw nsw i8 %Y, %X
748  %BO1 = shl nuw nsw i8 %X, %X
749  %r = urem i8 %BO0, %BO1
750  ret i8 %r
751}
752
753define i8 @urem_mul_XX_shl_XZ(i8 %X, i8 %Z) {
754; CHECK-LABEL: @urem_mul_XX_shl_XZ(
755; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]]
756; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]]
757; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
758; CHECK-NEXT:    ret i8 [[R]]
759;
760  %BO0 = mul nuw nsw i8 %X, %X
761  %BO1 = shl nuw nsw i8 %X, %Z
762  %r = urem i8 %BO0, %BO1
763  ret i8 %r
764}
765
766define i8 @urem_mul_XY_shl_XX(i8 %X, i8 %Y) {
767; CHECK-LABEL: @urem_mul_XY_shl_XX(
768; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
769; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
770; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
771; CHECK-NEXT:    ret i8 [[R]]
772;
773  %BO0 = mul nuw nsw i8 %X, %Y
774  %BO1 = shl nuw nsw i8 %X, %X
775  %r = urem i8 %BO0, %BO1
776  ret i8 %r
777}
778
779define i8 @urem_shl_XX_mul_ZX(i8 %X, i8 %Z) {
780; CHECK-LABEL: @urem_shl_XX_mul_ZX(
781; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
782; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]]
783; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
784; CHECK-NEXT:    ret i8 [[R]]
785;
786  %BO0 = shl nuw nsw i8 %X, %X
787  %BO1 = mul nuw nsw i8 %Z, %X
788  %r = urem i8 %BO0, %BO1
789  ret i8 %r
790}
791
792define i8 @urem_shl_YX_mul_XX(i8 %X, i8 %Y) {
793; CHECK-LABEL: @urem_shl_YX_mul_XX(
794; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
795; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]]
796; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
797; CHECK-NEXT:    ret i8 [[R]]
798;
799  %BO0 = shl nuw nsw i8 %Y, %X
800  %BO1 = mul nuw nsw i8 %X, %X
801  %r = urem i8 %BO0, %BO1
802  ret i8 %r
803}
804
805define i8 @urem_shl_XX_mul_XZ(i8 %X, i8 %Z) {
806; CHECK-LABEL: @urem_shl_XX_mul_XZ(
807; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
808; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
809; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
810; CHECK-NEXT:    ret i8 [[R]]
811;
812  %BO0 = shl nuw nsw i8 %X, %X
813  %BO1 = mul nuw nsw i8 %X, %Z
814  %r = urem i8 %BO0, %BO1
815  ret i8 %r
816}
817
818define i8 @urem_shl_XY_mul_XX(i8 %X, i8 %Y) {
819; CHECK-LABEL: @urem_shl_XY_mul_XX(
820; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
821; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]]
822; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
823; CHECK-NEXT:    ret i8 [[R]]
824;
825  %BO0 = shl nuw nsw i8 %X, %Y
826  %BO1 = mul nuw nsw i8 %X, %X
827  %r = urem i8 %BO0, %BO1
828  ret i8 %r
829}
830
831define i8 @urem_mul_XX_shl_XX(i8 %X) {
832; CHECK-LABEL: @urem_mul_XX_shl_XX(
833; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]]
834; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
835; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
836; CHECK-NEXT:    ret i8 [[R]]
837;
838  %BO0 = mul nuw nsw i8 %X, %X
839  %BO1 = shl nuw nsw i8 %X, %X
840  %r = urem i8 %BO0, %BO1
841  ret i8 %r
842}
843
844define i8 @urem_shl_XX_mul_XX(i8 %X) {
845; CHECK-LABEL: @urem_shl_XX_mul_XX(
846; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
847; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]]
848; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
849; CHECK-NEXT:    ret i8 [[R]]
850;
851  %BO0 = shl nuw nsw i8 %X, %X
852  %BO1 = mul nuw nsw i8 %X, %X
853  %r = urem i8 %BO0, %BO1
854  ret i8 %r
855}
856
857; Negative test: No attribute vscale_range to indicate range
858define i64 @urem_shl_vscale() {
859; CHECK-LABEL: @urem_shl_vscale(
860; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
861; CHECK-NEXT:    [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 2
862; CHECK-NEXT:    [[REM:%.*]] = urem i64 1024, [[SHIFT]]
863; CHECK-NEXT:    ret i64 [[REM]]
864;
865  %vscale = call i64 @llvm.vscale.i64()
866  %shift = shl nuw nsw i64 %vscale, 2
867  %rem = urem i64 1024, %shift
868  ret i64 %rem
869}
870
871define i64 @urem_shl_vscale_range() vscale_range(1,16) {
872; CHECK-LABEL: @urem_shl_vscale_range(
873; CHECK-NEXT:    ret i64 0
874;
875  %vscale = call i64 @llvm.vscale.i64()
876  %shift = shl nuw nsw i64 %vscale, 2
877  %rem = urem i64 1024, %shift
878  ret i64 %rem
879}
880
881define i64 @urem_vscale_range() vscale_range(1,16) {
882; CHECK-LABEL: @urem_vscale_range(
883; CHECK-NEXT:    ret i64 0
884;
885  %vscale = call i64 @llvm.vscale.i64()
886  %shift = shl nuw nsw i64 %vscale, 6
887  %rem = urem i64 1024, %shift
888  ret i64 %rem
889}
890
891define i64 @urem_shl_vscale_out_of_range() vscale_range(1,16) {
892; CHECK-LABEL: @urem_shl_vscale_out_of_range(
893; CHECK-NEXT:    ret i64 1024
894;
895  %vscale = call i64 @llvm.vscale.i64()
896  %shift = shl nuw nsw i64 %vscale, 11
897  %rem = urem i64 1024, %shift
898  ret i64 %rem
899}
900
901; Negative test: The min value 1 << 10 is overlap to 1024
902define i64 @urem_shl_vscale_overlap() vscale_range(1,16) {
903; CHECK-LABEL: @urem_shl_vscale_overlap(
904; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
905; CHECK-NEXT:    [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 10
906; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[SHIFT]], 2047
907; CHECK-NEXT:    [[REM:%.*]] = and i64 [[TMP1]], 1024
908; CHECK-NEXT:    ret i64 [[REM]]
909;
910  %vscale = call i64 @llvm.vscale.i64()
911  %shift = shl nuw nsw i64 %vscale, 10
912  %rem = urem i64 1024, %shift
913  ret i64 %rem
914}
915
916define i64 @and_add_vscale_range_low() vscale_range(1,16) {
917; CHECK-LABEL: @and_add_vscale_range_low(
918; CHECK-NEXT:    ret i64 0
919;
920  %vscale = call i64 @llvm.vscale.i64()
921  %shift = shl nuw nsw i64 %vscale, 6
922  %add = add i64 %shift, -1
923  %rem = and i64 1024, %add
924  ret i64 %rem
925}
926
927; TODO: have no bits that may be part of the mask set,
928; but now expect the const is a power of two
929define i64 @and_add_shl_vscale_not_power2() vscale_range(1,16) {
930; CHECK-LABEL: @and_add_shl_vscale_not_power2(
931; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
932; CHECK-NEXT:    [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 6
933; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[SHIFT]], 4095
934; CHECK-NEXT:    [[REM:%.*]] = and i64 [[ADD]], 3072
935; CHECK-NEXT:    ret i64 [[REM]]
936;
937  %vscale = call i64 @llvm.vscale.i64()
938  %shift = shl nuw nsw i64 %vscale, 6
939  %add = add i64 %shift, -1
940  %rem = and i64 3072, %add
941  ret i64 %rem
942}
943
944; Allow for INT_MIN, https://alive2.llvm.org/ce/z/yZ_I2a
945define i32 @and_add_shl_vscale_not_power2_negative() vscale_range(1,16) {
946; CHECK-LABEL: @and_add_shl_vscale_not_power2_negative(
947; CHECK-NEXT:    ret i32 0
948;
949  %vscale = call i32 @llvm.vscale.i32()
950  %shift = shl nuw nsw i32 %vscale, 6
951  %add = add i32 %shift, -1
952  %rem = and i32 -2147483648, %add
953  ret i32 %rem
954}
955
956; Negative test: the %sign may be 0, https://alive2.llvm.org/ce/z/WU_j4a
957define i32 @and_add_and (i32 %x) {
958; CHECK-LABEL: @and_add_and(
959; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 24
960; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -2147483648
961; CHECK-NEXT:    [[AND:%.*]] = xor i32 [[TMP2]], -2147483648
962; CHECK-NEXT:    ret i32 [[AND]]
963;
964  %x1 = lshr i32 %x, 7
965  %sign = and i32 %x1, 1  ; %sign = (%x >> 7) & 1
966  %add = add i32 %sign, -1
967  %and = and i32 %add, 2147483648
968  ret i32 %and
969}
970
971