xref: /llvm-project/llvm/test/Transforms/InstCombine/mul.ll (revision 78f7ca0980f3369da19e3cbb01890fe718307ac2)
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 i32 @llvm.abs.i32(i32, i1)
6
7define i32 @pow2_multiplier(i32 %A) {
8; CHECK-LABEL: @pow2_multiplier(
9; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 1
10; CHECK-NEXT:    ret i32 [[B]]
11;
12  %B = mul i32 %A, 2
13  ret i32 %B
14}
15
16define <2 x i32> @pow2_multiplier_vec(<2 x i32> %A) {
17; CHECK-LABEL: @pow2_multiplier_vec(
18; CHECK-NEXT:    [[B:%.*]] = shl <2 x i32> [[A:%.*]], splat (i32 3)
19; CHECK-NEXT:    ret <2 x i32> [[B]]
20;
21  %B = mul <2 x i32> %A, <i32 8, i32 8>
22  ret <2 x i32> %B
23}
24
25define i8 @combine_shl(i8 %A) {
26; CHECK-LABEL: @combine_shl(
27; CHECK-NEXT:    [[C:%.*]] = shl i8 [[A:%.*]], 6
28; CHECK-NEXT:    ret i8 [[C]]
29;
30  %B = mul i8 %A, 8
31  %C = mul i8 %B, 8
32  ret i8 %C
33}
34
35define i32 @neg(i32 %i) {
36; CHECK-LABEL: @neg(
37; CHECK-NEXT:    [[T:%.*]] = sub i32 0, [[I:%.*]]
38; CHECK-NEXT:    ret i32 [[T]]
39;
40  %t = mul i32 %i, -1
41  ret i32 %t
42}
43
44; Use the sign-bit as a mask:
45; (zext (A < 0)) * B --> (A >> 31) & B
46
47define i32 @test10(i32 %a, i32 %b) {
48; CHECK-LABEL: @test10(
49; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0
50; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
51; CHECK-NEXT:    ret i32 [[E]]
52;
53  %c = icmp slt i32 %a, 0
54  %d = zext i1 %c to i32
55  %e = mul i32 %d, %b
56  ret i32 %e
57}
58
59define i32 @test11(i32 %a, i32 %b) {
60; CHECK-LABEL: @test11(
61; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0
62; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
63; CHECK-NEXT:    ret i32 [[E]]
64;
65  %c = icmp sle i32 %a, -1
66  %d = zext i1 %c to i32
67  %e = mul i32 %d, %b
68  ret i32 %e
69}
70
71declare void @use32(i32)
72
73define i32 @test12(i32 %a, i32 %b) {
74; CHECK-LABEL: @test12(
75; CHECK-NEXT:    [[A_LOBIT:%.*]] = lshr i32 [[A:%.*]], 31
76; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A]], 0
77; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
78; CHECK-NEXT:    call void @use32(i32 [[A_LOBIT]])
79; CHECK-NEXT:    ret i32 [[E]]
80;
81  %c = icmp ugt i32 %a, 2147483647
82  %d = zext i1 %c to i32
83  %e = mul i32 %d, %b
84  call void @use32(i32 %d)
85  ret i32 %e
86}
87
88; rdar://7293527
89define i32 @shl1(i32 %a, i32 %b) {
90; CHECK-LABEL: @shl1(
91; CHECK-NEXT:    [[M1:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]
92; CHECK-NEXT:    ret i32 [[M1]]
93;
94  %shl = shl i32 1, %b
95  %m = mul i32 %shl, %a
96  ret i32 %m
97}
98
99define i32 @shl1_nsw_nsw(i32 %A, i32 %B) {
100; CHECK-LABEL: @shl1_nsw_nsw(
101; CHECK-NEXT:    [[D1:%.*]] = shl nsw i32 [[A:%.*]], [[B:%.*]]
102; CHECK-NEXT:    ret i32 [[D1]]
103;
104  %shl = shl nsw i32 1, %B
105  %D = mul nsw i32 %A, %shl
106  ret i32 %D
107}
108
109define <2 x i32> @shl1_nsw_nsw_commute(<2 x i32> %A, <2 x i32> %B) {
110; CHECK-LABEL: @shl1_nsw_nsw_commute(
111; CHECK-NEXT:    [[D1:%.*]] = shl nsw <2 x i32> [[A:%.*]], [[B:%.*]]
112; CHECK-NEXT:    ret <2 x i32> [[D1]]
113;
114  %shl = shl nsw <2 x i32> <i32 1, i32 poison>, %B
115  %D = mul nsw <2 x i32> %shl, %A
116  ret <2 x i32> %D
117}
118
119define i32 @shl1_nuw(i32 %A, i32 %B) {
120; CHECK-LABEL: @shl1_nuw(
121; CHECK-NEXT:    [[D1:%.*]] = shl nuw i32 [[A:%.*]], [[B:%.*]]
122; CHECK-NEXT:    ret i32 [[D1]]
123;
124  %shl = shl i32 1, %B
125  %D = mul nuw i32 %A, %shl
126  ret i32 %D
127}
128
129define i32 @shl1_nuw_commute(i32 %A, i32 %B) {
130; CHECK-LABEL: @shl1_nuw_commute(
131; CHECK-NEXT:    [[D1:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]
132; CHECK-NEXT:    ret i32 [[D1]]
133;
134  %shl = shl nuw i32 1, %B
135  %D = mul i32 %shl, %A
136  ret i32 %D
137}
138
139define i32 @shl1_nsw(i32 %A) {
140; CHECK-LABEL: @shl1_nsw(
141; CHECK-NEXT:    [[SHL:%.*]] = shl nuw i32 1, [[A:%.*]]
142; CHECK-NEXT:    [[C1:%.*]] = shl i32 [[SHL]], [[A]]
143; CHECK-NEXT:    ret i32 [[C1]]
144;
145  %shl = shl i32 1, %A
146  %C = mul nsw i32 %shl, %shl
147  ret i32 %C
148}
149
150define i5 @shl1_increment(i5 %x, i5 %y) {
151; CHECK-LABEL: @shl1_increment(
152; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i5 [[Y:%.*]]
153; CHECK-NEXT:    [[MULSHL:%.*]] = shl i5 [[Y_FR]], [[X:%.*]]
154; CHECK-NEXT:    [[M1:%.*]] = add i5 [[MULSHL]], [[Y_FR]]
155; CHECK-NEXT:    ret i5 [[M1]]
156;
157  %pow2x = shl i5 1, %x
158  %x1 = add i5 %pow2x, 1
159  %m = mul i5 %x1, %y
160  ret i5 %m
161}
162
163define <3 x i5> @shl1_nuw_increment_commute(<3 x i5> %x, <3 x i5> noundef %p) {
164; CHECK-LABEL: @shl1_nuw_increment_commute(
165; CHECK-NEXT:    [[Y:%.*]] = ashr <3 x i5> [[P:%.*]], splat (i5 1)
166; CHECK-NEXT:    [[MULSHL:%.*]] = shl nuw <3 x i5> [[Y]], [[X:%.*]]
167; CHECK-NEXT:    [[M1:%.*]] = add nuw <3 x i5> [[MULSHL]], [[Y]]
168; CHECK-NEXT:    ret <3 x i5> [[M1]]
169;
170  %y = ashr <3 x i5> %p, <i5 1, i5 1, i5 1> ; thwart complexity-based canonicalization
171  %pow2x = shl <3 x i5> <i5 1, i5 poison, i5 1>, %x
172  %x1 = add <3 x i5> %pow2x, <i5 1, i5 poison, i5 1>
173  %m = mul nuw <3 x i5> %y, %x1
174  ret <3 x i5> %m
175}
176
177define i5 @shl1_nsw_increment(i5 %x, i5 %y) {
178; CHECK-LABEL: @shl1_nsw_increment(
179; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i5 [[Y:%.*]]
180; CHECK-NEXT:    [[MULSHL:%.*]] = shl i5 [[Y_FR]], [[X:%.*]]
181; CHECK-NEXT:    [[M1:%.*]] = add i5 [[MULSHL]], [[Y_FR]]
182; CHECK-NEXT:    ret i5 [[M1]]
183;
184  %pow2x = shl i5 1, %x
185  %x1 = add i5 %pow2x, 1
186  %m = mul nsw i5 %x1, %y
187  ret i5 %m
188}
189
190define i5 @shl1_nsw_nsw_increment(i5 %x, i5 %y) {
191; CHECK-LABEL: @shl1_nsw_nsw_increment(
192; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i5 [[Y:%.*]]
193; CHECK-NEXT:    [[MULSHL:%.*]] = shl nsw i5 [[Y_FR]], [[X:%.*]]
194; CHECK-NEXT:    [[M1:%.*]] = add nsw i5 [[MULSHL]], [[Y_FR]]
195; CHECK-NEXT:    ret i5 [[M1]]
196;
197  %pow2x = shl nsw i5 1, %x
198  %x1 = add i5 %pow2x, 1
199  %m = mul nsw i5 %y, %x1
200  ret i5 %m
201}
202
203define i5 @shl1_nsw_nsw_increment_commute(i5 %x, i5 %y) {
204; CHECK-LABEL: @shl1_nsw_nsw_increment_commute(
205; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i5 [[Y:%.*]]
206; CHECK-NEXT:    [[MULSHL:%.*]] = shl i5 [[Y_FR]], [[X:%.*]]
207; CHECK-NEXT:    [[M1:%.*]] = add i5 [[MULSHL]], [[Y_FR]]
208; CHECK-NEXT:    ret i5 [[M1]]
209;
210  %pow2x = shl nsw i5 1, %x
211  %x1 = add nsw i5 %pow2x, 1
212  %m = mul i5 %x1, %y
213  ret i5 %m
214}
215
216define i32 @shl1_increment_use(i32 %x, i32 %y) {
217; CHECK-LABEL: @shl1_increment_use(
218; CHECK-NEXT:    [[POW2X:%.*]] = shl nuw i32 1, [[X:%.*]]
219; CHECK-NEXT:    call void @use32(i32 [[POW2X]])
220; CHECK-NEXT:    [[X1:%.*]] = add nuw i32 [[POW2X]], 1
221; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X1]], [[Y:%.*]]
222; CHECK-NEXT:    ret i32 [[M]]
223;
224  %pow2x = shl i32 1, %x
225  call void @use32(i32 %pow2x)
226  %x1 = add i32 %pow2x, 1
227  %m = mul i32 %x1, %y
228  ret i32 %m
229}
230
231; ((-1 << x) ^ -1) * y --> (y << x) - y
232
233define i8 @shl1_decrement(i8 %x, i8 %y) {
234; CHECK-LABEL: @shl1_decrement(
235; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i8 [[Y:%.*]]
236; CHECK-NEXT:    [[MULSHL:%.*]] = shl i8 [[Y_FR]], [[X:%.*]]
237; CHECK-NEXT:    [[M1:%.*]] = sub i8 [[MULSHL]], [[Y_FR]]
238; CHECK-NEXT:    ret i8 [[M1]]
239;
240  %pow2x = shl i8 -1, %x
241  %x1 = xor i8 %pow2x, -1
242  %m = mul i8 %x1, %y
243  ret i8 %m
244}
245
246define i8 @shl1_decrement_commute(i8 %x, i8 noundef %p) {
247; CHECK-LABEL: @shl1_decrement_commute(
248; CHECK-NEXT:    [[Y:%.*]] = ashr i8 [[P:%.*]], 1
249; CHECK-NEXT:    [[MULSHL:%.*]] = shl i8 [[Y]], [[X:%.*]]
250; CHECK-NEXT:    [[M1:%.*]] = sub i8 [[MULSHL]], [[Y]]
251; CHECK-NEXT:    ret i8 [[M1]]
252;
253  %y = ashr i8 %p, 1 ; thwart complexity-based canonicalization
254  %pow2x = shl i8 1, %x
255  %x1 = add i8 %pow2x, -1
256  %m = mul i8 %y, %x1
257  ret i8 %m
258}
259
260define i8 @shl1_nuw_decrement(i8 %x, i8 %y) {
261; CHECK-LABEL: @shl1_nuw_decrement(
262; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i8 [[Y:%.*]]
263; CHECK-NEXT:    [[MULSHL:%.*]] = shl i8 [[Y_FR]], [[X:%.*]]
264; CHECK-NEXT:    [[M1:%.*]] = sub i8 [[MULSHL]], [[Y_FR]]
265; CHECK-NEXT:    ret i8 [[M1]]
266;
267  %pow2x = shl i8 -1, %x
268  %x1 = xor i8 %pow2x, -1
269  %m = mul nuw i8 %x1, %y
270  ret i8 %m
271}
272
273define i8 @shl1_nsw_decrement(i8 %x, i8 %y) {
274; CHECK-LABEL: @shl1_nsw_decrement(
275; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i8 [[Y:%.*]]
276; CHECK-NEXT:    [[MULSHL:%.*]] = shl i8 [[Y_FR]], [[X:%.*]]
277; CHECK-NEXT:    [[M1:%.*]] = sub i8 [[MULSHL]], [[Y_FR]]
278; CHECK-NEXT:    ret i8 [[M1]]
279;
280  %pow2x = shl nsw i8 -1, %x
281  %x1 = xor i8 %pow2x, -1
282  %m = mul nsw i8 %x1, %y
283  ret i8 %m
284}
285
286; negative test - extra use would require more instructions
287
288define i32 @shl1_decrement_use(i32 %x, i32 %y) {
289; CHECK-LABEL: @shl1_decrement_use(
290; CHECK-NEXT:    [[NOTMASK:%.*]] = shl nsw i32 -1, [[X:%.*]]
291; CHECK-NEXT:    [[X1:%.*]] = xor i32 [[NOTMASK]], -1
292; CHECK-NEXT:    call void @use32(i32 [[X1]])
293; CHECK-NEXT:    [[M:%.*]] = mul i32 [[Y:%.*]], [[X1]]
294; CHECK-NEXT:    ret i32 [[M]]
295;
296  %pow2x = shl i32 1, %x
297  %x1 = add i32 %pow2x, -1
298  call void @use32(i32 %x1)
299  %m = mul i32 %x1, %y
300  ret i32 %m
301}
302
303; the fold works for vectors too and if 'y' is a constant, sub becomes add
304
305define <2 x i8> @shl1_decrement_vec(<2 x i8> %x) {
306; CHECK-LABEL: @shl1_decrement_vec(
307; CHECK-NEXT:    [[MULSHL:%.*]] = shl <2 x i8> <i8 42, i8 -3>, [[X:%.*]]
308; CHECK-NEXT:    [[M1:%.*]] = add <2 x i8> [[MULSHL]], <i8 -42, i8 3>
309; CHECK-NEXT:    ret <2 x i8> [[M1]]
310;
311  %pow2x = shl <2 x i8> <i8 -1, i8 -1>, %x
312  %x1 = xor <2 x i8> %pow2x, <i8 -1, i8 -1>
313  %m = mul <2 x i8> %x1, <i8 42, i8 -3>
314  ret <2 x i8> %m
315}
316
317; X * Y (when Y is a boolean) --> Y ? X : 0
318
319define i32 @mul_bool(i32 %x, i1 %y) {
320; CHECK-LABEL: @mul_bool(
321; CHECK-NEXT:    [[M:%.*]] = select i1 [[Y:%.*]], i32 [[X:%.*]], i32 0
322; CHECK-NEXT:    ret i32 [[M]]
323;
324  %z = zext i1 %y to i32
325  %m = mul i32 %z, %x
326  ret i32 %m
327}
328
329define <2 x i32> @mul_bool_vec(<2 x i32> %x, <2 x i1> %y) {
330; CHECK-LABEL: @mul_bool_vec(
331; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> [[X:%.*]], <2 x i32> zeroinitializer
332; CHECK-NEXT:    ret <2 x i32> [[M]]
333;
334  %z = zext <2 x i1> %y to <2 x i32>
335  %m = mul <2 x i32> %z, %x
336  ret <2 x i32> %m
337}
338
339define <2 x i32> @mul_bool_vec_commute(<2 x i32> %px, <2 x i1> %y) {
340; CHECK-LABEL: @mul_bool_vec_commute(
341; CHECK-NEXT:    [[X:%.*]] = mul <2 x i32> [[PX:%.*]], [[PX]]
342; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i32> [[X]], <2 x i32> zeroinitializer
343; CHECK-NEXT:    ret <2 x i32> [[M]]
344;
345  %x = mul <2 x i32> %px, %px  ; thwart complexity-based canonicalization
346  %z = zext <2 x i1> %y to <2 x i32>
347  %m = mul <2 x i32> %x, %z
348  ret <2 x i32> %m
349}
350
351; X * C (when X is a sext boolean) --> X ? -C : 0
352
353define i32 @mul_sext_bool(i1 %x) {
354; CHECK-LABEL: @mul_sext_bool(
355; CHECK-NEXT:    [[M:%.*]] = select i1 [[X:%.*]], i32 -42, i32 0
356; CHECK-NEXT:    ret i32 [[M]]
357;
358  %s = sext i1 %x to i32
359  %m = mul i32 %s, 42
360  ret i32 %m
361}
362
363define i32 @mul_sext_bool_use(i1 %x) {
364; CHECK-LABEL: @mul_sext_bool_use(
365; CHECK-NEXT:    [[S:%.*]] = sext i1 [[X:%.*]] to i32
366; CHECK-NEXT:    call void @use32(i32 [[S]])
367; CHECK-NEXT:    [[M:%.*]] = select i1 [[X]], i32 -42, i32 0
368; CHECK-NEXT:    ret i32 [[M]]
369;
370  %s = sext i1 %x to i32
371  call void @use32(i32 %s)
372  %m = mul i32 %s, 42
373  ret i32 %m
374}
375
376define <2 x i8> @mul_sext_bool_vec(<2 x i1> %x) {
377; CHECK-LABEL: @mul_sext_bool_vec(
378; CHECK-NEXT:    [[M:%.*]] = select <2 x i1> [[X:%.*]], <2 x i8> <i8 -42, i8 -128>, <2 x i8> zeroinitializer
379; CHECK-NEXT:    ret <2 x i8> [[M]]
380;
381  %s = sext <2 x i1> %x to <2 x i8>
382  %m = mul <2 x i8> %s, <i8 42, i8 -128>
383  ret <2 x i8> %m
384}
385
386define <3 x i7> @mul_bools(<3 x i1> %x, <3 x i1> %y) {
387; CHECK-LABEL: @mul_bools(
388; CHECK-NEXT:    [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]
389; CHECK-NEXT:    [[R:%.*]] = zext <3 x i1> [[MULBOOL]] to <3 x i7>
390; CHECK-NEXT:    ret <3 x i7> [[R]]
391;
392  %zx = zext <3 x i1> %x to <3 x i7>
393  %zy = zext <3 x i1> %y to <3 x i7>
394  %r = mul <3 x i7> %zx, %zy
395  ret <3 x i7> %r
396}
397
398define i32 @mul_bools_use1(i1 %x, i1 %y) {
399; CHECK-LABEL: @mul_bools_use1(
400; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
401; CHECK-NEXT:    call void @use32(i32 [[ZY]])
402; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]
403; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32
404; CHECK-NEXT:    ret i32 [[R]]
405;
406  %zx = zext i1 %x to i32
407  %zy = zext i1 %y to i32
408  call void @use32(i32 %zy)
409  %r = mul i32 %zx, %zy
410  ret i32 %r
411}
412
413define i32 @mul_bools_use2(i1 %x, i1 %y) {
414; CHECK-LABEL: @mul_bools_use2(
415; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
416; CHECK-NEXT:    call void @use32(i32 [[ZY]])
417; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]
418; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32
419; CHECK-NEXT:    ret i32 [[R]]
420;
421  %zx = zext i1 %x to i32
422  %zy = zext i1 %y to i32
423  call void @use32(i32 %zy)
424  %r = mul i32 %zy, %zx
425  ret i32 %r
426}
427
428define i32 @mul_bools_use3(i1 %x, i1 %y) {
429; CHECK-LABEL: @mul_bools_use3(
430; CHECK-NEXT:    [[ZX:%.*]] = zext i1 [[X:%.*]] to i32
431; CHECK-NEXT:    call void @use32(i32 [[ZX]])
432; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
433; CHECK-NEXT:    call void @use32(i32 [[ZY]])
434; CHECK-NEXT:    [[R:%.*]] = select i1 [[X]], i32 [[ZY]], i32 0
435; CHECK-NEXT:    ret i32 [[R]]
436;
437  %zx = zext i1 %x to i32
438  call void @use32(i32 %zx)
439  %zy = zext i1 %y to i32
440  call void @use32(i32 %zy)
441  %r = mul i32 %zx, %zy
442  ret i32 %r
443}
444
445define <3 x i32> @mul_bools_sext(<3 x i1> %x, <3 x i1> %y) {
446; CHECK-LABEL: @mul_bools_sext(
447; CHECK-NEXT:    [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]
448; CHECK-NEXT:    [[R:%.*]] = zext <3 x i1> [[MULBOOL]] to <3 x i32>
449; CHECK-NEXT:    ret <3 x i32> [[R]]
450;
451  %sx = sext <3 x i1> %x to <3 x i32>
452  %sy = sext <3 x i1> %y to <3 x i32>
453  %r = mul <3 x i32> %sx, %sy
454  ret <3 x i32> %r
455}
456
457define i32 @mul_bools_sext_use1(i1 %x, i1 %y) {
458; CHECK-LABEL: @mul_bools_sext_use1(
459; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
460; CHECK-NEXT:    call void @use32(i32 [[SY]])
461; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]
462; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32
463; CHECK-NEXT:    ret i32 [[R]]
464;
465  %sx = sext i1 %x to i32
466  %sy = sext i1 %y to i32
467  call void @use32(i32 %sy)
468  %r = mul i32 %sx, %sy
469  ret i32 %r
470}
471
472define i32 @mul_bools_sext_use2(i1 %x, i1 %y) {
473; CHECK-LABEL: @mul_bools_sext_use2(
474; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
475; CHECK-NEXT:    call void @use32(i32 [[SY]])
476; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]
477; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32
478; CHECK-NEXT:    ret i32 [[R]]
479;
480  %sx = sext i1 %x to i32
481  %sy = sext i1 %y to i32
482  call void @use32(i32 %sy)
483  %r = mul i32 %sy, %sx
484  ret i32 %r
485}
486
487define i32 @mul_bools_sext_use3(i1 %x, i1 %y) {
488; CHECK-LABEL: @mul_bools_sext_use3(
489; CHECK-NEXT:    [[SX:%.*]] = sext i1 [[X:%.*]] to i32
490; CHECK-NEXT:    call void @use32(i32 [[SX]])
491; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
492; CHECK-NEXT:    call void @use32(i32 [[SY]])
493; CHECK-NEXT:    [[R:%.*]] = mul nsw i32 [[SY]], [[SX]]
494; CHECK-NEXT:    ret i32 [[R]]
495;
496  %sx = sext i1 %x to i32
497  call void @use32(i32 %sx)
498  %sy = sext i1 %y to i32
499  call void @use32(i32 %sy)
500  %r = mul i32 %sy, %sx
501  ret i32 %r
502}
503
504define i32 @mul_bools_sext_one_use_per_op(i1 %x, i1 %y) {
505; CHECK-LABEL: @mul_bools_sext_one_use_per_op(
506; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]
507; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32
508; CHECK-NEXT:    ret i32 [[R]]
509;
510  %sx = sext i1 %x to i32
511  %sy = sext i1 %y to i32
512  %r = mul i32 %sx, %sy
513  ret i32 %r
514}
515
516define i32 @mul_bool_sext_one_user(i1 %x) {
517; CHECK-LABEL: @mul_bool_sext_one_user(
518; CHECK-NEXT:    [[R:%.*]] = zext i1 [[X:%.*]] to i32
519; CHECK-NEXT:    ret i32 [[R]]
520;
521  %sx = sext i1 %x to i32
522  %r = mul i32 %sx, %sx
523  ret i32 %r
524}
525
526define i32 @mul_bools_zext_one_use_per_op(i1 %x, i1 %y) {
527; CHECK-LABEL: @mul_bools_zext_one_use_per_op(
528; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y:%.*]]
529; CHECK-NEXT:    [[R:%.*]] = zext i1 [[MULBOOL]] to i32
530; CHECK-NEXT:    ret i32 [[R]]
531;
532  %zx = zext i1 %x to i32
533  %zy = zext i1 %y to i32
534  %r = mul i32 %zx, %zy
535  ret i32 %r
536}
537
538define i32 @mul_bool_zext_one_user(i1 %x) {
539; CHECK-LABEL: @mul_bool_zext_one_user(
540; CHECK-NEXT:    [[R:%.*]] = zext i1 [[X:%.*]] to i32
541; CHECK-NEXT:    ret i32 [[R]]
542;
543  %sx = zext i1 %x to i32
544  %r = mul i32 %sx, %sx
545  ret i32 %r
546}
547
548define i32 @mul_bool_sext_one_extra_user(i1 %x) {
549; CHECK-LABEL: @mul_bool_sext_one_extra_user(
550; CHECK-NEXT:    [[SX:%.*]] = sext i1 [[X:%.*]] to i32
551; CHECK-NEXT:    call void @use32(i32 [[SX]])
552; CHECK-NEXT:    [[R:%.*]] = zext i1 [[X]] to i32
553; CHECK-NEXT:    ret i32 [[R]]
554;
555  %sx = sext i1 %x to i32
556  call void @use32(i32 %sx)
557  %r = mul i32 %sx, %sx
558  ret i32 %r
559}
560
561define i32 @mul_bool_zext_one_extra_user(i1 %x) {
562; CHECK-LABEL: @mul_bool_zext_one_extra_user(
563; CHECK-NEXT:    [[SX:%.*]] = zext i1 [[X:%.*]] to i32
564; CHECK-NEXT:    call void @use32(i32 [[SX]])
565; CHECK-NEXT:    [[R:%.*]] = zext i1 [[X]] to i32
566; CHECK-NEXT:    ret i32 [[R]]
567;
568  %sx = zext i1 %x to i32
569  call void @use32(i32 %sx)
570  %r = mul i32 %sx, %sx
571  ret i32 %r
572}
573
574define <3 x i32> @mul_bools_mixed_ext(<3 x i1> %x, <3 x i1> %y) {
575; CHECK-LABEL: @mul_bools_mixed_ext(
576; CHECK-NEXT:    [[MULBOOL:%.*]] = and <3 x i1> [[X:%.*]], [[Y:%.*]]
577; CHECK-NEXT:    [[R:%.*]] = sext <3 x i1> [[MULBOOL]] to <3 x i32>
578; CHECK-NEXT:    ret <3 x i32> [[R]]
579;
580  %zx = zext <3 x i1> %x to <3 x i32>
581  %sy = sext <3 x i1> %y to <3 x i32>
582  %r = mul <3 x i32> %zx, %sy
583  ret <3 x i32> %r
584}
585
586define i32 @mul_bools_mixed_ext_use1(i1 %x, i1 %y) {
587; CHECK-LABEL: @mul_bools_mixed_ext_use1(
588; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
589; CHECK-NEXT:    call void @use32(i32 [[ZY]])
590; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[X:%.*]], [[Y]]
591; CHECK-NEXT:    [[R:%.*]] = sext i1 [[MULBOOL]] to i32
592; CHECK-NEXT:    ret i32 [[R]]
593;
594  %sx = sext i1 %x to i32
595  %zy = zext i1 %y to i32
596  call void @use32(i32 %zy)
597  %r = mul i32 %sx, %zy
598  ret i32 %r
599}
600
601define i32 @mul_bools_mixed_ext_use2(i1 %x, i1 %y) {
602; CHECK-LABEL: @mul_bools_mixed_ext_use2(
603; CHECK-NEXT:    [[SY:%.*]] = sext i1 [[Y:%.*]] to i32
604; CHECK-NEXT:    call void @use32(i32 [[SY]])
605; CHECK-NEXT:    [[MULBOOL:%.*]] = and i1 [[Y]], [[X:%.*]]
606; CHECK-NEXT:    [[R:%.*]] = sext i1 [[MULBOOL]] to i32
607; CHECK-NEXT:    ret i32 [[R]]
608;
609  %zx = zext i1 %x to i32
610  %sy = sext i1 %y to i32
611  call void @use32(i32 %sy)
612  %r = mul i32 %sy, %zx
613  ret i32 %r
614}
615
616define i32 @mul_bools_mixed_ext_use3(i1 %x, i1 %y) {
617; CHECK-LABEL: @mul_bools_mixed_ext_use3(
618; CHECK-NEXT:    [[SX:%.*]] = sext i1 [[X:%.*]] to i32
619; CHECK-NEXT:    call void @use32(i32 [[SX]])
620; CHECK-NEXT:    [[ZY:%.*]] = zext i1 [[Y:%.*]] to i32
621; CHECK-NEXT:    call void @use32(i32 [[ZY]])
622; CHECK-NEXT:    [[R:%.*]] = select i1 [[Y]], i32 [[SX]], i32 0
623; CHECK-NEXT:    ret i32 [[R]]
624;
625  %sx = sext i1 %x to i32
626  call void @use32(i32 %sx)
627  %zy = zext i1 %y to i32
628  call void @use32(i32 %zy)
629  %r = mul i32 %zy, %sx
630  ret i32 %r
631}
632
633; (A >>u 31) * B --> (A >>s 31) & B --> A < 0 ? B : 0
634
635define i32 @signbit_mul(i32 %a, i32 %b) {
636; CHECK-LABEL: @signbit_mul(
637; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A:%.*]], 0
638; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
639; CHECK-NEXT:    ret i32 [[E]]
640;
641  %d = lshr i32 %a, 31
642  %e = mul i32 %d, %b
643  ret i32 %e
644}
645
646define i32 @signbit_mul_commute_extra_use(i32 %a, i32 %b) {
647; CHECK-LABEL: @signbit_mul_commute_extra_use(
648; CHECK-NEXT:    [[D:%.*]] = lshr i32 [[A:%.*]], 31
649; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[A]], 0
650; CHECK-NEXT:    [[E:%.*]] = select i1 [[ISNEG]], i32 [[B:%.*]], i32 0
651; CHECK-NEXT:    call void @use32(i32 [[D]])
652; CHECK-NEXT:    ret i32 [[E]]
653;
654  %d = lshr i32 %a, 31
655  %e = mul i32 %b, %d
656  call void @use32(i32 %d)
657  ret i32 %e
658}
659
660; (A >>u 31)) * B --> (A >>s 31) & B --> A < 0 ? B : 0
661
662define <2 x i32> @signbit_mul_vec(<2 x i32> %a, <2 x i32> %b) {
663; CHECK-LABEL: @signbit_mul_vec(
664; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <2 x i32> [[A:%.*]], zeroinitializer
665; CHECK-NEXT:    [[E:%.*]] = select <2 x i1> [[ISNEG]], <2 x i32> [[B:%.*]], <2 x i32> zeroinitializer
666; CHECK-NEXT:    ret <2 x i32> [[E]]
667;
668  %d = lshr <2 x i32> %a, <i32 31, i32 31>
669  %e = mul <2 x i32> %d, %b
670  ret <2 x i32> %e
671}
672
673define <2 x i32> @signbit_mul_vec_commute(<2 x i32> %a, <2 x i32> %b) {
674; CHECK-LABEL: @signbit_mul_vec_commute(
675; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <2 x i32> [[A:%.*]], zeroinitializer
676; CHECK-NEXT:    [[E:%.*]] = select <2 x i1> [[ISNEG]], <2 x i32> [[B:%.*]], <2 x i32> zeroinitializer
677; CHECK-NEXT:    ret <2 x i32> [[E]]
678;
679  %d = lshr <2 x i32> %a, <i32 31, i32 31>
680  %e = mul <2 x i32> %b, %d
681  ret <2 x i32> %e
682}
683
684; (A & 1) * B --> (lowbit A) ? B : 0
685
686define i32 @lowbit_mul(i32 %a, i32 %b) {
687; CHECK-LABEL: @lowbit_mul(
688; CHECK-NEXT:    [[TMP1:%.*]] = trunc i32 [[A:%.*]] to i1
689; CHECK-NEXT:    [[E:%.*]] = select i1 [[TMP1]], i32 [[B:%.*]], i32 0
690; CHECK-NEXT:    ret i32 [[E]]
691;
692  %d = and i32 %a, 1
693  %e = mul i32 %d, %b
694  ret i32 %e
695}
696
697; (A & 1) * B --> (lowbit A) ? B : 0
698
699define <2 x i17> @lowbit_mul_commute(<2 x i17> %a, <2 x i17> %p) {
700; CHECK-LABEL: @lowbit_mul_commute(
701; CHECK-NEXT:    [[B:%.*]] = xor <2 x i17> [[P:%.*]], <i17 42, i17 43>
702; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i17> [[A:%.*]] to <2 x i1>
703; CHECK-NEXT:    [[E:%.*]] = select <2 x i1> [[TMP1]], <2 x i17> [[B]], <2 x i17> zeroinitializer
704; CHECK-NEXT:    ret <2 x i17> [[E]]
705;
706  %b = xor <2 x i17> %p, <i17 42, i17 43> ; thwart complexity-based canonicalization
707  %d = and <2 x i17> %a, <i17 1, i17 1>
708  %e = mul <2 x i17> %b, %d
709  ret <2 x i17> %e
710}
711
712; negative test - extra use
713
714define i32 @lowbit_mul_use(i32 %a, i32 %b) {
715; CHECK-LABEL: @lowbit_mul_use(
716; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], 1
717; CHECK-NEXT:    call void @use32(i32 [[D]])
718; CHECK-NEXT:    [[E:%.*]] = mul nuw i32 [[D]], [[B:%.*]]
719; CHECK-NEXT:    ret i32 [[E]]
720;
721  %d = and i32 %a, 1
722  call void @use32(i32 %d)
723  %e = mul i32 %d, %b
724  ret i32 %e
725}
726
727; negative test - wrong mask
728
729define i32 @not_lowbit_mul(i32 %a, i32 %b) {
730; CHECK-LABEL: @not_lowbit_mul(
731; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], 2
732; CHECK-NEXT:    [[E:%.*]] = mul i32 [[D]], [[B:%.*]]
733; CHECK-NEXT:    ret i32 [[E]]
734;
735  %d = and i32 %a, 2
736  %e = mul i32 %d, %b
737  ret i32 %e
738}
739
740define i32 @signsplat_mul(i32 %x) {
741; CHECK-LABEL: @signsplat_mul(
742; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt i32 [[X:%.*]], 0
743; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[ISNEG]], i32 -42, i32 0
744; CHECK-NEXT:    ret i32 [[MUL]]
745;
746  %ash = ashr i32 %x, 31
747  %mul = mul i32 %ash, 42
748  ret i32 %mul
749}
750
751define <2 x i32> @signsplat_mul_vec(<2 x i32> %x) {
752; CHECK-LABEL: @signsplat_mul_vec(
753; CHECK-NEXT:    [[ISNEG:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer
754; CHECK-NEXT:    [[MUL:%.*]] = select <2 x i1> [[ISNEG]], <2 x i32> <i32 -42, i32 3>, <2 x i32> zeroinitializer
755; CHECK-NEXT:    ret <2 x i32> [[MUL]]
756;
757  %ash = ashr <2 x i32> %x, <i32 31, i32 31>
758  %mul = mul <2 x i32> %ash, <i32 42, i32 -3>
759  ret <2 x i32> %mul
760}
761
762; negative test - wrong shift amount
763
764define i32 @not_signsplat_mul(i32 %x) {
765; CHECK-LABEL: @not_signsplat_mul(
766; CHECK-NEXT:    [[ASH:%.*]] = ashr i32 [[X:%.*]], 30
767; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ASH]], 42
768; CHECK-NEXT:    ret i32 [[MUL]]
769;
770  %ash = ashr i32 %x, 30
771  %mul = mul i32 %ash, 42
772  ret i32 %mul
773}
774
775; negative test - extra use
776
777define i32 @signsplat_mul_use(i32 %x) {
778; CHECK-LABEL: @signsplat_mul_use(
779; CHECK-NEXT:    [[ASH:%.*]] = ashr i32 [[X:%.*]], 31
780; CHECK-NEXT:    call void @use32(i32 [[ASH]])
781; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ASH]], -42
782; CHECK-NEXT:    ret i32 [[MUL]]
783;
784  %ash = ashr i32 %x, 31
785  call void @use32(i32 %ash)
786  %mul = mul i32 %ash, -42
787  ret i32 %mul
788}
789
790define i32 @test18(i32 %A, i32 %B) {
791; CHECK-LABEL: @test18(
792; CHECK-NEXT:    ret i32 0
793;
794  %C = and i32 %A, 1
795  %D = and i32 %B, 1
796  %E = mul i32 %C, %D
797  %F = and i32 %E, 16
798  ret i32 %F
799}
800
801declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
802declare void @use(i1)
803
804define i32 @test19(i32 %A, i32 %B) {
805; CHECK-LABEL: @test19(
806; CHECK-NEXT:    call void @use(i1 false)
807; CHECK-NEXT:    ret i32 0
808;
809  %C = and i32 %A, 1
810  %D = and i32 %B, 1
811
812; It would be nice if we also started proving that this doesn't overflow.
813  %E = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %C, i32 %D)
814  %F = extractvalue {i32, i1} %E, 0
815  %G = extractvalue {i32, i1} %E, 1
816  call void @use(i1 %G)
817  %H = and i32 %F, 16
818  ret i32 %H
819}
820
821define <2 x i64> @test20(<2 x i64> %A) {
822; CHECK-LABEL: @test20(
823; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i64> [[A:%.*]], <i64 3, i64 2>
824; CHECK-NEXT:    [[C:%.*]] = add <2 x i64> [[TMP1]], <i64 36, i64 28>
825; CHECK-NEXT:    ret <2 x i64> [[C]]
826;
827  %B = add <2 x i64> %A, <i64 12, i64 14>
828  %C = mul <2 x i64> %B, <i64 3, i64 2>
829  ret <2 x i64> %C
830}
831
832@g = internal global i32 0, align 4
833
834define i32 @PR20079(i32 %a) {
835; CHECK-LABEL: @PR20079(
836; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A:%.*]], -1
837; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ADD]], ptrtoint (ptr @g to i32)
838; CHECK-NEXT:    ret i32 [[MUL]]
839;
840  %add = add i32 %a, -1
841  %mul = mul nsw i32 %add, ptrtoint (ptr @g to i32)
842  ret i32 %mul
843}
844
845; Keep nuw flag in this change, https://alive2.llvm.org/ce/z/-Wowpk
846define i32 @add_mul_nuw(i32 %a) {
847; CHECK-LABEL: @add_mul_nuw(
848; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw i32 [[A:%.*]], 3
849; CHECK-NEXT:    [[MUL:%.*]] = add nuw i32 [[TMP1]], 9
850; CHECK-NEXT:    ret i32 [[MUL]]
851;
852  %add = add nuw i32 %a, 3
853  %mul = mul nuw i32 %add, 3
854  ret i32 %mul
855}
856
857; Don't propagate nsw flag in this change
858define i32 @add_mul_nsw(i32 %a) {
859; CHECK-LABEL: @add_mul_nsw(
860; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3
861; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9
862; CHECK-NEXT:    ret i32 [[MUL]]
863;
864  %add = add nsw i32 %a, 3
865  %mul = mul nsw i32 %add, 3
866  ret i32 %mul
867}
868
869; Only the add or only the mul has nuw, https://alive2.llvm.org/ce/z/vPwbEa
870define i32 @only_add_nuw(i32 %a) {
871; CHECK-LABEL: @only_add_nuw(
872; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3
873; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9
874; CHECK-NEXT:    ret i32 [[MUL]]
875;
876  %add = add nuw i32 %a, 3
877  %mul = mul i32 %add, 3
878  ret i32 %mul
879}
880
881define i32 @only_mul_nuw(i32 %a) {
882; CHECK-LABEL: @only_mul_nuw(
883; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3
884; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9
885; CHECK-NEXT:    ret i32 [[MUL]]
886;
887  %add = add i32 %a, 3
888  %mul = mul nuw i32 %add, 3
889  ret i32 %mul
890}
891
892; Don't propagate nsw flag in this change, https://alive2.llvm.org/ce/z/jJ8rZd
893define i32 @PR57278_shl(i32 %a) {
894; CHECK-LABEL: @PR57278_shl(
895; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 12
896; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9
897; CHECK-NEXT:    ret i32 [[MUL]]
898;
899  %shl = shl nsw i32 %a, 2
900  %add = or i32 %shl, 3
901  %mul = mul nsw i32 %add, 3
902  ret i32 %mul
903}
904
905; Negative test: Have common bits set
906define i32 @PR57278_shl_1(i32 %a) {
907; CHECK-LABEL: @PR57278_shl_1(
908; CHECK-NEXT:    [[SHL:%.*]] = shl nsw i32 [[A:%.*]], 2
909; CHECK-NEXT:    [[ADD:%.*]] = or i32 [[SHL]], 4
910; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ADD]], 3
911; CHECK-NEXT:    ret i32 [[MUL]]
912;
913  %shl = shl nsw i32 %a, 2
914  %add = or i32 %shl, 4
915  %mul = mul nsw i32 %add, 3
916  ret i32 %mul
917}
918
919; Keep nuw flag in this change, https://alive2.llvm.org/ce/z/awsQrx
920define i32 @PR57278_mul(i32 %a) {
921; CHECK-LABEL: @PR57278_mul(
922; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw i32 [[A:%.*]], 36
923; CHECK-NEXT:    [[MUL:%.*]] = add nuw i32 [[TMP1]], 9
924; CHECK-NEXT:    ret i32 [[MUL]]
925;
926  %mul0 = mul nuw i32 %a, 12
927  %add = or i32 %mul0, 3
928  %mul = mul nuw i32 %add, 3
929  ret i32 %mul
930}
931
932; Negative test: Have common bits set, https://alive2.llvm.org/ce/z/bHZRh5
933define i32 @PR57278_mul_1(i32 %a) {
934; CHECK-LABEL: @PR57278_mul_1(
935; CHECK-NEXT:    [[MUL0:%.*]] = mul nuw i32 [[A:%.*]], 12
936; CHECK-NEXT:    [[ADD:%.*]] = or i32 [[MUL0]], 4
937; CHECK-NEXT:    [[MUL:%.*]] = mul nuw i32 [[ADD]], 3
938; CHECK-NEXT:    ret i32 [[MUL]]
939;
940  %mul0 = mul nuw i32 %a, 12
941  %add = or i32 %mul0, 4
942  %mul = mul nuw i32 %add, 3
943  ret i32 %mul
944}
945
946; Test the haveNoCommonBitsSet with assume, https://alive2.llvm.org/ce/z/AXKBjK
947define i32 @PR57278_mul_assume(i32 %a) {
948; CHECK-LABEL: @PR57278_mul_assume(
949; CHECK-NEXT:    [[COMBITS:%.*]] = and i32 [[A:%.*]], 3
950; CHECK-NEXT:    [[NOCOMBITS:%.*]] = icmp eq i32 [[COMBITS]], 0
951; CHECK-NEXT:    call void @llvm.assume(i1 [[NOCOMBITS]])
952; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A]], 5
953; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 15
954; CHECK-NEXT:    ret i32 [[MUL]]
955;
956  %combits = and i32 %a , 3
957  %nocombits = icmp eq i32 %combits, 0
958  call void @llvm.assume(i1 %nocombits)
959
960  %add = or i32 %a, 3
961  %mul = mul i32 %add, 5
962  ret i32 %mul
963}
964
965declare void @llvm.assume(i1)
966
967define i32 @PR57278_or_disjoint_nuw(i32 %a) {
968; CHECK-LABEL: @PR57278_or_disjoint_nuw(
969; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw i32 [[A:%.*]], 3
970; CHECK-NEXT:    [[MUL:%.*]] = add nuw i32 [[TMP1]], 9
971; CHECK-NEXT:    ret i32 [[MUL]]
972;
973  %add = or disjoint i32 %a, 3
974  %mul = mul nuw i32 %add, 3
975  ret i32 %mul
976}
977
978define i32 @PR57278_or_disjoint_nsw(i32 %a) {
979; CHECK-LABEL: @PR57278_or_disjoint_nsw(
980; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 3
981; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[TMP1]], 9
982; CHECK-NEXT:    ret i32 [[MUL]]
983;
984  %add = or disjoint i32 %a, 3
985  %mul = mul nsw i32 %add, 3
986  ret i32 %mul
987}
988
989; https://alive2.llvm.org/ce/z/XYpv9q
990define <2 x i32> @PR57278_shl_vec(<2 x i32> %v1) {
991; CHECK-LABEL: @PR57278_shl_vec(
992; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw <2 x i32> [[V1:%.*]], <i32 12, i32 24>
993; CHECK-NEXT:    [[MUL:%.*]] = add nuw <2 x i32> [[TMP1]], splat (i32 9)
994; CHECK-NEXT:    ret <2 x i32> [[MUL]]
995;
996  %shl = shl nuw <2 x i32> %v1, <i32 2, i32 3>
997  %add = or <2 x i32> %shl, <i32 3, i32 3>
998  %mul = mul nuw <2 x i32> %add, <i32 3, i32 3>
999  ret <2 x i32> %mul
1000}
1001
1002; TODO: vector with poison should also be supported, https://alive2.llvm.org/ce/z/XYpv9q
1003define <2 x i32> @PR57278_shl_vec_poison(<2 x i32> %v1) {
1004; CHECK-LABEL: @PR57278_shl_vec_poison(
1005; CHECK-NEXT:    [[SHL:%.*]] = shl nuw <2 x i32> [[V1:%.*]], <i32 2, i32 poison>
1006; CHECK-NEXT:    [[TMP1:%.*]] = mul nuw <2 x i32> [[SHL]], <i32 3, i32 poison>
1007; CHECK-NEXT:    [[MUL:%.*]] = add nuw <2 x i32> [[TMP1]], <i32 9, i32 poison>
1008; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1009;
1010  %shl = shl nuw <2 x i32> %v1, <i32 2, i32 poison>
1011  %add = or <2 x i32> %shl, <i32 3, i32 poison>
1012  %mul = mul nuw <2 x i32> %add, <i32 3, i32 poison>
1013  ret <2 x i32> %mul
1014}
1015
1016define <2 x i1> @test21(<2 x i1> %A, <2 x i1> %B) {
1017; CHECK-LABEL: @test21(
1018; CHECK-NEXT:    [[C:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]
1019; CHECK-NEXT:    ret <2 x i1> [[C]]
1020;
1021  %C = mul <2 x i1> %A, %B
1022  ret <2 x i1> %C
1023}
1024
1025define i32 @test22(i32 %A) {
1026; CHECK-LABEL: @test22(
1027; CHECK-NEXT:    [[B:%.*]] = sub nsw i32 0, [[A:%.*]]
1028; CHECK-NEXT:    ret i32 [[B]]
1029;
1030  %B = mul nsw i32 %A, -1
1031  ret i32 %B
1032}
1033
1034define i32 @test23(i32 %A) {
1035; CHECK-LABEL: @test23(
1036; CHECK-NEXT:    [[C:%.*]] = mul nuw i32 [[A:%.*]], 6
1037; CHECK-NEXT:    ret i32 [[C]]
1038;
1039  %B = shl nuw i32 %A, 1
1040  %C = mul nuw i32 %B, 3
1041  ret i32 %C
1042}
1043
1044define i32 @test24(i32 %A) {
1045; CHECK-LABEL: @test24(
1046; CHECK-NEXT:    [[C:%.*]] = mul nsw i32 [[A:%.*]], 6
1047; CHECK-NEXT:    ret i32 [[C]]
1048;
1049  %B = shl nsw i32 %A, 1
1050  %C = mul nsw i32 %B, 3
1051  ret i32 %C
1052}
1053
1054define i32 @neg_neg_mul(i32 %A, i32 %B) {
1055; CHECK-LABEL: @neg_neg_mul(
1056; CHECK-NEXT:    [[E:%.*]] = mul i32 [[A:%.*]], [[B:%.*]]
1057; CHECK-NEXT:    ret i32 [[E]]
1058;
1059  %C = sub i32 0, %A
1060  %D = sub i32 0, %B
1061  %E = mul i32 %C, %D
1062  ret i32 %E
1063}
1064
1065define i32 @neg_neg_mul_nsw(i32 %A, i32 %B) {
1066; CHECK-LABEL: @neg_neg_mul_nsw(
1067; CHECK-NEXT:    [[E:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
1068; CHECK-NEXT:    ret i32 [[E]]
1069;
1070  %C = sub nsw i32 0, %A
1071  %D = sub nsw i32 0, %B
1072  %E = mul nsw i32 %C, %D
1073  ret i32 %E
1074}
1075
1076define i124 @neg_neg_mul_apint(i124 %A, i124 %B) {
1077; CHECK-LABEL: @neg_neg_mul_apint(
1078; CHECK-NEXT:    [[E:%.*]] = mul i124 [[A:%.*]], [[B:%.*]]
1079; CHECK-NEXT:    ret i124 [[E]]
1080;
1081  %C = sub i124 0, %A
1082  %D = sub i124 0, %B
1083  %E = mul i124 %C, %D
1084  ret i124 %E
1085}
1086
1087define i32 @neg_mul_constant(i32 %A) {
1088; CHECK-LABEL: @neg_mul_constant(
1089; CHECK-NEXT:    [[E:%.*]] = mul i32 [[A:%.*]], -7
1090; CHECK-NEXT:    ret i32 [[E]]
1091;
1092  %C = sub i32 0, %A
1093  %E = mul i32 %C, 7
1094  ret i32 %E
1095}
1096
1097define i55 @neg_mul_constant_apint(i55 %A) {
1098; CHECK-LABEL: @neg_mul_constant_apint(
1099; CHECK-NEXT:    [[E:%.*]] = mul i55 [[A:%.*]], -7
1100; CHECK-NEXT:    ret i55 [[E]]
1101;
1102  %C = sub i55 0, %A
1103  %E = mul i55 %C, 7
1104  ret i55 %E
1105}
1106
1107define <3 x i8> @neg_mul_constant_vec(<3 x i8> %a) {
1108; CHECK-LABEL: @neg_mul_constant_vec(
1109; CHECK-NEXT:    [[B:%.*]] = mul <3 x i8> [[A:%.*]], splat (i8 -5)
1110; CHECK-NEXT:    ret <3 x i8> [[B]]
1111;
1112  %A = sub <3 x i8> zeroinitializer, %a
1113  %B = mul <3 x i8> %A, <i8 5, i8 5, i8 5>
1114  ret <3 x i8> %B
1115}
1116
1117define <3 x i4> @neg_mul_constant_vec_weird(<3 x i4> %a) {
1118; CHECK-LABEL: @neg_mul_constant_vec_weird(
1119; CHECK-NEXT:    [[B:%.*]] = mul <3 x i4> [[A:%.*]], splat (i4 -5)
1120; CHECK-NEXT:    ret <3 x i4> [[B]]
1121;
1122  %A = sub <3 x i4> zeroinitializer, %a
1123  %B = mul <3 x i4> %A, <i4 5, i4 5, i4 5>
1124  ret <3 x i4> %B
1125}
1126
1127define i64 @test29(i31 %A, i31 %B) {
1128; CHECK-LABEL: @test29(
1129; CHECK-NEXT:    [[C:%.*]] = sext i31 [[A:%.*]] to i64
1130; CHECK-NEXT:    [[D:%.*]] = sext i31 [[B:%.*]] to i64
1131; CHECK-NEXT:    [[E:%.*]] = mul nsw i64 [[C]], [[D]]
1132; CHECK-NEXT:    ret i64 [[E]]
1133;
1134  %C = sext i31 %A to i64
1135  %D = sext i31 %B to i64
1136  %E = mul i64 %C, %D
1137  ret i64 %E
1138}
1139
1140define i64 @test30(i32 %A, i32 %B) {
1141; CHECK-LABEL: @test30(
1142; CHECK-NEXT:    [[C:%.*]] = zext i32 [[A:%.*]] to i64
1143; CHECK-NEXT:    [[D:%.*]] = zext i32 [[B:%.*]] to i64
1144; CHECK-NEXT:    [[E:%.*]] = mul nuw i64 [[C]], [[D]]
1145; CHECK-NEXT:    ret i64 [[E]]
1146;
1147  %C = zext i32 %A to i64
1148  %D = zext i32 %B to i64
1149  %E = mul i64 %C, %D
1150  ret i64 %E
1151}
1152
1153@PR22087 = external global i32
1154define i32 @test31(i32 %V) {
1155; CHECK-LABEL: @test31(
1156; CHECK-NEXT:    [[CMP:%.*]] = icmp ne ptr inttoptr (i64 4 to ptr), @PR22087
1157; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[CMP]] to i32
1158; CHECK-NEXT:    [[MUL1:%.*]] = shl i32 [[V:%.*]], [[EXT]]
1159; CHECK-NEXT:    ret i32 [[MUL1]]
1160;
1161  %cmp = icmp ne ptr inttoptr (i64 4 to ptr), @PR22087
1162  %ext = zext i1 %cmp to i32
1163  %shl = shl i32 1, %ext
1164  %mul = mul i32 %V, %shl
1165  ret i32 %mul
1166}
1167
1168define i32 @test32(i32 %X) {
1169; CHECK-LABEL: @test32(
1170; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X:%.*]], 31
1171; CHECK-NEXT:    ret i32 [[MUL]]
1172;
1173  %mul = mul nsw i32 %X, -2147483648
1174  ret i32 %mul
1175}
1176
1177define <2 x i32> @test32vec(<2 x i32> %X) {
1178; CHECK-LABEL: @test32vec(
1179; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[X:%.*]], splat (i32 31)
1180; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1181;
1182  %mul = mul nsw <2 x i32> %X, <i32 -2147483648, i32 -2147483648>
1183  ret <2 x i32> %mul
1184}
1185
1186define i32 @test33(i32 %X) {
1187; CHECK-LABEL: @test33(
1188; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i32 [[X:%.*]], 30
1189; CHECK-NEXT:    ret i32 [[MUL]]
1190;
1191  %mul = mul nsw i32 %X, 1073741824
1192  ret i32 %mul
1193}
1194
1195define <2 x i32> @test33vec(<2 x i32> %X) {
1196; CHECK-LABEL: @test33vec(
1197; CHECK-NEXT:    [[MUL:%.*]] = shl nsw <2 x i32> [[X:%.*]], splat (i32 30)
1198; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1199;
1200  %mul = mul nsw <2 x i32> %X, <i32 1073741824, i32 1073741824>
1201  ret <2 x i32> %mul
1202}
1203
1204define i128 @test34(i128 %X) {
1205; CHECK-LABEL: @test34(
1206; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i128 [[X:%.*]], 1
1207; CHECK-NEXT:    ret i128 [[MUL]]
1208;
1209  %mul = mul nsw i128 %X, 2
1210  ret i128 %mul
1211}
1212
1213define i32 @test_mul_canonicalize_op0(i32 %x, i32 %y) {
1214; CHECK-LABEL: @test_mul_canonicalize_op0(
1215; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1216; CHECK-NEXT:    [[MUL:%.*]] = sub i32 0, [[TMP1]]
1217; CHECK-NEXT:    ret i32 [[MUL]]
1218;
1219  %neg = sub i32 0, %x
1220  %mul = mul i32 %neg, %y
1221  ret i32 %mul
1222}
1223
1224define i32 @test_mul_canonicalize_op1(i32 %x, i32 %z) {
1225; CHECK-LABEL: @test_mul_canonicalize_op1(
1226; CHECK-NEXT:    [[Y_NEG:%.*]] = mul i32 [[Z:%.*]], -3
1227; CHECK-NEXT:    [[DOTNEG:%.*]] = mul i32 [[Y_NEG]], [[X:%.*]]
1228; CHECK-NEXT:    ret i32 [[DOTNEG]]
1229;
1230  %y = mul i32 %z, 3
1231  %neg = sub i32 0, %x
1232  %mul = mul i32 %y, %neg
1233  ret i32 %mul
1234}
1235
1236define i32 @test_mul_canonicalize_nsw(i32 %x, i32 %y) {
1237; CHECK-LABEL: @test_mul_canonicalize_nsw(
1238; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1239; CHECK-NEXT:    [[MUL:%.*]] = sub i32 0, [[TMP1]]
1240; CHECK-NEXT:    ret i32 [[MUL]]
1241;
1242  %neg = sub nsw i32 0, %x
1243  %mul = mul nsw i32 %neg, %y
1244  ret i32 %mul
1245}
1246
1247define <2 x i32> @test_mul_canonicalize_vec(<2 x i32> %x, <2 x i32> %y) {
1248; CHECK-LABEL: @test_mul_canonicalize_vec(
1249; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i32> [[X:%.*]], [[Y:%.*]]
1250; CHECK-NEXT:    [[MUL:%.*]] = sub <2 x i32> zeroinitializer, [[TMP1]]
1251; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1252;
1253  %neg = sub <2 x i32> <i32 0, i32 0>, %x
1254  %mul = mul <2 x i32> %neg, %y
1255  ret <2 x i32> %mul
1256}
1257
1258define i32 @test_mul_canonicalize_multiple_uses(i32 %x, i32 %y) {
1259; CHECK-LABEL: @test_mul_canonicalize_multiple_uses(
1260; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1261; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1262; CHECK-NEXT:    ret i32 [[MUL2]]
1263;
1264  %neg = sub i32 0, %x
1265  %mul = mul i32 %neg, %y
1266  %mul2 = mul i32 %mul, %neg
1267  ret i32 %mul2
1268}
1269
1270define i32 @mul_nsw_mul_nsw_neg(i32 %x, i32 %y) {
1271; CHECK-LABEL: @mul_nsw_mul_nsw_neg(
1272; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1273; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1274; CHECK-NEXT:    ret i32 [[MUL2]]
1275;
1276  %neg = sub i32 0, %x
1277  %mul = mul nsw i32 %neg, %y
1278  %mul2 = mul nsw i32 %mul, %neg
1279  ret i32 %mul2
1280}
1281
1282define i32 @mul_mul_nsw_neg(i32 %x,i32 %y) {
1283; CHECK-LABEL: @mul_mul_nsw_neg(
1284; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1285; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1286; CHECK-NEXT:    ret i32 [[MUL2]]
1287;
1288  %neg = sub i32 0, %x
1289  %mul = mul nsw i32 %neg, %y
1290  %mul2 = mul i32 %mul, %neg
1291  ret i32 %mul2
1292}
1293
1294define i32 @mul_nsw_mul_neg(i32 %x,i32 %y) {
1295; CHECK-LABEL: @mul_nsw_mul_neg(
1296; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
1297; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1298; CHECK-NEXT:    ret i32 [[MUL2]]
1299;
1300  %neg = sub i32 0, %x
1301  %mul = mul i32 %neg, %y
1302  %mul2 = mul nsw i32 %mul, %neg
1303  ret i32 %mul2
1304}
1305
1306define i32 @mul_nsw_mul_neg_onearg(i32 %x) {
1307; CHECK-LABEL: @mul_nsw_mul_neg_onearg(
1308; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]
1309; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1310; CHECK-NEXT:    ret i32 [[MUL2]]
1311;
1312  %neg = sub i32 0, %x
1313  %mul = mul i32 %neg, %x
1314  %mul2 = mul nsw i32 %mul, %neg
1315  ret i32 %mul2
1316}
1317
1318define i8 @mul_mul_nsw_neg_onearg(i8 %x) {
1319; CHECK-LABEL: @mul_mul_nsw_neg_onearg(
1320; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i8 [[X:%.*]], [[X]]
1321; CHECK-NEXT:    [[MUL2:%.*]] = mul i8 [[MUL_NEG]], [[X]]
1322; CHECK-NEXT:    ret i8 [[MUL2]]
1323;
1324  %neg = sub i8 0, %x
1325  %mul = mul nsw i8 %neg, %x
1326  %mul2 = mul i8 %mul, %neg
1327  ret i8 %mul2
1328}
1329
1330define i32 @mul_nsw_mul_nsw_neg_onearg(i32 %x) {
1331; CHECK-LABEL: @mul_nsw_mul_nsw_neg_onearg(
1332; CHECK-NEXT:    [[MUL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]
1333; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL_NEG]], [[X]]
1334; CHECK-NEXT:    ret i32 [[MUL2]]
1335;
1336  %neg = sub i32 0, %x
1337  %mul = mul nsw i32 %neg, %x
1338  %mul2 = mul nsw i32 %mul, %neg
1339  ret i32 %mul2
1340}
1341
1342define i32 @mul_nsw_shl_nsw_neg(i32 %x, i32 %y) {
1343; CHECK-LABEL: @mul_nsw_shl_nsw_neg(
1344; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
1345; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1346; CHECK-NEXT:    ret i32 [[MUL]]
1347;
1348  %neg = sub i32 0, %x
1349  %shl = shl nsw i32 %neg, %y
1350  %mul = mul nsw i32 %shl, %neg
1351  ret i32 %mul
1352}
1353
1354define i32 @mul_shl_nsw_neg(i32 %x,i32 %y) {
1355; CHECK-LABEL: @mul_shl_nsw_neg(
1356; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
1357; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1358; CHECK-NEXT:    ret i32 [[MUL]]
1359;
1360  %neg = sub i32 0, %x
1361  %shl = shl nsw i32 %neg, %y
1362  %mul = mul i32 %shl, %neg
1363  ret i32 %mul
1364}
1365
1366define i32 @mul_nsw_shl_neg(i32 %x,i32 %y) {
1367; CHECK-LABEL: @mul_nsw_shl_neg(
1368; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[Y:%.*]]
1369; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1370; CHECK-NEXT:    ret i32 [[MUL]]
1371;
1372  %neg = sub i32 0, %x
1373  %shl = shl i32 %neg, %y
1374  %mul = mul nsw i32 %shl, %neg
1375  ret i32 %mul
1376}
1377
1378define i32 @mul_nsw_shl_neg_onearg(i32 %x) {
1379; CHECK-LABEL: @mul_nsw_shl_neg_onearg(
1380; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i32 [[X:%.*]], [[X]]
1381; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1382; CHECK-NEXT:    ret i32 [[MUL]]
1383;
1384  %neg = sub i32 0, %x
1385  %shl = shl i32 %neg, %x
1386  %mul = mul nsw i32 %shl, %neg
1387  ret i32 %mul
1388}
1389
1390define i8 @mul_shl_nsw_neg_onearg(i8 %x) {
1391; CHECK-LABEL: @mul_shl_nsw_neg_onearg(
1392; CHECK-NEXT:    [[SHL_NEG:%.*]] = shl i8 [[X:%.*]], [[X]]
1393; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[SHL_NEG]], [[X]]
1394; CHECK-NEXT:    ret i8 [[MUL]]
1395;
1396  %neg = sub i8 0, %x
1397  %shl = shl nsw i8 %neg, %x
1398  %mul = mul i8 %shl, %neg
1399  ret i8 %mul
1400}
1401
1402define i32 @mul_nsw_shl_nsw_neg_onearg(i32 %x) {
1403; CHECK-LABEL: @mul_nsw_shl_nsw_neg_onearg(
1404; CHECK-NEXT:    [[SHL_NEG:%.*]] = mul i32 [[X:%.*]], [[X]]
1405; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[SHL_NEG]], [[X]]
1406; CHECK-NEXT:    ret i32 [[MUL]]
1407;
1408  %neg = sub i32 0, %x
1409  %shl = mul nsw i32 %neg, %x
1410  %mul = mul nsw i32 %shl, %neg
1411  ret i32 %mul
1412}
1413
1414define i32 @mul_use_mul_neg(i32 %x,i32 %y) {
1415; CHECK-LABEL: @mul_use_mul_neg(
1416; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]
1417; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[Y:%.*]], [[NEG]]
1418; CHECK-NEXT:    call void @use32(i32 [[MUL]])
1419; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL]], [[NEG]]
1420; CHECK-NEXT:    ret i32 [[MUL2]]
1421;
1422  %neg = sub i32 0, %x
1423  %mul = mul i32 %neg, %y
1424  call void @use32(i32 %mul)
1425  %mul2 = mul i32 %mul, %neg
1426  ret i32 %mul2
1427}
1428
1429define i32 @mul_shl_use_mul_neg(i32 %x,i32 %y) {
1430; CHECK-LABEL: @mul_shl_use_mul_neg(
1431; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]
1432; CHECK-NEXT:    [[SHL:%.*]] = shl i32 [[NEG]], [[Y:%.*]]
1433; CHECK-NEXT:    call void @use32(i32 [[SHL]])
1434; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[SHL]], [[NEG]]
1435; CHECK-NEXT:    ret i32 [[MUL2]]
1436;
1437  %neg = sub i32 0, %x
1438  %shl = shl i32 %neg, %y
1439  call void @use32(i32 %shl)
1440  %mul2 = mul i32 %shl, %neg
1441  ret i32 %mul2
1442}
1443
1444@X = global i32 5
1445
1446define i64 @test_mul_canonicalize_neg_is_not_undone(i64 %L1) {
1447; Check we do not undo the canonicalization of 0 - (X * Y), if Y is a constant
1448; expr.
1449; CHECK-LABEL: @test_mul_canonicalize_neg_is_not_undone(
1450; CHECK-NEXT:    [[B4:%.*]] = mul i64 [[L1:%.*]], sub (i64 0, i64 ptrtoint (ptr @X to i64))
1451; CHECK-NEXT:    ret i64 [[B4]]
1452;
1453  %v1 = ptrtoint ptr @X to i64
1454  %B8 = sub i64 0, %v1
1455  %B4 = mul i64 %B8, %L1
1456  ret i64 %B4
1457}
1458
1459define i32 @negate_if_true(i32 %x, i1 %cond) {
1460; CHECK-LABEL: @negate_if_true(
1461; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]
1462; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], i32 [[TMP1]], i32 [[X]]
1463; CHECK-NEXT:    ret i32 [[R]]
1464;
1465  %sel = select i1 %cond, i32 -1, i32 1
1466  %r = mul i32 %sel, %x
1467  ret i32 %r
1468}
1469
1470define i32 @negate_if_false(i32 %x, i1 %cond) {
1471; CHECK-LABEL: @negate_if_false(
1472; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[X:%.*]]
1473; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], i32 [[X]], i32 [[TMP1]]
1474; CHECK-NEXT:    ret i32 [[R]]
1475;
1476  %sel = select i1 %cond, i32 1, i32 -1
1477  %r = mul i32 %sel, %x
1478  ret i32 %r
1479}
1480
1481define <2 x i8> @negate_if_true_commute(<2 x i8> %px, i1 %cond) {
1482; CHECK-LABEL: @negate_if_true_commute(
1483; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> splat (i8 42), [[PX:%.*]]
1484; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw <2 x i8> zeroinitializer, [[X]]
1485; CHECK-NEXT:    [[R:%.*]] = select i1 [[COND:%.*]], <2 x i8> [[TMP1]], <2 x i8> [[X]]
1486; CHECK-NEXT:    ret <2 x i8> [[R]]
1487;
1488  %x = sdiv <2 x i8> <i8 42, i8 42>, %px  ; thwart complexity-based canonicalization
1489  %sel = select i1 %cond, <2 x i8> <i8 -1, i8 -1>, <2 x i8> <i8 1, i8 1>
1490  %r = mul <2 x i8> %x, %sel
1491  ret <2 x i8> %r
1492}
1493
1494define <2 x i8> @negate_if_false_commute(<2 x i8> %px, <2 x i1> %cond) {
1495; CHECK-LABEL: @negate_if_false_commute(
1496; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> <i8 42, i8 5>, [[PX:%.*]]
1497; CHECK-NEXT:    [[TMP1:%.*]] = sub <2 x i8> zeroinitializer, [[X]]
1498; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[COND:%.*]], <2 x i8> [[X]], <2 x i8> [[TMP1]]
1499; CHECK-NEXT:    ret <2 x i8> [[R]]
1500;
1501  %x = sdiv <2 x i8> <i8 42, i8 5>, %px  ; thwart complexity-based canonicalization
1502  %sel = select <2 x i1> %cond, <2 x i8> <i8 1, i8 poison>, <2 x i8> <i8 -1, i8 -1>
1503  %r = mul <2 x i8> %x, %sel
1504  ret <2 x i8> %r
1505}
1506
1507; Negative test
1508
1509define i32 @negate_if_true_extra_use(i32 %x, i1 %cond) {
1510; CHECK-LABEL: @negate_if_true_extra_use(
1511; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], i32 -1, i32 1
1512; CHECK-NEXT:    call void @use32(i32 [[SEL]])
1513; CHECK-NEXT:    [[R:%.*]] = mul i32 [[SEL]], [[X:%.*]]
1514; CHECK-NEXT:    ret i32 [[R]]
1515;
1516  %sel = select i1 %cond, i32 -1, i32 1
1517  call void @use32(i32 %sel)
1518  %r = mul i32 %sel, %x
1519  ret i32 %r
1520}
1521
1522; Negative test
1523
1524define <2 x i8> @negate_if_true_wrong_constant(<2 x i8> %px, i1 %cond) {
1525; CHECK-LABEL: @negate_if_true_wrong_constant(
1526; CHECK-NEXT:    [[X:%.*]] = sdiv <2 x i8> splat (i8 42), [[PX:%.*]]
1527; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND:%.*]], <2 x i8> <i8 -1, i8 0>, <2 x i8> splat (i8 1)
1528; CHECK-NEXT:    [[R:%.*]] = mul <2 x i8> [[X]], [[SEL]]
1529; CHECK-NEXT:    ret <2 x i8> [[R]]
1530;
1531  %x = sdiv <2 x i8> <i8 42, i8 42>, %px  ; thwart complexity-based canonicalization
1532  %sel = select i1 %cond, <2 x i8> <i8 -1, i8 0>, <2 x i8> <i8 1, i8 1>
1533  %r = mul <2 x i8> %x, %sel
1534  ret <2 x i8> %r
1535}
1536
1537; (C ? (X /exact Y) : 1) * Y -> C ? X : Y
1538define i32 @mul_div_select(i32 %x, i32 %y, i1 %c) {
1539; CHECK-LABEL: @mul_div_select(
1540; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]
1541; CHECK-NEXT:    ret i32 [[MUL]]
1542;
1543  %div = udiv exact i32 %x, %y
1544  %sel = select i1 %c, i32 %div, i32 1
1545  %mul = mul i32 %sel, %y
1546  ret i32 %mul
1547}
1548
1549; fold mul(abs(x),abs(x)) -> mul(x,x)
1550define i31 @combine_mul_abs_i31(i31 %0) {
1551; CHECK-LABEL: @combine_mul_abs_i31(
1552; CHECK-NEXT:    [[M:%.*]] = mul i31 [[TMP0:%.*]], [[TMP0]]
1553; CHECK-NEXT:    ret i31 [[M]]
1554;
1555  %c = icmp slt i31 %0, 0
1556  %s = sub nsw i31 0, %0
1557  %r = select i1 %c, i31 %s, i31 %0
1558  %m = mul i31 %r, %r
1559  ret i31 %m
1560}
1561
1562define i32 @combine_mul_abs_i32(i32 %0) {
1563; CHECK-LABEL: @combine_mul_abs_i32(
1564; CHECK-NEXT:    [[M:%.*]] = mul i32 [[TMP0:%.*]], [[TMP0]]
1565; CHECK-NEXT:    ret i32 [[M]]
1566;
1567  %c = icmp slt i32 %0, 0
1568  %s = sub nsw i32 0, %0
1569  %r = select i1 %c, i32 %s, i32 %0
1570  %m = mul i32 %r, %r
1571  ret i32 %m
1572}
1573
1574define <4 x i32> @combine_mul_abs_v4i32(<4 x i32> %0) {
1575; CHECK-LABEL: @combine_mul_abs_v4i32(
1576; CHECK-NEXT:    [[M:%.*]] = mul <4 x i32> [[TMP0:%.*]], [[TMP0]]
1577; CHECK-NEXT:    ret <4 x i32> [[M]]
1578;
1579  %c = icmp slt <4 x i32> %0, zeroinitializer
1580  %s = sub nsw <4 x i32> zeroinitializer, %0
1581  %r = select <4 x i1> %c, <4 x i32> %s, <4 x i32> %0
1582  %m = mul <4 x i32> %r, %r
1583  ret <4 x i32> %m
1584}
1585
1586; fold mul(nabs(x),nabs(x)) -> mul(x,x)
1587define i31 @combine_mul_nabs_i31(i31 %0) {
1588; CHECK-LABEL: @combine_mul_nabs_i31(
1589; CHECK-NEXT:    [[M:%.*]] = mul i31 [[TMP0:%.*]], [[TMP0]]
1590; CHECK-NEXT:    ret i31 [[M]]
1591;
1592  %c = icmp slt i31 %0, 0
1593  %s = sub nsw i31 0, %0
1594  %r = select i1 %c, i31 %0, i31 %s
1595  %m = mul i31 %r, %r
1596  ret i31 %m
1597}
1598
1599define i32 @combine_mul_nabs_i32(i32 %0) {
1600; CHECK-LABEL: @combine_mul_nabs_i32(
1601; CHECK-NEXT:    [[M:%.*]] = mul i32 [[TMP0:%.*]], [[TMP0]]
1602; CHECK-NEXT:    ret i32 [[M]]
1603;
1604  %c = icmp slt i32 %0, 0
1605  %s = sub nsw i32 0, %0
1606  %r = select i1 %c, i32 %0, i32 %s
1607  %m = mul i32 %r, %r
1608  ret i32 %m
1609}
1610
1611define <4 x i32> @combine_mul_nabs_v4i32(<4 x i32> %0) {
1612; CHECK-LABEL: @combine_mul_nabs_v4i32(
1613; CHECK-NEXT:    [[M:%.*]] = mul <4 x i32> [[TMP0:%.*]], [[TMP0]]
1614; CHECK-NEXT:    ret <4 x i32> [[M]]
1615;
1616  %c = icmp slt <4 x i32> %0, zeroinitializer
1617  %s = sub nsw <4 x i32> zeroinitializer, %0
1618  %r = select <4 x i1> %c, <4 x i32> %0, <4 x i32> %s
1619  %m = mul <4 x i32> %r, %r
1620  ret <4 x i32> %m
1621}
1622
1623define i32 @combine_mul_abs_intrin(i32 %x) {
1624; CHECK-LABEL: @combine_mul_abs_intrin(
1625; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], [[X]]
1626; CHECK-NEXT:    ret i32 [[MUL]]
1627;
1628  %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
1629  %mul = mul i32 %abs, %abs
1630  ret i32 %mul
1631}
1632
1633define i32 @combine_mul_nabs_intrin(i32 %x) {
1634; CHECK-LABEL: @combine_mul_nabs_intrin(
1635; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[X:%.*]], [[X]]
1636; CHECK-NEXT:    ret i32 [[MUL]]
1637;
1638  %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
1639  %neg = sub i32 0, %abs
1640  %mul = mul i32 %neg, %neg
1641  ret i32 %mul
1642}
1643
1644; z * splat(0) = splat(0), even for scalable vectors
1645define <vscale x 2 x i64> @mul_scalable_splat_zero(<vscale x 2 x i64> %z) {
1646; CHECK-LABEL: @mul_scalable_splat_zero(
1647; CHECK-NEXT:    ret <vscale x 2 x i64> zeroinitializer
1648;
1649  %shuf = shufflevector <vscale x 2 x i64> insertelement (<vscale x 2 x i64> poison, i64 0, i32 0), <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
1650  %t3 = mul <vscale x 2 x i64> %shuf, %z
1651  ret <vscale x 2 x i64> %t3
1652}
1653
1654; fold mul(abs(x),abs(y)) -> abs(mul(x,y))
1655define i32 @combine_mul_abs_x_abs_y(i32 %x, i32 %y) {
1656; CHECK-LABEL: @combine_mul_abs_x_abs_y(
1657; CHECK-NEXT:    [[TMP1:%.*]] = mul nsw i32 [[X:%.*]], [[Y:%.*]]
1658; CHECK-NEXT:    [[MUL:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 true)
1659; CHECK-NEXT:    ret i32 [[MUL]]
1660;
1661  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 true)
1662  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 true)
1663  %mul = mul nsw i32 %abs_x, %abs_y
1664  ret i32 %mul
1665}
1666
1667define i32 @combine_mul_abs_x_abs_y_no_nsw(i32 %x, i32 %y) {
1668; CHECK-LABEL: @combine_mul_abs_x_abs_y_no_nsw(
1669; CHECK-NEXT:    [[ABS_X:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
1670; CHECK-NEXT:    [[ABS_Y:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 true)
1671; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[ABS_X]], [[ABS_Y]]
1672; CHECK-NEXT:    ret i32 [[MUL]]
1673;
1674  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 true)
1675  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 true)
1676  %mul = mul i32 %abs_x, %abs_y
1677  ret i32 %mul
1678}
1679
1680define i32 @combine_mul_abs_x_abs_y_poison_1(i32 %x, i32 %y) {
1681; CHECK-LABEL: @combine_mul_abs_x_abs_y_poison_1(
1682; CHECK-NEXT:    [[ABS_X:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
1683; CHECK-NEXT:    [[ABS_Y:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 false)
1684; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ABS_X]], [[ABS_Y]]
1685; CHECK-NEXT:    ret i32 [[MUL]]
1686;
1687  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 true)
1688  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 false)
1689  %mul = mul nsw i32 %abs_x, %abs_y
1690  ret i32 %mul
1691}
1692
1693define i32 @combine_mul_abs_x_abs_y_poison_2(i32 %x, i32 %y) {
1694; CHECK-LABEL: @combine_mul_abs_x_abs_y_poison_2(
1695; CHECK-NEXT:    [[ABS_X:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
1696; CHECK-NEXT:    [[ABS_Y:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 false)
1697; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[ABS_X]], [[ABS_Y]]
1698; CHECK-NEXT:    ret i32 [[MUL]]
1699;
1700  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 false)
1701  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 false)
1702  %mul = mul nsw i32 %abs_x, %abs_y
1703  ret i32 %mul
1704}
1705
1706define i32 @combine_mul_abs_x_abs_y_not_oneuse(i32 %x, i32 %y) {
1707; CHECK-LABEL: @combine_mul_abs_x_abs_y_not_oneuse(
1708; CHECK-NEXT:    [[ABS_X:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)
1709; CHECK-NEXT:    [[ABS_Y:%.*]] = call i32 @llvm.abs.i32(i32 [[Y:%.*]], i1 true)
1710; CHECK-NEXT:    [[ABS_X1:%.*]] = add nuw i32 [[ABS_Y]], 1
1711; CHECK-NEXT:    [[RET:%.*]] = mul i32 [[ABS_X]], [[ABS_X1]]
1712; CHECK-NEXT:    ret i32 [[RET]]
1713;
1714  %abs_x = call i32 @llvm.abs.i32(i32 %x, i1 true)
1715  %abs_y = call i32 @llvm.abs.i32(i32 %y, i1 true)
1716  %mul = mul nsw i32 %abs_x, %abs_y
1717  %ret = add i32 %mul, %abs_x
1718  ret i32 %ret
1719}
1720
1721;
1722; fold mul(sub(x,y),negpow2) -> shl(sub(y,x),log2(pow2))
1723;
1724
1725define i32 @mulsub1(i32 %a0, i32 %a1) {
1726; CHECK-LABEL: @mulsub1(
1727; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub i32 [[A0:%.*]], [[A1:%.*]]
1728; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[SUB_NEG]], 2
1729; CHECK-NEXT:    ret i32 [[MUL]]
1730;
1731  %sub = sub i32 %a1, %a0
1732  %mul = mul i32 %sub, -4
1733  ret i32 %mul
1734}
1735
1736define <2 x i32> @mulsub1_vec(<2 x i32> %a0, <2 x i32> %a1) {
1737; CHECK-LABEL: @mulsub1_vec(
1738; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub <2 x i32> [[A0:%.*]], [[A1:%.*]]
1739; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], splat (i32 2)
1740; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1741;
1742  %sub = sub <2 x i32> %a1, %a0
1743  %mul = mul <2 x i32> %sub, <i32 -4, i32 -4>
1744  ret <2 x i32> %mul
1745}
1746
1747define <2 x i32> @mulsub1_vec_nonuniform(<2 x i32> %a0, <2 x i32> %a1) {
1748; CHECK-LABEL: @mulsub1_vec_nonuniform(
1749; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub <2 x i32> [[A0:%.*]], [[A1:%.*]]
1750; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], <i32 2, i32 3>
1751; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1752;
1753  %sub = sub <2 x i32> %a1, %a0
1754  %mul = mul <2 x i32> %sub, <i32 -4, i32 -8>
1755  ret <2 x i32> %mul
1756}
1757
1758define <2 x i32> @mulsub1_vec_nonuniform_poison(<2 x i32> %a0, <2 x i32> %a1) {
1759; CHECK-LABEL: @mulsub1_vec_nonuniform_poison(
1760; CHECK-NEXT:    [[SUB_NEG:%.*]] = sub <2 x i32> [[A0:%.*]], [[A1:%.*]]
1761; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], <i32 2, i32 0>
1762; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1763;
1764  %sub = sub <2 x i32> %a1, %a0
1765  %mul = mul <2 x i32> %sub, <i32 -4, i32 poison>
1766  ret <2 x i32> %mul
1767}
1768
1769define i32 @mulsub2(i32 %a0) {
1770; CHECK-LABEL: @mulsub2(
1771; CHECK-NEXT:    [[SUB_NEG:%.*]] = shl i32 [[A0:%.*]], 2
1772; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[SUB_NEG]], -64
1773; CHECK-NEXT:    ret i32 [[MUL]]
1774;
1775  %sub = sub i32 16, %a0
1776  %mul = mul i32 %sub, -4
1777  ret i32 %mul
1778}
1779
1780define <2 x i32> @mulsub2_vec(<2 x i32> %a0) {
1781; CHECK-LABEL: @mulsub2_vec(
1782; CHECK-NEXT:    [[SUB_NEG:%.*]] = shl <2 x i32> [[A0:%.*]], splat (i32 2)
1783; CHECK-NEXT:    [[MUL:%.*]] = add <2 x i32> [[SUB_NEG]], splat (i32 -64)
1784; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1785;
1786  %sub = sub <2 x i32> <i32 16, i32 16>, %a0
1787  %mul = mul <2 x i32> %sub, <i32 -4, i32 -4>
1788  ret <2 x i32> %mul
1789}
1790
1791define <2 x i32> @mulsub2_vec_nonuniform(<2 x i32> %a0) {
1792; CHECK-LABEL: @mulsub2_vec_nonuniform(
1793; CHECK-NEXT:    [[SUB_NEG:%.*]] = add <2 x i32> [[A0:%.*]], <i32 -16, i32 -32>
1794; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], <i32 2, i32 3>
1795; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1796;
1797  %sub = sub <2 x i32> <i32 16, i32 32>, %a0
1798  %mul = mul <2 x i32> %sub, <i32 -4, i32 -8>
1799  ret <2 x i32> %mul
1800}
1801
1802define <2 x i32> @mulsub2_vec_nonuniform_poison(<2 x i32> %a0) {
1803; CHECK-LABEL: @mulsub2_vec_nonuniform_poison(
1804; CHECK-NEXT:    [[SUB_NEG:%.*]] = add <2 x i32> [[A0:%.*]], <i32 -16, i32 -32>
1805; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[SUB_NEG]], <i32 2, i32 0>
1806; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1807;
1808  %sub = sub <2 x i32> <i32 16, i32 32>, %a0
1809  %mul = mul <2 x i32> %sub, <i32 -4, i32 poison>
1810  ret <2 x i32> %mul
1811}
1812
1813define i8 @mulsub_nsw(i8 %a1, i8 %a2) {
1814; CHECK-LABEL: @mulsub_nsw(
1815; CHECK-NEXT:    [[A_NEG:%.*]] = sub nsw i8 [[A2:%.*]], [[A1:%.*]]
1816; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i8 [[A_NEG]], 1
1817; CHECK-NEXT:    ret i8 [[MUL]]
1818;
1819  %a = sub nsw i8 %a1, %a2
1820  %mul = mul nsw i8 %a, -2
1821  ret i8 %mul
1822}
1823
1824; It would be safe to keep the nsw on the shl here, but only because the mul
1825; to shl transform happens to replace poison with 0.
1826define <2 x i8> @mulsub_nsw_poison(<2 x i8> %a1, <2 x i8> %a2) {
1827; CHECK-LABEL: @mulsub_nsw_poison(
1828; CHECK-NEXT:    [[A_NEG:%.*]] = sub nsw <2 x i8> [[A2:%.*]], [[A1:%.*]]
1829; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i8> [[A_NEG]], <i8 1, i8 0>
1830; CHECK-NEXT:    ret <2 x i8> [[MUL]]
1831;
1832  %a = sub nsw <2 x i8> %a1, %a2
1833  %mul = mul nsw <2 x i8> %a, <i8 -2, i8 poison>
1834  ret <2 x i8> %mul
1835}
1836
1837define i32 @muladd2(i32 %a0) {
1838; CHECK-LABEL: @muladd2(
1839; CHECK-NEXT:    [[TMP1:%.*]] = shl i32 [[A0:%.*]], 2
1840; CHECK-NEXT:    [[MUL:%.*]] = sub i32 -64, [[TMP1]]
1841; CHECK-NEXT:    ret i32 [[MUL]]
1842;
1843  %add = add i32 %a0, 16
1844  %mul = mul i32 %add, -4
1845  ret i32 %mul
1846}
1847
1848define <2 x i32> @muladd2_vec(<2 x i32> %a0) {
1849; CHECK-LABEL: @muladd2_vec(
1850; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i32> [[A0:%.*]], splat (i32 2)
1851; CHECK-NEXT:    [[MUL:%.*]] = sub <2 x i32> splat (i32 -64), [[TMP1]]
1852; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1853;
1854  %add = add <2 x i32> %a0, <i32 16, i32 16>
1855  %mul = mul <2 x i32> %add, <i32 -4, i32 -4>
1856  ret <2 x i32> %mul
1857}
1858
1859define <2 x i32> @muladd2_vec_nonuniform(<2 x i32> %a0) {
1860; CHECK-LABEL: @muladd2_vec_nonuniform(
1861; CHECK-NEXT:    [[ADD_NEG:%.*]] = sub <2 x i32> <i32 -16, i32 -32>, [[A0:%.*]]
1862; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[ADD_NEG]], <i32 2, i32 3>
1863; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1864;
1865  %add = add <2 x i32> %a0, <i32 16, i32 32>
1866  %mul = mul <2 x i32> %add, <i32 -4, i32 -8>
1867  ret <2 x i32> %mul
1868}
1869
1870define <2 x i32> @muladd2_vec_nonuniform_poison(<2 x i32> %a0) {
1871; CHECK-LABEL: @muladd2_vec_nonuniform_poison(
1872; CHECK-NEXT:    [[ADD_NEG:%.*]] = sub <2 x i32> <i32 -16, i32 -32>, [[A0:%.*]]
1873; CHECK-NEXT:    [[MUL:%.*]] = shl <2 x i32> [[ADD_NEG]], <i32 2, i32 0>
1874; CHECK-NEXT:    ret <2 x i32> [[MUL]]
1875;
1876  %add = add <2 x i32> %a0, <i32 16, i32 32>
1877  %mul = mul <2 x i32> %add, <i32 -4, i32 poison>
1878  ret <2 x i32> %mul
1879}
1880
1881define i32 @mulmuladd2(i32 %a0, i32 %a1) {
1882; CHECK-LABEL: @mulmuladd2(
1883; CHECK-NEXT:    [[ADD_NEG:%.*]] = sub i32 1073741808, [[A0:%.*]]
1884; CHECK-NEXT:    [[MUL1_NEG:%.*]] = mul i32 [[ADD_NEG]], [[A1:%.*]]
1885; CHECK-NEXT:    [[MUL2:%.*]] = shl i32 [[MUL1_NEG]], 2
1886; CHECK-NEXT:    ret i32 [[MUL2]]
1887;
1888  %add = add i32 %a0, 16
1889  %mul1 = mul i32 %add, %a1
1890  %mul2 = mul i32 %mul1, -4
1891  ret i32 %mul2
1892}
1893define i32 @mulmuladd2_extrause0(i32 %a0, i32 %a1) {
1894; CHECK-LABEL: @mulmuladd2_extrause0(
1895; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A0:%.*]], 16
1896; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[ADD]], [[A1:%.*]]
1897; CHECK-NEXT:    call void @use32(i32 [[MUL1]])
1898; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL1]], -4
1899; CHECK-NEXT:    ret i32 [[MUL2]]
1900;
1901  %add = add i32 %a0, 16
1902  %mul1 = mul i32 %add, %a1
1903  call void @use32(i32 %mul1)
1904  %mul2 = mul i32 %mul1, -4
1905  ret i32 %mul2
1906}
1907define i32 @mulmuladd2_extrause1(i32 %a0, i32 %a1) {
1908; CHECK-LABEL: @mulmuladd2_extrause1(
1909; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A0:%.*]], 16
1910; CHECK-NEXT:    call void @use32(i32 [[ADD]])
1911; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[ADD]], [[A1:%.*]]
1912; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL1]], -4
1913; CHECK-NEXT:    ret i32 [[MUL2]]
1914;
1915  %add = add i32 %a0, 16
1916  call void @use32(i32 %add)
1917  %mul1 = mul i32 %add, %a1
1918  %mul2 = mul i32 %mul1, -4
1919  ret i32 %mul2
1920}
1921define i32 @mulmuladd2_extrause2(i32 %a0, i32 %a1) {
1922; CHECK-LABEL: @mulmuladd2_extrause2(
1923; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[A0:%.*]], 16
1924; CHECK-NEXT:    call void @use32(i32 [[ADD]])
1925; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[ADD]], [[A1:%.*]]
1926; CHECK-NEXT:    call void @use32(i32 [[MUL1]])
1927; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 [[MUL1]], -4
1928; CHECK-NEXT:    ret i32 [[MUL2]]
1929;
1930  %add = add i32 %a0, 16
1931  call void @use32(i32 %add)
1932  %mul1 = mul i32 %add, %a1
1933  call void @use32(i32 %mul1)
1934  %mul2 = mul i32 %mul1, -4
1935  ret i32 %mul2
1936}
1937
1938define i32 @mulnot(i32 %a0) {
1939; CHECK-LABEL: @mulnot(
1940; CHECK-NEXT:    [[ADD_NEG:%.*]] = shl i32 [[A0:%.*]], 2
1941; CHECK-NEXT:    [[MUL:%.*]] = add i32 [[ADD_NEG]], 4
1942; CHECK-NEXT:    ret i32 [[MUL]]
1943;
1944  %add = xor i32 %a0, -1
1945  %mul = mul i32 %add, -4
1946  ret i32 %mul
1947}
1948
1949define i32 @mulnot_extrause(i32 %a0) {
1950; CHECK-LABEL: @mulnot_extrause(
1951; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[A0:%.*]], -1
1952; CHECK-NEXT:    call void @use32(i32 [[NOT]])
1953; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[NOT]], -4
1954; CHECK-NEXT:    ret i32 [[MUL]]
1955;
1956  %not = xor i32 %a0, -1
1957  call void @use32(i32 %not)
1958  %mul = mul i32 %not, -4
1959  ret i32 %mul
1960}
1961
1962define i32 @zext_negpow2(i8 %x) {
1963; CHECK-LABEL: @zext_negpow2(
1964; CHECK-NEXT:    [[X_NEG:%.*]] = sub i8 0, [[X:%.*]]
1965; CHECK-NEXT:    [[X_NEG_Z:%.*]] = zext i8 [[X_NEG]] to i32
1966; CHECK-NEXT:    [[R:%.*]] = shl nuw i32 [[X_NEG_Z]], 24
1967; CHECK-NEXT:    ret i32 [[R]]
1968;
1969  %zx = zext i8 %x to i32
1970  %r = mul i32 %zx, -16777216 ; -1 << 24
1971  ret i32 %r
1972}
1973
1974; splat constant
1975
1976define <2 x i14> @zext_negpow2_vec(<2 x i5> %x) {
1977; CHECK-LABEL: @zext_negpow2_vec(
1978; CHECK-NEXT:    [[X_NEG:%.*]] = sub <2 x i5> zeroinitializer, [[X:%.*]]
1979; CHECK-NEXT:    [[X_NEG_Z:%.*]] = zext <2 x i5> [[X_NEG]] to <2 x i14>
1980; CHECK-NEXT:    [[R:%.*]] = shl <2 x i14> [[X_NEG_Z]], splat (i14 11)
1981; CHECK-NEXT:    ret <2 x i14> [[R]]
1982;
1983  %zx = zext <2 x i5> %x to <2 x i14>
1984  %r = mul <2 x i14> %zx, <i14 -2048, i14 -2048> ; -1 << 11
1985  ret <2 x i14> %r
1986}
1987
1988; negative test - mul must be big enough to cover bitwidth diff
1989
1990define i32 @zext_negpow2_too_small(i8 %x) {
1991; CHECK-LABEL: @zext_negpow2_too_small(
1992; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X:%.*]] to i32
1993; CHECK-NEXT:    [[R:%.*]] = mul nsw i32 [[ZX]], -8388608
1994; CHECK-NEXT:    ret i32 [[R]]
1995;
1996  %zx = zext i8 %x to i32
1997  %r = mul i32 %zx, -8388608 ; -1 << 23
1998  ret i32 %r
1999}
2000
2001define i16 @sext_negpow2(i9 %x) {
2002; CHECK-LABEL: @sext_negpow2(
2003; CHECK-NEXT:    [[X_NEG:%.*]] = sub i9 0, [[X:%.*]]
2004; CHECK-NEXT:    [[X_NEG_Z:%.*]] = zext i9 [[X_NEG]] to i16
2005; CHECK-NEXT:    [[R:%.*]] = shl i16 [[X_NEG_Z]], 10
2006; CHECK-NEXT:    ret i16 [[R]]
2007;
2008  %sx = sext i9 %x to i16
2009  %r = mul i16 %sx, -1024 ; -1 << 10
2010  ret i16 %r
2011}
2012
2013; splat constant with poison element(s)
2014
2015define <2 x i16> @sext_negpow2_vec(<2 x i8> %x) {
2016; CHECK-LABEL: @sext_negpow2_vec(
2017; CHECK-NEXT:    [[X_NEG:%.*]] = sub <2 x i8> zeroinitializer, [[X:%.*]]
2018; CHECK-NEXT:    [[X_NEG_Z:%.*]] = zext <2 x i8> [[X_NEG]] to <2 x i16>
2019; CHECK-NEXT:    [[R:%.*]] = shl nuw <2 x i16> [[X_NEG_Z]], splat (i16 8)
2020; CHECK-NEXT:    ret <2 x i16> [[R]]
2021;
2022  %sx = sext <2 x i8> %x to <2 x i16>
2023  %r = mul <2 x i16> %sx, <i16 -256, i16 poison> ; -1 << 8
2024  ret <2 x i16> %r
2025}
2026
2027; negative test - mul must be big enough to cover bitwidth diff
2028
2029define <2 x i16> @sext_negpow2_too_small_vec(<2 x i8> %x) {
2030; CHECK-LABEL: @sext_negpow2_too_small_vec(
2031; CHECK-NEXT:    [[SX:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i16>
2032; CHECK-NEXT:    [[R:%.*]] = mul nsw <2 x i16> [[SX]], <i16 -128, i16 poison>
2033; CHECK-NEXT:    ret <2 x i16> [[R]]
2034;
2035  %sx = sext <2 x i8> %x to <2 x i16>
2036  %r = mul <2 x i16> %sx, <i16 -128, i16 poison> ; -1 << 7
2037  ret <2 x i16> %r
2038}
2039
2040; negative test - too many uses
2041
2042define i32 @zext_negpow2_use(i8 %x) {
2043; CHECK-LABEL: @zext_negpow2_use(
2044; CHECK-NEXT:    [[ZX:%.*]] = zext i8 [[X:%.*]] to i32
2045; CHECK-NEXT:    call void @use32(i32 [[ZX]])
2046; CHECK-NEXT:    [[R:%.*]] = mul i32 [[ZX]], -16777216
2047; CHECK-NEXT:    ret i32 [[R]]
2048;
2049  %zx = zext i8 %x to i32
2050  call void @use32(i32 %zx)
2051  %r = mul i32 %zx, -16777216 ; -1 << 24
2052  ret i32 %r
2053}
2054
2055define i32 @mul_sext_icmp_with_zero(i32 %x) {
2056; CHECK-LABEL: @mul_sext_icmp_with_zero(
2057; CHECK-NEXT:    ret i32 0
2058;
2059  %cmp = icmp eq i32 %x, 0
2060  %sext = sext i1 %cmp to i32
2061  %mul = mul i32 %sext, %x
2062  ret i32 %mul
2063}
2064
2065define i32 @test_mul_sext_bool(i1 %x, i32 %y) {
2066; CHECK-LABEL: @test_mul_sext_bool(
2067; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]
2068; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[TMP1]], i32 0
2069; CHECK-NEXT:    ret i32 [[MUL]]
2070;
2071  %sext = sext i1 %x to i32
2072  %mul = mul i32 %sext, %y
2073  ret i32 %mul
2074}
2075
2076define i32 @test_mul_sext_bool_nuw(i1 %x, i32 %y) {
2077; CHECK-LABEL: @test_mul_sext_bool_nuw(
2078; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 0, [[Y:%.*]]
2079; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[TMP1]], i32 0
2080; CHECK-NEXT:    ret i32 [[MUL]]
2081;
2082  %sext = sext i1 %x to i32
2083  %mul = mul nuw i32 %sext, %y
2084  ret i32 %mul
2085}
2086
2087define i32 @test_mul_sext_bool_nsw(i1 %x, i32 %y) {
2088; CHECK-LABEL: @test_mul_sext_bool_nsw(
2089; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i32 0, [[Y:%.*]]
2090; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[TMP1]], i32 0
2091; CHECK-NEXT:    ret i32 [[MUL]]
2092;
2093  %sext = sext i1 %x to i32
2094  %mul = mul nsw i32 %sext, %y
2095  ret i32 %mul
2096}
2097
2098define i32 @test_mul_sext_bool_nuw_nsw(i1 %x, i32 %y) {
2099; CHECK-LABEL: @test_mul_sext_bool_nuw_nsw(
2100; CHECK-NEXT:    [[TMP1:%.*]] = sub nsw i32 0, [[Y:%.*]]
2101; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[TMP1]], i32 0
2102; CHECK-NEXT:    ret i32 [[MUL]]
2103;
2104  %sext = sext i1 %x to i32
2105  %mul = mul nuw nsw i32 %sext, %y
2106  ret i32 %mul
2107}
2108
2109define i32 @test_mul_sext_bool_commuted(i1 %x, i32 %y) {
2110; CHECK-LABEL: @test_mul_sext_bool_commuted(
2111; CHECK-NEXT:    [[TMP1:%.*]] = xor i32 [[Y:%.*]], -2
2112; CHECK-NEXT:    [[YY_NEG:%.*]] = add i32 [[TMP1]], 1
2113; CHECK-NEXT:    [[MUL:%.*]] = select i1 [[X:%.*]], i32 [[YY_NEG]], i32 0
2114; CHECK-NEXT:    ret i32 [[MUL]]
2115;
2116  %yy = xor i32 %y, 1
2117  %sext = sext i1 %x to i32
2118  %mul = mul i32 %yy, %sext
2119  ret i32 %mul
2120}
2121
2122define i32 @test_mul_sext_nonbool(i2 %x, i32 %y) {
2123; CHECK-LABEL: @test_mul_sext_nonbool(
2124; CHECK-NEXT:    [[SEXT:%.*]] = sext i2 [[X:%.*]] to i32
2125; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[Y:%.*]], [[SEXT]]
2126; CHECK-NEXT:    ret i32 [[MUL]]
2127;
2128  %sext = sext i2 %x to i32
2129  %mul = mul i32 %sext, %y
2130  ret i32 %mul
2131}
2132
2133define i32 @test_mul_sext_multiuse(i1 %x, i32 %y) {
2134; CHECK-LABEL: @test_mul_sext_multiuse(
2135; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[X:%.*]] to i32
2136; CHECK-NEXT:    tail call void @use(i32 [[SEXT]])
2137; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[Y:%.*]], [[SEXT]]
2138; CHECK-NEXT:    ret i32 [[MUL]]
2139;
2140  %sext = sext i1 %x to i32
2141  tail call void @use(i32 %sext)
2142  %mul = mul i32 %sext, %y
2143  ret i32 %mul
2144}
2145
2146define i8 @mul_nsw_nonneg(i8 %x, i8 %y) {
2147; CHECK-LABEL: @mul_nsw_nonneg(
2148; CHECK-NEXT:    [[X_NNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
2149; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NNEG]])
2150; CHECK-NEXT:    [[Y_NNEG:%.*]] = icmp sgt i8 [[Y:%.*]], -1
2151; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NNEG]])
2152; CHECK-NEXT:    [[MUL:%.*]] = mul nuw nsw i8 [[X]], [[Y]]
2153; CHECK-NEXT:    ret i8 [[MUL]]
2154;
2155  %x.nneg = icmp sge i8 %x, 0
2156  call void @llvm.assume(i1 %x.nneg)
2157  %y.nneg = icmp sge i8 %y, 0
2158  call void @llvm.assume(i1 %y.nneg)
2159  %mul = mul nsw i8 %x, %y
2160  ret i8 %mul
2161}
2162
2163define i8 @mul_nsw_not_nonneg1(i8 %x, i8 %y) {
2164; CHECK-LABEL: @mul_nsw_not_nonneg1(
2165; CHECK-NEXT:    [[Y_NNEG:%.*]] = icmp sgt i8 [[Y:%.*]], -1
2166; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NNEG]])
2167; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i8 [[X:%.*]], [[Y]]
2168; CHECK-NEXT:    ret i8 [[MUL]]
2169;
2170  %y.nneg = icmp sge i8 %y, 0
2171  call void @llvm.assume(i1 %y.nneg)
2172  %mul = mul nsw i8 %x, %y
2173  ret i8 %mul
2174}
2175
2176define i8 @mul_nsw_not_nonneg2(i8 %x, i8 %y) {
2177; CHECK-LABEL: @mul_nsw_not_nonneg2(
2178; CHECK-NEXT:    [[X_NNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
2179; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NNEG]])
2180; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i8 [[X]], [[Y:%.*]]
2181; CHECK-NEXT:    ret i8 [[MUL]]
2182;
2183  %x.nneg = icmp sge i8 %x, 0
2184  call void @llvm.assume(i1 %x.nneg)
2185  %mul = mul nsw i8 %x, %y
2186  ret i8 %mul
2187}
2188
2189define i8 @mul_not_nsw_nonneg(i8 %x, i8 %y) {
2190; CHECK-LABEL: @mul_not_nsw_nonneg(
2191; CHECK-NEXT:    [[X_NNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
2192; CHECK-NEXT:    call void @llvm.assume(i1 [[X_NNEG]])
2193; CHECK-NEXT:    [[Y_NNEG:%.*]] = icmp sgt i8 [[Y:%.*]], -1
2194; CHECK-NEXT:    call void @llvm.assume(i1 [[Y_NNEG]])
2195; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X]], [[Y]]
2196; CHECK-NEXT:    ret i8 [[MUL]]
2197;
2198  %x.nneg = icmp sge i8 %x, 0
2199  call void @llvm.assume(i1 %x.nneg)
2200  %y.nneg = icmp sge i8 %y, 0
2201  call void @llvm.assume(i1 %y.nneg)
2202  %mul = mul i8 %x, %y
2203  ret i8 %mul
2204}
2205