[clang] Document the return value of __builtin_COLUMN (#118360)
[llvm-project.git] / llvm / test / Transforms / InstCombine / mul.ll
blob0f3137cdd0be363a384d6d192569bf3343efcb44
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
5 declare i32 @llvm.abs.i32(i32, i1)
7 define i32 @pow2_multiplier(i32 %A) {
8 ; CHECK-LABEL: @pow2_multiplier(
9 ; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 1
10 ; CHECK-NEXT:    ret i32 [[B]]
12   %B = mul i32 %A, 2
13   ret i32 %B
16 define <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]]
21   %B = mul <2 x i32> %A, <i32 8, i32 8>
22   ret <2 x i32> %B
25 define i8 @combine_shl(i8 %A) {
26 ; CHECK-LABEL: @combine_shl(
27 ; CHECK-NEXT:    [[C:%.*]] = shl i8 [[A:%.*]], 6
28 ; CHECK-NEXT:    ret i8 [[C]]
30   %B = mul i8 %A, 8
31   %C = mul i8 %B, 8
32   ret i8 %C
35 define i32 @neg(i32 %i) {
36 ; CHECK-LABEL: @neg(
37 ; CHECK-NEXT:    [[T:%.*]] = sub i32 0, [[I:%.*]]
38 ; CHECK-NEXT:    ret i32 [[T]]
40   %t = mul i32 %i, -1
41   ret i32 %t
44 ; Use the sign-bit as a mask:
45 ; (zext (A < 0)) * B --> (A >> 31) & B
47 define 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]]
53   %c = icmp slt i32 %a, 0
54   %d = zext i1 %c to i32
55   %e = mul i32 %d, %b
56   ret i32 %e
59 define 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]]
65   %c = icmp sle i32 %a, -1
66   %d = zext i1 %c to i32
67   %e = mul i32 %d, %b
68   ret i32 %e
71 declare void @use32(i32)
73 define 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]]
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
88 ; rdar://7293527
89 define i32 @shl1(i32 %a, i32 %b) {
90 ; CHECK-LABEL: @shl1(
91 ; CHECK-NEXT:    [[M1:%.*]] = shl i32 [[A:%.*]], [[B:%.*]]
92 ; CHECK-NEXT:    ret i32 [[M1]]
94   %shl = shl i32 1, %b
95   %m = mul i32 %shl, %a
96   ret i32 %m
99 define 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]]
104   %shl = shl nsw i32 1, %B
105   %D = mul nsw i32 %A, %shl
106   ret i32 %D
109 define <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]]
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
119 define 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]]
124   %shl = shl i32 1, %B
125   %D = mul nuw i32 %A, %shl
126   ret i32 %D
129 define 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]]
134   %shl = shl nuw i32 1, %B
135   %D = mul i32 %shl, %A
136   ret i32 %D
139 define 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]]
145   %shl = shl i32 1, %A
146   %C = mul nsw i32 %shl, %shl
147   ret i32 %C
150 define 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]]
157   %pow2x = shl i5 1, %x
158   %x1 = add i5 %pow2x, 1
159   %m = mul i5 %x1, %y
160   ret i5 %m
163 define <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]]
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
177 define 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]]
184   %pow2x = shl i5 1, %x
185   %x1 = add i5 %pow2x, 1
186   %m = mul nsw i5 %x1, %y
187   ret i5 %m
190 define 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]]
197   %pow2x = shl nsw i5 1, %x
198   %x1 = add i5 %pow2x, 1
199   %m = mul nsw i5 %y, %x1
200   ret i5 %m
203 define 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]]
210   %pow2x = shl nsw i5 1, %x
211   %x1 = add nsw i5 %pow2x, 1
212   %m = mul i5 %x1, %y
213   ret i5 %m
216 define 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]]
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
231 ; ((-1 << x) ^ -1) * y --> (y << x) - y
233 define 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]]
240   %pow2x = shl i8 -1, %x
241   %x1 = xor i8 %pow2x, -1
242   %m = mul i8 %x1, %y
243   ret i8 %m
246 define 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]]
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
260 define 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]]
267   %pow2x = shl i8 -1, %x
268   %x1 = xor i8 %pow2x, -1
269   %m = mul nuw i8 %x1, %y
270   ret i8 %m
273 define 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]]
280   %pow2x = shl nsw i8 -1, %x
281   %x1 = xor i8 %pow2x, -1
282   %m = mul nsw i8 %x1, %y
283   ret i8 %m
286 ; negative test - extra use would require more instructions
288 define 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]]
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
303 ; the fold works for vectors too and if 'y' is a constant, sub becomes add
305 define <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]]
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
317 ; X * Y (when Y is a boolean) --> Y ? X : 0
319 define 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]]
324   %z = zext i1 %y to i32
325   %m = mul i32 %z, %x
326   ret i32 %m
329 define <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]]
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
339 define <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]]
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
351 ; X * C (when X is a sext boolean) --> X ? -C : 0
353 define 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]]
358   %s = sext i1 %x to i32
359   %m = mul i32 %s, 42
360   ret i32 %m
363 define 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]]
370   %s = sext i1 %x to i32
371   call void @use32(i32 %s)
372   %m = mul i32 %s, 42
373   ret i32 %m
376 define <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]]
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
386 define <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]]
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
398 define 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]]
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
413 define 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]]
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
428 define 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]]
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
445 define <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]]
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
457 define 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]]
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
472 define 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]]
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
487 define 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]]
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
504 define 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]]
510   %sx = sext i1 %x to i32
511   %sy = sext i1 %y to i32
512   %r = mul i32 %sx, %sy
513   ret i32 %r
516 define 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]]
521   %sx = sext i1 %x to i32
522   %r = mul i32 %sx, %sx
523   ret i32 %r
526 define 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]]
532   %zx = zext i1 %x to i32
533   %zy = zext i1 %y to i32
534   %r = mul i32 %zx, %zy
535   ret i32 %r
538 define 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]]
543   %sx = zext i1 %x to i32
544   %r = mul i32 %sx, %sx
545   ret i32 %r
548 define 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]]
555   %sx = sext i1 %x to i32
556   call void @use32(i32 %sx)
557   %r = mul i32 %sx, %sx
558   ret i32 %r
561 define 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]]
568   %sx = zext i1 %x to i32
569   call void @use32(i32 %sx)
570   %r = mul i32 %sx, %sx
571   ret i32 %r
574 define <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]]
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
586 define 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]]
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
601 define 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]]
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
616 define 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]]
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
633 ; (A >>u 31) * B --> (A >>s 31) & B --> A < 0 ? B : 0
635 define 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]]
641   %d = lshr i32 %a, 31
642   %e = mul i32 %d, %b
643   ret i32 %e
646 define 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]]
654   %d = lshr i32 %a, 31
655   %e = mul i32 %b, %d
656   call void @use32(i32 %d)
657   ret i32 %e
660 ; (A >>u 31)) * B --> (A >>s 31) & B --> A < 0 ? B : 0
662 define <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]]
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
673 define <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]]
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
684 ; (A & 1) * B --> (lowbit A) ? B : 0
686 define 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]]
692   %d = and i32 %a, 1
693   %e = mul i32 %d, %b
694   ret i32 %e
697 ; (A & 1) * B --> (lowbit A) ? B : 0
699 define <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]]
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
712 ; negative test - extra use
714 define 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]]
721   %d = and i32 %a, 1
722   call void @use32(i32 %d)
723   %e = mul i32 %d, %b
724   ret i32 %e
727 ; negative test - wrong mask
729 define 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]]
735   %d = and i32 %a, 2
736   %e = mul i32 %d, %b
737   ret i32 %e
740 define 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]]
746   %ash = ashr i32 %x, 31
747   %mul = mul i32 %ash, 42
748   ret i32 %mul
751 define <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]]
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
762 ; negative test - wrong shift amount
764 define 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]]
770   %ash = ashr i32 %x, 30
771   %mul = mul i32 %ash, 42
772   ret i32 %mul
775 ; negative test - extra use
777 define 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]]
784   %ash = ashr i32 %x, 31
785   call void @use32(i32 %ash)
786   %mul = mul i32 %ash, -42
787   ret i32 %mul
790 define i32 @test18(i32 %A, i32 %B) {
791 ; CHECK-LABEL: @test18(
792 ; CHECK-NEXT:    ret i32 0
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
801 declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32)
802 declare void @use(i1)
804 define i32 @test19(i32 %A, i32 %B) {
805 ; CHECK-LABEL: @test19(
806 ; CHECK-NEXT:    call void @use(i1 false)
807 ; CHECK-NEXT:    ret i32 0
809   %C = and i32 %A, 1
810   %D = and i32 %B, 1
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
821 define <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]]
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
832 @g = internal global i32 0, align 4
834 define 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]]
840   %add = add i32 %a, -1
841   %mul = mul nsw i32 %add, ptrtoint (ptr @g to i32)
842   ret i32 %mul
845 ; Keep nuw flag in this change, https://alive2.llvm.org/ce/z/-Wowpk
846 define 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]]
852   %add = add nuw i32 %a, 3
853   %mul = mul nuw i32 %add, 3
854   ret i32 %mul
857 ; Don't propagate nsw flag in this change
858 define 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]]
864   %add = add nsw i32 %a, 3
865   %mul = mul nsw i32 %add, 3
866   ret i32 %mul
869 ; Only the add or only the mul has nuw, https://alive2.llvm.org/ce/z/vPwbEa
870 define 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]]
876   %add = add nuw i32 %a, 3
877   %mul = mul i32 %add, 3
878   ret i32 %mul
881 define 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]]
887   %add = add i32 %a, 3
888   %mul = mul nuw i32 %add, 3
889   ret i32 %mul
892 ; Don't propagate nsw flag in this change, https://alive2.llvm.org/ce/z/jJ8rZd
893 define 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]]
899   %shl = shl nsw i32 %a, 2
900   %add = or i32 %shl, 3
901   %mul = mul nsw i32 %add, 3
902   ret i32 %mul
905 ; Negative test: Have common bits set
906 define 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]]
913   %shl = shl nsw i32 %a, 2
914   %add = or i32 %shl, 4
915   %mul = mul nsw i32 %add, 3
916   ret i32 %mul
919 ; Keep nuw flag in this change, https://alive2.llvm.org/ce/z/awsQrx
920 define 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]]
926   %mul0 = mul nuw i32 %a, 12
927   %add = or i32 %mul0, 3
928   %mul = mul nuw i32 %add, 3
929   ret i32 %mul
932 ; Negative test: Have common bits set, https://alive2.llvm.org/ce/z/bHZRh5
933 define 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]]
940   %mul0 = mul nuw i32 %a, 12
941   %add = or i32 %mul0, 4
942   %mul = mul nuw i32 %add, 3
943   ret i32 %mul
946 ; Test the haveNoCommonBitsSet with assume, https://alive2.llvm.org/ce/z/AXKBjK
947 define 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]]
956   %combits = and i32 %a , 3
957   %nocombits = icmp eq i32 %combits, 0
958   call void @llvm.assume(i1 %nocombits)
960   %add = or i32 %a, 3
961   %mul = mul i32 %add, 5
962   ret i32 %mul
965 declare void @llvm.assume(i1)
967 define 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]]
973   %add = or disjoint i32 %a, 3
974   %mul = mul nuw i32 %add, 3
975   ret i32 %mul
978 define 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]]
984   %add = or disjoint i32 %a, 3
985   %mul = mul nsw i32 %add, 3
986   ret i32 %mul
989 ; https://alive2.llvm.org/ce/z/XYpv9q
990 define <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]]
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
1002 ; TODO: vector with poison should also be supported, https://alive2.llvm.org/ce/z/XYpv9q
1003 define <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]]
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
1016 define <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]]
1021   %C = mul <2 x i1> %A, %B
1022   ret <2 x i1> %C
1025 define i32 @test22(i32 %A) {
1026 ; CHECK-LABEL: @test22(
1027 ; CHECK-NEXT:    [[B:%.*]] = sub nsw i32 0, [[A:%.*]]
1028 ; CHECK-NEXT:    ret i32 [[B]]
1030   %B = mul nsw i32 %A, -1
1031   ret i32 %B
1034 define i32 @test23(i32 %A) {
1035 ; CHECK-LABEL: @test23(
1036 ; CHECK-NEXT:    [[C:%.*]] = mul nuw i32 [[A:%.*]], 6
1037 ; CHECK-NEXT:    ret i32 [[C]]
1039   %B = shl nuw i32 %A, 1
1040   %C = mul nuw i32 %B, 3
1041   ret i32 %C
1044 define i32 @test24(i32 %A) {
1045 ; CHECK-LABEL: @test24(
1046 ; CHECK-NEXT:    [[C:%.*]] = mul nsw i32 [[A:%.*]], 6
1047 ; CHECK-NEXT:    ret i32 [[C]]
1049   %B = shl nsw i32 %A, 1
1050   %C = mul nsw i32 %B, 3
1051   ret i32 %C
1054 define 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]]
1059   %C = sub i32 0, %A
1060   %D = sub i32 0, %B
1061   %E = mul i32 %C, %D
1062   ret i32 %E
1065 define 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]]
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
1076 define 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]]
1081   %C = sub i124 0, %A
1082   %D = sub i124 0, %B
1083   %E = mul i124 %C, %D
1084   ret i124 %E
1087 define 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]]
1092   %C = sub i32 0, %A
1093   %E = mul i32 %C, 7
1094   ret i32 %E
1097 define 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]]
1102   %C = sub i55 0, %A
1103   %E = mul i55 %C, 7
1104   ret i55 %E
1107 define <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]]
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
1117 define <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]]
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
1127 define 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]]
1134   %C = sext i31 %A to i64
1135   %D = sext i31 %B to i64
1136   %E = mul i64 %C, %D
1137   ret i64 %E
1140 define 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]]
1147   %C = zext i32 %A to i64
1148   %D = zext i32 %B to i64
1149   %E = mul i64 %C, %D
1150   ret i64 %E
1153 @PR22087 = external global i32
1154 define 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]]
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
1168 define i32 @test32(i32 %X) {
1169 ; CHECK-LABEL: @test32(
1170 ; CHECK-NEXT:    [[MUL:%.*]] = shl i32 [[X:%.*]], 31
1171 ; CHECK-NEXT:    ret i32 [[MUL]]
1173   %mul = mul nsw i32 %X, -2147483648
1174   ret i32 %mul
1177 define <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]]
1182   %mul = mul nsw <2 x i32> %X, <i32 -2147483648, i32 -2147483648>
1183   ret <2 x i32> %mul
1186 define i32 @test33(i32 %X) {
1187 ; CHECK-LABEL: @test33(
1188 ; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i32 [[X:%.*]], 30
1189 ; CHECK-NEXT:    ret i32 [[MUL]]
1191   %mul = mul nsw i32 %X, 1073741824
1192   ret i32 %mul
1195 define <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]]
1200   %mul = mul nsw <2 x i32> %X, <i32 1073741824, i32 1073741824>
1201   ret <2 x i32> %mul
1204 define i128 @test34(i128 %X) {
1205 ; CHECK-LABEL: @test34(
1206 ; CHECK-NEXT:    [[MUL:%.*]] = shl nsw i128 [[X:%.*]], 1
1207 ; CHECK-NEXT:    ret i128 [[MUL]]
1209   %mul = mul nsw i128 %X, 2
1210   ret i128 %mul
1213 define 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]]
1219   %neg = sub i32 0, %x
1220   %mul = mul i32 %neg, %y
1221   ret i32 %mul
1224 define 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]]
1230   %y = mul i32 %z, 3
1231   %neg = sub i32 0, %x
1232   %mul = mul i32 %y, %neg
1233   ret i32 %mul
1236 define 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]]
1242   %neg = sub nsw i32 0, %x
1243   %mul = mul nsw i32 %neg, %y
1244   ret i32 %mul
1247 define <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]]
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
1258 define 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]]
1264   %neg = sub i32 0, %x
1265   %mul = mul i32 %neg, %y
1266   %mul2 = mul i32 %mul, %neg
1267   ret i32 %mul2
1270 define 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]]
1276   %neg = sub i32 0, %x
1277   %mul = mul nsw i32 %neg, %y
1278   %mul2 = mul nsw i32 %mul, %neg
1279   ret i32 %mul2
1282 define 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]]
1288   %neg = sub i32 0, %x
1289   %mul = mul nsw i32 %neg, %y
1290   %mul2 = mul i32 %mul, %neg
1291   ret i32 %mul2
1294 define 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]]
1300   %neg = sub i32 0, %x
1301   %mul = mul i32 %neg, %y
1302   %mul2 = mul nsw i32 %mul, %neg
1303   ret i32 %mul2
1306 define 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]]
1312   %neg = sub i32 0, %x
1313   %mul = mul i32 %neg, %x
1314   %mul2 = mul nsw i32 %mul, %neg
1315   ret i32 %mul2
1318 define 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]]
1324   %neg = sub i8 0, %x
1325   %mul = mul nsw i8 %neg, %x
1326   %mul2 = mul i8 %mul, %neg
1327   ret i8 %mul2
1330 define 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]]
1336   %neg = sub i32 0, %x
1337   %mul = mul nsw i32 %neg, %x
1338   %mul2 = mul nsw i32 %mul, %neg
1339   ret i32 %mul2
1342 define 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]]
1348   %neg = sub i32 0, %x
1349   %shl = shl nsw i32 %neg, %y
1350   %mul = mul nsw i32 %shl, %neg
1351   ret i32 %mul
1354 define 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]]
1360   %neg = sub i32 0, %x
1361   %shl = shl nsw i32 %neg, %y
1362   %mul = mul i32 %shl, %neg
1363   ret i32 %mul
1366 define 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]]
1372   %neg = sub i32 0, %x
1373   %shl = shl i32 %neg, %y
1374   %mul = mul nsw i32 %shl, %neg
1375   ret i32 %mul
1378 define 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]]
1384   %neg = sub i32 0, %x
1385   %shl = shl i32 %neg, %x
1386   %mul = mul nsw i32 %shl, %neg
1387   ret i32 %mul
1390 define 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]]
1396   %neg = sub i8 0, %x
1397   %shl = shl nsw i8 %neg, %x
1398   %mul = mul i8 %shl, %neg
1399   ret i8 %mul
1402 define 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]]
1408   %neg = sub i32 0, %x
1409   %shl = mul nsw i32 %neg, %x
1410   %mul = mul nsw i32 %shl, %neg
1411   ret i32 %mul
1414 define 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]]
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
1429 define 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]]
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
1444 @X = global i32 5
1446 define 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]]
1453   %v1 = ptrtoint ptr @X to i64
1454   %B8 = sub i64 0, %v1
1455   %B4 = mul i64 %B8, %L1
1456   ret i64 %B4
1459 define 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]]
1465   %sel = select i1 %cond, i32 -1, i32 1
1466   %r = mul i32 %sel, %x
1467   ret i32 %r
1470 define 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]]
1476   %sel = select i1 %cond, i32 1, i32 -1
1477   %r = mul i32 %sel, %x
1478   ret i32 %r
1481 define <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]]
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
1494 define <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]]
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
1507 ; Negative test
1509 define 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]]
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
1522 ; Negative test
1524 define <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]]
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
1537 ; (C ? (X /exact Y) : 1) * Y -> C ? X : Y
1538 define 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]]
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
1549 ; fold mul(abs(x),abs(x)) -> mul(x,x)
1550 define 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]]
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
1562 define 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]]
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
1574 define <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]]
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
1586 ; fold mul(nabs(x),nabs(x)) -> mul(x,x)
1587 define 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]]
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
1599 define 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]]
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
1611 define <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]]
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
1623 define 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]]
1628   %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)
1629   %mul = mul i32 %abs, %abs
1630   ret i32 %mul
1633 define 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]]
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
1644 ; z * splat(0) = splat(0), even for scalable vectors
1645 define <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
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
1654 ; fold mul(abs(x),abs(y)) -> abs(mul(x,y))
1655 define 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]]
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
1667 define 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]]
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
1680 define 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]]
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
1693 define 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]]
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
1706 define 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]]
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
1722 ; fold mul(sub(x,y),negpow2) -> shl(sub(y,x),log2(pow2))
1725 define 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]]
1731   %sub = sub i32 %a1, %a0
1732   %mul = mul i32 %sub, -4
1733   ret i32 %mul
1736 define <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]]
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
1747 define <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]]
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
1758 define <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]]
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
1769 define 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]]
1775   %sub = sub i32 16, %a0
1776   %mul = mul i32 %sub, -4
1777   ret i32 %mul
1780 define <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]]
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
1791 define <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]]
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
1802 define <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]]
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
1813 define 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]]
1819   %a = sub nsw i8 %a1, %a2
1820   %mul = mul nsw i8 %a, -2
1821   ret i8 %mul
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.
1826 define <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]]
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
1837 define 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]]
1843   %add = add i32 %a0, 16
1844   %mul = mul i32 %add, -4
1845   ret i32 %mul
1848 define <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]]
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
1859 define <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]]
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
1870 define <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]]
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
1881 define 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]]
1888   %add = add i32 %a0, 16
1889   %mul1 = mul i32 %add, %a1
1890   %mul2 = mul i32 %mul1, -4
1891   ret i32 %mul2
1893 define 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]]
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
1907 define 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]]
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
1921 define 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]]
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
1938 define 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]]
1944   %add = xor i32 %a0, -1
1945   %mul = mul i32 %add, -4
1946   ret i32 %mul
1949 define 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]]
1956   %not = xor i32 %a0, -1
1957   call void @use32(i32 %not)
1958   %mul = mul i32 %not, -4
1959   ret i32 %mul
1962 define 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]]
1969   %zx = zext i8 %x to i32
1970   %r = mul i32 %zx, -16777216 ; -1 << 24
1971   ret i32 %r
1974 ; splat constant
1976 define <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]]
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
1988 ; negative test - mul must be big enough to cover bitwidth diff
1990 define 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]]
1996   %zx = zext i8 %x to i32
1997   %r = mul i32 %zx, -8388608 ; -1 << 23
1998   ret i32 %r
2001 define 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]]
2008   %sx = sext i9 %x to i16
2009   %r = mul i16 %sx, -1024 ; -1 << 10
2010   ret i16 %r
2013 ; splat constant with poison element(s)
2015 define <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]]
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
2027 ; negative test - mul must be big enough to cover bitwidth diff
2029 define <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]]
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
2040 ; negative test - too many uses
2042 define 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]]
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
2055 define i32 @mul_sext_icmp_with_zero(i32 %x) {
2056 ; CHECK-LABEL: @mul_sext_icmp_with_zero(
2057 ; CHECK-NEXT:    ret i32 0
2059   %cmp = icmp eq i32 %x, 0
2060   %sext = sext i1 %cmp to i32
2061   %mul = mul i32 %sext, %x
2062   ret i32 %mul
2065 define 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]]
2071   %sext = sext i1 %x to i32
2072   %mul = mul i32 %sext, %y
2073   ret i32 %mul
2076 define 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]]
2082   %sext = sext i1 %x to i32
2083   %mul = mul nuw i32 %sext, %y
2084   ret i32 %mul
2087 define 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]]
2093   %sext = sext i1 %x to i32
2094   %mul = mul nsw i32 %sext, %y
2095   ret i32 %mul
2098 define 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]]
2104   %sext = sext i1 %x to i32
2105   %mul = mul nuw nsw i32 %sext, %y
2106   ret i32 %mul
2109 define 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]]
2116   %yy = xor i32 %y, 1
2117   %sext = sext i1 %x to i32
2118   %mul = mul i32 %yy, %sext
2119   ret i32 %mul
2122 define 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]]
2128   %sext = sext i2 %x to i32
2129   %mul = mul i32 %sext, %y
2130   ret i32 %mul
2133 define 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]]
2140   %sext = sext i1 %x to i32
2141   tail call void @use(i32 %sext)
2142   %mul = mul i32 %sext, %y
2143   ret i32 %mul
2146 define 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]]
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
2163 define 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]]
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
2176 define 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]]
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
2189 define 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]]
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