xref: /llvm-project/llvm/test/Transforms/InstCombine/div.ll (revision 56c091ea7106507b36015297ee9005c9d5fab0bf)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3; RUN: opt < %s -passes=instcombine -use-constant-int-for-fixed-length-splat -S | FileCheck %s
4
5declare void @use(i32)
6
7define i32 @test1(i32 %A) {
8; CHECK-LABEL: @test1(
9; CHECK-NEXT:    ret i32 [[A:%.*]]
10;
11  %B = sdiv i32 %A, 1
12  ret i32 %B
13}
14
15define i32 @test2(i32 %A) {
16; CHECK-LABEL: @test2(
17; CHECK-NEXT:    [[B1:%.*]] = lshr i32 [[A:%.*]], 3
18; CHECK-NEXT:    ret i32 [[B1]]
19;
20  %B = udiv i32 %A, 8
21  ret i32 %B
22}
23
24define i32 @sdiv_by_minus1(i32 %A) {
25; CHECK-LABEL: @sdiv_by_minus1(
26; CHECK-NEXT:    [[B:%.*]] = sub nsw i32 0, [[A:%.*]]
27; CHECK-NEXT:    ret i32 [[B]]
28;
29  %B = sdiv i32 %A, -1
30  ret i32 %B
31}
32
33define <2 x i64> @sdiv_by_minus1_vec(<2 x i64> %x) {
34; CHECK-LABEL: @sdiv_by_minus1_vec(
35; CHECK-NEXT:    [[DIV:%.*]] = sub nsw <2 x i64> zeroinitializer, [[X:%.*]]
36; CHECK-NEXT:    ret <2 x i64> [[DIV]]
37;
38  %div = sdiv <2 x i64> %x, <i64 -1, i64 -1>
39  ret <2 x i64> %div
40}
41
42define <2 x i64> @sdiv_by_minus1_vec_poison_elt(<2 x i64> %x) {
43; CHECK-LABEL: @sdiv_by_minus1_vec_poison_elt(
44; CHECK-NEXT:    ret <2 x i64> poison
45;
46  %div = sdiv <2 x i64> %x, <i64 -1, i64 poison>
47  ret <2 x i64> %div
48}
49
50define i32 @sdiv_by_sext_minus1(i1 %x, i32 %y) {
51; CHECK-LABEL: @sdiv_by_sext_minus1(
52; CHECK-NEXT:    [[DIV:%.*]] = sub nsw i32 0, [[Y:%.*]]
53; CHECK-NEXT:    ret i32 [[DIV]]
54;
55  %sext = sext i1 %x to i32
56  %div = sdiv i32 %y, %sext
57  ret i32 %div
58}
59
60define <2 x i32> @sdiv_by_sext_minus1_vec(<2 x i1> %x, <2 x i32> %y) {
61; CHECK-LABEL: @sdiv_by_sext_minus1_vec(
62; CHECK-NEXT:    [[DIV:%.*]] = sub nsw <2 x i32> zeroinitializer, [[Y:%.*]]
63; CHECK-NEXT:    ret <2 x i32> [[DIV]]
64;
65  %sext = sext <2 x i1> %x to <2 x i32>
66  %div = sdiv <2 x i32> %y, %sext
67  ret <2 x i32> %div
68}
69
70define i8 @udiv_by_negative(i8 %x) {
71; CHECK-LABEL: @udiv_by_negative(
72; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], -7
73; CHECK-NEXT:    [[A:%.*]] = zext i1 [[TMP1]] to i8
74; CHECK-NEXT:    ret i8 [[A]]
75;
76  %A = udiv i8 %x, 250
77  ret i8 %A
78}
79
80define i32 @udiv_by_minus1(i32 %A) {
81; CHECK-LABEL: @udiv_by_minus1(
82; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[A:%.*]], -1
83; CHECK-NEXT:    [[B:%.*]] = zext i1 [[TMP1]] to i32
84; CHECK-NEXT:    ret i32 [[B]]
85;
86  %B = udiv i32 %A, -1
87  ret i32 %B
88}
89
90define <2 x i64> @udiv_by_minus1_vec(<2 x i64> %x) {
91; CHECK-LABEL: @udiv_by_minus1_vec(
92; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i64> [[X:%.*]], splat (i64 -1)
93; CHECK-NEXT:    [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i64>
94; CHECK-NEXT:    ret <2 x i64> [[DIV]]
95;
96  %div = udiv <2 x i64> %x, <i64 -1, i64 -1>
97  ret <2 x i64> %div
98}
99
100define i32 @udiv_by_sext_all_ones(i1 %x, i32 %y) {
101; CHECK-LABEL: @udiv_by_sext_all_ones(
102; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[Y:%.*]], -1
103; CHECK-NEXT:    [[DIV:%.*]] = zext i1 [[TMP1]] to i32
104; CHECK-NEXT:    ret i32 [[DIV]]
105;
106  %sext = sext i1 %x to i32
107  %div = udiv i32 %y, %sext
108  ret i32 %div
109}
110
111define <2 x i32> @udiv_by_sext_all_ones_vec(<2 x i1> %x, <2 x i32> %y) {
112; CHECK-LABEL: @udiv_by_sext_all_ones_vec(
113; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[Y:%.*]], splat (i32 -1)
114; CHECK-NEXT:    [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
115; CHECK-NEXT:    ret <2 x i32> [[DIV]]
116;
117  %sext = sext <2 x i1> %x to <2 x i32>
118  %div = udiv <2 x i32> %y, %sext
119  ret <2 x i32> %div
120}
121
122define i32 @test5(i32 %A) {
123; CHECK-LABEL: @test5(
124; CHECK-NEXT:    ret i32 0
125;
126  %B = udiv i32 %A, -16
127  %C = udiv i32 %B, -4
128  ret i32 %C
129}
130
131define i1 @test6(i32 %A) {
132; CHECK-LABEL: @test6(
133; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A:%.*]], 123
134; CHECK-NEXT:    ret i1 [[C]]
135;
136  %B = udiv i32 %A, 123
137  ; A < 123
138  %C = icmp eq i32 %B, 0
139  ret i1 %C
140}
141
142define i1 @test7(i32 %A) {
143; CHECK-LABEL: @test7(
144; CHECK-NEXT:    [[A_OFF:%.*]] = add i32 [[A:%.*]], -20
145; CHECK-NEXT:    [[C:%.*]] = icmp ult i32 [[A_OFF]], 10
146; CHECK-NEXT:    ret i1 [[C]]
147;
148  %B = udiv i32 %A, 10
149  ; A >= 20 && A < 30
150  %C = icmp eq i32 %B, 2
151  ret i1 %C
152}
153
154define <2 x i1> @test7vec(<2 x i32> %A) {
155; CHECK-LABEL: @test7vec(
156; CHECK-NEXT:    [[A_OFF:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -20)
157; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i32> [[A_OFF]], splat (i32 10)
158; CHECK-NEXT:    ret <2 x i1> [[C]]
159;
160  %B = udiv <2 x i32> %A, <i32 10, i32 10>
161  %C = icmp eq <2 x i32> %B, <i32 2, i32 2>
162  ret <2 x i1> %C
163}
164
165define i1 @test8(i8 %A) {
166; CHECK-LABEL: @test8(
167; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[A:%.*]], -11
168; CHECK-NEXT:    ret i1 [[C]]
169;
170  %B = udiv i8 %A, 123
171  ; A >= 246
172  %C = icmp eq i8 %B, 2
173  ret i1 %C
174}
175
176define <2 x i1> @test8vec(<2 x i8> %A) {
177; CHECK-LABEL: @test8vec(
178; CHECK-NEXT:    [[C:%.*]] = icmp ugt <2 x i8> [[A:%.*]], splat (i8 -11)
179; CHECK-NEXT:    ret <2 x i1> [[C]]
180;
181  %B = udiv <2 x i8> %A, <i8 123, i8 123>
182  %C = icmp eq <2 x i8> %B, <i8 2, i8 2>
183  ret <2 x i1> %C
184}
185
186define i1 @test9(i8 %A) {
187; CHECK-LABEL: @test9(
188; CHECK-NEXT:    [[C:%.*]] = icmp ult i8 [[A:%.*]], -10
189; CHECK-NEXT:    ret i1 [[C]]
190;
191  %B = udiv i8 %A, 123
192  ; A < 246
193  %C = icmp ne i8 %B, 2
194  ret i1 %C
195}
196
197define <2 x i1> @test9vec(<2 x i8> %A) {
198; CHECK-LABEL: @test9vec(
199; CHECK-NEXT:    [[C:%.*]] = icmp ult <2 x i8> [[A:%.*]], splat (i8 -10)
200; CHECK-NEXT:    ret <2 x i1> [[C]]
201;
202  %B = udiv <2 x i8> %A, <i8 123, i8 123>
203  %C = icmp ne <2 x i8> %B, <i8 2, i8 2>
204  ret <2 x i1> %C
205}
206
207define i32 @test10(i32 %X, i1 %C) {
208; CHECK-LABEL: @test10(
209; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i32 6, i32 3
210; CHECK-NEXT:    [[R1:%.*]] = lshr i32 [[X:%.*]], [[TMP1]]
211; CHECK-NEXT:    ret i32 [[R1]]
212;
213  %V = select i1 %C, i32 64, i32 8
214  %R = udiv i32 %X, %V
215  ret i32 %R
216}
217
218define i32 @test11(i32 %X, i1 %C) {
219; CHECK-LABEL: @test11(
220; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i32 10, i32 5
221; CHECK-NEXT:    [[B1:%.*]] = lshr i32 [[X:%.*]], [[TMP1]]
222; CHECK-NEXT:    ret i32 [[B1]]
223;
224  %A = select i1 %C, i32 1024, i32 32
225  %B = udiv i32 %X, %A
226  ret i32 %B
227}
228
229; PR2328
230define i32 @test12(i32 %x) {
231; CHECK-LABEL: @test12(
232; CHECK-NEXT:    ret i32 1
233;
234  %tmp3 = udiv i32 %x, %x		; 1
235  ret i32 %tmp3
236}
237
238define i32 @test13(i32 %x) {
239; CHECK-LABEL: @test13(
240; CHECK-NEXT:    ret i32 1
241;
242  %tmp3 = sdiv i32 %x, %x		; 1
243  ret i32 %tmp3
244}
245
246define i32 @test14(i8 %x) {
247; CHECK-LABEL: @test14(
248; CHECK-NEXT:    ret i32 0
249;
250  %zext = zext i8 %x to i32
251  %div = udiv i32 %zext, 257	; 0
252  ret i32 %div
253}
254
255; PR9814
256define i32 @test15(i32 %a, i32 %b) {
257; CHECK-LABEL: @test15(
258; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], -2
259; CHECK-NEXT:    [[DIV21:%.*]] = lshr i32 [[A:%.*]], [[TMP1]]
260; CHECK-NEXT:    ret i32 [[DIV21]]
261;
262  %shl = shl i32 1, %b
263  %div = lshr i32 %shl, 2
264  %div2 = udiv i32 %a, %div
265  ret i32 %div2
266}
267
268define <2 x i64> @test16(<2 x i64> %x) {
269; CHECK-LABEL: @test16(
270; CHECK-NEXT:    [[DIV:%.*]] = udiv <2 x i64> [[X:%.*]], splat (i64 192)
271; CHECK-NEXT:    ret <2 x i64> [[DIV]]
272;
273  %shr = lshr <2 x i64> %x, <i64 5, i64 5>
274  %div = udiv <2 x i64> %shr, <i64 6, i64 6>
275  ret <2 x i64> %div
276}
277
278define i32 @test19(i32 %x) {
279; CHECK-LABEL: @test19(
280; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 1
281; CHECK-NEXT:    [[A:%.*]] = zext i1 [[TMP1]] to i32
282; CHECK-NEXT:    ret i32 [[A]]
283;
284  %A = udiv i32 1, %x
285  ret i32 %A
286}
287
288define <2 x i32> @test19vec(<2 x i32> %x) {
289; CHECK-LABEL: @test19vec(
290; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 1)
291; CHECK-NEXT:    [[A:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
292; CHECK-NEXT:    ret <2 x i32> [[A]]
293;
294  %A = udiv <2 x i32> <i32 1, i32 1>, %x
295  ret <2 x i32> %A
296}
297
298define i32 @test20(i32 %x) {
299; CHECK-LABEL: @test20(
300; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X:%.*]]
301; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X_FR]], 1
302; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
303; CHECK-NEXT:    [[A:%.*]] = select i1 [[TMP2]], i32 [[X_FR]], i32 0
304; CHECK-NEXT:    ret i32 [[A]]
305;
306  %A = sdiv i32 1, %x
307  ret i32 %A
308}
309
310define <2 x i32> @test20vec(<2 x i32> %x) {
311; CHECK-LABEL: @test20vec(
312; CHECK-NEXT:    [[X_FR:%.*]] = freeze <2 x i32> [[X:%.*]]
313; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X_FR]], splat (i32 1)
314; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 3)
315; CHECK-NEXT:    [[A:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[X_FR]], <2 x i32> zeroinitializer
316; CHECK-NEXT:    ret <2 x i32> [[A]]
317;
318  %A = sdiv <2 x i32> <i32 1, i32 1>, %x
319  ret <2 x i32> %A
320}
321
322define i32 @test21(i32 %a) {
323; CHECK-LABEL: @test21(
324; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], 3
325; CHECK-NEXT:    ret i32 [[DIV]]
326;
327  %shl = shl nsw i32 %a, 2
328  %div = sdiv i32 %shl, 12
329  ret i32 %div
330}
331
332define i32 @test22(i32 %a) {
333; CHECK-LABEL: @test22(
334; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[A:%.*]], 4
335; CHECK-NEXT:    ret i32 [[DIV]]
336;
337  %mul = mul nsw i32 %a, 3
338  %div = sdiv i32 %mul, 12
339  ret i32 %div
340}
341
342define i32 @test23(i32 %a) {
343; CHECK-LABEL: @test23(
344; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[A:%.*]], 3
345; CHECK-NEXT:    ret i32 [[DIV]]
346;
347  %shl = shl nuw i32 %a, 2
348  %div = udiv i32 %shl, 12
349  ret i32 %div
350}
351
352define i32 @test24(i32 %a) {
353; CHECK-LABEL: @test24(
354; CHECK-NEXT:    [[DIV1:%.*]] = lshr i32 [[A:%.*]], 2
355; CHECK-NEXT:    ret i32 [[DIV1]]
356;
357  %mul = mul nuw i32 %a, 3
358  %div = udiv i32 %mul, 12
359  ret i32 %div
360}
361
362define i32 @test25(i32 %a) {
363; CHECK-LABEL: @test25(
364; CHECK-NEXT:    [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 1
365; CHECK-NEXT:    ret i32 [[DIV]]
366;
367  %shl = shl nsw i32 %a, 2
368  %div = sdiv i32 %shl, 2
369  ret i32 %div
370}
371
372define i32 @test26(i32 %a) {
373; CHECK-LABEL: @test26(
374; CHECK-NEXT:    [[DIV:%.*]] = shl nsw i32 [[A:%.*]], 2
375; CHECK-NEXT:    ret i32 [[DIV]]
376;
377  %mul = mul nsw i32 %a, 12
378  %div = sdiv i32 %mul, 3
379  ret i32 %div
380}
381
382define i32 @test27(i32 %a) {
383; CHECK-LABEL: @test27(
384; CHECK-NEXT:    [[DIV:%.*]] = shl nuw i32 [[A:%.*]], 1
385; CHECK-NEXT:    ret i32 [[DIV]]
386;
387  %shl = shl nuw i32 %a, 2
388  %div = udiv i32 %shl, 2
389  ret i32 %div
390}
391
392define i32 @test28(i32 %a) {
393; CHECK-LABEL: @test28(
394; CHECK-NEXT:    [[DIV:%.*]] = mul nuw i32 [[A:%.*]], 12
395; CHECK-NEXT:    ret i32 [[DIV]]
396;
397  %mul = mul nuw i32 %a, 36
398  %div = udiv i32 %mul, 3
399  ret i32 %div
400}
401
402define i32 @test29(i32 %a) {
403; CHECK-LABEL: @test29(
404; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], 0
405; CHECK-NEXT:    [[DIV:%.*]] = zext i1 [[TMP1]] to i32
406; CHECK-NEXT:    ret i32 [[DIV]]
407;
408  %mul = shl nsw i32 %a, 31
409  %div = sdiv i32 %mul, -2147483648
410  ret i32 %div
411}
412
413define i32 @test30(i32 %a) {
414; CHECK-LABEL: @test30(
415; CHECK-NEXT:    ret i32 [[A:%.*]]
416;
417  %mul = shl nuw i32 %a, 31
418  %div = udiv i32 %mul, -2147483648
419  ret i32 %div
420}
421
422define <2 x i32> @test31(<2 x i32> %x) {
423; CHECK-LABEL: @test31(
424; CHECK-NEXT:    ret <2 x i32> zeroinitializer
425;
426  %shr = lshr <2 x i32> %x, <i32 31, i32 31>
427  %div = udiv <2 x i32> %shr, <i32 2147483647, i32 2147483647>
428  ret <2 x i32> %div
429}
430
431define i32 @test32(i32 %a, i32 %b) {
432; CHECK-LABEL: @test32(
433; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], -1
434; CHECK-NEXT:    [[DIV2:%.*]] = lshr i32 [[A:%.*]], [[TMP1]]
435; CHECK-NEXT:    ret i32 [[DIV2]]
436;
437  %shl = shl i32 2, %b
438  %div = lshr i32 %shl, 2
439  %div2 = udiv i32 %a, %div
440  ret i32 %div2
441}
442
443define <2 x i64> @test33(<2 x i64> %x) {
444; CHECK-LABEL: @test33(
445; CHECK-NEXT:    [[DIV:%.*]] = udiv exact <2 x i64> [[X:%.*]], splat (i64 192)
446; CHECK-NEXT:    ret <2 x i64> [[DIV]]
447;
448  %shr = lshr exact <2 x i64> %x, <i64 5, i64 5>
449  %div = udiv exact <2 x i64> %shr, <i64 6, i64 6>
450  ret <2 x i64> %div
451}
452
453; -X / C --> X / -C (if negation does not overflow)
454
455define i8 @sdiv_negated_dividend_constant_divisor(i8 %x) {
456; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor(
457; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], 42
458; CHECK-NEXT:    ret i8 [[D]]
459;
460  %neg = sub nsw i8 0, %x
461  %d = sdiv i8 %neg, -42
462  ret i8 %d
463}
464
465define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_splat(<2 x i8> %x) {
466; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_splat(
467; CHECK-NEXT:    [[D:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 42)
468; CHECK-NEXT:    ret <2 x i8> [[D]]
469;
470  %neg = sub nsw <2 x i8> zeroinitializer, %x
471  %d = sdiv <2 x i8> %neg, <i8 -42, i8 -42>
472  ret <2 x i8> %d
473}
474
475define i8 @sdiv_exact_negated_dividend_constant_divisor(i8 %x) {
476; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor(
477; CHECK-NEXT:    [[D:%.*]] = sdiv exact i8 [[X:%.*]], 42
478; CHECK-NEXT:    ret i8 [[D]]
479;
480  %neg = sub nsw i8 0, %x
481  %d = sdiv exact i8 %neg, -42
482  ret i8 %d
483}
484
485define <2 x i8> @sdiv_exact_negated_dividend_constant_divisor_vec_splat(<2 x i8> %x) {
486; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec_splat(
487; CHECK-NEXT:    [[D:%.*]] = sdiv exact <2 x i8> [[X:%.*]], splat (i8 42)
488; CHECK-NEXT:    ret <2 x i8> [[D]]
489;
490  %neg = sub nsw <2 x i8> zeroinitializer, %x
491  %d = sdiv exact <2 x i8> %neg, <i8 -42, i8 -42>
492  ret <2 x i8> %d
493}
494
495define i8 @sdiv_negated_dividend_constant_divisor_smin(i8 %x) {
496; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_smin(
497; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128
498; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i8
499; CHECK-NEXT:    ret i8 [[D]]
500;
501  %neg = sub nsw i8 0, %x
502  %d = sdiv i8 %neg, -128
503  ret i8 %d
504}
505
506define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_splat_smin(<2 x i8> %x) {
507; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_splat_smin(
508; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)
509; CHECK-NEXT:    [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>
510; CHECK-NEXT:    ret <2 x i8> [[D]]
511;
512  %neg = sub nsw <2 x i8> zeroinitializer, %x
513  %d = sdiv <2 x i8> %neg, <i8 -128, i8 -128>
514  ret <2 x i8> %d
515}
516
517define <2 x i8> @sdiv_negated_dividend_constant_divisor_vec_poison(<2 x i8> %x) {
518; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec_poison(
519; CHECK-NEXT:    ret <2 x i8> poison
520;
521  %neg = sub nsw <2 x i8> zeroinitializer, %x
522  %d = sdiv <2 x i8> %neg, <i8 -128, i8 poison>
523  ret <2 x i8> %d
524}
525
526define <2 x i64> @sdiv_negated_dividend_constant_divisor_vec(<2 x i64> %x) {
527; CHECK-LABEL: @sdiv_negated_dividend_constant_divisor_vec(
528; CHECK-NEXT:    [[DIV1_NEG:%.*]] = sdiv <2 x i64> [[X:%.*]], <i64 -3, i64 -4>
529; CHECK-NEXT:    ret <2 x i64> [[DIV1_NEG]]
530;
531  %neg = sub nsw <2 x i64> zeroinitializer, %x
532  %div = sdiv <2 x i64> %neg, <i64 3, i64 4>
533  ret <2 x i64> %div
534}
535
536define <2 x i64> @sdiv_exact_negated_dividend_constant_divisor_vec(<2 x i64> %x) {
537; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec(
538; CHECK-NEXT:    [[DIV1_NEG:%.*]] = sdiv exact <2 x i64> [[X:%.*]], <i64 -3, i64 -4>
539; CHECK-NEXT:    ret <2 x i64> [[DIV1_NEG]]
540;
541  %neg = sub nsw <2 x i64> zeroinitializer, %x
542  %div = sdiv exact <2 x i64> %neg, <i64 3, i64 4>
543  ret <2 x i64> %div
544}
545
546; Can't negate signed min vector element.
547
548define <2 x i8> @sdiv_exact_negated_dividend_constant_divisor_vec_overflow(<2 x i8> %x) {
549; CHECK-LABEL: @sdiv_exact_negated_dividend_constant_divisor_vec_overflow(
550; CHECK-NEXT:    [[DIV1:%.*]] = sdiv exact <2 x i8> [[X:%.*]], <i8 -128, i8 42>
551; CHECK-NEXT:    [[DIV:%.*]] = sub nsw <2 x i8> zeroinitializer, [[DIV1]]
552; CHECK-NEXT:    ret <2 x i8> [[DIV]]
553;
554  %neg = sub nsw <2 x i8> zeroinitializer, %x
555  %div = sdiv exact <2 x i8> %neg, <i8 -128, i8 42>
556  ret <2 x i8> %div
557}
558
559define i32 @test35(i32 %A) {
560; CHECK-LABEL: @test35(
561; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 2147483647
562; CHECK-NEXT:    [[MUL:%.*]] = udiv exact i32 [[AND]], 2147483647
563; CHECK-NEXT:    ret i32 [[MUL]]
564;
565  %and = and i32 %A, 2147483647
566  %mul = sdiv exact i32 %and, 2147483647
567  ret i32 %mul
568}
569
570define <2 x i32> @test35vec(<2 x i32> %A) {
571; CHECK-LABEL: @test35vec(
572; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647)
573; CHECK-NEXT:    [[MUL:%.*]] = udiv exact <2 x i32> [[AND]], splat (i32 2147483647)
574; CHECK-NEXT:    ret <2 x i32> [[MUL]]
575;
576  %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647>
577  %mul = sdiv exact <2 x i32> %and, <i32 2147483647, i32 2147483647>
578  ret <2 x i32> %mul
579}
580
581define i32 @test36(i32 %A) {
582; CHECK-LABEL: @test36(
583; CHECK-NEXT:    [[AND:%.*]] = and i32 [[A:%.*]], 2147483647
584; CHECK-NEXT:    [[MUL:%.*]] = lshr exact i32 [[AND]], [[A]]
585; CHECK-NEXT:    ret i32 [[MUL]]
586;
587  %and = and i32 %A, 2147483647
588  %shl = shl nsw i32 1, %A
589  %mul = sdiv exact i32 %and, %shl
590  ret i32 %mul
591}
592
593define <2 x i32> @test36vec(<2 x i32> %A) {
594; CHECK-LABEL: @test36vec(
595; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647)
596; CHECK-NEXT:    [[MUL:%.*]] = lshr exact <2 x i32> [[AND]], [[A]]
597; CHECK-NEXT:    ret <2 x i32> [[MUL]]
598;
599  %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647>
600  %shl = shl nsw <2 x i32> <i32 1, i32 1>, %A
601  %mul = sdiv exact <2 x i32> %and, %shl
602  ret <2 x i32> %mul
603}
604
605define i32 @test37(ptr %b, i1 %c1) {
606; CHECK-LABEL: @test37(
607; CHECK-NEXT:  entry:
608; CHECK-NEXT:    store i32 0, ptr [[B:%.*]], align 4
609; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOR_RHS:%.*]], label [[LOR_END:%.*]]
610; CHECK:       lor.rhs:
611; CHECK-NEXT:    br label [[LOR_END]]
612; CHECK:       lor.end:
613; CHECK-NEXT:    ret i32 0
614;
615entry:
616  store i32 0, ptr %b, align 4
617  %0 = load i32, ptr %b, align 4
618  br i1 %c1, label %lor.rhs, label %lor.end
619
620lor.rhs:                                          ; preds = %entry
621  %mul = mul nsw i32 1, %0
622  br label %lor.end
623
624lor.end:                                          ; preds = %lor.rhs, %entry
625  %t.0 = phi i32 [ %0, %entry ], [ %mul, %lor.rhs ]
626  %div = sdiv i32 %t.0, 2
627  ret i32 %div
628}
629
630; We can perform the division in the smaller type.
631
632define i32 @shrink(i8 %x) {
633; CHECK-LABEL: @shrink(
634; CHECK-NEXT:    [[TMP1:%.*]] = sdiv i8 [[X:%.*]], 127
635; CHECK-NEXT:    [[DIV:%.*]] = sext i8 [[TMP1]] to i32
636; CHECK-NEXT:    ret i32 [[DIV]]
637;
638  %conv = sext i8 %x to i32
639  %div = sdiv i32 %conv, 127
640  ret i32 %div
641}
642
643; Division in the smaller type can lead to more optimizations.
644
645define i32 @zap(i8 %x) {
646; CHECK-LABEL: @zap(
647; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128
648; CHECK-NEXT:    [[DIV:%.*]] = zext i1 [[TMP1]] to i32
649; CHECK-NEXT:    ret i32 [[DIV]]
650;
651  %conv = sext i8 %x to i32
652  %div = sdiv i32 %conv, -128
653  ret i32 %div
654}
655
656; Splat constant divisors should get the same folds.
657
658define <3 x i32> @shrink_vec(<3 x i8> %x) {
659; CHECK-LABEL: @shrink_vec(
660; CHECK-NEXT:    [[TMP1:%.*]] = sdiv <3 x i8> [[X:%.*]], splat (i8 127)
661; CHECK-NEXT:    [[DIV:%.*]] = sext <3 x i8> [[TMP1]] to <3 x i32>
662; CHECK-NEXT:    ret <3 x i32> [[DIV]]
663;
664  %conv = sext <3 x i8> %x to <3 x i32>
665  %div = sdiv <3 x i32> %conv, <i32 127, i32 127, i32 127>
666  ret <3 x i32> %div
667}
668
669define <2 x i32> @zap_vec(<2 x i8> %x) {
670; CHECK-LABEL: @zap_vec(
671; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)
672; CHECK-NEXT:    [[DIV:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32>
673; CHECK-NEXT:    ret <2 x i32> [[DIV]]
674;
675  %conv = sext <2 x i8> %x to <2 x i32>
676  %div = sdiv <2 x i32> %conv, <i32 -128, i32 -128>
677  ret <2 x i32> %div
678}
679
680; But we can't do this if the signed constant won't fit in the original type.
681
682define i32 @shrink_no(i8 %x) {
683; CHECK-LABEL: @shrink_no(
684; CHECK-NEXT:    [[CONV:%.*]] = sext i8 [[X:%.*]] to i32
685; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 [[CONV]], 128
686; CHECK-NEXT:    ret i32 [[DIV]]
687;
688  %conv = sext i8 %x to i32
689  %div = sdiv i32 %conv, 128
690  ret i32 %div
691}
692
693; When the divisor is known larger than the quotient,
694; InstSimplify should kill it before InstCombine sees it.
695
696define i32 @shrink_no2(i8 %x) {
697; CHECK-LABEL: @shrink_no2(
698; CHECK-NEXT:    ret i32 0
699;
700  %conv = sext i8 %x to i32
701  %div = sdiv i32 %conv, -129
702  ret i32 %div
703}
704
705define i32 @shrink_no3(i16 %x) {
706; CHECK-LABEL: @shrink_no3(
707; CHECK-NEXT:    ret i32 0
708;
709  %conv = sext i16 %x to i32
710  %div = sdiv i32 %conv, 65535
711  ret i32 %div
712}
713
714; This previously crashed when trying to simplify the zext/icmp this becomes.
715define <2 x i8> @PR34841(<2 x i8> %x) {
716; CHECK-LABEL: @PR34841(
717; CHECK-NEXT:    ret <2 x i8> zeroinitializer
718;
719  %neg = and <2 x i8> %x, <i8 2, i8 2>
720  %div = udiv <2 x i8> <i8 1, i8 1>, %neg
721  ret <2 x i8> %div
722}
723
724; X / (X * Y) -> 1 / Y if the multiplication does not overflow
725
726define i8 @div_factor_signed(i8 %x, i8 %y) {
727; CHECK-LABEL: @div_factor_signed(
728; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i8 [[Y:%.*]]
729; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y_FR]], 1
730; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], 3
731; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i8 [[Y_FR]], i8 0
732; CHECK-NEXT:    ret i8 [[R]]
733;
734  %a = mul nsw i8 %x, %y
735  %r = sdiv i8 %x, %a
736  ret i8 %r
737}
738
739; X / (Y * X) -> 1 / Y if the multiplication does not overflow
740
741define <2 x i8> @div_factor_signed_vec(<2 x i8> %x, <2 x i8> %y) {
742; CHECK-LABEL: @div_factor_signed_vec(
743; CHECK-NEXT:    [[Y_FR:%.*]] = freeze <2 x i8> [[Y:%.*]]
744; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[Y_FR]], splat (i8 1)
745; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i8> [[TMP1]], splat (i8 3)
746; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i8> [[Y_FR]], <2 x i8> zeroinitializer
747; CHECK-NEXT:    ret <2 x i8> [[R]]
748;
749  %a = mul nsw <2 x i8> %y, %x
750  %r = sdiv <2 x i8> %x, %a
751  ret <2 x i8> %r
752}
753
754; X / (Y * X) -> 1 / Y if the multiplication does not overflow
755
756define i8 @div_factor_unsigned(i8 %x, i8 %y) {
757; CHECK-LABEL: @div_factor_unsigned(
758; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 1
759; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i8
760; CHECK-NEXT:    ret i8 [[R]]
761;
762  %a = mul nuw i8 %y, %x
763  %r = udiv i8 %x, %a
764  ret i8 %r
765}
766
767; X / (X * Y) -> 1 / Y if the multiplication does not overflow
768
769define <2 x i8> @div_factor_unsigned_vec(<2 x i8> %x, <2 x i8> %y) {
770; CHECK-LABEL: @div_factor_unsigned_vec(
771; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[Y:%.*]], splat (i8 1)
772; CHECK-NEXT:    [[R:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>
773; CHECK-NEXT:    ret <2 x i8> [[R]]
774;
775  %a = mul nuw <2 x i8> %x, %y
776  %r = udiv <2 x i8> %x, %a
777  ret <2 x i8> %r
778}
779
780define i8 @udiv_common_factor(i8 %x, i8 %y, i8 %z) {
781; CHECK-LABEL: @udiv_common_factor(
782; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
783; CHECK-NEXT:    ret i8 [[C]]
784;
785  %a = mul nuw i8 %z, %x
786  %b = mul nuw i8 %z, %y
787  %c = udiv i8 %a, %b
788  ret i8 %c
789}
790
791define <2 x i8> @udiv_common_factor_commute1_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
792; CHECK-LABEL: @udiv_common_factor_commute1_vec(
793; CHECK-NEXT:    [[C:%.*]] = udiv <2 x i8> [[X:%.*]], [[Y:%.*]]
794; CHECK-NEXT:    ret <2 x i8> [[C]]
795;
796  %a = mul nuw <2 x i8> %x, %z
797  %b = mul nuw <2 x i8> %z, %y
798  %c = udiv <2 x i8> %a, %b
799  ret <2 x i8> %c
800}
801
802define i8 @udiv_common_factor_commute2(i8 %x, i8 %y, i8 %z) {
803; CHECK-LABEL: @udiv_common_factor_commute2(
804; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
805; CHECK-NEXT:    ret i8 [[C]]
806;
807  %a = mul nuw i8 %x, %z
808  %b = mul nuw i8 %y, %z
809  %c = udiv i8 %a, %b
810  ret i8 %c
811}
812
813define i8 @udiv_common_factor_commute3(i8 %x, i8 %y, i8 %z) {
814; CHECK-LABEL: @udiv_common_factor_commute3(
815; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[X:%.*]], [[Y:%.*]]
816; CHECK-NEXT:    ret i8 [[C]]
817;
818  %a = mul nuw i8 %z, %x
819  %b = mul nuw i8 %y, %z
820  %c = udiv i8 %a, %b
821  ret i8 %c
822}
823
824; Negative test: both mul must be 'nuw'.
825
826define i8 @udiv_common_factor_not_nuw(i8 %x, i8 %y, i8 %z) {
827; CHECK-LABEL: @udiv_common_factor_not_nuw(
828; CHECK-NEXT:    [[A:%.*]] = mul i8 [[Z:%.*]], [[X:%.*]]
829; CHECK-NEXT:    [[B:%.*]] = mul nuw i8 [[Z]], [[Y:%.*]]
830; CHECK-NEXT:    [[C:%.*]] = udiv i8 [[A]], [[B]]
831; CHECK-NEXT:    ret i8 [[C]]
832;
833  %a = mul i8 %z, %x
834  %b = mul nuw i8 %z, %y
835  %c = udiv i8 %a, %b
836  ret i8 %c
837}
838
839; Negative test: both mul must be 'nuw'.
840
841define <2 x i8> @udiv_common_factor_not_nuw_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
842; CHECK-LABEL: @udiv_common_factor_not_nuw_vec(
843; CHECK-NEXT:    [[A:%.*]] = mul nuw <2 x i8> [[Z:%.*]], [[X:%.*]]
844; CHECK-NEXT:    [[B:%.*]] = mul <2 x i8> [[Z]], [[Y:%.*]]
845; CHECK-NEXT:    [[C:%.*]] = udiv <2 x i8> [[A]], [[B]]
846; CHECK-NEXT:    ret <2 x i8> [[C]]
847;
848  %a = mul nuw <2 x i8> %z, %x
849  %b = mul <2 x i8> %z, %y
850  %c = udiv <2 x i8> %a, %b
851  ret <2 x i8> %c
852}
853
854define i32 @test_exact_nsw_exact(i32 %x) {
855; CHECK-LABEL: @test_exact_nsw_exact(
856; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv exact i32 [[X:%.*]], -3
857; CHECK-NEXT:    ret i32 [[DIV_NEG]]
858;
859  %div = sdiv exact i32 %x, 3
860  %neg = sub nsw i32 0, %div
861  ret i32 %neg
862}
863
864define <2 x i64> @test_exact_vec(<2 x i64> %x) {
865; CHECK-LABEL: @test_exact_vec(
866; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv exact <2 x i64> [[X:%.*]], <i64 -3, i64 -4>
867; CHECK-NEXT:    ret <2 x i64> [[DIV_NEG]]
868;
869  %div = sdiv exact <2 x i64> %x, <i64 3, i64 4>
870  %neg = sub nsw <2 x i64> zeroinitializer, %div
871  ret <2 x i64> %neg
872}
873
874; Constant is safe to negate.
875
876define <2 x i8> @negate_sdiv_vec_splat(<2 x i8> %x) {
877; CHECK-LABEL: @negate_sdiv_vec_splat(
878; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 -42)
879; CHECK-NEXT:    ret <2 x i8> [[DIV_NEG]]
880;
881  %div = sdiv <2 x i8> %x, <i8 42, i8 42>
882  %neg = sub <2 x i8> zeroinitializer, %div
883  ret <2 x i8> %neg
884}
885
886; Dividing by poison is UB.
887
888define <2 x i8> @negate_sdiv_vec_poison_elt(<2 x i8> %x) {
889; CHECK-LABEL: @negate_sdiv_vec_poison_elt(
890; CHECK-NEXT:    ret <2 x i8> poison
891;
892  %div = sdiv <2 x i8> %x, <i8 poison, i8 42>
893  %neg = sub <2 x i8> zeroinitializer, %div
894  ret <2 x i8> %neg
895}
896
897; Division by -1 may be UB (if numerator is the signed min val), but div-by-1 can be simplified.
898
899define <2 x i8> @negate_sdiv_vec_splat_one(<2 x i8> %x) {
900; CHECK-LABEL: @negate_sdiv_vec_splat_one(
901; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]
902; CHECK-NEXT:    ret <2 x i8> [[NEG]]
903;
904  %div = sdiv <2 x i8> %x, <i8 1, i8 1>
905  %neg = sub <2 x i8> zeroinitializer, %div
906  ret <2 x i8> %neg
907}
908
909; Can't negate signed-min constant, but can convert to a compare..
910
911define <2 x i8> @negate_sdiv_vec_splat_signed_min(<2 x i8> %x) {
912; CHECK-LABEL: @negate_sdiv_vec_splat_signed_min(
913; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)
914; CHECK-NEXT:    [[DIV_NEG:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
915; CHECK-NEXT:    ret <2 x i8> [[DIV_NEG]]
916;
917  %div = sdiv <2 x i8> %x, <i8 -128, i8 -128>
918  %neg = sub <2 x i8> zeroinitializer, %div
919  ret <2 x i8> %neg
920}
921
922; Division by -1 may be UB for any element of a vector.
923
924define <2 x i8> @negate_sdiv_vec_one_element(<2 x i8> %x) {
925; CHECK-LABEL: @negate_sdiv_vec_one_element(
926; CHECK-NEXT:    [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 -1, i8 1>
927; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]]
928; CHECK-NEXT:    ret <2 x i8> [[NEG]]
929;
930  %div = sdiv <2 x i8> %x, <i8 -1, i8 1>
931  %neg = sub <2 x i8> zeroinitializer, %div
932  ret <2 x i8> %neg
933}
934
935; Can't negate signed-min constant for any element of a vector.
936
937define <2 x i8> @negate_sdiv_vec_signed_min_elt(<2 x i8> %x) {
938; CHECK-LABEL: @negate_sdiv_vec_signed_min_elt(
939; CHECK-NEXT:    [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 -1, i8 -128>
940; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]]
941; CHECK-NEXT:    ret <2 x i8> [[NEG]]
942;
943  %div = sdiv <2 x i8> %x, <i8 -1, i8 -128>
944  %neg = sub <2 x i8> zeroinitializer, %div
945  ret <2 x i8> %neg
946}
947
948; Division by -1 may be UB and can't negate signed-min.
949
950define <2 x i8> @negate_sdiv_vec_signed_min_and_one_elt(<2 x i8> %x) {
951; CHECK-LABEL: @negate_sdiv_vec_signed_min_and_one_elt(
952; CHECK-NEXT:    [[DIV:%.*]] = sdiv <2 x i8> [[X:%.*]], <i8 1, i8 -128>
953; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i8> zeroinitializer, [[DIV]]
954; CHECK-NEXT:    ret <2 x i8> [[NEG]]
955;
956  %div = sdiv <2 x i8> %x, <i8 1, i8 -128>
957  %neg = sub <2 x i8> zeroinitializer, %div
958  ret <2 x i8> %neg
959}
960
961define i32 @test_exact_nonsw_exact(i32 %x) {
962; CHECK-LABEL: @test_exact_nonsw_exact(
963; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv exact i32 [[X:%.*]], -3
964; CHECK-NEXT:    ret i32 [[DIV_NEG]]
965;
966  %div = sdiv exact i32 %x, 3
967  %neg = sub i32 0, %div
968  ret i32 %neg
969}
970
971define i32 @test_exact_nsw_noexact(i32 %x) {
972; CHECK-LABEL: @test_exact_nsw_noexact(
973; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv i32 [[X:%.*]], -3
974; CHECK-NEXT:    ret i32 [[DIV_NEG]]
975;
976  %div = sdiv i32 %x, 3
977  %neg = sub nsw i32 0, %div
978  ret i32 %neg
979}
980
981define i32 @test_exact_nonsw_noexact(i32 %x) {
982; CHECK-LABEL: @test_exact_nonsw_noexact(
983; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv i32 [[X:%.*]], -3
984; CHECK-NEXT:    ret i32 [[DIV_NEG]]
985;
986  %div = sdiv i32 %x, 3
987  %neg = sub i32 0, %div
988  ret i32 %neg
989}
990
991define i32 @test_exact_div_nonconst(i32 %x, i32 %y) {
992; CHECK-LABEL: @test_exact_div_nonconst(
993; CHECK-NEXT:    [[DIV:%.*]] = sdiv exact i32 [[X:%.*]], [[Y:%.*]]
994; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[DIV]]
995; CHECK-NEXT:    ret i32 [[NEG]]
996;
997  %div = sdiv exact i32 %x, %y
998  %neg = sub nsw i32 0, %div
999  ret i32 %neg
1000}
1001
1002define i32 @test_exact_div_one(i32 %x) {
1003; CHECK-LABEL: @test_exact_div_one(
1004; CHECK-NEXT:    [[NEG:%.*]] = sub nsw i32 0, [[X:%.*]]
1005; CHECK-NEXT:    ret i32 [[NEG]]
1006;
1007  %div = sdiv exact i32 %x, 1
1008  %neg = sub nsw i32 0, %div
1009  ret i32 %neg
1010}
1011
1012define i8 @test_exact_div_minSigned(i8 %x) {
1013; CHECK-LABEL: @test_exact_div_minSigned(
1014; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128
1015; CHECK-NEXT:    [[DIV_NEG:%.*]] = sext i1 [[TMP1]] to i8
1016; CHECK-NEXT:    ret i8 [[DIV_NEG]]
1017;
1018  %div = sdiv exact i8 %x, -128
1019  %neg = sub nsw i8 0, %div
1020  ret i8 %neg
1021}
1022
1023; X / INT_MIN --> X == INT_MIN
1024
1025define i8 @sdiv_by_int_min(i8 %x) {
1026; CHECK-LABEL: @sdiv_by_int_min(
1027; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[X:%.*]], -128
1028; CHECK-NEXT:    [[D:%.*]] = zext i1 [[TMP1]] to i8
1029; CHECK-NEXT:    ret i8 [[D]]
1030;
1031  %d = sdiv i8 %x, -128
1032  ret i8 %d
1033}
1034
1035define <2 x i8> @sdiv_by_int_min_vec_splat(<2 x i8> %x) {
1036; CHECK-LABEL: @sdiv_by_int_min_vec_splat(
1037; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)
1038; CHECK-NEXT:    [[D:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>
1039; CHECK-NEXT:    ret <2 x i8> [[D]]
1040;
1041  %d = sdiv <2 x i8> %x, <i8 -128, i8 -128>
1042  ret <2 x i8> %d
1043}
1044
1045define <2 x i8> @sdiv_by_int_min_vec_splat_poison(<2 x i8> %x) {
1046; CHECK-LABEL: @sdiv_by_int_min_vec_splat_poison(
1047; CHECK-NEXT:    ret <2 x i8> poison
1048;
1049  %d = sdiv <2 x i8> %x, <i8 -128, i8 poison>
1050  ret <2 x i8> %d
1051}
1052
1053define <2 x i8> @sdiv_by_negconst_v2i8(<2 x i8> %x) {
1054; CHECK-LABEL: @sdiv_by_negconst_v2i8(
1055; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv <2 x i8> [[X:%.*]], splat (i8 108)
1056; CHECK-NEXT:    ret <2 x i8> [[DIV_NEG]]
1057;
1058  %div = sdiv <2 x i8> %x, <i8 -108, i8 -108>
1059  %sub = sub <2 x i8> zeroinitializer, %div
1060  ret <2 x i8> %sub
1061}
1062
1063define <vscale x 2 x i8> @sdiv_by_negconst_nxv2i8(<vscale x 2 x i8> %x) {
1064; CHECK-LABEL: @sdiv_by_negconst_nxv2i8(
1065; CHECK-NEXT:    [[DIV_NEG:%.*]] = sdiv <vscale x 2 x i8> [[X:%.*]], splat (i8 108)
1066; CHECK-NEXT:    ret <vscale x 2 x i8> [[DIV_NEG]]
1067;
1068  %div = sdiv <vscale x 2 x i8> %x, splat (i8 -108)
1069  %sub = sub <vscale x 2 x i8> zeroinitializer, %div
1070  ret <vscale x 2 x i8> %sub
1071}
1072
1073define <2 x i8> @sdiv_by_minSigned_v2i8(<2 x i8> %x) {
1074; CHECK-LABEL: @sdiv_by_minSigned_v2i8(
1075; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i8> [[X:%.*]], splat (i8 -128)
1076; CHECK-NEXT:    [[DIV_NEG:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
1077; CHECK-NEXT:    ret <2 x i8> [[DIV_NEG]]
1078;
1079  %div = sdiv <2 x i8> %x, <i8 -128, i8 -128>
1080  %sub = sub <2 x i8> zeroinitializer, %div
1081  ret <2 x i8> %sub
1082}
1083
1084define <vscale x 2 x i8> @sdiv_by_minSigned_nxv2i8(<vscale x 2 x i8> %x) {
1085; CHECK-LABEL: @sdiv_by_minSigned_nxv2i8(
1086; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <vscale x 2 x i8> [[X:%.*]], splat (i8 -128)
1087; CHECK-NEXT:    [[DIV_NEG:%.*]] = sext <vscale x 2 x i1> [[TMP1]] to <vscale x 2 x i8>
1088; CHECK-NEXT:    ret <vscale x 2 x i8> [[DIV_NEG]]
1089;
1090  %div = sdiv <vscale x 2 x i8> %x, splat (i8 -128)
1091  %sub = sub <vscale x 2 x i8> zeroinitializer, %div
1092  ret <vscale x 2 x i8> %sub
1093}
1094
1095define i32 @sdiv_constant_dividend_select_of_constants_divisor(i1 %b) {
1096; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor(
1097; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i32 3, i32 -14
1098; CHECK-NEXT:    ret i32 [[R]]
1099;
1100  %s = select i1 %b, i32 12, i32 -3
1101  %r = sdiv i32 42, %s
1102  ret i32 %r
1103}
1104
1105define i32 @sdiv_constant_dividend_select_of_constants_divisor_use(i1 %b) {
1106; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_use(
1107; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
1108; CHECK-NEXT:    call void @use(i32 [[S]])
1109; CHECK-NEXT:    [[R:%.*]] = select i1 [[B]], i32 3, i32 -14
1110; CHECK-NEXT:    ret i32 [[R]]
1111;
1112  %s = select i1 %b, i32 12, i32 -3
1113  call void @use(i32 %s)
1114  %r = sdiv i32 42, %s
1115  ret i32 %r
1116}
1117
1118define i32 @sdiv_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) {
1119; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_0_arm(
1120; CHECK-NEXT:    ret i32 3
1121;
1122  %s = select i1 %b, i32 12, i32 0
1123  %r = sdiv i32 42, %s
1124  ret i32 %r
1125}
1126
1127; negative test - not safe to speculate div with variable divisor
1128
1129define i32 @sdiv_constant_dividend_select_divisor1(i1 %b, i32 %x) {
1130; CHECK-LABEL: @sdiv_constant_dividend_select_divisor1(
1131; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3
1132; CHECK-NEXT:    [[R:%.*]] = sdiv i32 42, [[S]]
1133; CHECK-NEXT:    ret i32 [[R]]
1134;
1135  %s = select i1 %b, i32 %x, i32 -3
1136  %r = sdiv i32 42, %s
1137  ret i32 %r
1138}
1139
1140; negative test - not safe to speculate div with variable divisor
1141
1142define i32 @sdiv_constant_dividend_select_divisor2(i1 %b, i32 %x) {
1143; CHECK-LABEL: @sdiv_constant_dividend_select_divisor2(
1144; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]]
1145; CHECK-NEXT:    [[R:%.*]] = sdiv i32 42, [[S]]
1146; CHECK-NEXT:    ret i32 [[R]]
1147;
1148  %s = select i1 %b, i32 12, i32 %x
1149  %r = sdiv i32 42, %s
1150  ret i32 %r
1151}
1152
1153define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec(i1 %b) {
1154; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec(
1155; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 8>, <2 x i8> splat (i8 -10)
1156; CHECK-NEXT:    ret <2 x i8> [[R]]
1157;
1158  %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>
1159  %r = sdiv <2 x i8> <i8 42, i8 -42>, %s
1160  ret <2 x i8> %r
1161}
1162
1163; Div-by-0 element is immediate UB, so select is simplified.
1164
1165define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) {
1166; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec_ub1(
1167; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 poison, i8 8>, <2 x i8> splat (i8 -10)
1168; CHECK-NEXT:    ret <2 x i8> [[R]]
1169;
1170  %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4>
1171  %r = sdiv <2 x i8> <i8 42, i8 -42>, %s
1172  ret <2 x i8> %r
1173}
1174
1175; SMIN / -1 element is poison.
1176
1177define <2 x i8> @sdiv_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) {
1178; CHECK-LABEL: @sdiv_constant_dividend_select_of_constants_divisor_vec_ub2(
1179; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 25>, <2 x i8> <i8 -10, i8 poison>
1180; CHECK-NEXT:    ret <2 x i8> [[R]]
1181;
1182  %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>
1183  %r = sdiv <2 x i8> <i8 42, i8 -128>, %s
1184  ret <2 x i8> %r
1185}
1186
1187; negative test - must have constant dividend
1188
1189define i32 @sdiv_select_of_constants_divisor(i1 %b, i32 %x) {
1190; CHECK-LABEL: @sdiv_select_of_constants_divisor(
1191; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
1192; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[X:%.*]], [[S]]
1193; CHECK-NEXT:    ret i32 [[R]]
1194;
1195  %s = select i1 %b, i32 12, i32 -3
1196  %r = sdiv i32 %x, %s
1197  ret i32 %r
1198}
1199
1200define i32 @udiv_constant_dividend_select_of_constants_divisor(i1 %b) {
1201; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor(
1202; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], i32 3, i32 0
1203; CHECK-NEXT:    ret i32 [[R]]
1204;
1205  %s = select i1 %b, i32 12, i32 -3
1206  %r = udiv i32 42, %s
1207  ret i32 %r
1208}
1209
1210define i32 @udiv_constant_dividend_select_of_constants_divisor_use(i1 %b) {
1211; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_use(
1212; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
1213; CHECK-NEXT:    call void @use(i32 [[S]])
1214; CHECK-NEXT:    [[R:%.*]] = select i1 [[B]], i32 3, i32 0
1215; CHECK-NEXT:    ret i32 [[R]]
1216;
1217  %s = select i1 %b, i32 12, i32 -3
1218  call void @use(i32 %s)
1219  %r = udiv i32 42, %s
1220  ret i32 %r
1221}
1222
1223; Div-by-0 is immediate UB, so select is simplified.
1224
1225define i32 @udiv_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) {
1226; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_0_arm(
1227; CHECK-NEXT:    ret i32 3
1228;
1229  %s = select i1 %b, i32 12, i32 0
1230  %r = udiv i32 42, %s
1231  ret i32 %r
1232}
1233
1234; negative test - not safe to speculate div with variable divisor
1235
1236define i32 @udiv_constant_dividend_select_divisor1(i1 %b, i32 %x) {
1237; CHECK-LABEL: @udiv_constant_dividend_select_divisor1(
1238; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3
1239; CHECK-NEXT:    [[R:%.*]] = udiv i32 42, [[S]]
1240; CHECK-NEXT:    ret i32 [[R]]
1241;
1242  %s = select i1 %b, i32 %x, i32 -3
1243  %r = udiv i32 42, %s
1244  ret i32 %r
1245}
1246
1247; negative test - not safe to speculate div with variable divisor
1248
1249define i32 @udiv_constant_dividend_select_divisor2(i1 %b, i32 %x) {
1250; CHECK-LABEL: @udiv_constant_dividend_select_divisor2(
1251; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]]
1252; CHECK-NEXT:    [[R:%.*]] = udiv i32 42, [[S]]
1253; CHECK-NEXT:    ret i32 [[R]]
1254;
1255  %s = select i1 %b, i32 12, i32 %x
1256  %r = udiv i32 42, %s
1257  ret i32 %r
1258}
1259
1260define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec(i1 %b) {
1261; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec(
1262; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 0>, <2 x i8> <i8 0, i8 53>
1263; CHECK-NEXT:    ret <2 x i8> [[R]]
1264;
1265  %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>
1266  %r = udiv <2 x i8> <i8 42, i8 -42>, %s
1267  ret <2 x i8> %r
1268}
1269
1270; Div-by-0 element is immediate UB, so select is simplified.
1271
1272define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) {
1273; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec_ub1(
1274; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 poison, i8 0>, <2 x i8> <i8 0, i8 53>
1275; CHECK-NEXT:    ret <2 x i8> [[R]]
1276;
1277  %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4>
1278  %r = udiv <2 x i8> <i8 42, i8 -42>, %s
1279  ret <2 x i8> %r
1280}
1281
1282; There's no unsigned equivalent to "SMIN / -1", so this is just the usual constant folding.
1283
1284define <2 x i8> @udiv_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) {
1285; CHECK-LABEL: @udiv_constant_dividend_select_of_constants_divisor_vec_ub2(
1286; CHECK-NEXT:    [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 3, i8 0>, <2 x i8> zeroinitializer
1287; CHECK-NEXT:    ret <2 x i8> [[R]]
1288;
1289  %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>
1290  %r = udiv <2 x i8> <i8 42, i8 -128>, %s
1291  ret <2 x i8> %r
1292}
1293
1294; negative test - must have constant dividend
1295
1296define i32 @udiv_select_of_constants_divisor(i1 %b, i32 %x) {
1297; CHECK-LABEL: @udiv_select_of_constants_divisor(
1298; CHECK-NEXT:    [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3
1299; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[X:%.*]], [[S]]
1300; CHECK-NEXT:    ret i32 [[R]]
1301;
1302  %s = select i1 %b, i32 12, i32 -3
1303  %r = udiv i32 %x, %s
1304  ret i32 %r
1305}
1306
1307; PR34063
1308; 1 / X !=/== -1
1309
1310define i1 @sdiv_one_icmpeq_one(i32 %x) {
1311; CHECK-LABEL: @sdiv_one_icmpeq_one(
1312; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X:%.*]]
1313; CHECK-NEXT:    [[B1:%.*]] = icmp eq i32 [[X_FR]], 1
1314; CHECK-NEXT:    ret i1 [[B1]]
1315;
1316  %A = sdiv i32 1, %x
1317  %B = icmp eq i32 %A, 1
1318  ret i1 %B
1319}
1320
1321define i1 @sdiv_one_icmpeq_negone(i32 %x) {
1322; CHECK-LABEL: @sdiv_one_icmpeq_negone(
1323; CHECK-NEXT:    [[X_FR:%.*]] = freeze i32 [[X:%.*]]
1324; CHECK-NEXT:    [[B1:%.*]] = icmp eq i32 [[X_FR]], -1
1325; CHECK-NEXT:    ret i1 [[B1]]
1326;
1327  %A = sdiv i32 1, %x
1328  %B = icmp eq i32 %A, -1
1329  ret i1 %B
1330}
1331
1332define i1 @udiv_one_icmpeq_one(i32 %x) {
1333; CHECK-LABEL: @udiv_one_icmpeq_one(
1334; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], 1
1335; CHECK-NEXT:    ret i1 [[TMP1]]
1336;
1337  %A = udiv i32 1, %x
1338  %B = icmp eq i32 %A, 1
1339  ret i1 %B
1340}
1341
1342define i1 @udiv_one_icmpne_one(i32 %x) {
1343; CHECK-LABEL: @udiv_one_icmpne_one(
1344; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 1
1345; CHECK-NEXT:    ret i1 [[TMP1]]
1346;
1347  %A = udiv i32 1, %x
1348  %B = icmp ne i32 %A, 1
1349  ret i1 %B
1350}
1351
1352; ((X * Y) / Z) / X --> Y / Z
1353
1354define i8 @udiv_udiv_mul_nuw(i8 %x, i8 %y, i8 %z) {
1355; CHECK-LABEL: @udiv_udiv_mul_nuw(
1356; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[Y:%.*]], [[Z:%.*]]
1357; CHECK-NEXT:    ret i8 [[R]]
1358;
1359  %m = mul nuw i8 %x, %y
1360  %d = udiv i8 %m, %z
1361  %r = udiv i8 %d, %x
1362  ret i8 %r
1363}
1364
1365; exact propagates and commute is ok
1366
1367define i8 @udiv_udiv_mul_nuw_exact_exact(i8 %x, i8 %y, i8 %z) {
1368; CHECK-LABEL: @udiv_udiv_mul_nuw_exact_exact(
1369; CHECK-NEXT:    [[R:%.*]] = udiv exact i8 [[Y:%.*]], [[Z:%.*]]
1370; CHECK-NEXT:    ret i8 [[R]]
1371;
1372  %m = mul nuw i8 %y, %x
1373  %d = udiv exact i8 %m, %z
1374  %r = udiv exact i8 %d, %x
1375  ret i8 %r
1376}
1377
1378; extra uses are ok
1379
1380define i32 @udiv_udiv_mul_nuw_exact_use(i32 %x, i32 %y, i32 %z) {
1381; CHECK-LABEL: @udiv_udiv_mul_nuw_exact_use(
1382; CHECK-NEXT:    [[M:%.*]] = mul nuw i32 [[X:%.*]], [[Y:%.*]]
1383; CHECK-NEXT:    call void @use(i32 [[M]])
1384; CHECK-NEXT:    [[R:%.*]] = udiv i32 [[Y]], [[Z:%.*]]
1385; CHECK-NEXT:    ret i32 [[R]]
1386;
1387  %m = mul nuw i32 %x, %y
1388  call void @use(i32 %m)
1389  %d = udiv exact i32 %m, %z
1390  %r = udiv i32 %d, %x
1391  ret i32 %r
1392}
1393
1394; negative test - must have nuw
1395
1396define i8 @udiv_udiv_mul_nsw(i8 %x, i8 %y, i8 %z) {
1397; CHECK-LABEL: @udiv_udiv_mul_nsw(
1398; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]]
1399; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[M]], [[Z:%.*]]
1400; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[D]], [[X]]
1401; CHECK-NEXT:    ret i8 [[R]]
1402;
1403  %m = mul nsw i8 %x, %y
1404  %d = udiv i8 %m, %z
1405  %r = udiv i8 %d, %x
1406  ret i8 %r
1407}
1408
1409; negative test - opcode mismatch
1410
1411define i8 @udiv_sdiv_mul_nuw(i8 %x, i8 %y, i8 %z) {
1412; CHECK-LABEL: @udiv_sdiv_mul_nuw(
1413; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
1414; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[M]], [[Z:%.*]]
1415; CHECK-NEXT:    [[R:%.*]] = udiv i8 [[D]], [[X]]
1416; CHECK-NEXT:    ret i8 [[R]]
1417;
1418  %m = mul nuw i8 %x, %y
1419  %d = sdiv i8 %m, %z
1420  %r = udiv i8 %d, %x
1421  ret i8 %r
1422}
1423
1424; ((Y * X) / Z) / X --> Y / Z
1425
1426define <2 x i8> @sdiv_sdiv_mul_nsw(<2 x i8> %x, <2 x i8> %y, <2 x i8> %z) {
1427; CHECK-LABEL: @sdiv_sdiv_mul_nsw(
1428; CHECK-NEXT:    [[R:%.*]] = sdiv <2 x i8> [[Y:%.*]], [[Z:%.*]]
1429; CHECK-NEXT:    ret <2 x i8> [[R]]
1430;
1431  %m = mul nsw <2 x i8> %y, %x
1432  %d = sdiv <2 x i8> %m, %z
1433  %r = sdiv <2 x i8> %d, %x
1434  ret <2 x i8> %r
1435}
1436
1437; (X * C0) / (X * C1) --> C0 / C1
1438define i8 @sdiv_mul_nsw_mul_nsw(i8 %x,i8 %y,i8 %z) {
1439; CHECK-LABEL: @sdiv_mul_nsw_mul_nsw(
1440; CHECK-NEXT:    [[ADD4:%.*]] = mul nsw i8 [[X:%.*]], [[Z:%.*]]
1441; CHECK-NEXT:    [[ADD5:%.*]] = mul nsw i8 [[X]], [[Y:%.*]]
1442; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[ADD5]], [[ADD4]]
1443; CHECK-NEXT:    ret i8 [[DIV]]
1444;
1445  %add4 = mul nsw i8 %x, %z
1446  %add5 = mul nsw i8 %x, %y
1447  %div = sdiv i8 %add5, %add4
1448  ret i8 %div
1449}
1450
1451define i8 @udiv_mul_nuw_mul_nuw(i8 %x,i8 %y,i8 %z) {
1452; CHECK-LABEL: @udiv_mul_nuw_mul_nuw(
1453; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[Y:%.*]], [[Z:%.*]]
1454; CHECK-NEXT:    ret i8 [[DIV]]
1455;
1456  %add4 = mul nuw i8 %x, %z
1457  %add5 = mul nuw i8 %x, %y
1458  %div = udiv i8 %add5, %add4
1459  ret i8 %div
1460}
1461
1462define i8 @sdiv_mul_nsw_constant_mul_nsw_constant(i8 %x) {
1463; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_nsw_constant(
1464; CHECK-NEXT:    ret i8 2
1465;
1466  %add4 = mul nsw i8 %x, 5
1467  %add5 = mul nsw i8 %x, 10
1468  %div = sdiv i8 %add5, %add4
1469  ret i8 %div
1470}
1471
1472define i4 @sdiv_mul_nsw_constant_mul_constant(i4 %a) {
1473; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant(
1474; CHECK-NEXT:    [[ADD4:%.*]] = mul i4 [[A:%.*]], 3
1475; CHECK-NEXT:    [[ADD5:%.*]] = mul nsw i4 [[A]], 6
1476; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]
1477; CHECK-NEXT:    ret i4 [[DIV]]
1478;
1479  %add4 = mul i4 %a, 3
1480  %add5 = mul nsw i4 %a, 6
1481  %div = sdiv i4 %add5, %add4
1482  ret i4 %div
1483}
1484define i4 @sdiv_mul_nsw_constant_mul_constant2(i4 %a) {
1485; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant2(
1486; CHECK-NEXT:    [[ADD4:%.*]] = sub i4 0, [[A:%.*]]
1487; CHECK-NEXT:    [[ADD5:%.*]] = shl i4 [[A]], 3
1488; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]
1489; CHECK-NEXT:    ret i4 [[DIV]]
1490;
1491  %add4 = mul i4 %a, 15
1492  %add5 = mul nsw i4 %a, 8
1493  %div = sdiv i4 %add5, %add4
1494  ret i4 %div
1495}
1496
1497define i4 @sdiv_mul_nsw_constant_mul_constant3(i4 %a) {
1498; CHECK-LABEL: @sdiv_mul_nsw_constant_mul_constant3(
1499; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i4 [[A:%.*]], -8
1500; CHECK-NEXT:    [[DIV:%.*]] = select i1 [[TMP1]], i4 1, i4 -1
1501; CHECK-NEXT:    ret i4 [[DIV]]
1502;
1503  %add4 = mul i4 %a, 15
1504  %add5 = mul nsw i4 %a, 1
1505  %div = sdiv i4 %add5, %add4
1506  ret i4 %div
1507}
1508
1509define i4 @sdiv_mul_nsw_mul(i4 %a) {
1510; CHECK-LABEL: @sdiv_mul_nsw_mul(
1511; CHECK-NEXT:    [[ADD4:%.*]] = sub i4 0, [[A:%.*]]
1512; CHECK-NEXT:    [[ADD5:%.*]] = shl i4 [[A]], 3
1513; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]
1514; CHECK-NEXT:    ret i4 [[DIV]]
1515;
1516  %add4 = mul i4 %a, -1
1517  %add5 = mul nsw i4 %a, -8
1518  %div = sdiv i4 %add5, %add4
1519  ret i4 %div
1520}
1521
1522define i4 @udiv_mul_nuw_constant_mul_constant(i4 %a) {
1523; CHECK-LABEL: @udiv_mul_nuw_constant_mul_constant(
1524; CHECK-NEXT:    ret i4 2
1525;
1526  %add4 = mul i4 %a, 3
1527  %add5 = mul nuw i4 %a, 6
1528  %div = udiv i4 %add5, %add4
1529  ret i4 %div
1530}
1531
1532define i4 @udiv_mul_nuw_mul_negative(i4 %a) {
1533; CHECK-LABEL: @udiv_mul_nuw_mul_negative(
1534; CHECK-NEXT:    [[ADD4:%.*]] = mul i4 [[A:%.*]], -3
1535; CHECK-NEXT:    [[ADD5:%.*]] = shl nuw i4 [[A]], 2
1536; CHECK-NEXT:    [[DIV:%.*]] = udiv i4 [[ADD5]], [[ADD4]]
1537; CHECK-NEXT:    ret i4 [[DIV]]
1538;
1539  %add4 = mul i4 %a, 13
1540  %add5 = mul nuw i4 %a, 4
1541  %div = udiv i4 %add5, %add4
1542  ret i4 %div
1543}
1544
1545define i4 @sdiv_mul_nsw_mul_nsw_allones(i4 %a) {
1546; CHECK-LABEL: @sdiv_mul_nsw_mul_nsw_allones(
1547; CHECK-NEXT:    [[ADD4:%.*]] = sub nsw i4 0, [[A:%.*]]
1548; CHECK-NEXT:    [[ADD5:%.*]] = shl i4 [[A]], 3
1549; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]
1550; CHECK-NEXT:    ret i4 [[DIV]]
1551;
1552  %add4 = mul nsw i4 %a, -1
1553  %add5 = mul nsw i4 %a, -8
1554  %div = sdiv i4 %add5, %add4
1555  ret i4 %div
1556}
1557
1558define i4 @sdiv_mul_nsw_mul_signmask(i4 %a, i4 %c2) {
1559; CHECK-LABEL: @sdiv_mul_nsw_mul_signmask(
1560; CHECK-NEXT:    [[ADD4:%.*]] = shl i4 [[A:%.*]], 3
1561; CHECK-NEXT:    [[ADD5:%.*]] = mul nsw i4 [[A]], [[C2:%.*]]
1562; CHECK-NEXT:    [[DIV:%.*]] = sdiv i4 [[ADD5]], [[ADD4]]
1563; CHECK-NEXT:    ret i4 [[DIV]]
1564;
1565  %add4 = mul nsw i4 %a, -8
1566  %add5 = mul nsw i4 %a, %c2
1567  %div = sdiv i4 %add5, %add4
1568  ret i4 %div
1569}
1570
1571define i32 @sdiv_sub1(i32 %arg) {
1572; CHECK-LABEL: @sdiv_sub1(
1573; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[ARG:%.*]], -2147483648
1574; CHECK-NEXT:    [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -1
1575; CHECK-NEXT:    ret i32 [[DIV]]
1576;
1577  %neg = sub i32 0, %arg
1578  %div = sdiv i32 %neg, %arg
1579  ret i32 %div
1580}
1581
1582define i32 @sdiv_sub2(i32 %arg) {
1583; CHECK-LABEL: @sdiv_sub2(
1584; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[ARG:%.*]], -2147483648
1585; CHECK-NEXT:    [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -1
1586; CHECK-NEXT:    ret i32 [[DIV]]
1587;
1588  %neg = sub i32 0, %arg
1589  %div = sdiv i32 %arg, %neg
1590  ret i32 %div
1591}
1592
1593define i32 @sub_sdiv_multiuse(i32 %arg) {
1594; CHECK-LABEL: @sub_sdiv_multiuse(
1595; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[ARG:%.*]]
1596; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[ARG]], -2147483648
1597; CHECK-NEXT:    [[DIV:%.*]] = select i1 [[TMP1]], i32 1, i32 -1
1598; CHECK-NEXT:    call void @use(i32 [[NEG]])
1599; CHECK-NEXT:    ret i32 [[DIV]]
1600;
1601  %neg = sub i32 0, %arg
1602  %div = sdiv i32 %arg, %neg
1603  call void @use(i32 %neg)
1604  ret i32 %div
1605}
1606
1607define i32 @sdiv_sub_sub(i32 %x ,i32 %y) {
1608; CHECK-LABEL: @sdiv_sub_sub(
1609; CHECK-NEXT:    [[S:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
1610; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[S]], -2147483648
1611; CHECK-NEXT:    [[D:%.*]] = select i1 [[TMP1]], i32 1, i32 -1
1612; CHECK-NEXT:    ret i32 [[D]]
1613;
1614  %s = sub i32 %x, %y
1615  %u = sub i32 %y, %x
1616  %d = sdiv i32 %s, %u
1617  ret i32 %d
1618}
1619
1620define i32 @sdiv_mul_sub(i32 %x, i32 %y) {
1621; CHECK-LABEL: @sdiv_mul_sub(
1622; CHECK-NEXT:    [[M:%.*]] = mul i32 [[Y:%.*]], [[X:%.*]]
1623; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32 [[M]], -2147483648
1624; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i32 1, i32 -1
1625; CHECK-NEXT:    ret i32 [[R]]
1626;
1627  %m = mul i32 %y, %x
1628  %d = sub i32 0, %m
1629  %r = sdiv i32 %d, %m
1630  ret i32 %r
1631}
1632
1633define i32 @sdiv_mul_sub_nsw(i32 %x, i32 %y) {
1634; CHECK-LABEL: @sdiv_mul_sub_nsw(
1635; CHECK-NEXT:    ret i32 -1
1636;
1637  %m = mul i32 %y, %x
1638  %n = sub nsw i32 0, %m
1639  %d = sdiv i32 %m, %n
1640  ret i32 %d
1641}
1642
1643define i32 @sdiv_mul_nsw_sub_nsw(i32 %x, i32 %y) {
1644; CHECK-LABEL: @sdiv_mul_nsw_sub_nsw(
1645; CHECK-NEXT:    ret i32 -1
1646;
1647  %m = mul nsw i32 %y, %x
1648  %n = sub nsw i32 0, %m
1649  %d = sdiv i32 %m, %n
1650  ret i32 %d
1651}
1652
1653; exact propagates
1654
1655define i8 @sdiv_sdiv_mul_nsw_exact_exact(i8 %x, i8 %y, i8 %z) {
1656; CHECK-LABEL: @sdiv_sdiv_mul_nsw_exact_exact(
1657; CHECK-NEXT:    [[R:%.*]] = sdiv exact i8 [[Y:%.*]], [[Z:%.*]]
1658; CHECK-NEXT:    ret i8 [[R]]
1659;
1660  %m = mul nsw i8 %x, %y
1661  %d = sdiv exact i8 %m, %z
1662  %r = sdiv exact i8 %d, %x
1663  ret i8 %r
1664}
1665
1666; extra uses are ok
1667
1668define i32 @sdiv_sdiv_mul_nsw_exact_use(i32 %x, i32 %y, i32 %z) {
1669; CHECK-LABEL: @sdiv_sdiv_mul_nsw_exact_use(
1670; CHECK-NEXT:    [[M:%.*]] = mul nsw i32 [[X:%.*]], [[Y:%.*]]
1671; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[M]], [[Z:%.*]]
1672; CHECK-NEXT:    call void @use(i32 [[D]])
1673; CHECK-NEXT:    [[R:%.*]] = sdiv i32 [[Y]], [[Z]]
1674; CHECK-NEXT:    ret i32 [[R]]
1675;
1676  %m = mul nsw i32 %x, %y
1677  %d = sdiv i32 %m, %z
1678  call void @use(i32 %d)
1679  %r = sdiv exact i32 %d, %x
1680  ret i32 %r
1681}
1682
1683; negative test - must have nsw
1684
1685define i8 @sdiv_sdiv_mul_nuw(i8 %x, i8 %y, i8 %z) {
1686; CHECK-LABEL: @sdiv_sdiv_mul_nuw(
1687; CHECK-NEXT:    [[M:%.*]] = mul nuw i8 [[X:%.*]], [[Y:%.*]]
1688; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[M]], [[Z:%.*]]
1689; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[D]], [[X]]
1690; CHECK-NEXT:    ret i8 [[R]]
1691;
1692  %m = mul nuw i8 %x, %y
1693  %d = sdiv i8 %m, %z
1694  %r = sdiv i8 %d, %x
1695  ret i8 %r
1696}
1697
1698; negative test - opcode mismatch
1699
1700define i8 @sdiv_udiv_mul_nsw(i8 %x, i8 %y, i8 %z) {
1701; CHECK-LABEL: @sdiv_udiv_mul_nsw(
1702; CHECK-NEXT:    [[M:%.*]] = mul nsw i8 [[X:%.*]], [[Y:%.*]]
1703; CHECK-NEXT:    [[D:%.*]] = udiv i8 [[M]], [[Z:%.*]]
1704; CHECK-NEXT:    [[R:%.*]] = sdiv i8 [[D]], [[X]]
1705; CHECK-NEXT:    ret i8 [[R]]
1706;
1707  %m = mul nsw i8 %x, %y
1708  %d = udiv i8 %m, %z
1709  %r = sdiv i8 %d, %x
1710  ret i8 %r
1711}
1712
1713; ((X * C2) + C1) / C2 --> X + C1/C2
1714
1715define i6 @sdiv_distribute_mul_nsw_add_nsw(i6 %x) {
1716; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw(
1717; CHECK-NEXT:    [[DIV:%.*]] = add nsw i6 [[X:%.*]], -5
1718; CHECK-NEXT:    ret i6 [[DIV]]
1719;
1720  %mul = mul nsw i6 %x, 3
1721  %add = add nsw i6 %mul, -15
1722  %div = sdiv i6 %add, 3
1723  ret i6 %div
1724}
1725
1726; extra uses are ok
1727
1728define i32 @sdiv_distribute_mul_nsw_add_nsw_uses(i32 %x) {
1729; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw_uses(
1730; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[X:%.*]], 42
1731; CHECK-NEXT:    call void @use(i32 [[MUL]])
1732; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[MUL]], 126
1733; CHECK-NEXT:    call void @use(i32 [[ADD]])
1734; CHECK-NEXT:    [[DIV:%.*]] = add nsw i32 [[X]], 3
1735; CHECK-NEXT:    ret i32 [[DIV]]
1736;
1737  %mul = mul nsw i32 %x, 42
1738  call void @use(i32 %mul)
1739  %add = add nsw i32 %mul, 126
1740  call void @use(i32 %add)
1741  %div = sdiv i32 %add, 42
1742  ret i32 %div
1743}
1744
1745; vector splats work
1746
1747define <2 x i6> @udiv_distribute_mul_nuw_add_nuw(<2 x i6> %x) {
1748; CHECK-LABEL: @udiv_distribute_mul_nuw_add_nuw(
1749; CHECK-NEXT:    [[DIV:%.*]] = add nuw <2 x i6> [[X:%.*]], splat (i6 5)
1750; CHECK-NEXT:    ret <2 x i6> [[DIV]]
1751;
1752  %mul = mul nuw <2 x i6> %x, <i6 3, i6 3>
1753  %add = add nuw <2 x i6> %mul, <i6 15, i6 15>
1754  %div = udiv <2 x i6> %add, <i6 3, i6 3>
1755  ret <2 x i6> %div
1756}
1757
1758; negative test - constants must be evenly divisible
1759
1760define i6 @sdiv_distribute_mul_nsw_add_nsw_not_multiple_offset(i6 %x) {
1761; CHECK-LABEL: @sdiv_distribute_mul_nsw_add_nsw_not_multiple_offset(
1762; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i6 [[X:%.*]], 3
1763; CHECK-NEXT:    [[ADD:%.*]] = add nsw i6 [[MUL]], -16
1764; CHECK-NEXT:    [[DIV:%.*]] = sdiv i6 [[ADD]], 3
1765; CHECK-NEXT:    ret i6 [[DIV]]
1766;
1767  %mul = mul nsw i6 %x, 3
1768  %add = add nsw i6 %mul, -16
1769  %div = sdiv i6 %add, 3
1770  ret i6 %div
1771}
1772
1773; constants do not have to be evenly divisible with unsigned division
1774
1775define i6 @udiv_distribute_mul_nuw_add_nuw_not_multiple_offset(i6 %x) {
1776; CHECK-LABEL: @udiv_distribute_mul_nuw_add_nuw_not_multiple_offset(
1777; CHECK-NEXT:    [[DIV:%.*]] = add nuw i6 [[X:%.*]], 2
1778; CHECK-NEXT:    ret i6 [[DIV]]
1779;
1780  %mul = mul nuw i6 %x, 3
1781  %add = add nuw i6 %mul, 7
1782  %div = udiv i6 %add, 3
1783  ret i6 %div
1784}
1785
1786; negative test - wrong no-wrap
1787
1788define i6 @sdiv_distribute_mul_nuw_add_nsw(i6 %x) {
1789; CHECK-LABEL: @sdiv_distribute_mul_nuw_add_nsw(
1790; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i6 [[X:%.*]], 3
1791; CHECK-NEXT:    [[ADD:%.*]] = add nsw i6 [[MUL]], -15
1792; CHECK-NEXT:    [[DIV:%.*]] = sdiv i6 [[ADD]], 3
1793; CHECK-NEXT:    ret i6 [[DIV]]
1794;
1795  %mul = mul nuw i6 %x, 3
1796  %add = add nsw i6 %mul, -15
1797  %div = sdiv i6 %add, 3
1798  ret i6 %div
1799}
1800
1801; negative test - wrong no-wrap
1802
1803define i6 @udiv_distribute_mul_nsw_add_nuw(i6 %x) {
1804; CHECK-LABEL: @udiv_distribute_mul_nsw_add_nuw(
1805; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i6 [[X:%.*]], 3
1806; CHECK-NEXT:    [[ADD:%.*]] = add nuw i6 [[MUL]], 9
1807; CHECK-NEXT:    [[DIV:%.*]] = udiv i6 [[ADD]], 3
1808; CHECK-NEXT:    ret i6 [[DIV]]
1809;
1810  %mul = mul nsw i6 %x, 3
1811  %add = add nuw i6 %mul, 9
1812  %div = udiv i6 %add, 3
1813  ret i6 %div
1814}
1815
1816define i32 @fold_disjoint_or_over_sdiv(i32 %x) {
1817; CHECK-LABEL: @fold_disjoint_or_over_sdiv(
1818; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[X:%.*]], 9
1819; CHECK-NEXT:    ret i32 [[R]]
1820;
1821  %mul = mul nsw i32 %x, 9
1822  %or = or disjoint i32 %mul, 81
1823  %r = sdiv i32 %or, 9
1824  ret i32 %r
1825}
1826
1827define i32 @fold_disjoint_or_over_udiv(i32 %x) {
1828; CHECK-LABEL: @fold_disjoint_or_over_udiv(
1829; CHECK-NEXT:    [[R:%.*]] = add nuw i32 [[X:%.*]], 9
1830; CHECK-NEXT:    ret i32 [[R]]
1831;
1832  %mul = mul nuw i32 %x, 9
1833  %or = or disjoint i32 %mul, 81
1834  %r = udiv i32 %or, 9
1835  ret i32 %r
1836}
1837
1838define i8 @udiv_trunc_shl(i32 %x) {
1839; CHECK-LABEL: @udiv_trunc_shl(
1840; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1841; CHECK-NEXT:    [[UDIV1:%.*]] = lshr i8 8, [[TMP1]]
1842; CHECK-NEXT:    ret i8 [[UDIV1]]
1843;
1844  %lshr = shl i32 1, %x
1845  %trunc = trunc i32 %lshr to i8
1846  %div = udiv i8 8, %trunc
1847  ret i8 %div
1848}
1849
1850define i32 @zext_udiv_trunc_lshr(i32 %x) {
1851; CHECK-LABEL: @zext_udiv_trunc_lshr(
1852; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8
1853; CHECK-NEXT:    [[TMP2:%.*]] = sub i8 5, [[TMP1]]
1854; CHECK-NEXT:    [[UDIV1:%.*]] = lshr i8 8, [[TMP2]]
1855; CHECK-NEXT:    [[ZEXT:%.*]] = zext nneg i8 [[UDIV1]] to i32
1856; CHECK-NEXT:    ret i32 [[ZEXT]]
1857;
1858  %lshr = lshr i32 32, %x
1859  %trunc = trunc i32 %lshr to i8
1860  %div = udiv i8 8, %trunc
1861  %zext = zext i8 %div to i32
1862  ret i32 %zext
1863}
1864
1865define i32 @udiv_and_shl(i32 %a, i32 %b, i32 %c) {
1866; CHECK-LABEL: @udiv_and_shl(
1867; CHECK-NEXT:    [[DIV1:%.*]] = lshr i32 [[C:%.*]], [[A:%.*]]
1868; CHECK-NEXT:    ret i32 [[DIV1]]
1869;
1870  %shl = shl i32 1, %a
1871  %and = and i32 %b, %shl
1872  %div = udiv i32 %c, %and
1873  ret i32 %div
1874}
1875