xref: /llvm-project/llvm/test/Transforms/InstCombine/div-shift.ll (revision 2d5f07c82836bde6f5ae16518931a78783a22ec8)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use(i8)
5declare void @use32(i32)
6
7declare i8 @llvm.umin.i8(i8, i8)
8declare i8 @llvm.umax.i8(i8, i8)
9declare i8 @llvm.smin.i8(i8, i8)
10declare i8 @llvm.smax.i8(i8, i8)
11
12define i32 @t1(i16 zeroext %x, i32 %y) {
13; CHECK-LABEL: @t1(
14; CHECK-NEXT:    [[CONV:%.*]] = zext i16 [[X:%.*]] to i32
15; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[Y:%.*]], 1
16; CHECK-NEXT:    [[D1:%.*]] = lshr i32 [[CONV]], [[TMP1]]
17; CHECK-NEXT:    ret i32 [[D1]]
18;
19  %conv = zext i16 %x to i32
20  %s = shl i32 2, %y
21  %d = sdiv i32 %conv, %s
22  ret i32 %d
23}
24
25define <2 x i32> @t1vec(<2 x i16> %x, <2 x i32> %y) {
26; CHECK-LABEL: @t1vec(
27; CHECK-NEXT:    [[CONV:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32>
28; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[Y:%.*]], splat (i32 1)
29; CHECK-NEXT:    [[D1:%.*]] = lshr <2 x i32> [[CONV]], [[TMP1]]
30; CHECK-NEXT:    ret <2 x i32> [[D1]]
31;
32  %conv = zext <2 x i16> %x to <2 x i32>
33  %s = shl <2 x i32> <i32 2, i32 2>, %y
34  %d = sdiv <2 x i32> %conv, %s
35  ret <2 x i32> %d
36}
37
38; rdar://11721329
39define i64 @t2(i64 %x, i32 %y) {
40; CHECK-LABEL: @t2(
41; CHECK-NEXT:    [[TMP1:%.*]] = zext nneg i32 [[Y:%.*]] to i64
42; CHECK-NEXT:    [[TMP2:%.*]] = lshr i64 [[X:%.*]], [[TMP1]]
43; CHECK-NEXT:    ret i64 [[TMP2]]
44;
45  %1 = shl i32 1, %y
46  %2 = zext i32 %1 to i64
47  %3 = udiv i64 %x, %2
48  ret i64 %3
49}
50
51; PR13250
52define i64 @t3(i64 %x, i32 %y) {
53; CHECK-LABEL: @t3(
54; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[Y:%.*]], 2
55; CHECK-NEXT:    [[TMP2:%.*]] = zext nneg i32 [[TMP1]] to i64
56; CHECK-NEXT:    [[TMP3:%.*]] = lshr i64 [[X:%.*]], [[TMP2]]
57; CHECK-NEXT:    ret i64 [[TMP3]]
58;
59  %1 = shl i32 4, %y
60  %2 = zext i32 %1 to i64
61  %3 = udiv i64 %x, %2
62  ret i64 %3
63}
64
65define i32 @t4(i32 %x, i32 %y) {
66; CHECK-LABEL: @t4(
67; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 5)
68; CHECK-NEXT:    [[TMP2:%.*]] = lshr i32 [[X:%.*]], [[TMP1]]
69; CHECK-NEXT:    ret i32 [[TMP2]]
70;
71  %1 = shl i32 1, %y
72  %2 = icmp ult i32 %1, 32
73  %3 = select i1 %2, i32 32, i32 %1
74  %4 = udiv i32 %x, %3
75  ret i32 %4
76}
77
78define i32 @t5(i1 %x, i1 %y, i32 %V) {
79; CHECK-LABEL: @t5(
80; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[X:%.*]], i32 5, i32 6
81; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[Y:%.*]], i32 [[TMP1]], i32 [[V:%.*]]
82; CHECK-NEXT:    [[TMP3:%.*]] = lshr i32 [[V]], [[TMP2]]
83; CHECK-NEXT:    ret i32 [[TMP3]]
84;
85  %1 = shl i32 1, %V
86  %2 = select i1 %x, i32 32, i32 64
87  %3 = select i1 %y, i32 %2, i32 %1
88  %4 = udiv i32 %V, %3
89  ret i32 %4
90}
91
92define i32 @t6(i32 %x, i32 %z) {
93; CHECK-LABEL: @t6(
94; CHECK-NEXT:    [[DIVISOR:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 1)
95; CHECK-NEXT:    [[Y:%.*]] = udiv i32 [[Z:%.*]], [[DIVISOR]]
96; CHECK-NEXT:    ret i32 [[Y]]
97;
98  %x_is_zero = icmp eq i32 %x, 0
99  %divisor = select i1 %x_is_zero, i32 1, i32 %x
100  %y = udiv i32 %z, %divisor
101  ret i32 %y
102}
103
104define i8 @udiv_umin(i8 %x, i8 %y, i8 %z) {
105; CHECK-LABEL: @udiv_umin(
106; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[Y:%.*]], i8 [[Z:%.*]])
107; CHECK-NEXT:    [[D1:%.*]] = lshr i8 [[X:%.*]], [[TMP1]]
108; CHECK-NEXT:    ret i8 [[D1]]
109;
110  %y2 = shl i8 1, %y
111  %z2 = shl i8 1, %z
112  %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z2)
113  %d = udiv i8 %x, %m
114  ret i8 %d
115}
116
117define i8 @udiv_umax(i8 %x, i8 %y, i8 %z) {
118; CHECK-LABEL: @udiv_umax(
119; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[Y:%.*]], i8 [[Z:%.*]])
120; CHECK-NEXT:    [[D1:%.*]] = lshr i8 [[X:%.*]], [[TMP1]]
121; CHECK-NEXT:    ret i8 [[D1]]
122;
123  %y2 = shl i8 1, %y
124  %z2 = shl i8 1, %z
125  %m = call i8 @llvm.umax.i8(i8 %y2, i8 %z2)
126  %d = udiv i8 %x, %m
127  ret i8 %d
128}
129
130; Negative test, cannot take exact log2
131define i8 @udiv_umin_(i8 %x, i8 %y, i8 %z) {
132; CHECK-LABEL: @udiv_umin_(
133; CHECK-NEXT:    [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]]
134; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z:%.*]])
135; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X:%.*]], [[M]]
136; CHECK-NEXT:    ret i8 [[D]]
137;
138  %y2 = shl i8 1, %y
139  %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z)
140  %d = udiv i8 %x, %m
141  ret i8 %d
142}
143
144; Negative test, extra use
145define i8 @udiv_umin_extra_use(i8 %x, i8 %y, i8 %z) {
146; CHECK-LABEL: @udiv_umin_extra_use(
147; CHECK-NEXT:    [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]]
148; CHECK-NEXT:    [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]]
149; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.umin.i8(i8 [[Y2]], i8 [[Z2]])
150; CHECK-NEXT:    call void @use(i8 [[M]])
151; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[M]], i1 true)
152; CHECK-NEXT:    [[D:%.*]] = lshr i8 [[X:%.*]], [[TMP1]]
153; CHECK-NEXT:    ret i8 [[D]]
154;
155  %y2 = shl i8 1, %y
156  %z2 = shl i8 1, %z
157  %m = call i8 @llvm.umin.i8(i8 %y2, i8 %z2)
158  call void @use(i8 %m)
159  %d = udiv i8 %x, %m
160  ret i8 %d
161}
162
163; Negative test, signed min/max
164define i8 @udiv_smin(i8 %x, i8 %y, i8 %z) {
165; CHECK-LABEL: @udiv_smin(
166; CHECK-NEXT:    [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]]
167; CHECK-NEXT:    [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]]
168; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.smin.i8(i8 [[Y2]], i8 [[Z2]])
169; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[M]], i1 true)
170; CHECK-NEXT:    [[D:%.*]] = lshr i8 [[X:%.*]], [[TMP1]]
171; CHECK-NEXT:    ret i8 [[D]]
172;
173  %y2 = shl i8 1, %y
174  %z2 = shl i8 1, %z
175  %m = call i8 @llvm.smin.i8(i8 %y2, i8 %z2)
176  %d = udiv i8 %x, %m
177  ret i8 %d
178}
179
180; Negative test, signed min/max
181define i8 @udiv_smax(i8 %x, i8 %y, i8 %z) {
182; CHECK-LABEL: @udiv_smax(
183; CHECK-NEXT:    [[Y2:%.*]] = shl nuw i8 1, [[Y:%.*]]
184; CHECK-NEXT:    [[Z2:%.*]] = shl nuw i8 1, [[Z:%.*]]
185; CHECK-NEXT:    [[M:%.*]] = call i8 @llvm.smax.i8(i8 [[Y2]], i8 [[Z2]])
186; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[M]], i1 true)
187; CHECK-NEXT:    [[D:%.*]] = lshr i8 [[X:%.*]], [[TMP1]]
188; CHECK-NEXT:    ret i8 [[D]]
189;
190  %y2 = shl i8 1, %y
191  %z2 = shl i8 1, %z
192  %m = call i8 @llvm.smax.i8(i8 %y2, i8 %z2)
193  %d = udiv i8 %x, %m
194  ret i8 %d
195}
196
197; (X << C1) / X -> 1 << C1 optimizations
198
199define i32 @t7(i32 %x) {
200; CHECK-LABEL: @t7(
201; CHECK-NEXT:    ret i32 4
202;
203  %shl = shl nsw i32 %x, 2
204  %r = sdiv i32 %shl, %x
205  ret i32 %r
206}
207
208; make sure the previous opt doesn't take place for wrapped shifts
209
210define i32 @t8(i32 %x) {
211; CHECK-LABEL: @t8(
212; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 2
213; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[SHL]], [[X]]
214; CHECK-NEXT:    ret i32 [[R]]
215;
216  %shl = shl i32 %x, 2
217  %r = sdiv i32 %shl, %x
218  ret i32 %r
219}
220
221define <2 x i32> @t9(<2 x i32> %x) {
222; CHECK-LABEL: @t9(
223; CHECK-NEXT:    ret <2 x i32> <i32 4, i32 8>
224;
225  %shl = shl nsw <2 x i32> %x, <i32 2, i32 3>
226  %r = sdiv <2 x i32> %shl, %x
227  ret <2 x i32> %r
228}
229
230define i32 @t10(i32 %x, i32 %y) {
231; CHECK-LABEL: @t10(
232; CHECK-NEXT:    [[R:%.*]] = shl nuw nsw i32 1, [[Y:%.*]]
233; CHECK-NEXT:    ret i32 [[R]]
234;
235  %shl = shl nsw i32 %x, %y
236  %r = sdiv i32 %shl, %x
237  ret i32 %r
238}
239
240define <2 x i32> @t11(<2 x i32> %x, <2 x i32> %y) {
241; CHECK-LABEL: @t11(
242; CHECK-NEXT:    [[R:%.*]] = shl nuw nsw <2 x i32> splat (i32 1), [[Y:%.*]]
243; CHECK-NEXT:    ret <2 x i32> [[R]]
244;
245  %shl = shl nsw <2 x i32> %x, %y
246  %r = sdiv <2 x i32> %shl, %x
247  ret <2 x i32> %r
248}
249
250define i32 @t12(i32 %x) {
251; CHECK-LABEL: @t12(
252; CHECK-NEXT:    ret i32 4
253;
254  %shl = shl nuw i32 %x, 2
255  %r = udiv i32 %shl, %x
256  ret i32 %r
257}
258
259; make sure the previous opt doesn't take place for wrapped shifts
260
261define i32 @t13(i32 %x) {
262; CHECK-LABEL: @t13(
263; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[X:%.*]], 2
264; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[SHL]], [[X]]
265; CHECK-NEXT:    ret i32 [[R]]
266;
267  %shl = shl i32 %x, 2
268  %r = udiv i32 %shl, %x
269  ret i32 %r
270}
271
272define <2 x i32> @t14(<2 x i32> %x) {
273; CHECK-LABEL: @t14(
274; CHECK-NEXT:    ret <2 x i32> <i32 4, i32 8>
275;
276  %shl = shl nuw <2 x i32> %x, <i32 2, i32 3>
277  %r = udiv <2 x i32> %shl, %x
278  ret <2 x i32> %r
279}
280
281define i32 @t15(i32 %x, i32 %y) {
282; CHECK-LABEL: @t15(
283; CHECK-NEXT:    [[R:%.*]] = shl nuw i32 1, [[Y:%.*]]
284; CHECK-NEXT:    ret i32 [[R]]
285;
286  %shl = shl nuw i32 %x, %y
287  %r = udiv i32 %shl, %x
288  ret i32 %r
289}
290
291define <2 x i32> @t16(<2 x i32> %x, <2 x i32> %y) {
292; CHECK-LABEL: @t16(
293; CHECK-NEXT:    [[R:%.*]] = shl nuw <2 x i32> splat (i32 1), [[Y:%.*]]
294; CHECK-NEXT:    ret <2 x i32> [[R]]
295;
296  %shl = shl nuw <2 x i32> %x, %y
297  %r = udiv <2 x i32> %shl, %x
298  ret <2 x i32> %r
299}
300
301; (X * Y) s/ (X << Z) --> Y s/ (1 << Z)
302
303define i5 @sdiv_mul_shl_nsw(i5 %x, i5 %y, i5 %z) {
304; CHECK-LABEL: @sdiv_mul_shl_nsw(
305; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]]
306; CHECK-NEXT:    [[D:%.*]] = sdiv i5 [[Y:%.*]], [[TMP1]]
307; CHECK-NEXT:    ret i5 [[D]]
308;
309  %m1 = mul nsw i5 %x, %y
310  %m2 = shl nsw i5 %x, %z
311  %d = sdiv i5 %m1, %m2
312  ret i5 %d
313}
314
315; (Y * Z) s/ (X << Z) --> Y s/ (1 << Z)
316
317define i5 @sdiv_mul_shl_nsw_exact_commute1(i5 %x, i5 %y, i5 %z) {
318; CHECK-LABEL: @sdiv_mul_shl_nsw_exact_commute1(
319; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]]
320; CHECK-NEXT:    [[D:%.*]] = sdiv exact i5 [[Y:%.*]], [[TMP1]]
321; CHECK-NEXT:    ret i5 [[D]]
322;
323  %m1 = mul nsw i5 %y, %x
324  %m2 = shl nsw i5 %x, %z
325  %d = sdiv exact i5 %m1, %m2
326  ret i5 %d
327}
328
329; negative test - shl is not commutative
330
331define i5 @sdiv_mul_shl_nsw_commute2(i5 %x, i5 %y, i5 %z) {
332; CHECK-LABEL: @sdiv_mul_shl_nsw_commute2(
333; CHECK-NEXT:    [[M1:%.*]] = mul nsw i5 [[Y:%.*]], [[X:%.*]]
334; CHECK-NEXT:    [[M2:%.*]] = shl nsw i5 [[Z:%.*]], [[X]]
335; CHECK-NEXT:    [[D:%.*]] = sdiv i5 [[M1]], [[M2]]
336; CHECK-NEXT:    ret i5 [[D]]
337;
338  %m1 = mul nsw i5 %y, %x
339  %m2 = shl nsw i5 %z, %x
340  %d = sdiv i5 %m1, %m2
341  ret i5 %d
342}
343
344; extra use is ok
345
346define i8 @sdiv_mul_shl_nsw_use1(i8 %x, i8 %y, i8 %z) {
347; CHECK-LABEL: @sdiv_mul_shl_nsw_use1(
348; CHECK-NEXT:    [[M1:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]]
349; CHECK-NEXT:    call void @use(i8 [[M1]])
350; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i8 1, [[Z:%.*]]
351; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[Y]], [[TMP1]]
352; CHECK-NEXT:    ret i8 [[D]]
353;
354  %m1 = mul nsw i8 %x, %y
355  call void @use(i8 %m1)
356  %m2 = shl nsw i8 %x, %z
357  %d = sdiv i8 %m1, %m2
358  ret i8 %d
359}
360
361; extra use is ok
362
363define i8 @sdiv_mul_shl_nsw_use2(i8 %x, i8 %y, i8 %z) {
364; CHECK-LABEL: @sdiv_mul_shl_nsw_use2(
365; CHECK-NEXT:    [[M2:%.*]] = shl nsw i8 [[X:%.*]], [[Z:%.*]]
366; CHECK-NEXT:    call void @use(i8 [[M2]])
367; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i8 1, [[Z]]
368; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[Y:%.*]], [[TMP1]]
369; CHECK-NEXT:    ret i8 [[D]]
370;
371  %m1 = mul nsw i8 %x, %y
372  %m2 = shl nsw i8 %x, %z
373  call void @use(i8 %m2)
374  %d = sdiv i8 %m1, %m2
375  ret i8 %d
376}
377
378; negative test - both operands can't have extra uses
379
380define i8 @sdiv_mul_shl_nsw_use3(i8 %x, i8 %y, i8 %z) {
381; CHECK-LABEL: @sdiv_mul_shl_nsw_use3(
382; CHECK-NEXT:    [[M1:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]]
383; CHECK-NEXT:    call void @use(i8 [[M1]])
384; CHECK-NEXT:    [[M2:%.*]] = shl nsw i8 [[X]], [[Z:%.*]]
385; CHECK-NEXT:    call void @use(i8 [[M2]])
386; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[M1]], [[M2]]
387; CHECK-NEXT:    ret i8 [[D]]
388;
389  %m1 = mul nsw i8 %x, %y
390  call void @use(i8 %m1)
391  %m2 = shl nsw i8 %x, %z
392  call void @use(i8 %m2)
393  %d = sdiv i8 %m1, %m2
394  ret i8 %d
395}
396
397; negative test - shl must be divisor
398
399define i5 @sdiv_shl_mul_nsw(i5 %x, i5 %y, i5 %z) {
400; CHECK-LABEL: @sdiv_shl_mul_nsw(
401; CHECK-NEXT:    [[M1:%.*]] = shl nsw i5 [[Z:%.*]], [[X:%.*]]
402; CHECK-NEXT:    [[M2:%.*]] = mul nsw i5 [[X]], [[Y:%.*]]
403; CHECK-NEXT:    [[D:%.*]] = sdiv i5 [[M1]], [[M2]]
404; CHECK-NEXT:    ret i5 [[D]]
405;
406  %m1 = shl nsw i5 %z, %x
407  %m2 = mul nsw i5 %x, %y
408  %d = sdiv i5 %m1, %m2
409  ret i5 %d
410}
411
412; negative test - wrong no-wrap
413
414define i5 @sdiv_mul_shl_missing_nsw1(i5 %x, i5 %y, i5 %z) {
415; CHECK-LABEL: @sdiv_mul_shl_missing_nsw1(
416; CHECK-NEXT:    [[M1:%.*]] = mul nsw i5 [[X:%.*]], [[Y:%.*]]
417; CHECK-NEXT:    [[M2:%.*]] = shl nuw i5 [[Y]], [[Z:%.*]]
418; CHECK-NEXT:    [[D:%.*]] = sdiv i5 [[M1]], [[M2]]
419; CHECK-NEXT:    ret i5 [[D]]
420;
421  %m1 = mul nsw i5 %x, %y
422  %m2 = shl nuw i5 %y, %z
423  %d = sdiv i5 %m1, %m2
424  ret i5 %d
425}
426
427; negative test - wrong no-wrap
428
429define i5 @sdiv_mul_shl_missing_nsw2(i5 %x, i5 %y, i5 %z) {
430; CHECK-LABEL: @sdiv_mul_shl_missing_nsw2(
431; CHECK-NEXT:    [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]]
432; CHECK-NEXT:    [[M2:%.*]] = shl nsw i5 [[Y]], [[Z:%.*]]
433; CHECK-NEXT:    [[D:%.*]] = sdiv i5 [[M1]], [[M2]]
434; CHECK-NEXT:    ret i5 [[D]]
435;
436  %m1 = mul nuw i5 %x, %y
437  %m2 = shl nsw i5 %y, %z
438  %d = sdiv i5 %m1, %m2
439  ret i5 %d
440}
441
442; (X * Y) u/ (X << Z) --> Y u>> Z
443
444define i5 @udiv_mul_shl_nuw(i5 %x, i5 %y, i5 %z) {
445; CHECK-LABEL: @udiv_mul_shl_nuw(
446; CHECK-NEXT:    [[D:%.*]] = lshr i5 [[Y:%.*]], [[Z:%.*]]
447; CHECK-NEXT:    ret i5 [[D]]
448;
449  %m1 = mul nuw i5 %x, %y
450  %m2 = shl nuw i5 %x, %z
451  %d = udiv i5 %m1, %m2
452  ret i5 %d
453}
454
455; (Y * X) u/ (X << Z) --> Y u>> Z
456
457define i5 @udiv_mul_shl_nuw_exact_commute1(i5 %x, i5 %y, i5 %z) {
458; CHECK-LABEL: @udiv_mul_shl_nuw_exact_commute1(
459; CHECK-NEXT:    [[D:%.*]] = lshr exact i5 [[Y:%.*]], [[Z:%.*]]
460; CHECK-NEXT:    ret i5 [[D]]
461;
462  %m1 = mul nuw i5 %y, %x
463  %m2 = shl nuw i5 %x, %z
464  %d = udiv exact i5 %m1, %m2
465  ret i5 %d
466}
467
468; negative test - shl is not commutative
469
470define i5 @udiv_mul_shl_nuw_commute2(i5 %x, i5 %y, i5 %z) {
471; CHECK-LABEL: @udiv_mul_shl_nuw_commute2(
472; CHECK-NEXT:    [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]]
473; CHECK-NEXT:    [[M2:%.*]] = shl nuw i5 [[Z:%.*]], [[X]]
474; CHECK-NEXT:    [[D:%.*]] = udiv i5 [[M1]], [[M2]]
475; CHECK-NEXT:    ret i5 [[D]]
476;
477  %m1 = mul nuw i5 %x, %y
478  %m2 = shl nuw i5 %z, %x
479  %d = udiv i5 %m1, %m2
480  ret i5 %d
481}
482
483; extra uses are ok
484
485define i8 @udiv_mul_shl_nsw_use1(i8 %x, i8 %y, i8 %z) {
486; CHECK-LABEL: @udiv_mul_shl_nsw_use1(
487; CHECK-NEXT:    [[M1:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
488; CHECK-NEXT:    call void @use(i8 [[M1]])
489; CHECK-NEXT:    [[D:%.*]] = lshr i8 [[Y]], [[Z:%.*]]
490; CHECK-NEXT:    ret i8 [[D]]
491;
492  %m1 = mul nuw i8 %x, %y
493  call void @use(i8 %m1)
494  %m2 = shl nuw i8 %x, %z
495  %d = udiv i8 %m1, %m2
496  ret i8 %d
497}
498
499; extra uses are ok
500
501define i8 @udiv_mul_shl_nsw_use2(i8 %x, i8 %y, i8 %z) {
502; CHECK-LABEL: @udiv_mul_shl_nsw_use2(
503; CHECK-NEXT:    [[M2:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]]
504; CHECK-NEXT:    call void @use(i8 [[M2]])
505; CHECK-NEXT:    [[D:%.*]] = lshr i8 [[Y:%.*]], [[Z]]
506; CHECK-NEXT:    ret i8 [[D]]
507;
508  %m1 = mul nuw i8 %x, %y
509  %m2 = shl nuw i8 %x, %z
510  call void @use(i8 %m2)
511  %d = udiv i8 %m1, %m2
512  ret i8 %d
513}
514
515; extra uses are ok
516
517define i8 @udiv_mul_shl_nsw_use3(i8 %x, i8 %y, i8 %z) {
518; CHECK-LABEL: @udiv_mul_shl_nsw_use3(
519; CHECK-NEXT:    [[M1:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
520; CHECK-NEXT:    call void @use(i8 [[M1]])
521; CHECK-NEXT:    [[M2:%.*]] = shl nuw i8 [[X]], [[Z:%.*]]
522; CHECK-NEXT:    call void @use(i8 [[M2]])
523; CHECK-NEXT:    [[D:%.*]] = lshr i8 [[Y]], [[Z]]
524; CHECK-NEXT:    ret i8 [[D]]
525;
526  %m1 = mul nuw i8 %x, %y
527  call void @use(i8 %m1)
528  %m2 = shl nuw i8 %x, %z
529  call void @use(i8 %m2)
530  %d = udiv i8 %m1, %m2
531  ret i8 %d
532}
533
534; (X << Z) / (X * Y) -> (1 << Z) / Y
535
536define i5 @udiv_shl_mul_nuw(i5 %x, i5 %y, i5 %z) {
537; CHECK-LABEL: @udiv_shl_mul_nuw(
538; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]]
539; CHECK-NEXT:    [[D:%.*]] = udiv i5 [[TMP1]], [[Y:%.*]]
540; CHECK-NEXT:    ret i5 [[D]]
541;
542  %m1 = shl nuw i5 %x, %z
543  %m2 = mul nuw i5 %x, %y
544  %d = udiv i5 %m1, %m2
545  ret i5 %d
546}
547
548define i5 @udiv_shl_mul_nuw_swap(i5 %x, i5 %y, i5 %z) {
549; CHECK-LABEL: @udiv_shl_mul_nuw_swap(
550; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]]
551; CHECK-NEXT:    [[D:%.*]] = udiv i5 [[TMP1]], [[Y:%.*]]
552; CHECK-NEXT:    ret i5 [[D]]
553;
554  %m1 = shl nuw i5 %x, %z
555  %m2 = mul nuw i5 %y, %x
556  %d = udiv i5 %m1, %m2
557  ret i5 %d
558}
559
560define i5 @udiv_shl_mul_nuw_exact(i5 %x, i5 %y, i5 %z) {
561; CHECK-LABEL: @udiv_shl_mul_nuw_exact(
562; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i5 1, [[Z:%.*]]
563; CHECK-NEXT:    [[D:%.*]] = udiv exact i5 [[TMP1]], [[Y:%.*]]
564; CHECK-NEXT:    ret i5 [[D]]
565;
566  %m1 = shl nuw i5 %x, %z
567  %m2 = mul nuw i5 %x, %y
568  %d = udiv exact i5 %m1, %m2
569  ret i5 %d
570}
571
572define <2 x i4> @udiv_shl_mul_nuw_vec(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
573; CHECK-LABEL: @udiv_shl_mul_nuw_vec(
574; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw <2 x i4> splat (i4 1), [[Z:%.*]]
575; CHECK-NEXT:    [[D:%.*]] = udiv <2 x i4> [[TMP1]], [[Y:%.*]]
576; CHECK-NEXT:    ret <2 x i4> [[D]]
577;
578  %m1 = shl nuw <2 x i4> %x, %z
579  %m2 = mul nuw <2 x i4> %y, %x
580  %d = udiv <2 x i4> %m1, %m2
581  ret <2 x i4> %d
582}
583
584define i8 @udiv_shl_mul_nuw_extra_use_of_shl(i8 %x, i8 %y, i8 %z) {
585; CHECK-LABEL: @udiv_shl_mul_nuw_extra_use_of_shl(
586; CHECK-NEXT:    [[M1:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]]
587; CHECK-NEXT:    call void @use(i8 [[M1]])
588; CHECK-NEXT:    [[TMP1:%.*]] = shl nuw i8 1, [[Z]]
589; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[TMP1]], [[Y:%.*]]
590; CHECK-NEXT:    ret i8 [[D]]
591;
592  %m1 = shl nuw i8 %x, %z
593  call void @use(i8 %m1)
594  %m2 = mul nuw i8 %y, %x
595  %d = udiv i8 %m1, %m2
596  ret i8 %d
597}
598
599; negative test - extra use
600
601define i8 @udiv_shl_mul_nuw_extra_use_of_mul(i8 %x, i8 %y, i8 %z) {
602; CHECK-LABEL: @udiv_shl_mul_nuw_extra_use_of_mul(
603; CHECK-NEXT:    [[M1:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]]
604; CHECK-NEXT:    [[M2:%.*]] = mul nuw i8 [[Y:%.*]], [[X]]
605; CHECK-NEXT:    call void @use(i8 [[M2]])
606; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[M1]], [[M2]]
607; CHECK-NEXT:    ret i8 [[D]]
608;
609  %m1 = shl nuw i8 %x, %z
610  %m2 = mul nuw i8 %y, %x
611  call void @use(i8 %m2)
612  %d = udiv i8 %m1, %m2
613  ret i8 %d
614}
615
616define i8 @udiv_shl_mul_nuw_extra_use(i8 %x, i8 %y, i8 %z) {
617; CHECK-LABEL: @udiv_shl_mul_nuw_extra_use(
618; CHECK-NEXT:    [[M1:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]]
619; CHECK-NEXT:    call void @use(i8 [[M1]])
620; CHECK-NEXT:    [[M2:%.*]] = mul nuw i8 [[Y:%.*]], [[X]]
621; CHECK-NEXT:    call void @use(i8 [[M2]])
622; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[M1]], [[M2]]
623; CHECK-NEXT:    ret i8 [[D]]
624;
625  %m1 = shl nuw i8 %x, %z
626  call void @use(i8 %m1)
627  %m2 = mul nuw i8 %y, %x
628  call void @use(i8 %m2)
629  %d = udiv i8 %m1, %m2
630  ret i8 %d
631}
632
633; negative test - sdiv
634
635define i5 @sdiv_shl_mul_nuw(i5 %x, i5 %y, i5 %z) {
636; CHECK-LABEL: @sdiv_shl_mul_nuw(
637; CHECK-NEXT:    [[M1:%.*]] = shl nuw i5 [[X:%.*]], [[Z:%.*]]
638; CHECK-NEXT:    [[M2:%.*]] = mul nuw i5 [[X]], [[Y:%.*]]
639; CHECK-NEXT:    [[D:%.*]] = sdiv i5 [[M1]], [[M2]]
640; CHECK-NEXT:    ret i5 [[D]]
641;
642  %m1 = shl nuw i5 %x, %z
643  %m2 = mul nuw i5 %x, %y
644  %d = sdiv i5 %m1, %m2
645  ret i5 %d
646}
647
648; negative test - wrong no-wrap
649
650define i5 @udiv_mul_shl_missing_nsw1(i5 %x, i5 %y, i5 %z) {
651; CHECK-LABEL: @udiv_mul_shl_missing_nsw1(
652; CHECK-NEXT:    [[M1:%.*]] = mul nsw i5 [[X:%.*]], [[Y:%.*]]
653; CHECK-NEXT:    [[M2:%.*]] = shl nuw i5 [[Y]], [[Z:%.*]]
654; CHECK-NEXT:    [[D:%.*]] = udiv i5 [[M1]], [[M2]]
655; CHECK-NEXT:    ret i5 [[D]]
656;
657  %m1 = mul nsw i5 %x, %y
658  %m2 = shl nuw i5 %y, %z
659  %d = udiv i5 %m1, %m2
660  ret i5 %d
661}
662
663; negative test - wrong no-wrap
664
665define i5 @udiv_mul_shl_missing_nsw2(i5 %x, i5 %y, i5 %z) {
666; CHECK-LABEL: @udiv_mul_shl_missing_nsw2(
667; CHECK-NEXT:    [[M1:%.*]] = mul nuw i5 [[X:%.*]], [[Y:%.*]]
668; CHECK-NEXT:    [[M2:%.*]] = shl nsw i5 [[Y]], [[Z:%.*]]
669; CHECK-NEXT:    [[D:%.*]] = udiv i5 [[M1]], [[M2]]
670; CHECK-NEXT:    ret i5 [[D]]
671;
672  %m1 = mul nuw i5 %x, %y
673  %m2 = shl nsw i5 %y, %z
674  %d = udiv i5 %m1, %m2
675  ret i5 %d
676}
677
678define i8 @udiv_shl_nuw(i8 %x, i8 %y, i8 %z) {
679; CHECK-LABEL: @udiv_shl_nuw(
680; CHECK-NEXT:    [[S:%.*]] = shl nuw i8 [[Y:%.*]], [[Z:%.*]]
681; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X:%.*]], [[S]]
682; CHECK-NEXT:    ret i8 [[D]]
683;
684  %s = shl nuw i8 %y, %z
685  %d = udiv i8 %x, %s
686  ret i8 %d
687}
688
689define <2 x i4> @udiv_shl_nuw_exact(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
690; CHECK-LABEL: @udiv_shl_nuw_exact(
691; CHECK-NEXT:    [[S:%.*]] = shl nuw <2 x i4> [[Y:%.*]], [[Z:%.*]]
692; CHECK-NEXT:    [[D:%.*]] = udiv exact <2 x i4> [[X:%.*]], [[S]]
693; CHECK-NEXT:    ret <2 x i4> [[D]]
694;
695  %s = shl nuw <2 x i4> %y, %z
696  %d = udiv exact <2 x i4> %x, %s
697  ret <2 x i4> %d
698}
699
700define i8 @udiv_shl(i8 %x, i8 %y, i8 %z) {
701; CHECK-LABEL: @udiv_shl(
702; CHECK-NEXT:    [[S:%.*]] = shl i8 [[Y:%.*]], [[Z:%.*]]
703; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X:%.*]], [[S]]
704; CHECK-NEXT:    ret i8 [[D]]
705;
706  %s = shl i8 %y, %z
707  %d = udiv i8 %x, %s
708  ret i8 %d
709}
710
711define i8 @udiv_shl_nuw_use(i8 %x, i8 %y, i8 %z) {
712; CHECK-LABEL: @udiv_shl_nuw_use(
713; CHECK-NEXT:    [[S:%.*]] = shl nuw i8 [[Y:%.*]], [[Z:%.*]]
714; CHECK-NEXT:    call void @use(i8 [[S]])
715; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X:%.*]], [[S]]
716; CHECK-NEXT:    ret i8 [[D]]
717;
718  %s = shl nuw i8 %y, %z
719  call void @use(i8 %s)
720  %d = udiv i8 %x, %s
721  ret i8 %d
722}
723
724; ((X * Y) >> Z) / X --> Y >> Z
725
726define i8 @udiv_lshr_mul_nuw(i8 %x, i8 %y, i8 %z) {
727; CHECK-LABEL: @udiv_lshr_mul_nuw(
728; CHECK-NEXT:    [[DIV:%.*]] = lshr i8 [[Y:%.*]], [[Z:%.*]]
729; CHECK-NEXT:    ret i8 [[DIV]]
730;
731  %m = mul nuw i8 %x, %y
732  %s = lshr i8 %m, %z
733  %div = udiv i8 %s, %x
734  ret i8 %div
735}
736
737; ((Y * X) >> Z) / X --> Y >> Z
738
739define <2 x i4> @udiv_lshr_mul_nuw_exact_commute1(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
740; CHECK-LABEL: @udiv_lshr_mul_nuw_exact_commute1(
741; CHECK-NEXT:    [[DIV:%.*]] = lshr exact <2 x i4> [[Y:%.*]], [[Z:%.*]]
742; CHECK-NEXT:    ret <2 x i4> [[DIV]]
743;
744  %m = mul nuw <2 x i4> %y, %x
745  %s = lshr exact <2 x i4> %m, %z
746  %div = udiv exact <2 x i4> %s, %x
747  ret <2 x i4> %div
748}
749
750; negative test - mul is shifted amount, not shifted value
751
752define i8 @udiv_lshr_mul_nuw_commute2(i8 %x, i8 %y, i8 %z) {
753; CHECK-LABEL: @udiv_lshr_mul_nuw_commute2(
754; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[Y:%.*]], [[X:%.*]]
755; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[Z:%.*]], [[M]]
756; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[S]], [[X]]
757; CHECK-NEXT:    ret i8 [[DIV]]
758;
759  %m = mul nuw i8 %y, %x
760  %s = lshr i8 %z, %m
761  %div = udiv i8 %s, %x
762  ret i8 %div
763}
764
765; extra uses are ok
766
767define i8 @udiv_lshr_mul_nuw_use1(i8 %x, i8 %y, i8 %z) {
768; CHECK-LABEL: @udiv_lshr_mul_nuw_use1(
769; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
770; CHECK-NEXT:    call void @use(i8 [[M]])
771; CHECK-NEXT:    [[DIV:%.*]] = lshr i8 [[Y]], [[Z:%.*]]
772; CHECK-NEXT:    ret i8 [[DIV]]
773;
774  %m = mul nuw i8 %x, %y
775  call void @use(i8 %m)
776  %s = lshr i8 %m, %z
777  %div = udiv i8 %s, %x
778  ret i8 %div
779}
780
781; extra uses are ok
782
783define i8 @udiv_lshr_mul_nuw_use2(i8 %x, i8 %y, i8 %z) {
784; CHECK-LABEL: @udiv_lshr_mul_nuw_use2(
785; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
786; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[M]], [[Z:%.*]]
787; CHECK-NEXT:    call void @use(i8 [[S]])
788; CHECK-NEXT:    [[DIV:%.*]] = lshr i8 [[Y]], [[Z]]
789; CHECK-NEXT:    ret i8 [[DIV]]
790;
791  %m = mul nuw i8 %x, %y
792  %s = lshr i8 %m, %z
793  call void @use(i8 %s)
794  %div = udiv i8 %s, %x
795  ret i8 %div
796}
797
798; extra uses are ok
799
800define i8 @udiv_lshr_mul_nuw_use3(i8 %x, i8 %y, i8 %z) {
801; CHECK-LABEL: @udiv_lshr_mul_nuw_use3(
802; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
803; CHECK-NEXT:    call void @use(i8 [[M]])
804; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[M]], [[Z:%.*]]
805; CHECK-NEXT:    call void @use(i8 [[S]])
806; CHECK-NEXT:    [[DIV:%.*]] = lshr i8 [[Y]], [[Z]]
807; CHECK-NEXT:    ret i8 [[DIV]]
808;
809  %m = mul nuw i8 %x, %y
810  call void @use(i8 %m)
811  %s = lshr i8 %m, %z
812  call void @use(i8 %s)
813  %div = udiv i8 %s, %x
814  ret i8 %div
815}
816
817; negative test - must have nuw
818
819define i8 @udiv_lshr_mul_nsw(i8 %x, i8 %y, i8 %z) {
820; CHECK-LABEL: @udiv_lshr_mul_nsw(
821; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]]
822; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[M]], [[Z:%.*]]
823; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[S]], [[X]]
824; CHECK-NEXT:    ret i8 [[DIV]]
825;
826  %m = mul nsw i8 %x, %y
827  %s = lshr i8 %m, %z
828  %div = udiv i8 %s, %x
829  ret i8 %div
830}
831
832; negative test - doesn't fold with signed div
833
834define i8 @sdiv_lshr_mul_nsw(i8 %x, i8 %y, i8 %z) {
835; CHECK-LABEL: @sdiv_lshr_mul_nsw(
836; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]]
837; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[M]], [[Z:%.*]]
838; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[S]], [[X]]
839; CHECK-NEXT:    ret i8 [[DIV]]
840;
841  %m = mul nsw i8 %x, %y
842  %s = lshr i8 %m, %z
843  %div = sdiv i8 %s, %x
844  ret i8 %div
845}
846
847; (X << Z) / (Y << Z) --> X / Y
848
849define i8 @sdiv_shl_shl_nsw2_nuw(i8 %x, i8 %y, i8 %z) {
850; CHECK-LABEL: @sdiv_shl_shl_nsw2_nuw(
851; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], [[Y:%.*]]
852; CHECK-NEXT:    ret i8 [[D]]
853;
854  %xz = shl nsw i8 %x, %z
855  %yz = shl nsw nuw i8 %y, %z
856  %d = sdiv i8 %xz, %yz
857  ret i8 %d
858}
859
860; extra uses are ok and 'exact' propagates
861
862define i8 @sdiv_shl_shl_nsw2_nuw_exact_use(i8 %x, i8 %y, i8 %z) {
863; CHECK-LABEL: @sdiv_shl_shl_nsw2_nuw_exact_use(
864; CHECK-NEXT:    [[XZ:%.*]] = shl nsw i8 [[X:%.*]], [[Z:%.*]]
865; CHECK-NEXT:    call void @use(i8 [[XZ]])
866; CHECK-NEXT:    [[D:%.*]] = sdiv exact i8 [[X]], [[Y:%.*]]
867; CHECK-NEXT:    ret i8 [[D]]
868;
869  %xz = shl nsw i8 %x, %z
870  call void @use(i8 %xz)
871  %yz = shl nsw nuw i8 %y, %z
872  %d = sdiv exact i8 %xz, %yz
873  ret i8 %d
874}
875
876; negative test - wrong wrap
877
878define i8 @sdiv_shl_shl_nsw_nuw2(i8 %x, i8 %y, i8 %z) {
879; CHECK-LABEL: @sdiv_shl_shl_nsw_nuw2(
880; CHECK-NEXT:    [[XZ:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]]
881; CHECK-NEXT:    [[YZ:%.*]] = shl nuw nsw i8 [[Y:%.*]], [[Z]]
882; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[XZ]], [[YZ]]
883; CHECK-NEXT:    ret i8 [[D]]
884;
885  %xz = shl nuw i8 %x, %z
886  %yz = shl nsw nuw i8 %y, %z
887  %d = sdiv i8 %xz, %yz
888  ret i8 %d
889}
890
891; negative test - wrong wrap
892
893define i8 @sdiv_shl_shl_nsw_nuw(i8 %x, i8 %y, i8 %z) {
894; CHECK-LABEL: @sdiv_shl_shl_nsw_nuw(
895; CHECK-NEXT:    [[XZ:%.*]] = shl nsw i8 [[X:%.*]], [[Z:%.*]]
896; CHECK-NEXT:    [[YZ:%.*]] = shl nuw i8 [[Y:%.*]], [[Z]]
897; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[XZ]], [[YZ]]
898; CHECK-NEXT:    ret i8 [[D]]
899;
900  %xz = shl nsw i8 %x, %z
901  %yz = shl nuw i8 %y, %z
902  %d = sdiv i8 %xz, %yz
903  ret i8 %d
904}
905
906; negative test - wrong wrap
907
908define i8 @sdiv_shl_shl_nuw_nsw2(i8 %x, i8 %y, i8 %z) {
909; CHECK-LABEL: @sdiv_shl_shl_nuw_nsw2(
910; CHECK-NEXT:    [[XZ:%.*]] = shl nuw nsw i8 [[X:%.*]], [[Z:%.*]]
911; CHECK-NEXT:    [[YZ:%.*]] = shl nsw i8 [[Y:%.*]], [[Z]]
912; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[XZ]], [[YZ]]
913; CHECK-NEXT:    ret i8 [[D]]
914;
915  %xz = shl nuw nsw i8 %x, %z
916  %yz = shl nsw i8 %y, %z
917  %d = sdiv i8 %xz, %yz
918  ret i8 %d
919}
920
921; (X << Z) / (Y << Z) --> X / Y
922
923define <2 x i8> @udiv_shl_shl_nuw2(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
924; CHECK-LABEL: @udiv_shl_shl_nuw2(
925; CHECK-NEXT:    [[D:%.*]] = udiv <2 x i8> [[X:%.*]], [[Y:%.*]]
926; CHECK-NEXT:    ret <2 x i8> [[D]]
927;
928  %xz = shl nuw <2 x i8> %x, %z
929  %yz = shl nuw <2 x i8> %y, %z
930  %d = udiv <2 x i8> %xz, %yz
931  ret <2 x i8> %d
932}
933
934; extra uses are ok and 'exact' propagates
935
936define i8 @udiv_shl_shl_nuw2_exact_use2(i8 %x, i8 %y, i8 %z) {
937; CHECK-LABEL: @udiv_shl_shl_nuw2_exact_use2(
938; CHECK-NEXT:    [[XZ:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]]
939; CHECK-NEXT:    call void @use(i8 [[XZ]])
940; CHECK-NEXT:    [[YZ:%.*]] = shl nuw i8 [[Y:%.*]], [[Z]]
941; CHECK-NEXT:    call void @use(i8 [[YZ]])
942; CHECK-NEXT:    [[D:%.*]] = udiv exact i8 [[X]], [[Y]]
943; CHECK-NEXT:    ret i8 [[D]]
944;
945  %xz = shl nuw i8 %x, %z
946  call void @use(i8 %xz)
947  %yz = shl nuw i8 %y, %z
948  call void @use(i8 %yz)
949  %d = udiv exact i8 %xz, %yz
950  ret i8 %d
951}
952
953; negative test - wrong wrap
954
955define i8 @udiv_shl_shl_nuw_nsw(i8 %x, i8 %y, i8 %z) {
956; CHECK-LABEL: @udiv_shl_shl_nuw_nsw(
957; CHECK-NEXT:    [[XZ:%.*]] = shl nuw i8 [[X:%.*]], [[Z:%.*]]
958; CHECK-NEXT:    [[YZ:%.*]] = shl nsw i8 [[Y:%.*]], [[Z]]
959; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[XZ]], [[YZ]]
960; CHECK-NEXT:    ret i8 [[D]]
961;
962  %xz = shl nuw i8 %x, %z
963  %yz = shl nsw i8 %y, %z
964  %d = udiv i8 %xz, %yz
965  ret i8 %d
966}
967
968; negative test - wrong wrap
969
970define i8 @udiv_shl_shl_nsw_nuw(i8 %x, i8 %y, i8 %z) {
971; CHECK-LABEL: @udiv_shl_shl_nsw_nuw(
972; CHECK-NEXT:    [[XZ:%.*]] = shl nsw i8 [[X:%.*]], [[Z:%.*]]
973; CHECK-NEXT:    [[YZ:%.*]] = shl nuw i8 [[Y:%.*]], [[Z]]
974; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[XZ]], [[YZ]]
975; CHECK-NEXT:    ret i8 [[D]]
976;
977  %xz = shl nsw i8 %x, %z
978  %yz = shl nuw i8 %y, %z
979  %d = udiv i8 %xz, %yz
980  ret i8 %d
981}
982
983define i8 @udiv_shl_shl_nuw_nsw2(i8 %x, i8 %y, i8 %z) {
984; CHECK-LABEL: @udiv_shl_shl_nuw_nsw2(
985; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
986; CHECK-NEXT:    ret i8 [[D]]
987;
988  %xz = shl nuw nsw i8 %x, %z
989  %yz = shl nsw i8 %y, %z
990  %d = udiv i8 %xz, %yz
991  ret i8 %d
992}
993
994; TODO: X / (Y << Z) --> (X >> Z) / Y
995; https://alive2.llvm.org/ce/z/FjoN_A
996
997define i8 @udiv_shl_nuw_divisor(i8 %x, i8 %y, i8 %z) {
998; CHECK-LABEL: @udiv_shl_nuw_divisor(
999; CHECK-NEXT:    [[S:%.*]] = shl nuw i8 [[Y:%.*]], [[Z:%.*]]
1000; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[X:%.*]], [[S]]
1001; CHECK-NEXT:    ret i8 [[D]]
1002;
1003  %s = shl nuw i8 %y, %z
1004  %d = udiv i8 %x, %s
1005  ret i8 %d
1006}
1007
1008define i8 @udiv_fail_shl_overflow(i8 %x, i8 %y) {
1009; CHECK-LABEL: @udiv_fail_shl_overflow(
1010; CHECK-NEXT:    [[SHL:%.*]] = shl i8 2, [[Y:%.*]]
1011; CHECK-NEXT:    [[MIN:%.*]] = call i8 @llvm.umax.i8(i8 [[SHL]], i8 1)
1012; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[MIN]], i1 true)
1013; CHECK-NEXT:    [[MUL:%.*]] = lshr i8 [[X:%.*]], [[TMP1]]
1014; CHECK-NEXT:    ret i8 [[MUL]]
1015;
1016  %shl = shl i8 2, %y
1017  %min = call i8 @llvm.umax.i8(i8 %shl, i8 1)
1018  %mul = udiv i8 %x, %min
1019  ret i8 %mul
1020}
1021
1022define i8 @udiv_shl_no_overflow(i8 %x, i8 %y) {
1023; CHECK-LABEL: @udiv_shl_no_overflow(
1024; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y:%.*]], 1
1025; CHECK-NEXT:    [[MUL1:%.*]] = lshr i8 [[X:%.*]], [[TMP1]]
1026; CHECK-NEXT:    ret i8 [[MUL1]]
1027;
1028  %shl = shl nuw i8 2, %y
1029  %min = call i8 @llvm.umax.i8(i8 %shl, i8 1)
1030  %mul = udiv i8 %x, %min
1031  ret i8 %mul
1032}
1033
1034; (X<<Y) / (X<<Z) -> 1 << Y >> Z
1035
1036define i32 @sdiv_shl_pair_const(i32 %a) {
1037; CHECK-LABEL: @sdiv_shl_pair_const(
1038; CHECK-NEXT:  entry:
1039; CHECK-NEXT:    ret i32 2
1040;
1041entry:
1042  %lhs = shl nsw i32 %a, 2
1043  %rhs = shl nsw i32 %a, 1
1044  %div = sdiv i32 %lhs, %rhs
1045  ret i32 %div
1046}
1047
1048define i32 @udiv_shl_pair_const(i32 %a) {
1049; CHECK-LABEL: @udiv_shl_pair_const(
1050; CHECK-NEXT:  entry:
1051; CHECK-NEXT:    ret i32 2
1052;
1053entry:
1054  %lhs = shl nuw i32 %a, 2
1055  %rhs = shl nuw i32 %a, 1
1056  %div = udiv i32 %lhs, %rhs
1057  ret i32 %div
1058}
1059
1060define i32 @sdiv_shl_pair1(i32 %a, i32 %x, i32 %y) {
1061; CHECK-LABEL: @sdiv_shl_pair1(
1062; CHECK-NEXT:  entry:
1063; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]]
1064; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]]
1065; CHECK-NEXT:    ret i32 [[DIV]]
1066;
1067entry:
1068  %lhs = shl nsw i32 %a, %x
1069  %rhs = shl nuw nsw i32 %a, %y
1070  %div = sdiv i32 %lhs, %rhs
1071  ret i32 %div
1072}
1073
1074define i32 @sdiv_shl_pair2(i32 %a, i32 %x, i32 %y) {
1075; CHECK-LABEL: @sdiv_shl_pair2(
1076; CHECK-NEXT:  entry:
1077; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]]
1078; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]]
1079; CHECK-NEXT:    ret i32 [[DIV]]
1080;
1081entry:
1082  %lhs = shl nuw nsw i32 %a, %x
1083  %rhs = shl nsw i32 %a, %y
1084  %div = sdiv i32 %lhs, %rhs
1085  ret i32 %div
1086}
1087
1088define i32 @sdiv_shl_pair3(i32 %a, i32 %x, i32 %y) {
1089; CHECK-LABEL: @sdiv_shl_pair3(
1090; CHECK-NEXT:  entry:
1091; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]]
1092; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]]
1093; CHECK-NEXT:    ret i32 [[DIV]]
1094;
1095entry:
1096  %lhs = shl nsw i32 %a, %x
1097  %rhs = shl nsw i32 %a, %y
1098  %div = sdiv i32 %lhs, %rhs
1099  ret i32 %div
1100}
1101
1102define i32 @sdiv_shl_no_pair_fail(i32 %a, i32 %b, i32 %x, i32 %y) {
1103; CHECK-LABEL: @sdiv_shl_no_pair_fail(
1104; CHECK-NEXT:  entry:
1105; CHECK-NEXT:    [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]]
1106; CHECK-NEXT:    [[RHS:%.*]] = shl nuw i32 [[B:%.*]], [[Y:%.*]]
1107; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]]
1108; CHECK-NEXT:    ret i32 [[DIV]]
1109;
1110entry:
1111  %lhs = shl nuw nsw i32 %a, %x
1112  %rhs = shl nuw i32 %b, %y
1113  %div = sdiv i32 %lhs, %rhs
1114  ret i32 %div
1115}
1116
1117define i32 @udiv_shl_pair1(i32 %a, i32 %x, i32 %y) {
1118; CHECK-LABEL: @udiv_shl_pair1(
1119; CHECK-NEXT:  entry:
1120; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]]
1121; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]]
1122; CHECK-NEXT:    ret i32 [[DIV]]
1123;
1124entry:
1125  %lhs = shl nuw i32 %a, %x
1126  %rhs = shl nuw i32 %a, %y
1127  %div = udiv i32 %lhs, %rhs
1128  ret i32 %div
1129}
1130
1131define i32 @udiv_shl_pair2(i32 %a, i32 %x, i32 %y) {
1132; CHECK-LABEL: @udiv_shl_pair2(
1133; CHECK-NEXT:  entry:
1134; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]]
1135; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]]
1136; CHECK-NEXT:    ret i32 [[DIV]]
1137;
1138entry:
1139  %lhs = shl nuw nsw i32 %a, %x
1140  %rhs = shl nuw i32 %a, %y
1141  %div = udiv i32 %lhs, %rhs
1142  ret i32 %div
1143}
1144
1145define i32 @udiv_shl_pair3(i32 %a, i32 %x, i32 %y) {
1146; CHECK-LABEL: @udiv_shl_pair3(
1147; CHECK-NEXT:  entry:
1148; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw i32 1, [[X:%.*]]
1149; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]]
1150; CHECK-NEXT:    ret i32 [[DIV]]
1151;
1152entry:
1153  %lhs = shl nuw i32 %a, %x
1154  %rhs = shl nuw nsw i32 %a, %y
1155  %div = udiv i32 %lhs, %rhs
1156  ret i32 %div
1157}
1158
1159define i32 @sdiv_shl_pair_overflow_fail1(i32 %a, i32 %x, i32 %y) {
1160; CHECK-LABEL: @sdiv_shl_pair_overflow_fail1(
1161; CHECK-NEXT:  entry:
1162; CHECK-NEXT:    [[LHS:%.*]] = shl i32 [[A:%.*]], [[X:%.*]]
1163; CHECK-NEXT:    [[RHS:%.*]] = shl nsw i32 [[A]], [[Y:%.*]]
1164; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]]
1165; CHECK-NEXT:    ret i32 [[DIV]]
1166;
1167entry:
1168  %lhs = shl i32 %a, %x
1169  %rhs = shl nsw i32 %a, %y
1170  %div = sdiv i32 %lhs, %rhs
1171  ret i32 %div
1172}
1173
1174define i32 @sdiv_shl_pair_overflow_fail2(i32 %a, i32 %x, i32 %y) {
1175; CHECK-LABEL: @sdiv_shl_pair_overflow_fail2(
1176; CHECK-NEXT:  entry:
1177; CHECK-NEXT:    [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]]
1178; CHECK-NEXT:    [[RHS:%.*]] = shl nuw i32 [[A]], [[Y:%.*]]
1179; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[LHS]], [[RHS]]
1180; CHECK-NEXT:    ret i32 [[DIV]]
1181;
1182entry:
1183  %lhs = shl nsw i32 %a, %x
1184  %rhs = shl nuw i32 %a, %y
1185  %div = sdiv i32 %lhs, %rhs
1186  ret i32 %div
1187}
1188
1189define i32 @udiv_shl_pair_overflow_fail1(i32 %a, i32 %x, i32 %y) {
1190; CHECK-LABEL: @udiv_shl_pair_overflow_fail1(
1191; CHECK-NEXT:  entry:
1192; CHECK-NEXT:    [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]]
1193; CHECK-NEXT:    [[RHS:%.*]] = shl nuw i32 [[A]], [[Y:%.*]]
1194; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]]
1195; CHECK-NEXT:    ret i32 [[DIV]]
1196;
1197entry:
1198  %lhs = shl nsw i32 %a, %x
1199  %rhs = shl nuw i32 %a, %y
1200  %div = udiv i32 %lhs, %rhs
1201  ret i32 %div
1202}
1203
1204define i32 @udiv_shl_pair_overflow_fail2(i32 %a, i32 %x, i32 %y) {
1205; CHECK-LABEL: @udiv_shl_pair_overflow_fail2(
1206; CHECK-NEXT:  entry:
1207; CHECK-NEXT:    [[LHS:%.*]] = shl nsw i32 [[A:%.*]], [[X:%.*]]
1208; CHECK-NEXT:    [[RHS:%.*]] = shl i32 [[A]], [[Y:%.*]]
1209; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]]
1210; CHECK-NEXT:    ret i32 [[DIV]]
1211;
1212entry:
1213  %lhs = shl nsw i32 %a, %x
1214  %rhs = shl i32 %a, %y
1215  %div = udiv i32 %lhs, %rhs
1216  ret i32 %div
1217}
1218
1219define i32 @udiv_shl_pair_overflow_fail3(i32 %a, i32 %x, i32 %y) {
1220; CHECK-LABEL: @udiv_shl_pair_overflow_fail3(
1221; CHECK-NEXT:  entry:
1222; CHECK-NEXT:    [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]]
1223; CHECK-NEXT:    [[RHS:%.*]] = shl i32 [[A]], [[Y:%.*]]
1224; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[LHS]], [[RHS]]
1225; CHECK-NEXT:    ret i32 [[DIV]]
1226;
1227entry:
1228  %lhs = shl nuw nsw i32 %a, %x
1229  %rhs = shl i32 %a, %y
1230  %div = udiv i32 %lhs, %rhs
1231  ret i32 %div
1232}
1233
1234define i32 @sdiv_shl_pair_multiuse1(i32 %a, i32 %x, i32 %y) {
1235; CHECK-LABEL: @sdiv_shl_pair_multiuse1(
1236; CHECK-NEXT:  entry:
1237; CHECK-NEXT:    [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]]
1238; CHECK-NEXT:    call void @use32(i32 [[LHS]])
1239; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X]]
1240; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y:%.*]]
1241; CHECK-NEXT:    ret i32 [[DIV]]
1242;
1243entry:
1244  %lhs = shl nuw nsw i32 %a, %x
1245  call void @use32(i32 %lhs)
1246  %rhs = shl nsw i32 %a, %y
1247  %div = sdiv i32 %lhs, %rhs
1248  ret i32 %div
1249}
1250
1251define i32 @sdiv_shl_pair_multiuse2(i32 %a, i32 %x, i32 %y) {
1252; CHECK-LABEL: @sdiv_shl_pair_multiuse2(
1253; CHECK-NEXT:  entry:
1254; CHECK-NEXT:    [[RHS:%.*]] = shl nsw i32 [[A:%.*]], [[Y:%.*]]
1255; CHECK-NEXT:    call void @use32(i32 [[RHS]])
1256; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X:%.*]]
1257; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y]]
1258; CHECK-NEXT:    ret i32 [[DIV]]
1259;
1260entry:
1261  %lhs = shl nuw nsw i32 %a, %x
1262  %rhs = shl nsw i32 %a, %y
1263  call void @use32(i32 %rhs)
1264  %div = sdiv i32 %lhs, %rhs
1265  ret i32 %div
1266}
1267
1268define i32 @sdiv_shl_pair_multiuse3(i32 %a, i32 %x, i32 %y) {
1269; CHECK-LABEL: @sdiv_shl_pair_multiuse3(
1270; CHECK-NEXT:  entry:
1271; CHECK-NEXT:    [[LHS:%.*]] = shl nuw nsw i32 [[A:%.*]], [[X:%.*]]
1272; CHECK-NEXT:    [[RHS:%.*]] = shl nsw i32 [[A]], [[Y:%.*]]
1273; CHECK-NEXT:    call void @use32(i32 [[LHS]])
1274; CHECK-NEXT:    call void @use32(i32 [[RHS]])
1275; CHECK-NEXT:    [[SHL_DIVIDEND:%.*]] = shl nuw nsw i32 1, [[X]]
1276; CHECK-NEXT:    [[DIV:%.*]] = lshr i32 [[SHL_DIVIDEND]], [[Y]]
1277; CHECK-NEXT:    ret i32 [[DIV]]
1278;
1279entry:
1280  %lhs = shl nuw nsw i32 %a, %x
1281  %rhs = shl nsw i32 %a, %y
1282  call void @use32(i32 %lhs)
1283  call void @use32(i32 %rhs)
1284  %div = sdiv i32 %lhs, %rhs
1285  ret i32 %div
1286}
1287
1288@a = external global i32
1289define i32 @pr69291() {
1290; CHECK-LABEL: @pr69291(
1291; CHECK-NEXT:  entry:
1292; CHECK-NEXT:    ret i32 1
1293;
1294entry:
1295  %conv = load i32, ptr @a, align 1
1296  %add = shl nuw nsw i32 %conv, 1
1297  %add2 = shl nuw nsw i32 %conv, 1
1298  %div = sdiv i32 %add, %add2
1299  ret i32 %div
1300}
1301
1302define i8 @udiv_if_power_of_two(i8 %x, i8 %y) {
1303; CHECK-LABEL: @udiv_if_power_of_two(
1304; CHECK-NEXT:  start:
1305; CHECK-NEXT:    [[TMP0:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[Y:%.*]])
1306; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[TMP0]], 1
1307; CHECK-NEXT:    br i1 [[TMP1]], label [[BB1:%.*]], label [[BB3:%.*]]
1308; CHECK:       bb1:
1309; CHECK-NEXT:    [[TMP2:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[Y]], i1 true)
1310; CHECK-NEXT:    [[TMP3:%.*]] = lshr i8 [[X:%.*]], [[TMP2]]
1311; CHECK-NEXT:    br label [[BB3]]
1312; CHECK:       bb3:
1313; CHECK-NEXT:    [[_0_SROA_0_0:%.*]] = phi i8 [ [[TMP3]], [[BB1]] ], [ 0, [[START:%.*]] ]
1314; CHECK-NEXT:    ret i8 [[_0_SROA_0_0]]
1315;
1316start:
1317  %ctpop = tail call i8 @llvm.ctpop.i8(i8 %y)
1318  %cmp = icmp eq i8 %ctpop, 1
1319  br i1 %cmp, label %bb1, label %bb3
1320
1321bb1:
1322  %div = udiv i8 %x, %y
1323  br label %bb3
1324
1325bb3:
1326  %result = phi i8 [ %div, %bb1 ], [ 0, %start ]
1327  ret i8 %result
1328}
1329
1330define i8 @udiv_exact_assume_power_of_two(i8 %x, i8 %y) {
1331; CHECK-LABEL: @udiv_exact_assume_power_of_two(
1332; CHECK-NEXT:  start:
1333; CHECK-NEXT:    [[TMP0:%.*]] = tail call range(i8 1, 9) i8 @llvm.ctpop.i8(i8 [[Y:%.*]])
1334; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[TMP0]], 1
1335; CHECK-NEXT:    tail call void @llvm.assume(i1 [[COND]])
1336; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[Y]], i1 true)
1337; CHECK-NEXT:    [[_0:%.*]] = lshr exact i8 [[X:%.*]], [[TMP1]]
1338; CHECK-NEXT:    ret i8 [[_0]]
1339;
1340start:
1341  %ctpop = tail call i8 @llvm.ctpop.i8(i8 %y)
1342  %cond = icmp eq i8 %ctpop, 1
1343  tail call void @llvm.assume(i1 %cond)
1344  %div = udiv exact i8 %x, %y
1345  ret i8 %div
1346}
1347
1348define i7 @udiv_assume_power_of_two_illegal_type(i7 %x, i7 %y) {
1349; CHECK-LABEL: @udiv_assume_power_of_two_illegal_type(
1350; CHECK-NEXT:  start:
1351; CHECK-NEXT:    [[TMP0:%.*]] = tail call range(i7 1, 8) i7 @llvm.ctpop.i7(i7 [[Y:%.*]])
1352; CHECK-NEXT:    [[COND:%.*]] = icmp eq i7 [[TMP0]], 1
1353; CHECK-NEXT:    tail call void @llvm.assume(i1 [[COND]])
1354; CHECK-NEXT:    [[TMP1:%.*]] = call range(i7 0, 8) i7 @llvm.cttz.i7(i7 [[Y]], i1 true)
1355; CHECK-NEXT:    [[_0:%.*]] = lshr i7 [[X:%.*]], [[TMP1]]
1356; CHECK-NEXT:    ret i7 [[_0]]
1357;
1358start:
1359  %ctpop = tail call i7 @llvm.ctpop.i7(i7 %y)
1360  %cond = icmp eq i7 %ctpop, 1
1361  tail call void @llvm.assume(i1 %cond)
1362  %div = udiv i7 %x, %y
1363  ret i7 %div
1364}
1365
1366define i8 @udiv_assume_power_of_two_multiuse(i8 %x, i8 %y) {
1367; CHECK-LABEL: @udiv_assume_power_of_two_multiuse(
1368; CHECK-NEXT:  start:
1369; CHECK-NEXT:    [[TMP0:%.*]] = tail call range(i8 1, 9) i8 @llvm.ctpop.i8(i8 [[Y:%.*]])
1370; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[TMP0]], 1
1371; CHECK-NEXT:    tail call void @llvm.assume(i1 [[COND]])
1372; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[Y]], i1 true)
1373; CHECK-NEXT:    [[_0:%.*]] = lshr i8 [[X:%.*]], [[TMP1]]
1374; CHECK-NEXT:    call void @use(i8 [[_0]])
1375; CHECK-NEXT:    ret i8 [[_0]]
1376;
1377start:
1378  %ctpop = tail call i8 @llvm.ctpop.i8(i8 %y)
1379  %cond = icmp eq i8 %ctpop, 1
1380  tail call void @llvm.assume(i1 %cond)
1381  %div = udiv i8 %x, %y
1382  call void @use(i8 %div)
1383  ret i8 %div
1384}
1385
1386define i8 @udiv_power_of_two_negative(i8 %x, i8 %y, i8 %z) {
1387; CHECK-LABEL: @udiv_power_of_two_negative(
1388; CHECK-NEXT:  start:
1389; CHECK-NEXT:    [[CTPOP:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[Z:%.*]])
1390; CHECK-NEXT:    [[COND:%.*]] = icmp eq i8 [[CTPOP]], 1
1391; CHECK-NEXT:    tail call void @llvm.assume(i1 [[COND]])
1392; CHECK-NEXT:    [[_0:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
1393; CHECK-NEXT:    ret i8 [[_0]]
1394;
1395start:
1396  %ctpop = tail call i8 @llvm.ctpop.i8(i8 %z)
1397  %cond = icmp eq i8 %ctpop, 1
1398  tail call void @llvm.assume(i1 %cond)
1399  %div = udiv i8 %x, %y
1400  ret i8 %div
1401}
1402