Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / rem-mul-shl.ll
blob75f4d3f4fb07da5924a61a0f4e3b8fbaf24b2315
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3 declare void @use8(i8)
4 declare i64 @llvm.vscale.i64()
5 declare i32 @llvm.vscale.i32()
7 define 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:%.*]] = srem i8 [[BO0]], [[BO1]]
12 ; CHECK-NEXT:    ret i8 [[R]]
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
20 define 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]]
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
34 define <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
38   %BO0 = mul nuw <vscale x 16 x i8> %X, shufflevector(<vscale x 16 x i8> insertelement(<vscale x 16 x i8> poison, i8 15, i64 0) , <vscale x 16 x i8> poison, <vscale x 16 x i32> zeroinitializer)
39   %BO1 = mul <vscale x 16 x i8> %X, shufflevector(<vscale x 16 x i8> insertelement(<vscale x 16 x i8> poison, i8 5, i64 0) , <vscale x 16 x i8> poison, <vscale x 16 x i32> zeroinitializer)
40   %r = urem <vscale x 16 x i8> %BO0, %BO1
41   ret <vscale x 16 x i8> %r
44 define 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
48   %BO0 = mul nuw i8 %X, 15
49   %BO1 = mul i8 %X, 5
50   %r = urem i8 %BO0, %BO1
51   ret i8 %r
54 define 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
58   %BO0 = shl nuw i8 15, %X
59   %BO1 = shl i8 5, %X
60   %r = urem i8 %BO0, %BO1
61   ret i8 %r
64 define 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]]
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
77 define 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]]
82   %BO0 = mul i8 %X, 3
83   %BO1 = mul nuw i8 %X, 12
84   %r = urem i8 %BO0, %BO1
85   ret i8 %r
88 define 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]]
93   %BO0 = shl i8 3, %X
94   %BO1 = shl nuw i8 12, %X
95   %r = urem i8 %BO0, %BO1
96   ret i8 %r
99 define <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:%.*]], <i8 2, i8 2>
102 ; CHECK-NEXT:    ret <2 x i8> [[R]]
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
110 define 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]]
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
121 define 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]]
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
134 define 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]]
139   %BO0 = mul nuw i8 %X, 21
140   %BO1 = mul i8 %X, 6
141   %r = urem i8 %BO0, %BO1
142   ret i8 %r
145 define 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]]
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
158 define 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]]
165   %BO0 = mul nuw i8 %X, %Y
166   %BO1 = mul nuw i8 %Z, %X
167   %r = urem i8 %BO0, %BO1
168   ret i8 %r
171 define 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]]
178   %BO0 = mul nuw i8 10, %Y
179   %BO1 = shl nuw i8 10, %Z
180   %r = urem i8 %BO0, %BO1
181   ret i8 %r
184 define 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]]
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
197 define <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]]
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
210 define 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]]
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
225 define <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]]
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
238 define 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]]
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
251 ;; Signed Verions
252 define <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
256   %BO0 = mul nsw <vscale x 16 x i8> %X, shufflevector(<vscale x 16 x i8> insertelement(<vscale x 16 x i8> poison, i8 15, i64 0) , <vscale x 16 x i8> poison, <vscale x 16 x i32> zeroinitializer)
257   %BO1 = mul <vscale x 16 x i8> %X, shufflevector(<vscale x 16 x i8> insertelement(<vscale x 16 x i8> poison, i8 5, i64 0) , <vscale x 16 x i8> poison, <vscale x 16 x i32> zeroinitializer)
258   %r = srem <vscale x 16 x i8> %BO0, %BO1
259   ret <vscale x 16 x i8> %r
262 define 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
266   %BO0 = mul nsw i8 %X, 9
267   %BO1 = mul i8 %X, 3
268   %r = srem i8 %BO0, %BO1
269   ret i8 %r
272 define 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]]
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
285 define <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:%.*]], <i8 3, i8 3>
288 ; CHECK-NEXT:    ret <2 x i8> [[R]]
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
296 define 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]]
301   %BO0 = mul nuw i8 %X, 5
302   %BO1 = mul nsw i8 %X, 15
303   %r = srem i8 %BO0, %BO1
304   ret i8 %r
307 define <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> <i8 3, i8 3>, [[X:%.*]]
310 ; CHECK-NEXT:    ret <2 x i8> [[R]]
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
318 define 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]]
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
329 define 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]]
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
342 define 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]]
347   %BO0 = shl nsw i8 %X, 3
348   %BO1 = mul nsw i8 %X, 6
349   %r = srem i8 %BO0, %BO1
350   ret i8 %r
353 define 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]]
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
364 define <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:%.*]], <i8 1, i8 1>
367 ; CHECK-NEXT:    ret <2 x i8> [[R]]
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
375 define i8 @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag1(i8 %X) {
376 ; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag1(
377 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 10
378 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw i8 [[X]], 6
379 ; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
380 ; CHECK-NEXT:    ret i8 [[R]]
382   %BO0 = mul nsw nuw i8 %X, 10
383   %BO1 = mul nuw i8 %X, 6
384   %r = srem i8 %BO0, %BO1
385   ret i8 %r
388 define i8 @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag2(i8 %X) {
389 ; CHECK-LABEL: @srem_XY_XZ_with_CY_gt_CZ_fail_missing_flag2(
390 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw i8 [[X:%.*]], 4
391 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], 5
392 ; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
393 ; CHECK-NEXT:    ret i8 [[R]]
395   %BO0 = shl nuw i8 %X, 4
396   %BO1 = mul nsw nuw i8 %X, 5
397   %r = srem i8 %BO0, %BO1
398   ret i8 %r
401 define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ(i8 %X, i8 %Y, i8 %Z) {
402 ; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ(
403 ; CHECK-NEXT:    [[BO0:%.*]] = mul nsw i8 [[Y:%.*]], [[X:%.*]]
404 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
405 ; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
406 ; CHECK-NEXT:    ret i8 [[R]]
408   %BO0 = mul nsw i8 %Y, %X
409   %BO1 = mul nsw nuw i8 %X, %Z
410   %r = srem i8 %BO0, %BO1
411   ret i8 %r
414 define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nuw_out(i8 %X, i8 %Y, i8 %Z) {
415 ; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_with_nuw_out(
416 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]]
417 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]]
418 ; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
419 ; CHECK-NEXT:    ret i8 [[R]]
421   %BO0 = mul nsw nuw i8 %Y, %X
422   %BO1 = mul nsw nuw i8 %Z, %X
423   %r = srem i8 %BO0, %BO1
424   ret i8 %r
427 define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_shl(i8 %X, i8 %Y, i8 %Z) {
428 ; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_shl(
429 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
430 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]]
431 ; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
432 ; CHECK-NEXT:    ret i8 [[R]]
434   %BO0 = shl nsw nuw i8 %X, %Y
435   %BO1 = shl nsw nuw i8 %X, %Z
436   %r = srem i8 %BO0, %BO1
437   ret i8 %r
441 define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1(i8 %X, i8 %Y, i8 %Z) {
442 ; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags1(
443 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
444 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
445 ; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
446 ; CHECK-NEXT:    ret i8 [[R]]
448   %BO0 = mul nuw i8 %X, %Y
449   %BO1 = mul nsw nuw i8 %X, %Z
450   %r = srem i8 %BO0, %BO1
451   ret i8 %r
454 define i8 @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2(i8 %X, i8 %Y, i8 %Z) {
455 ; CHECK-LABEL: @srem_XY_XZ_with_Y_Z_is_mul_X_RemYZ_fail_missing_flags2(
456 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
457 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw i8 [[X]], [[Z:%.*]]
458 ; CHECK-NEXT:    [[R:%.*]] = srem i8 [[BO0]], [[BO1]]
459 ; CHECK-NEXT:    ret i8 [[R]]
461   %BO0 = mul nsw nuw i8 %X, %Y
462   %BO1 = mul nuw i8 %X, %Z
463   %r = srem i8 %BO0, %BO1
464   ret i8 %r
467 define i8 @urem_shl_XY_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) {
468 ; CHECK-LABEL: @urem_shl_XY_shl_ZX_fail(
469 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
470 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
471 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
472 ; CHECK-NEXT:    ret i8 [[R]]
474   %BO0 = shl nuw nsw i8 %X, %Y
475   %BO1 = shl nuw nsw i8 %Z, %X
476   %r = urem i8 %BO0, %BO1
477   ret i8 %r
480 define i8 @urem_mul_XY_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) {
481 ; CHECK-LABEL: @urem_mul_XY_shl_ZX_fail(
482 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
483 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
484 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
485 ; CHECK-NEXT:    ret i8 [[R]]
487   %BO0 = mul nuw nsw i8 %X, %Y
488   %BO1 = shl nuw nsw i8 %Z, %X
489   %r = urem i8 %BO0, %BO1
490   ret i8 %r
493 define i8 @urem_shl_YX_shl_XZ_fail(i8 %X, i8 %Z, i8 %Y) {
494 ; CHECK-LABEL: @urem_shl_YX_shl_XZ_fail(
495 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
496 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]]
497 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
498 ; CHECK-NEXT:    ret i8 [[R]]
500   %BO0 = shl nuw nsw i8 %Y, %X
501   %BO1 = shl nuw nsw i8 %X, %Z
502   %r = urem i8 %BO0, %BO1
503   ret i8 %r
506 define i8 @urem_shl_YX_mul_XZ_fail(i8 %X, i8 %Z, i8 %Y) {
507 ; CHECK-LABEL: @urem_shl_YX_mul_XZ_fail(
508 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
509 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
510 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
511 ; CHECK-NEXT:    ret i8 [[R]]
513   %BO0 = shl nuw nsw i8 %Y, %X
514   %BO1 = mul nuw nsw i8 %X, %Z
515   %r = urem i8 %BO0, %BO1
516   ret i8 %r
519 define i8 @urem_shl_YX_mul_ZX_fail(i8 %X, i8 %Z, i8 %Y) {
520 ; CHECK-LABEL: @urem_shl_YX_mul_ZX_fail(
521 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
522 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]]
523 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
524 ; CHECK-NEXT:    ret i8 [[R]]
526   %BO0 = shl nuw nsw i8 %Y, %X
527   %BO1 = mul nuw nsw i8 %Z, %X
528   %r = urem i8 %BO0, %BO1
529   ret i8 %r
532 define i8 @urem_mul_YX_shl_ZX_fail(i8 %X, i8 %Z, i8 %Y) {
533 ; CHECK-LABEL: @urem_mul_YX_shl_ZX_fail(
534 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]]
535 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
536 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
537 ; CHECK-NEXT:    ret i8 [[R]]
539   %BO0 = mul nuw nsw i8 %Y, %X
540   %BO1 = shl nuw nsw i8 %Z, %X
541   %r = urem i8 %BO0, %BO1
542   ret i8 %r
545 define i8 @urem_shl_CXY_shl_ZCX_fail(i8 %Z, i8 %Y) {
546 ; CHECK-LABEL: @urem_shl_CXY_shl_ZCX_fail(
547 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 3, [[Y:%.*]]
548 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], 3
549 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
550 ; CHECK-NEXT:    ret i8 [[R]]
552   %BO0 = shl nuw nsw i8 3, %Y
553   %BO1 = shl nuw nsw i8 %Z, 3
554   %r = urem i8 %BO0, %BO1
555   ret i8 %r
558 define i8 @urem_shl_YCX_shl_CXZ_fail(i8 %Z, i8 %Y) {
559 ; CHECK-LABEL: @urem_shl_YCX_shl_CXZ_fail(
560 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], 3
561 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 3, [[Z:%.*]]
562 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
563 ; CHECK-NEXT:    ret i8 [[R]]
565   %BO0 = shl nuw nsw i8 %Y, 3
566   %BO1 = shl nuw nsw i8 3, %Z
567   %r = urem i8 %BO0, %BO1
568   ret i8 %r
571 define i8 @urem_shl_YCX_mul_ZCX_fail(i8 %Z, i8 %Y) {
572 ; CHECK-LABEL: @urem_shl_YCX_mul_ZCX_fail(
573 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], 3
574 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], 10
575 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
576 ; CHECK-NEXT:    ret i8 [[R]]
578   %BO0 = shl nuw nsw i8 %Y, 3
579   %BO1 = mul nuw nsw i8 %Z, 10
580   %r = urem i8 %BO0, %BO1
581   ret i8 %r
584 define i8 @urem_mul_YCX_shl_ZCX_fail(i8 %Z, i8 %Y) {
585 ; CHECK-LABEL: @urem_mul_YCX_shl_ZCX_fail(
586 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], 3
587 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], 3
588 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
589 ; CHECK-NEXT:    ret i8 [[R]]
591   %BO0 = mul nuw nsw i8 %Y, 3
592   %BO1 = shl nuw nsw i8 %Z, 3
593   %r = urem i8 %BO0, %BO1
594   ret i8 %r
597 define i8 @urem_shl_XCY_shl_CZX_fail(i8 %X) {
598 ; CHECK-LABEL: @urem_shl_XCY_shl_CZX_fail(
599 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], 3
600 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 6, [[X]]
601 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
602 ; CHECK-NEXT:    ret i8 [[R]]
604   %BO0 = shl nuw nsw i8 %X, 3
605   %BO1 = shl nuw nsw i8 6, %X
606   %r = urem i8 %BO0, %BO1
607   ret i8 %r
610 define i8 @urem_mul_XCY_shl_CZX_fail(i8 %X) {
611 ; CHECK-LABEL: @urem_mul_XCY_shl_CZX_fail(
612 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], 6
613 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 3, [[X]]
614 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
615 ; CHECK-NEXT:    ret i8 [[R]]
617   %BO0 = mul nuw nsw i8 %X, 6
618   %BO1 = shl nuw nsw i8 3, %X
619   %r = urem i8 %BO0, %BO1
620   ret i8 %r
623 define i8 @urem_shl_CYX_shl_XCZ_fail(i8 %X) {
624 ; CHECK-LABEL: @urem_shl_CYX_shl_XCZ_fail(
625 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 3, [[X:%.*]]
626 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], 6
627 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
628 ; CHECK-NEXT:    ret i8 [[R]]
630   %BO0 = shl nuw nsw i8 3, %X
631   %BO1 = shl nuw nsw i8 %X, 6
632   %r = urem i8 %BO0, %BO1
633   ret i8 %r
636 define i8 @urem_shl_CYX_mul_XCZ_fail(i8 %X) {
637 ; CHECK-LABEL: @urem_shl_CYX_mul_XCZ_fail(
638 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 3, [[X:%.*]]
639 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], 10
640 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
641 ; CHECK-NEXT:    ret i8 [[R]]
643   %BO0 = shl nuw nsw i8 3, %X
644   %BO1 = mul nuw nsw i8 %X, 10
645   %r = urem i8 %BO0, %BO1
646   ret i8 %r
649 define i8 @urem_shl_XX_shl_ZX(i8 %X, i8 %Z) {
650 ; CHECK-LABEL: @urem_shl_XX_shl_ZX(
651 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
652 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
653 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
654 ; CHECK-NEXT:    ret i8 [[R]]
656   %BO0 = shl nuw nsw i8 %X, %X
657   %BO1 = shl nuw nsw i8 %Z, %X
658   %r = urem i8 %BO0, %BO1
659   ret i8 %r
662 define i8 @urem_shl_YX_shl_XX(i8 %X, i8 %Y) {
663 ; CHECK-LABEL: @urem_shl_YX_shl_XX(
664 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
665 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
666 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
667 ; CHECK-NEXT:    ret i8 [[R]]
669   %BO0 = shl nuw nsw i8 %Y, %X
670   %BO1 = shl nuw nsw i8 %X, %X
671   %r = urem i8 %BO0, %BO1
672   ret i8 %r
675 define i8 @urem_shl_XX_shl_XZ(i8 %X, i8 %Z) {
676 ; CHECK-LABEL: @urem_shl_XX_shl_XZ(
677 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
678 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]]
679 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
680 ; CHECK-NEXT:    ret i8 [[R]]
682   %BO0 = shl nuw nsw i8 %X, %X
683   %BO1 = shl nuw nsw i8 %X, %Z
684   %r = urem i8 %BO0, %BO1
685   ret i8 %r
688 define i8 @urem_shl_XY_shl_XX(i8 %X, i8 %Y) {
689 ; CHECK-LABEL: @urem_shl_XY_shl_XX(
690 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
691 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
692 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
693 ; CHECK-NEXT:    ret i8 [[R]]
695   %BO0 = shl nuw nsw i8 %X, %Y
696   %BO1 = shl nuw nsw i8 %X, %X
697   %r = urem i8 %BO0, %BO1
698   ret i8 %r
701 define i8 @urem_mul_XX_shl_ZX(i8 %X, i8 %Z) {
702 ; CHECK-LABEL: @urem_mul_XX_shl_ZX(
703 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]]
704 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[Z:%.*]], [[X]]
705 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
706 ; CHECK-NEXT:    ret i8 [[R]]
708   %BO0 = mul nuw nsw i8 %X, %X
709   %BO1 = shl nuw nsw i8 %Z, %X
710   %r = urem i8 %BO0, %BO1
711   ret i8 %r
714 define i8 @urem_mul_YX_shl_XX(i8 %X, i8 %Y) {
715 ; CHECK-LABEL: @urem_mul_YX_shl_XX(
716 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[Y:%.*]], [[X:%.*]]
717 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
718 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
719 ; CHECK-NEXT:    ret i8 [[R]]
721   %BO0 = mul nuw nsw i8 %Y, %X
722   %BO1 = shl nuw nsw i8 %X, %X
723   %r = urem i8 %BO0, %BO1
724   ret i8 %r
727 define i8 @urem_mul_XX_shl_XZ(i8 %X, i8 %Z) {
728 ; CHECK-LABEL: @urem_mul_XX_shl_XZ(
729 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]]
730 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[Z:%.*]]
731 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
732 ; CHECK-NEXT:    ret i8 [[R]]
734   %BO0 = mul nuw nsw i8 %X, %X
735   %BO1 = shl nuw nsw i8 %X, %Z
736   %r = urem i8 %BO0, %BO1
737   ret i8 %r
740 define i8 @urem_mul_XY_shl_XX(i8 %X, i8 %Y) {
741 ; CHECK-LABEL: @urem_mul_XY_shl_XX(
742 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[Y:%.*]]
743 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
744 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
745 ; CHECK-NEXT:    ret i8 [[R]]
747   %BO0 = mul nuw nsw i8 %X, %Y
748   %BO1 = shl nuw nsw i8 %X, %X
749   %r = urem i8 %BO0, %BO1
750   ret i8 %r
753 define i8 @urem_shl_XX_mul_ZX(i8 %X, i8 %Z) {
754 ; CHECK-LABEL: @urem_shl_XX_mul_ZX(
755 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
756 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[Z:%.*]], [[X]]
757 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
758 ; CHECK-NEXT:    ret i8 [[R]]
760   %BO0 = shl nuw nsw i8 %X, %X
761   %BO1 = mul nuw nsw i8 %Z, %X
762   %r = urem i8 %BO0, %BO1
763   ret i8 %r
766 define i8 @urem_shl_YX_mul_XX(i8 %X, i8 %Y) {
767 ; CHECK-LABEL: @urem_shl_YX_mul_XX(
768 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[X:%.*]]
769 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]]
770 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
771 ; CHECK-NEXT:    ret i8 [[R]]
773   %BO0 = shl nuw nsw i8 %Y, %X
774   %BO1 = mul nuw nsw i8 %X, %X
775   %r = urem i8 %BO0, %BO1
776   ret i8 %r
779 define i8 @urem_shl_XX_mul_XZ(i8 %X, i8 %Z) {
780 ; CHECK-LABEL: @urem_shl_XX_mul_XZ(
781 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
782 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[Z:%.*]]
783 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
784 ; CHECK-NEXT:    ret i8 [[R]]
786   %BO0 = shl nuw nsw i8 %X, %X
787   %BO1 = mul nuw nsw i8 %X, %Z
788   %r = urem i8 %BO0, %BO1
789   ret i8 %r
792 define i8 @urem_shl_XY_mul_XX(i8 %X, i8 %Y) {
793 ; CHECK-LABEL: @urem_shl_XY_mul_XX(
794 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Y:%.*]]
795 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]]
796 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
797 ; CHECK-NEXT:    ret i8 [[R]]
799   %BO0 = shl nuw nsw i8 %X, %Y
800   %BO1 = mul nuw nsw i8 %X, %X
801   %r = urem i8 %BO0, %BO1
802   ret i8 %r
805 define i8 @urem_mul_XX_shl_XX(i8 %X) {
806 ; CHECK-LABEL: @urem_mul_XX_shl_XX(
807 ; CHECK-NEXT:    [[BO0:%.*]] = mul nuw nsw i8 [[X:%.*]], [[X]]
808 ; CHECK-NEXT:    [[BO1:%.*]] = shl nuw nsw i8 [[X]], [[X]]
809 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
810 ; CHECK-NEXT:    ret i8 [[R]]
812   %BO0 = mul nuw nsw i8 %X, %X
813   %BO1 = shl nuw nsw i8 %X, %X
814   %r = urem i8 %BO0, %BO1
815   ret i8 %r
818 define i8 @urem_shl_XX_mul_XX(i8 %X) {
819 ; CHECK-LABEL: @urem_shl_XX_mul_XX(
820 ; CHECK-NEXT:    [[BO0:%.*]] = shl nuw nsw i8 [[X:%.*]], [[X]]
821 ; CHECK-NEXT:    [[BO1:%.*]] = mul nuw nsw i8 [[X]], [[X]]
822 ; CHECK-NEXT:    [[R:%.*]] = urem i8 [[BO0]], [[BO1]]
823 ; CHECK-NEXT:    ret i8 [[R]]
825   %BO0 = shl nuw nsw i8 %X, %X
826   %BO1 = mul nuw nsw i8 %X, %X
827   %r = urem i8 %BO0, %BO1
828   ret i8 %r
831 ; Negative test: No attribute vscale_range to indicate range
832 define i64 @urem_shl_vscale() {
833 ; CHECK-LABEL: @urem_shl_vscale(
834 ; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
835 ; CHECK-NEXT:    [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 2
836 ; CHECK-NEXT:    [[REM:%.*]] = urem i64 1024, [[SHIFT]]
837 ; CHECK-NEXT:    ret i64 [[REM]]
839   %vscale = call i64 @llvm.vscale.i64()
840   %shift = shl nuw nsw i64 %vscale, 2
841   %rem = urem i64 1024, %shift
842   ret i64 %rem
845 define i64 @urem_shl_vscale_range() vscale_range(1,16) {
846 ; CHECK-LABEL: @urem_shl_vscale_range(
847 ; CHECK-NEXT:    ret i64 0
849   %vscale = call i64 @llvm.vscale.i64()
850   %shift = shl nuw nsw i64 %vscale, 2
851   %rem = urem i64 1024, %shift
852   ret i64 %rem
855 define i64 @urem_vscale_range() vscale_range(1,16) {
856 ; CHECK-LABEL: @urem_vscale_range(
857 ; CHECK-NEXT:    ret i64 0
859   %vscale = call i64 @llvm.vscale.i64()
860   %shift = shl nuw nsw i64 %vscale, 6
861   %rem = urem i64 1024, %shift
862   ret i64 %rem
865 define i64 @urem_shl_vscale_out_of_range() vscale_range(1,16) {
866 ; CHECK-LABEL: @urem_shl_vscale_out_of_range(
867 ; CHECK-NEXT:    ret i64 1024
869   %vscale = call i64 @llvm.vscale.i64()
870   %shift = shl nuw nsw i64 %vscale, 11
871   %rem = urem i64 1024, %shift
872   ret i64 %rem
875 ; Negative test: The min value 1 << 10 is overlap to 1024
876 define i64 @urem_shl_vscale_overlap() vscale_range(1,16) {
877 ; CHECK-LABEL: @urem_shl_vscale_overlap(
878 ; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
879 ; CHECK-NEXT:    [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 10
880 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i64 [[SHIFT]], 2047
881 ; CHECK-NEXT:    [[REM:%.*]] = and i64 [[TMP1]], 1024
882 ; CHECK-NEXT:    ret i64 [[REM]]
884   %vscale = call i64 @llvm.vscale.i64()
885   %shift = shl nuw nsw i64 %vscale, 10
886   %rem = urem i64 1024, %shift
887   ret i64 %rem
890 define i64 @and_add_vscale_range_low() vscale_range(1,16) {
891 ; CHECK-LABEL: @and_add_vscale_range_low(
892 ; CHECK-NEXT:    ret i64 0
894   %vscale = call i64 @llvm.vscale.i64()
895   %shift = shl nuw nsw i64 %vscale, 6
896   %add = add i64 %shift, -1
897   %rem = and i64 1024, %add
898   ret i64 %rem
901 ; TODO: have no bits that may be part of the mask set,
902 ; but now expect the const is a power of two
903 define i64 @and_add_shl_vscale_not_power2() vscale_range(1,16) {
904 ; CHECK-LABEL: @and_add_shl_vscale_not_power2(
905 ; CHECK-NEXT:    [[VSCALE:%.*]] = call i64 @llvm.vscale.i64()
906 ; CHECK-NEXT:    [[SHIFT:%.*]] = shl nuw nsw i64 [[VSCALE]], 6
907 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i64 [[SHIFT]], 4095
908 ; CHECK-NEXT:    [[REM:%.*]] = and i64 [[ADD]], 3072
909 ; CHECK-NEXT:    ret i64 [[REM]]
911   %vscale = call i64 @llvm.vscale.i64()
912   %shift = shl nuw nsw i64 %vscale, 6
913   %add = add i64 %shift, -1
914   %rem = and i64 3072, %add
915   ret i64 %rem
918 ; Allow for INT_MIN, https://alive2.llvm.org/ce/z/yZ_I2a
919 define i32 @and_add_shl_vscale_not_power2_negative() vscale_range(1,16) {
920 ; CHECK-LABEL: @and_add_shl_vscale_not_power2_negative(
921 ; CHECK-NEXT:    ret i32 0
923   %vscale = call i32 @llvm.vscale.i32()
924   %shift = shl nuw nsw i32 %vscale, 6
925   %add = add i32 %shift, -1
926   %rem = and i32 -2147483648, %add
927   ret i32 %rem
930 ; Negative test: the %sign may be 0, https://alive2.llvm.org/ce/z/WU_j4a
931 define i32 @and_add_and (i32 %x) {
932 ; CHECK-LABEL: @and_add_and(
933 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[X:%.*]], 24
934 ; CHECK-NEXT:    [[TMP2:%.*]] = and i32 [[TMP1]], -2147483648
935 ; CHECK-NEXT:    [[AND:%.*]] = xor i32 [[TMP2]], -2147483648
936 ; CHECK-NEXT:    ret i32 [[AND]]
938   %x1 = lshr i32 %x, 7
939   %sign = and i32 %x1, 1  ; %sign = (%x >> 7) & 1
940   %add = add i32 %sign, -1
941   %and = and i32 %add, 2147483648
942   ret i32 %and