Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / InstCombine / add.ll
blobadb61cd4b9692fb74bf37c208981bb15a4ef996b
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(i8)
5 declare void @use_i1(i1)
7 define i32 @select_0_or_1_from_bool(i1 %x) {
8 ; CHECK-LABEL: @select_0_or_1_from_bool(
9 ; CHECK-NEXT:    [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
10 ; CHECK-NEXT:    [[ADD:%.*]] = zext i1 [[NOT_X]] to i32
11 ; CHECK-NEXT:    ret i32 [[ADD]]
13   %ext = sext i1 %x to i32
14   %add = add i32 %ext, 1
15   ret i32 %add
18 define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) {
19 ; CHECK-LABEL: @select_0_or_1_from_bool_vec(
20 ; CHECK-NEXT:    [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], <i1 true, i1 true>
21 ; CHECK-NEXT:    [[ADD:%.*]] = zext <2 x i1> [[NOT_X]] to <2 x i32>
22 ; CHECK-NEXT:    ret <2 x i32> [[ADD]]
24   %ext = sext <2 x i1> %x to <2 x i32>
25   %add = add <2 x i32> %ext, <i32 1, i32 1>
26   ret <2 x i32> %add
29 define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {
30 ; CHECK-LABEL: @select_C_minus_1_or_C_from_bool(
31 ; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[X:%.*]], i32 41, i32 42
32 ; CHECK-NEXT:    ret i32 [[ADD]]
34   %ext = sext i1 %x to i32
35   %add = add i32 %ext, 42
36   ret i32 %add
39 define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) {
40 ; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec(
41 ; CHECK-NEXT:    [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 41, i32 42>, <2 x i32> <i32 42, i32 43>
42 ; CHECK-NEXT:    ret <2 x i32> [[ADD]]
44   %ext = sext <2 x i1> %x to <2 x i32>
45   %add = add <2 x i32> %ext, <i32 42, i32 43>
46   ret <2 x i32> %add
49 ; This is an 'andn' of the low bit.
51 define i32 @flip_and_mask(i32 %x) {
52 ; CHECK-LABEL: @flip_and_mask(
53 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1
54 ; CHECK-NEXT:    [[INC:%.*]] = xor i32 [[TMP1]], 1
55 ; CHECK-NEXT:    ret i32 [[INC]]
57   %shl = shl i32 %x, 31
58   %shr = ashr i32 %shl, 31
59   %inc = add i32 %shr, 1
60   ret i32 %inc
63 define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {
64 ; CHECK-LABEL: @flip_and_mask_splat(
65 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], <i8 1, i8 1>
66 ; CHECK-NEXT:    [[INC:%.*]] = xor <2 x i8> [[TMP1]], <i8 1, i8 1>
67 ; CHECK-NEXT:    ret <2 x i8> [[INC]]
69   %shl = shl <2 x i8> %x, <i8 7, i8 7>
70   %shr = ashr <2 x i8> %shl, <i8 7, i8 7>
71   %inc = add <2 x i8> %shr, <i8 1, i8 1>
72   ret <2 x i8> %inc
75 define i32 @test1(i32 %A) {
76 ; CHECK-LABEL: @test1(
77 ; CHECK-NEXT:    ret i32 [[A:%.*]]
79   %B = add i32 %A, 0
80   ret i32 %B
83 define i32 @test2(i32 %A) {
84 ; CHECK-LABEL: @test2(
85 ; CHECK-NEXT:    ret i32 [[A:%.*]]
87   %B = add i32 %A, 5
88   %C = add i32 %B, -5
89   ret i32 %C
92 define i32 @test3(i32 %A) {
93 ; CHECK-LABEL: @test3(
94 ; CHECK-NEXT:    ret i32 [[A:%.*]]
96   %B = add i32 %A, 5
97   %C = sub i32 %B, 5
98   ret i32 %C
101 ; D = B + -A = B - A
102 define i32 @test4(i32 %A, i32 %B) {
103 ; CHECK-LABEL: @test4(
104 ; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
105 ; CHECK-NEXT:    ret i32 [[D]]
107   %C = sub i32 0, %A
108   %D = add i32 %B, %C
109   ret i32 %D
112 ; D = -A + B = B - A
113 define i32 @test5(i32 %A, i32 %B) {
114 ; CHECK-LABEL: @test5(
115 ; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
116 ; CHECK-NEXT:    ret i32 [[D]]
118   %C = sub i32 0, %A
119   %D = add i32 %C, %B
120   ret i32 %D
123 define i32 @test5_both_nsw(i32 %A, i32 %B) {
124 ; CHECK-LABEL: @test5_both_nsw(
125 ; CHECK-NEXT:    [[D:%.*]] = sub nsw i32 [[B:%.*]], [[A:%.*]]
126 ; CHECK-NEXT:    ret i32 [[D]]
128   %C = sub nsw i32 0, %A
129   %D = add nsw i32 %C, %B
130   ret i32 %D
133 define i32 @test5_neg_nsw(i32 %A, i32 %B) {
134 ; CHECK-LABEL: @test5_neg_nsw(
135 ; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
136 ; CHECK-NEXT:    ret i32 [[D]]
138   %C = sub nsw i32 0, %A
139   %D = add i32 %C, %B
140   ret i32 %D
143 define i32 @test5_add_nsw(i32 %A, i32 %B) {
144 ; CHECK-LABEL: @test5_add_nsw(
145 ; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
146 ; CHECK-NEXT:    ret i32 [[D]]
148   %C = sub i32 0, %A
149   %D = add nsw i32 %C, %B
150   ret i32 %D
153 define <2 x i8> @neg_op0_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) {
154 ; CHECK-LABEL: @neg_op0_vec_poison_elt(
155 ; CHECK-NEXT:    [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]]
156 ; CHECK-NEXT:    ret <2 x i8> [[R]]
158   %nega = sub <2 x i8> <i8 0, i8 poison>, %a
159   %r = add <2 x i8> %nega, %b
160   ret <2 x i8> %r
163 define <2 x i8> @neg_neg_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) {
164 ; CHECK-LABEL: @neg_neg_vec_poison_elt(
165 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]]
166 ; CHECK-NEXT:    [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
167 ; CHECK-NEXT:    ret <2 x i8> [[R]]
169   %nega = sub <2 x i8> <i8 poison, i8 0>, %a
170   %negb = sub <2 x i8> <i8 poison, i8 0>, %b
171   %r = add <2 x i8> %nega, %negb
172   ret <2 x i8> %r
175 ; C = 7*A+A == 8*A == A << 3
176 define i32 @test6(i32 %A) {
177 ; CHECK-LABEL: @test6(
178 ; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A:%.*]], 3
179 ; CHECK-NEXT:    ret i32 [[C]]
181   %B = mul i32 7, %A
182   %C = add i32 %B, %A
183   ret i32 %C
186 ; C = A+7*A == 8*A == A << 3
187 define i32 @test7(i32 %A) {
188 ; CHECK-LABEL: @test7(
189 ; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A:%.*]], 3
190 ; CHECK-NEXT:    ret i32 [[C]]
192   %B = mul i32 7, %A
193   %C = add i32 %A, %B
194   ret i32 %C
197 ; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
198 define i32 @test8(i32 %A, i32 %B) {
199 ; CHECK-LABEL: @test8(
200 ; CHECK-NEXT:    [[A1:%.*]] = and i32 [[A:%.*]], 7
201 ; CHECK-NEXT:    [[B1:%.*]] = and i32 [[B:%.*]], 128
202 ; CHECK-NEXT:    [[C:%.*]] = or disjoint i32 [[A1]], [[B1]]
203 ; CHECK-NEXT:    ret i32 [[C]]
205   %A1 = and i32 %A, 7
206   %B1 = and i32 %B, 128
207   %C = add i32 %A1, %B1
208   ret i32 %C
211 define i32 @test9(i32 %A) {
212 ; CHECK-LABEL: @test9(
213 ; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A:%.*]], 5
214 ; CHECK-NEXT:    ret i32 [[C]]
216   %B = shl i32 %A, 4
217   %C = add i32 %B, %B
218   ret i32 %C
221 ; a != -b
222 define i1 @test10(i8 %a, i8 %b) {
223 ; CHECK-LABEL: @test10(
224 ; CHECK-NEXT:    [[ADD:%.*]] = sub i8 0, [[B:%.*]]
225 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[ADD]], [[A:%.*]]
226 ; CHECK-NEXT:    ret i1 [[C]]
228   %add = add i8 %a, %b
229   %c = icmp ne i8 %add, 0
230   ret i1 %c
233 define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) {
234 ; CHECK-LABEL: @test10vec(
235 ; CHECK-NEXT:    [[C:%.*]] = sub <2 x i8> zeroinitializer, [[B:%.*]]
236 ; CHECK-NEXT:    [[D:%.*]] = icmp ne <2 x i8> [[C]], [[A:%.*]]
237 ; CHECK-NEXT:    ret <2 x i1> [[D]]
239   %c = add <2 x i8> %a, %b
240   %d = icmp ne <2 x i8> %c, zeroinitializer
241   ret <2 x i1> %d
244 define i1 @test11(i8 %A) {
245 ; CHECK-LABEL: @test11(
246 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A:%.*]], 1
247 ; CHECK-NEXT:    ret i1 [[C]]
249   %B = add i8 %A, -1
250   %c = icmp ne i8 %B, 0
251   ret i1 %c
254 define <2 x i1> @test11vec(<2 x i8> %a) {
255 ; CHECK-LABEL: @test11vec(
256 ; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], <i8 1, i8 1>
257 ; CHECK-NEXT:    ret <2 x i1> [[C]]
259   %b = add <2 x i8> %a, <i8 -1, i8 -1>
260   %c = icmp ne <2 x i8> %b, zeroinitializer
261   ret <2 x i1> %c
264 define i8 @reassoc_shl1(i8 %x, i8 %y) {
265 ; CHECK-LABEL: @reassoc_shl1(
266 ; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl i8 [[X:%.*]], 1
267 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[REASS_ADD]], [[Y:%.*]]
268 ; CHECK-NEXT:    ret i8 [[R]]
270   %a = add i8 %y, %x
271   %r = add i8 %a, %x
272   ret i8 %r
275 define <2 x i8> @reassoc_shl1_commute1(<2 x i8> %x, <2 x i8> %y) {
276 ; CHECK-LABEL: @reassoc_shl1_commute1(
277 ; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl <2 x i8> [[X:%.*]], <i8 1, i8 1>
278 ; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[REASS_ADD]], [[Y:%.*]]
279 ; CHECK-NEXT:    ret <2 x i8> [[R]]
281   %a = add <2 x i8> %x, %y
282   %r = add <2 x i8> %a, %x
283   ret <2 x i8> %r
286 define i8 @reassoc_shl1_commute2(i8 %px, i8 %py) {
287 ; CHECK-LABEL: @reassoc_shl1_commute2(
288 ; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[PX:%.*]]
289 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 43, [[PY:%.*]]
290 ; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl i8 [[X]], 1
291 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]]
292 ; CHECK-NEXT:    ret i8 [[R]]
294   %x = sdiv i8 42, %px ; thwart complexity-based canonicalization
295   %y = sdiv i8 43, %py ; thwart complexity-based canonicalization
296   %a = add i8 %y, %x
297   %r = add i8 %x, %a
298   ret i8 %r
301 define i8 @reassoc_shl1_commute3(i8 %px, i8 %py) {
302 ; CHECK-LABEL: @reassoc_shl1_commute3(
303 ; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[PX:%.*]]
304 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 43, [[PY:%.*]]
305 ; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl i8 [[X]], 1
306 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]]
307 ; CHECK-NEXT:    ret i8 [[R]]
309   %x = sdiv i8 42, %px ; thwart complexity-based canonicalization
310   %y = sdiv i8 43, %py ; thwart complexity-based canonicalization
311   %a = add i8 %x, %y
312   %r = add i8 %x, %a
313   ret i8 %r
316 define i8 @reassoc_shl1_extra_use(i8 %x, i8 %y) {
317 ; CHECK-LABEL: @reassoc_shl1_extra_use(
318 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
319 ; CHECK-NEXT:    call void @use(i8 [[A]])
320 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[A]], [[X]]
321 ; CHECK-NEXT:    ret i8 [[R]]
323   %a = add i8 %y, %x
324   call void @use(i8 %a)
325   %r = add i8 %a, %x
326   ret i8 %r
329 ;; TODO: shl A, 1?
330 define i32 @test13(i32 %A, i32 %B, i32 %C) {
331 ; CHECK-LABEL: @test13(
332 ; CHECK-NEXT:    [[D_OK:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
333 ; CHECK-NEXT:    [[E_OK:%.*]] = add i32 [[D_OK]], [[C:%.*]]
334 ; CHECK-NEXT:    [[F:%.*]] = add i32 [[E_OK]], [[A]]
335 ; CHECK-NEXT:    ret i32 [[F]]
337   %D_OK = add i32 %A, %B
338   %E_OK = add i32 %D_OK, %C
339   %F = add i32 %E_OK, %A
340   ret i32 %F
343 define i32 @test14(i32 %offset, i32 %difference) {
344 ; CHECK-LABEL: @test14(
345 ; CHECK-NEXT:    [[TMP_2:%.*]] = and i32 [[DIFFERENCE:%.*]], 3
346 ; CHECK-NEXT:    [[TMP_3_OK:%.*]] = add i32 [[TMP_2]], [[OFFSET:%.*]]
347 ; CHECK-NEXT:    [[TMP_5_MASK:%.*]] = and i32 [[DIFFERENCE]], -4
348 ; CHECK-NEXT:    [[TMP_8:%.*]] = add i32 [[TMP_3_OK]], [[TMP_5_MASK]]
349 ; CHECK-NEXT:    ret i32 [[TMP_8]]
351   %tmp.2 = and i32 %difference, 3
352   %tmp.3_OK = add i32 %tmp.2, %offset
353   %tmp.5.mask = and i32 %difference, -4
354   ; == add %offset, %difference
355   %tmp.8 = add i32 %tmp.3_OK, %tmp.5.mask
356   ret i32 %tmp.8
359 ; Only one bit set
360 define i8 @test15(i8 %A) {
361 ; CHECK-LABEL: @test15(
362 ; CHECK-NEXT:    [[C:%.*]] = and i8 [[A:%.*]], 16
363 ; CHECK-NEXT:    ret i8 [[C]]
365   %B = add i8 %A, -64
366   %C = and i8 %B, 16
367   ret i8 %C
370 define i32 @test17(i32 %A) {
371 ; CHECK-LABEL: @test17(
372 ; CHECK-NEXT:    [[C:%.*]] = sub i32 0, [[A:%.*]]
373 ; CHECK-NEXT:    ret i32 [[C]]
375   %B = xor i32 %A, -1
376   %C = add i32 %B, 1
377   ret i32 %C
380 define i8 @test18(i8 %A) {
381 ; CHECK-LABEL: @test18(
382 ; CHECK-NEXT:    [[C:%.*]] = sub i8 16, [[A:%.*]]
383 ; CHECK-NEXT:    ret i8 [[C]]
385   %B = xor i8 %A, -1
386   %C = add i8 %B, 17
387   ret i8 %C
390 ; ~X + -127 and (-128) - X with nsw are equally poisonous
391 define i8 @test18_nsw(i8 %A) {
392 ; CHECK-LABEL: @test18_nsw(
393 ; CHECK-NEXT:    [[C:%.*]] = sub nsw i8 -128, [[A:%.*]]
394 ; CHECK-NEXT:    ret i8 [[C]]
396   %B = xor i8 %A, -1
397   %C = add nsw i8 %B, -127
398   ret i8 %C
401 ; nuw couldn't propagate as nsw is.
402 define i8 @test18_nuw(i8 %A) {
403 ; CHECK-LABEL: @test18_nuw(
404 ; CHECK-NEXT:    [[C:%.*]] = sub i8 -128, [[A:%.*]]
405 ; CHECK-NEXT:    ret i8 [[C]]
407   %B = xor i8 %A, -1
408   %C = add nuw i8 %B, -127
409   ret i8 %C
412 ; 127 - X with nsw will be more poisonous than ~X + -128 with nsw. (see X = -1)
413 define i8 @test18_nsw_overflow(i8 %A) {
414 ; CHECK-LABEL: @test18_nsw_overflow(
415 ; CHECK-NEXT:    [[C:%.*]] = sub i8 127, [[A:%.*]]
416 ; CHECK-NEXT:    ret i8 [[C]]
418   %B = xor i8 %A, -1
419   %C = add nsw i8 %B, -128
420   ret i8 %C
423 define <2 x i64> @test18vec(<2 x i64> %A) {
424 ; CHECK-LABEL: @test18vec(
425 ; CHECK-NEXT:    [[ADD:%.*]] = sub <2 x i64> <i64 1, i64 2>, [[A:%.*]]
426 ; CHECK-NEXT:    ret <2 x i64> [[ADD]]
428   %xor = xor <2 x i64> %A, <i64 -1, i64 -1>
429   %add = add <2 x i64> %xor, <i64 2, i64 3>
430   ret <2 x i64> %add
433 define <2 x i8> @test18vec_nsw(<2 x i8> %A) {
434 ; CHECK-LABEL: @test18vec_nsw(
435 ; CHECK-NEXT:    [[C:%.*]] = sub nsw <2 x i8> <i8 -124, i8 -125>, [[A:%.*]]
436 ; CHECK-NEXT:    ret <2 x i8> [[C]]
438   %B = xor <2 x i8> %A, <i8 -1, i8 -1>
439   %C = add nsw <2 x i8> %B, <i8 -123, i8 -124>
440   ret <2 x i8> %C
443 define <2 x i8> @test18vec_nsw_false(<2 x i8> %A) {
444 ; CHECK-LABEL: @test18vec_nsw_false(
445 ; CHECK-NEXT:    [[C:%.*]] = sub nsw <2 x i8> <i8 -125, i8 -126>, [[A:%.*]]
446 ; CHECK-NEXT:    ret <2 x i8> [[C]]
448   %B = xor <2 x i8> %A, <i8 -1, i8 -1>
449   %C = add nsw <2 x i8> %B, <i8 -124, i8 -125>
450   ret <2 x i8> %C
454 define <2 x i8> @test18vec_nuw(<2 x i8> %A) {
455 ; CHECK-LABEL: @test18vec_nuw(
456 ; CHECK-NEXT:    [[C:%.*]] = sub <2 x i8> <i8 -128, i8 -127>, [[A:%.*]]
457 ; CHECK-NEXT:    ret <2 x i8> [[C]]
459   %B = xor <2 x i8> %A, <i8 -1, i8 -1>
460   %C = add nuw <2 x i8> %B, <i8 -127, i8 -126>
461   ret <2 x i8> %C
464 define <2 x i8> @test18vec_nsw_overflow(<2 x i8> %A) {
465 ; CHECK-LABEL: @test18vec_nsw_overflow(
466 ; CHECK-NEXT:    [[C:%.*]] = sub <2 x i8> <i8 -128, i8 127>, [[A:%.*]]
467 ; CHECK-NEXT:    ret <2 x i8> [[C]]
469   %B = xor <2 x i8> %A, <i8 -1, i8 -1>
470   %C = add nsw <2 x i8> %B, <i8 -127, i8 -128>
471   ret <2 x i8> %C
474 define i32 @test19(i1 %C) {
475 ; CHECK-LABEL: @test19(
476 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
477 ; CHECK-NEXT:    ret i32 [[V]]
479   %A = select i1 %C, i32 1000, i32 10
480   %V = add i32 %A, 123
481   ret i32 %V
484 define <2 x i32> @test19vec(i1 %C) {
485 ; CHECK-LABEL: @test19vec(
486 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
487 ; CHECK-NEXT:    ret <2 x i32> [[V]]
489   %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
490   %V = add <2 x i32> %A, <i32 123, i32 123>
491   ret <2 x i32> %V
494 ; This is an InstSimplify fold, but test it here to make sure that
495 ; InstCombine does not prevent the fold.
496 ; With NSW, add of sign bit -> or of sign bit.
498 define i32 @test20(i32 %x) {
499 ; CHECK-LABEL: @test20(
500 ; CHECK-NEXT:    ret i32 [[X:%.*]]
502   %y = xor i32 %x, -2147483648
503   %z = add nsw i32 %y, -2147483648
504   ret i32 %z
507 define i32 @xor_sign_bit(i32 %x) {
508 ; CHECK-LABEL: @xor_sign_bit(
509 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], -2147483606
510 ; CHECK-NEXT:    ret i32 [[ADD]]
512   %xor = xor i32 %x, 2147483648
513   %add = add i32 %xor, 42
514   ret i32 %add
517 define <2 x i32> @xor_sign_bit_vec_splat(<2 x i32> %x) {
518 ; CHECK-LABEL: @xor_sign_bit_vec_splat(
519 ; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> [[X:%.*]], <i32 -2147483606, i32 -2147483606>
520 ; CHECK-NEXT:    ret <2 x i32> [[ADD]]
522   %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648>
523   %add = add <2 x i32> %xor, <i32 42, i32 42>
524   ret <2 x i32> %add
527 ; No-wrap info allows converting the add to 'or'.
529 define i8 @add_nsw_signbit(i8 %x) {
530 ; CHECK-LABEL: @add_nsw_signbit(
531 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -128
532 ; CHECK-NEXT:    ret i8 [[Y]]
534   %y = add nsw i8 %x, -128
535   ret i8 %y
538 ; No-wrap info allows converting the add to 'or'.
540 define i8 @add_nuw_signbit(i8 %x) {
541 ; CHECK-LABEL: @add_nuw_signbit(
542 ; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -128
543 ; CHECK-NEXT:    ret i8 [[Y]]
545   %y = add nuw i8 %x, 128
546   ret i8 %y
549 define i32 @add_nsw_sext_add(i8 %x) {
550 ; CHECK-LABEL: @add_nsw_sext_add(
551 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
552 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 398
553 ; CHECK-NEXT:    ret i32 [[R]]
555   %add = add nsw i8 %x, 42
556   %ext = sext i8 %add to i32
557   %r = add i32 %ext, 356
558   ret i32 %r
561 ; Negative test - extra use of the sext means increase of instructions.
563 define i32 @add_nsw_sext_add_extra_use_1(i8 %x, ptr %p) {
564 ; CHECK-LABEL: @add_nsw_sext_add_extra_use_1(
565 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X:%.*]], 42
566 ; CHECK-NEXT:    [[EXT:%.*]] = sext i8 [[ADD]] to i32
567 ; CHECK-NEXT:    store i32 [[EXT]], ptr [[P:%.*]], align 4
568 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[EXT]], 356
569 ; CHECK-NEXT:    ret i32 [[R]]
571   %add = add nsw i8 %x, 42
572   %ext = sext i8 %add to i32
573   store i32 %ext, ptr %p
574   %r = add i32 %ext, 356
575   ret i32 %r
578 define <2 x i32> @add_nsw_sext_add_vec_extra_use_2(<2 x i8> %x, ptr %p) {
579 ; CHECK-LABEL: @add_nsw_sext_add_vec_extra_use_2(
580 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw <2 x i8> [[X:%.*]], <i8 42, i8 -5>
581 ; CHECK-NEXT:    store <2 x i8> [[ADD]], ptr [[P:%.*]], align 2
582 ; CHECK-NEXT:    [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>
583 ; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 398, i32 7>
584 ; CHECK-NEXT:    ret <2 x i32> [[R]]
586   %add = add nsw <2 x i8> %x, <i8 42, i8 -5>
587   store <2 x i8> %add, ptr %p
588   %ext = sext <2 x i8> %add to <2 x i32>
589   %r = add <2 x i32> %ext, <i32 356, i32 12>
590   ret <2 x i32> %r
593 define <2 x i32> @add_nuw_zext_add_vec(<2 x i16> %x) {
594 ; CHECK-LABEL: @add_nuw_zext_add_vec(
595 ; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32>
596 ; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 65850, i32 -7>
597 ; CHECK-NEXT:    ret <2 x i32> [[R]]
599   %add = add nuw <2 x i16> %x, <i16 -42, i16 5>
600   %ext = zext <2 x i16> %add to <2 x i32>
601   %r = add <2 x i32> %ext, <i32 356, i32 -12>
602   ret <2 x i32> %r
605 ; Negative test - extra use of the zext means increase of instructions.
607 define i64 @add_nuw_zext_add_extra_use_1(i8 %x, ptr %p) {
608 ; CHECK-LABEL: @add_nuw_zext_add_extra_use_1(
609 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
610 ; CHECK-NEXT:    [[EXT:%.*]] = zext i8 [[ADD]] to i64
611 ; CHECK-NEXT:    store i64 [[EXT]], ptr [[P:%.*]], align 4
612 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i64 [[EXT]], 356
613 ; CHECK-NEXT:    ret i64 [[R]]
615   %add = add nuw i8 %x, 42
616   %ext = zext i8 %add to i64
617   store i64 %ext, ptr %p
618   %r = add i64 %ext, 356
619   ret i64 %r
622 define i64 @add_nuw_zext_add_extra_use_2(i8 %x, ptr %p) {
623 ; CHECK-LABEL: @add_nuw_zext_add_extra_use_2(
624 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
625 ; CHECK-NEXT:    store i8 [[ADD]], ptr [[P:%.*]], align 1
626 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[X]] to i64
627 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i64 [[TMP1]], -314
628 ; CHECK-NEXT:    ret i64 [[R]]
630   %add = add nuw i8 %x, 42
631   store i8 %add, ptr %p
632   %ext = zext i8 %add to i64
633   %r = add i64 %ext, -356
634   ret i64 %r
637 define i1 @test21(i32 %x) {
638 ; CHECK-LABEL: @test21(
639 ; CHECK-NEXT:    [[Y:%.*]] = icmp eq i32 [[X:%.*]], 119
640 ; CHECK-NEXT:    ret i1 [[Y]]
642   %t = add i32 %x, 4
643   %y = icmp eq i32 %t, 123
644   ret i1 %y
647 define <2 x i1> @test21vec(<2 x i32> %x) {
648 ; CHECK-LABEL: @test21vec(
649 ; CHECK-NEXT:    [[Y:%.*]] = icmp eq <2 x i32> [[X:%.*]], <i32 119, i32 119>
650 ; CHECK-NEXT:    ret <2 x i1> [[Y]]
652   %t = add <2 x i32> %x, <i32 4, i32 4>
653   %y = icmp eq <2 x i32> %t, <i32 123, i32 123>
654   ret <2 x i1> %y
657 define i32 @test22(i32 %V) {
658 ; CHECK-LABEL: @test22(
659 ; CHECK-NEXT:    switch i32 [[V:%.*]], label [[DEFAULT:%.*]] [
660 ; CHECK-NEXT:      i32 10, label [[LAB1:%.*]]
661 ; CHECK-NEXT:      i32 20, label [[LAB2:%.*]]
662 ; CHECK-NEXT:    ]
663 ; CHECK:       Default:
664 ; CHECK-NEXT:    ret i32 123
665 ; CHECK:       Lab1:
666 ; CHECK-NEXT:    ret i32 12312
667 ; CHECK:       Lab2:
668 ; CHECK-NEXT:    ret i32 1231231
670   %V2 = add i32 %V, 10
671   switch i32 %V2, label %Default [
672   i32 20, label %Lab1
673   i32 30, label %Lab2
674   ]
676 Default:                ; preds = %0
677   ret i32 123
679 Lab1:           ; preds = %0
680   ret i32 12312
682 Lab2:           ; preds = %0
683   ret i32 1231231
686 define i32 @test23(i1 %C, i32 %a) {
687 ; CHECK-LABEL: @test23(
688 ; CHECK-NEXT:  entry:
689 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]]
690 ; CHECK:       else:
691 ; CHECK-NEXT:    br label [[ENDIF]]
692 ; CHECK:       endif:
693 ; CHECK-NEXT:    [[B_0:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[ELSE]] ]
694 ; CHECK-NEXT:    ret i32 [[B_0]]
696 entry:
697   br i1 %C, label %endif, label %else
699 else:           ; preds = %entry
700   br label %endif
702 endif:          ; preds = %else, %entry
703   %b.0 = phi i32 [ 0, %entry ], [ 1, %else ]
704   %tmp.4 = add i32 %b.0, 1
705   ret i32 %tmp.4
708 define i32 @test24(i32 %A) {
709 ; CHECK-LABEL: @test24(
710 ; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 1
711 ; CHECK-NEXT:    ret i32 [[B]]
713   %B = add i32 %A, 1
714   %C = shl i32 %B, 1
715   %D = sub i32 %C, 2
716   ret i32 %D
719 define i64 @test25(i64 %Y) {
720 ; CHECK-LABEL: @test25(
721 ; CHECK-NEXT:    [[TMP_8:%.*]] = shl i64 [[Y:%.*]], 3
722 ; CHECK-NEXT:    ret i64 [[TMP_8]]
724   %tmp.4 = shl i64 %Y, 2
725   %tmp.12 = shl i64 %Y, 2
726   %tmp.8 = add i64 %tmp.4, %tmp.12
727   ret i64 %tmp.8
730 define i32 @test26(i32 %A, i32 %B) {
731 ; CHECK-LABEL: @test26(
732 ; CHECK-NEXT:    ret i32 [[A:%.*]]
734   %C = add i32 %A, %B
735   %D = sub i32 %C, %B
736   ret i32 %D
739 ; Fold add through select.
740 define i32 @test27(i1 %C, i32 %X, i32 %Y) {
741 ; CHECK-LABEL: @test27(
742 ; CHECK-NEXT:    [[C_UPGRD_1_V:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 123
743 ; CHECK-NEXT:    ret i32 [[C_UPGRD_1_V]]
745   %A = add i32 %X, %Y
746   %B = add i32 %Y, 123
747   %C.upgrd.1 = select i1 %C, i32 %A, i32 %B
748   %D = sub i32 %C.upgrd.1, %Y
749   ret i32 %D
752 define i32 @test28(i32 %X) {
753 ; CHECK-LABEL: @test28(
754 ; CHECK-NEXT:    [[Z:%.*]] = sub i32 -1192, [[X:%.*]]
755 ; CHECK-NEXT:    ret i32 [[Z]]
757   %Y = add i32 %X, 1234
758   %Z = sub i32 42, %Y
759   ret i32 %Z
762 define i32 @test29(i32 %x, i32 %y) {
763 ; CHECK-LABEL: @test29(
764 ; CHECK-NEXT:    [[TMP_2:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
765 ; CHECK-NEXT:    [[TMP_7:%.*]] = and i32 [[X]], 63
766 ; CHECK-NEXT:    [[TMP_9:%.*]] = and i32 [[TMP_2]], -64
767 ; CHECK-NEXT:    [[TMP_10:%.*]] = or disjoint i32 [[TMP_7]], [[TMP_9]]
768 ; CHECK-NEXT:    ret i32 [[TMP_10]]
770   %tmp.2 = sub i32 %x, %y
771   %tmp.2.mask = and i32 %tmp.2, 63
772   %tmp.6 = add i32 %tmp.2.mask, %y
773   %tmp.7 = and i32 %tmp.6, 63
774   %tmp.9 = and i32 %tmp.2, -64
775   %tmp.10 = or i32 %tmp.7, %tmp.9
776   ret i32 %tmp.10
779 ; Add of sign bit -> xor of sign bit.
780 define i64 @test30(i64 %x) {
781 ; CHECK-LABEL: @test30(
782 ; CHECK-NEXT:    ret i64 [[X:%.*]]
784   %tmp.2 = xor i64 %x, -9223372036854775808
785   %tmp.4 = add i64 %tmp.2, -9223372036854775808
786   ret i64 %tmp.4
789 define i32 @test31(i32 %A) {
790 ; CHECK-LABEL: @test31(
791 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 5
792 ; CHECK-NEXT:    ret i32 [[TMP1]]
794   %B = add i32 %A, 4
795   %C = mul i32 %B, 5
796   %D = sub i32 %C, 20
797   ret i32 %D
800 define i32 @test32(i32 %A) {
801 ; CHECK-LABEL: @test32(
802 ; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 2
803 ; CHECK-NEXT:    ret i32 [[B]]
805   %B = add i32 %A, 4
806   %C = shl i32 %B, 2
807   %D = sub i32 %C, 16
808   ret i32 %D
811 define i8 @test33(i8 %A) {
812 ; CHECK-LABEL: @test33(
813 ; CHECK-NEXT:    [[C:%.*]] = or i8 [[A:%.*]], 1
814 ; CHECK-NEXT:    ret i8 [[C]]
816   %B = and i8 %A, -2
817   %C = add i8 %B, 1
818   ret i8 %C
821 define i8 @test34(i8 %A) {
822 ; CHECK-LABEL: @test34(
823 ; CHECK-NEXT:    [[C:%.*]] = and i8 [[A:%.*]], 12
824 ; CHECK-NEXT:    ret i8 [[C]]
826   %B = add i8 %A, 64
827   %C = and i8 %B, 12
828   ret i8 %C
831 ; If all bits affected by the add are included
832 ; in the mask, do the mask op before the add.
834 define i8 @masked_add(i8 %x) {
835 ; CHECK-LABEL: @masked_add(
836 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], -16
837 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[AND]], 96
838 ; CHECK-NEXT:    ret i8 [[R]]
840   %and = and i8 %x, 240 ; 0xf0
841   %r = add i8 %and, 96  ; 0x60
842   ret i8 %r
845 define <2 x i8> @masked_add_splat(<2 x i8> %x) {
846 ; CHECK-LABEL: @masked_add_splat(
847 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[X:%.*]], <i8 -64, i8 -64>
848 ; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[AND]], <i8 64, i8 64>
849 ; CHECK-NEXT:    ret <2 x i8> [[R]]
851   %and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0
852   %r = add <2 x i8> %and, <i8 64, i8 64>  ; 0x40
853   ret <2 x i8> %r
856 define i8 @not_masked_add(i8 %x) {
857 ; CHECK-LABEL: @not_masked_add(
858 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], 112
859 ; CHECK-NEXT:    [[R:%.*]] = add nuw i8 [[AND]], 96
860 ; CHECK-NEXT:    ret i8 [[R]]
862   %and = and i8 %x, 112 ; 0x70
863   %r = add i8 %and, 96  ; 0x60
864   ret i8 %r
867 define i8 @masked_add_multi_use(i8 %x) {
868 ; CHECK-LABEL: @masked_add_multi_use(
869 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], -16
870 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[AND]], 96
871 ; CHECK-NEXT:    call void @use(i8 [[AND]])
872 ; CHECK-NEXT:    ret i8 [[R]]
874   %and = and i8 %x, -16 ; 0xf0
875   %r = add i8 %and, 96  ; 0x60
876   call void @use(i8 %and) ; extra use
877   ret i8 %r
880 define i32 @test35(i32 %a) {
881 ; CHECK-LABEL: @test35(
882 ; CHECK-NEXT:    ret i32 -1
884   %tmpnot = xor i32 %a, -1
885   %tmp2 = add i32 %tmpnot, %a
886   ret i32 %tmp2
889 define i32 @test36(i32 %a) {
890 ; CHECK-LABEL: @test36(
891 ; CHECK-NEXT:    ret i32 0
893   %x = and i32 %a, -2
894   %y = and i32 %a, -126
895   %z = add i32 %x, %y
896   %q = and i32 %z, 1  ; always zero
897   ret i32 %q
900 define i1 @test37(i32 %a, i32 %b) {
901 ; CHECK-LABEL: @test37(
902 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
903 ; CHECK-NEXT:    ret i1 [[CMP]]
905   %add = add i32 %a, %b
906   %cmp = icmp eq i32 %add, %a
907   ret i1 %cmp
910 define i1 @test38(i32 %a, i32 %b) {
911 ; CHECK-LABEL: @test38(
912 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
913 ; CHECK-NEXT:    ret i1 [[CMP]]
915   %add = add i32 %a, %b
916   %cmp = icmp eq i32 %add, %b
917   ret i1 %cmp
920 define i1 @test39(i32 %a, i32 %b) {
921 ; CHECK-LABEL: @test39(
922 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
923 ; CHECK-NEXT:    ret i1 [[CMP]]
925   %add = add i32 %b, %a
926   %cmp = icmp eq i32 %add, %a
927   ret i1 %cmp
930 define i1 @test40(i32 %a, i32 %b) {
931 ; CHECK-LABEL: @test40(
932 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
933 ; CHECK-NEXT:    ret i1 [[CMP]]
935   %add = add i32 %b, %a
936   %cmp = icmp eq i32 %add, %b
937   ret i1 %cmp
940 ; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
942 define i64 @test41(i32 %a) {
943 ; CHECK-LABEL: @test41(
944 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i32 [[A:%.*]], 15
945 ; CHECK-NEXT:    [[SUB:%.*]] = zext i32 [[TMP1]] to i64
946 ; CHECK-NEXT:    ret i64 [[SUB]]
948   %add = add nuw i32 %a, 16
949   %zext = zext i32 %add to i64
950   %sub = add i64 %zext, -1
951   ret i64 %sub
954 define i64 @test41_multiuse_constants_cancel(i32 %a) {
955 ; CHECK-LABEL: @test41_multiuse_constants_cancel(
956 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A:%.*]], 1
957 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[ADD]] to i64
958 ; CHECK-NEXT:    [[SUB:%.*]] = zext i32 [[A]] to i64
959 ; CHECK-NEXT:    [[EXTRAUSE:%.*]] = add nuw nsw i64 [[ZEXT]], [[SUB]]
960 ; CHECK-NEXT:    ret i64 [[EXTRAUSE]]
962   %add = add nuw i32 %a, 1
963   %zext = zext i32 %add to i64
964   %sub = add i64 %zext, -1
965   %extrause = add i64 %zext, %sub
966   ret i64 %extrause
969 ; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
971 define <2 x i64> @test41vec(<2 x i32> %a) {
972 ; CHECK-LABEL: @test41vec(
973 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 15, i32 15>
974 ; CHECK-NEXT:    [[SUB:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
975 ; CHECK-NEXT:    ret <2 x i64> [[SUB]]
977   %add = add nuw <2 x i32> %a, <i32 16, i32 16>
978   %zext = zext <2 x i32> %add to <2 x i64>
979   %sub = add <2 x i64> %zext, <i64 -1, i64 -1>
980   ret <2 x i64> %sub
983 define <2 x i64> @test41vec_and_multiuse(<2 x i32> %a) {
984 ; CHECK-LABEL: @test41vec_and_multiuse(
985 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i32> [[A:%.*]], <i32 16, i32 16>
986 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i32> [[ADD]] to <2 x i64>
987 ; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl nuw nsw <2 x i64> [[ZEXT]], <i64 1, i64 1>
988 ; CHECK-NEXT:    [[EXTRAUSE:%.*]] = add nsw <2 x i64> [[REASS_ADD]], <i64 -1, i64 -1>
989 ; CHECK-NEXT:    ret <2 x i64> [[EXTRAUSE]]
991   %add = add nuw <2 x i32> %a, <i32 16, i32 16>
992   %zext = zext <2 x i32> %add to <2 x i64>
993   %sub = add <2 x i64> %zext, <i64 -1, i64 -1>
994   %extrause = add <2 x i64> %zext, %sub
995   ret <2 x i64> %extrause
998 define i32 @test42(i1 %C) {
999 ; CHECK-LABEL: @test42(
1000 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
1001 ; CHECK-NEXT:    ret i32 [[V]]
1003   %A = select i1 %C, i32 1000, i32 10
1004   %V = add i32 123, %A
1005   ret i32 %V
1008 define <2 x i32> @test42vec(i1 %C) {
1009 ; CHECK-LABEL: @test42vec(
1010 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 1123>, <2 x i32> <i32 133, i32 133>
1011 ; CHECK-NEXT:    ret <2 x i32> [[V]]
1013   %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
1014   %V = add <2 x i32> <i32 123, i32 123>, %A
1015   ret <2 x i32> %V
1018 define <2 x i32> @test42vec2(i1 %C) {
1019 ; CHECK-LABEL: @test42vec2(
1020 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363>
1021 ; CHECK-NEXT:    ret <2 x i32> [[V]]
1023   %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
1024   %V = add <2 x i32> <i32 123, i32 333>, %A
1025   ret <2 x i32> %V
1028 define i32 @test55(i1 %which) {
1029 ; CHECK-LABEL: @test55(
1030 ; CHECK-NEXT:  entry:
1031 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1032 ; CHECK:       delay:
1033 ; CHECK-NEXT:    br label [[FINAL]]
1034 ; CHECK:       final:
1035 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ]
1036 ; CHECK-NEXT:    ret i32 [[A]]
1038 entry:
1039   br i1 %which, label %final, label %delay
1041 delay:
1042   br label %final
1044 final:
1045   %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
1046   %value = add i32 123, %A
1047   ret i32 %value
1050 define <2 x i32> @test43vec(i1 %which) {
1051 ; CHECK-LABEL: @test43vec(
1052 ; CHECK-NEXT:  entry:
1053 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1054 ; CHECK:       delay:
1055 ; CHECK-NEXT:    br label [[FINAL]]
1056 ; CHECK:       final:
1057 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 1123>, [[ENTRY:%.*]] ], [ <i32 133, i32 133>, [[DELAY]] ]
1058 ; CHECK-NEXT:    ret <2 x i32> [[A]]
1060 entry:
1061   br i1 %which, label %final, label %delay
1063 delay:
1064   br label %final
1066 final:
1067   %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
1068   %value = add <2 x i32> <i32 123, i32 123>, %A
1069   ret <2 x i32> %value
1072 define <2 x i32> @test43vec2(i1 %which) {
1073 ; CHECK-LABEL: @test43vec2(
1074 ; CHECK-NEXT:  entry:
1075 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1076 ; CHECK:       delay:
1077 ; CHECK-NEXT:    br label [[FINAL]]
1078 ; CHECK:       final:
1079 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ]
1080 ; CHECK-NEXT:    ret <2 x i32> [[A]]
1082 entry:
1083   br i1 %which, label %final, label %delay
1085 delay:
1086   br label %final
1088 final:
1089   %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
1090   %value = add <2 x i32> <i32 123, i32 333>, %A
1091   ret <2 x i32> %value
1094 ; E = (A + 1) + ~B = A - B
1095 define i32 @add_not_increment(i32 %A, i32 %B) {
1096 ; CHECK-LABEL: @add_not_increment(
1097 ; CHECK-NEXT:    [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
1098 ; CHECK-NEXT:    ret i32 [[E]]
1100   %C = xor i32 %B, -1
1101   %D = add i32 %A, 1
1102   %E = add i32 %D, %C
1103   ret i32 %E
1106 ; E = (A + 1) + ~B = A - B
1107 define <2 x i32> @add_not_increment_vec(<2 x i32> %A, <2 x i32> %B) {
1108 ; CHECK-LABEL: @add_not_increment_vec(
1109 ; CHECK-NEXT:    [[E:%.*]] = sub <2 x i32> [[A:%.*]], [[B:%.*]]
1110 ; CHECK-NEXT:    ret <2 x i32> [[E]]
1112   %C = xor <2 x i32> %B, <i32 -1, i32 -1>
1113   %D = add <2 x i32> %A, <i32 1, i32 1>
1114   %E = add <2 x i32> %D, %C
1115   ret <2 x i32> %E
1118 ; E = ~B + (1 + A) = A - B
1119 define i32 @add_not_increment_commuted(i32 %A, i32 %B) {
1120 ; CHECK-LABEL: @add_not_increment_commuted(
1121 ; CHECK-NEXT:    [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
1122 ; CHECK-NEXT:    ret i32 [[E]]
1124   %C = xor i32 %B, -1
1125   %D = add i32 %A, 1
1126   %E = add i32 %C, %D
1127   ret i32 %E
1130 ; E = (A + ~B) + 1 = A - B
1131 define i32 @add_to_sub(i32 %M, i32 %B) {
1132 ; CHECK-LABEL: @add_to_sub(
1133 ; CHECK-NEXT:    [[A:%.*]] = mul i32 [[M:%.*]], 42
1134 ; CHECK-NEXT:    [[E:%.*]] = sub i32 [[A]], [[B:%.*]]
1135 ; CHECK-NEXT:    ret i32 [[E]]
1137   %A = mul i32 %M, 42          ; thwart complexity-based ordering
1138   %C = xor i32 %B, -1
1139   %D = add i32 %A, %C
1140   %E = add i32 %D, 1
1141   ret i32 %E
1144 ; E = (~B + A) + 1 = A - B
1145 define i32 @add_to_sub2(i32 %A, i32 %M) {
1146 ; CHECK-LABEL: @add_to_sub2(
1147 ; CHECK-NEXT:    [[B_NEG:%.*]] = mul i32 [[M:%.*]], -42
1148 ; CHECK-NEXT:    [[E:%.*]] = add i32 [[B_NEG]], [[A:%.*]]
1149 ; CHECK-NEXT:    ret i32 [[E]]
1151   %B = mul i32 %M, 42          ; thwart complexity-based ordering
1152   %C = xor i32 %B, -1
1153   %D = add i32 %C, %A
1154   %E = add i32 %D, 1
1155   ret i32 %E
1158 ; (X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2)
1159 define i32 @test44(i32 %A) {
1160 ; CHECK-LABEL: @test44(
1161 ; CHECK-NEXT:    [[C:%.*]] = and i32 [[A:%.*]], -124
1162 ; CHECK-NEXT:    ret i32 [[C]]
1164   %B = or i32 %A, 123
1165   %C = add i32 %B, -123
1166   ret i32 %C
1169 define i32 @test44_extra_use(i32 %A) {
1170 ; CHECK-LABEL: @test44_extra_use(
1171 ; CHECK-NEXT:    [[B:%.*]] = or i32 [[A:%.*]], 123
1172 ; CHECK-NEXT:    [[C:%.*]] = and i32 [[A]], -124
1173 ; CHECK-NEXT:    [[D:%.*]] = mul i32 [[B]], [[C]]
1174 ; CHECK-NEXT:    ret i32 [[D]]
1176   %B = or i32 %A, 123
1177   %C = add i32 %B, -123
1178   %D = mul i32 %B, %C
1179   ret i32 %D
1182 define i32 @test44_non_matching(i32 %A) {
1183 ; CHECK-LABEL: @test44_non_matching(
1184 ; CHECK-NEXT:    [[B:%.*]] = or i32 [[A:%.*]], 123
1185 ; CHECK-NEXT:    [[C:%.*]] = add i32 [[B]], -321
1186 ; CHECK-NEXT:    ret i32 [[C]]
1188   %B = or i32 %A, 123
1189   %C = add i32 %B, -321
1190   ret i32 %C
1193 define <2 x i32> @test44_vec(<2 x i32> %A) {
1194 ; CHECK-LABEL: @test44_vec(
1195 ; CHECK-NEXT:    [[C:%.*]] = and <2 x i32> [[A:%.*]], <i32 -124, i32 -124>
1196 ; CHECK-NEXT:    ret <2 x i32> [[C]]
1198   %B = or <2 x i32> %A, <i32 123, i32 123>
1199   %C = add <2 x i32> %B, <i32 -123, i32 -123>
1200   ret <2 x i32> %C
1203 define <2 x i32> @test44_vec_non_matching(<2 x i32> %A) {
1204 ; CHECK-LABEL: @test44_vec_non_matching(
1205 ; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 123>
1206 ; CHECK-NEXT:    [[C:%.*]] = add <2 x i32> [[B]], <i32 -321, i32 -321>
1207 ; CHECK-NEXT:    ret <2 x i32> [[C]]
1209   %B = or <2 x i32> %A, <i32 123, i32 123>
1210   %C = add <2 x i32> %B, <i32 -321, i32 -321>
1211   ret <2 x i32> %C
1214 define <2 x i32> @test44_vec_poison(<2 x i32> %A) {
1215 ; CHECK-LABEL: @test44_vec_poison(
1216 ; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 poison>
1217 ; CHECK-NEXT:    [[C:%.*]] = add nsw <2 x i32> [[B]], <i32 -123, i32 poison>
1218 ; CHECK-NEXT:    ret <2 x i32> [[C]]
1220   %B = or <2 x i32> %A, <i32 123, i32 poison>
1221   %C = add <2 x i32> %B, <i32 -123, i32 poison>
1222   ret <2 x i32> %C
1225 define <2 x i32> @test44_vec_non_splat(<2 x i32> %A) {
1226 ; CHECK-LABEL: @test44_vec_non_splat(
1227 ; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 456>
1228 ; CHECK-NEXT:    [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 -456>
1229 ; CHECK-NEXT:    ret <2 x i32> [[C]]
1231   %B = or <2 x i32> %A, <i32 123, i32 456>
1232   %C = add <2 x i32> %B, <i32 -123, i32 -456>
1233   ret <2 x i32> %C
1236 define i32 @lshr_add(i1 %x, i1 %y) {
1237 ; CHECK-LABEL: @lshr_add(
1238 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[X:%.*]], true
1239 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[Y:%.*]]
1240 ; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP2]] to i32
1241 ; CHECK-NEXT:    ret i32 [[R]]
1243   %xz = zext i1 %x to i32
1244   %ys = sext i1 %y to i32
1245   %sub = add i32 %xz, %ys
1246   %r = lshr i32 %sub, 31
1247   ret i32 %r
1250 define i5 @and_add(i1 %x, i1 %y) {
1251 ; CHECK-LABEL: @and_add(
1252 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[X:%.*]], true
1253 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP1]], [[Y:%.*]]
1254 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i5 -2, i5 0
1255 ; CHECK-NEXT:    ret i5 [[R]]
1257   %xz = zext i1 %x to i5
1258   %ys = sext i1 %y to i5
1259   %sub = add i5 %xz, %ys
1260   %r = and i5 %sub, 30
1261   ret i5 %r
1264 define <2 x i8> @ashr_add_commute(<2 x i1> %x, <2 x i1> %y) {
1265 ; CHECK-LABEL: @ashr_add_commute(
1266 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], <i1 true, i1 true>
1267 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i1> [[TMP1]], [[Y:%.*]]
1268 ; CHECK-NEXT:    [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i8>
1269 ; CHECK-NEXT:    ret <2 x i8> [[TMP3]]
1271   %xz = zext <2 x i1> %x to <2 x i8>
1272   %ys = sext <2 x i1> %y to <2 x i8>
1273   %sub = add nsw <2 x i8> %ys, %xz
1274   %r = ashr <2 x i8> %sub, <i8 1, i8 1>
1275   ret <2 x i8> %r
1278 define i32 @cmp_math(i32 %x, i32 %y) {
1279 ; CHECK-LABEL: @cmp_math(
1280 ; CHECK-NEXT:    [[LT:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
1281 ; CHECK-NEXT:    [[R:%.*]] = zext i1 [[LT]] to i32
1282 ; CHECK-NEXT:    ret i32 [[R]]
1284   %gt = icmp ugt i32 %x, %y
1285   %lt = icmp ult i32 %x, %y
1286   %xz = zext i1 %gt to i32
1287   %yz = zext i1 %lt to i32
1288   %s = sub i32 %xz, %yz
1289   %r = lshr i32 %s, 31
1290   ret i32 %r
1293 ; Negative test - wrong type
1295 define i32 @lshr_add_nonbool(i2 %x, i1 %y) {
1296 ; CHECK-LABEL: @lshr_add_nonbool(
1297 ; CHECK-NEXT:    [[XZ:%.*]] = zext i2 [[X:%.*]] to i32
1298 ; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1299 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1300 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1301 ; CHECK-NEXT:    ret i32 [[R]]
1303   %xz = zext i2 %x to i32
1304   %ys = sext i1 %y to i32
1305   %sub = add i32 %xz, %ys
1306   %r = lshr i32 %sub, 31
1307   ret i32 %r
1310 ; Negative test - wrong demand
1312 define i32 @and31_add(i1 %x, i1 %y) {
1313 ; CHECK-LABEL: @and31_add(
1314 ; CHECK-NEXT:    [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1315 ; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1316 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1317 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[SUB]], 31
1318 ; CHECK-NEXT:    ret i32 [[R]]
1320   %xz = zext i1 %x to i32
1321   %ys = sext i1 %y to i32
1322   %sub = add i32 %xz, %ys
1323   %r = and i32 %sub, 31
1324   ret i32 %r
1327 ; Negative test - extra use
1329 define i32 @lshr_add_use(i1 %x, i1 %y, ptr %p) {
1330 ; CHECK-LABEL: @lshr_add_use(
1331 ; CHECK-NEXT:    [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1332 ; CHECK-NEXT:    store i32 [[XZ]], ptr [[P:%.*]], align 4
1333 ; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1334 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1335 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1336 ; CHECK-NEXT:    ret i32 [[R]]
1338   %xz = zext i1 %x to i32
1339   store i32 %xz, ptr %p
1340   %ys = sext i1 %y to i32
1341   %sub = add i32 %xz, %ys
1342   %r = lshr i32 %sub, 31
1343   ret i32 %r
1346 ; Negative test - extra use
1348 define i32 @lshr_add_use2(i1 %x, i1 %y, ptr %p) {
1349 ; CHECK-LABEL: @lshr_add_use2(
1350 ; CHECK-NEXT:    [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1351 ; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1352 ; CHECK-NEXT:    store i32 [[YS]], ptr [[P:%.*]], align 4
1353 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1354 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1355 ; CHECK-NEXT:    ret i32 [[R]]
1357   %xz = zext i1 %x to i32
1358   %ys = sext i1 %y to i32
1359   store i32 %ys, ptr %p
1360   %sub = add i32 %xz, %ys
1361   %r = lshr i32 %sub, 31
1362   ret i32 %r
1365 define i32 @lshr_add_sexts(i1 %x, i1 %y) {
1366 ; CHECK-LABEL: @lshr_add_sexts(
1367 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
1368 ; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i32
1369 ; CHECK-NEXT:    ret i32 [[R]]
1371   %xs = sext i1 %x to i32
1372   %ys = sext i1 %y to i32
1373   %sub = add i32 %xs, %ys
1374   %r = lshr i32 %sub, 31
1375   ret i32 %r
1378 define i5 @and_add_sexts(i1 %x, i1 %y) {
1379 ; CHECK-LABEL: @and_add_sexts(
1380 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
1381 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i5 -2, i5 0
1382 ; CHECK-NEXT:    ret i5 [[R]]
1384   %xs = sext i1 %x to i5
1385   %ys = sext i1 %y to i5
1386   %sub = add i5 %xs, %ys
1387   %r = and i5 %sub, 30
1388   ret i5 %r
1391 define <2 x i8> @ashr_add_sexts(<2 x i1> %x, <2 x i1> %y) {
1392 ; CHECK-LABEL: @ashr_add_sexts(
1393 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i1> [[Y:%.*]], [[X:%.*]]
1394 ; CHECK-NEXT:    [[TMP2:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
1395 ; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
1397   %xs = sext <2 x i1> %x to <2 x i8>
1398   %ys = sext <2 x i1> %y to <2 x i8>
1399   %sub = add nsw <2 x i8> %ys, %xs
1400   %r = ashr <2 x i8> %sub, <i8 1, i8 1>
1401   ret <2 x i8> %r
1404 define i32 @cmp_math_sexts(i32 %x, i32 %y) {
1405 ; CHECK-LABEL: @cmp_math_sexts(
1406 ; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
1407 ; CHECK-NEXT:    [[R:%.*]] = zext i1 [[DOTNOT]] to i32
1408 ; CHECK-NEXT:    ret i32 [[R]]
1410   %gt = icmp ugt i32 %x, %y
1411   %lt = icmp ult i32 %x, %y
1412   %xz = sext i1 %gt to i32
1413   %yz = zext i1 %lt to i32
1414   %s = sub i32 %xz, %yz
1415   %r = lshr i32 %s, 31
1416   ret i32 %r
1419 ; Negative test - wrong type
1421 define i32 @lshr_add_nonbool_sexts(i2 %x, i1 %y) {
1422 ; CHECK-LABEL: @lshr_add_nonbool_sexts(
1423 ; CHECK-NEXT:    [[XS:%.*]] = sext i2 [[X:%.*]] to i32
1424 ; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1425 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1426 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1427 ; CHECK-NEXT:    ret i32 [[R]]
1429   %xs = sext i2 %x to i32
1430   %ys = sext i1 %y to i32
1431   %sub = add i32 %xs, %ys
1432   %r = lshr i32 %sub, 31
1433   ret i32 %r
1436 ; Negative test - wrong demand
1438 define i32 @and31_add_sexts(i1 %x, i1 %y) {
1439 ; CHECK-LABEL: @and31_add_sexts(
1440 ; CHECK-NEXT:    [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1441 ; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1442 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1443 ; CHECK-NEXT:    [[R:%.*]] = and i32 [[SUB]], 31
1444 ; CHECK-NEXT:    ret i32 [[R]]
1446   %xs = sext i1 %x to i32
1447   %ys = sext i1 %y to i32
1448   %sub = add i32 %xs, %ys
1449   %r = and i32 %sub, 31
1450   ret i32 %r
1453 define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
1454 ; CHECK-LABEL: @lshr_add_use_sexts(
1455 ; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1456 ; CHECK-NEXT:    store i32 [[YS]], ptr [[P:%.*]], align 4
1457 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y]]
1458 ; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i32
1459 ; CHECK-NEXT:    ret i32 [[R]]
1461   %xs = sext i1 %x to i32
1462   %ys = sext i1 %y to i32
1463   store i32 %ys, ptr %p
1464   %sub = add i32 %xs, %ys
1465   %r = lshr i32 %sub, 31
1466   ret i32 %r
1469 define i32 @lshr_add_use_sexts_2(i1 %x, i1 %y, ptr %p) {
1470 ; CHECK-LABEL: @lshr_add_use_sexts_2(
1471 ; CHECK-NEXT:    [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1472 ; CHECK-NEXT:    store i32 [[XS]], ptr [[P:%.*]], align 4
1473 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X]], [[Y:%.*]]
1474 ; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i32
1475 ; CHECK-NEXT:    ret i32 [[R]]
1477   %xs = sext i1 %x to i32
1478   store i32 %xs, ptr %p
1479   %ys = sext i1 %y to i32
1480   %sub = add i32 %xs, %ys
1481   %r = lshr i32 %sub, 31
1482   ret i32 %r
1485 ; Negative test - extra use
1487 declare void @use_sexts(i32, i32)
1489 define i32 @lshr_add_use_sexts_both(i1 %x, i1 %y) {
1490 ; CHECK-LABEL: @lshr_add_use_sexts_both(
1491 ; CHECK-NEXT:    [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1492 ; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1493 ; CHECK-NEXT:    call void @use_sexts(i32 [[XS]], i32 [[YS]])
1494 ; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1495 ; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1496 ; CHECK-NEXT:    ret i32 [[R]]
1498   %xs = sext i1 %x to i32
1499   %ys = sext i1 %y to i32
1500   call void @use_sexts(i32 %xs, i32 %ys)
1501   %sub = add i32 %xs, %ys
1502   %r = lshr i32 %sub, 31
1503   ret i32 %r
1506 define i8 @add_like_or_t0(i8 %x) {
1507 ; CHECK-LABEL: @add_like_or_t0(
1508 ; CHECK-NEXT:    [[I0:%.*]] = shl i8 [[X:%.*]], 4
1509 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[I0]], 57
1510 ; CHECK-NEXT:    ret i8 [[R]]
1512   %i0 = shl i8 %x, 4
1513   %i1 = or i8 %i0, 15 ; no common bits
1514   %r = add i8 %i1, 42
1515   ret i8 %r
1517 define i8 @add_like_or_n1(i8 %x) {
1518 ; CHECK-LABEL: @add_like_or_n1(
1519 ; CHECK-NEXT:    [[I0:%.*]] = shl i8 [[X:%.*]], 4
1520 ; CHECK-NEXT:    [[I1:%.*]] = or i8 [[I0]], 31
1521 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[I1]], 42
1522 ; CHECK-NEXT:    ret i8 [[R]]
1524   %i0 = shl i8 %x, 4
1525   %i1 = or i8 %i0, 31 ; 4'th bit might be common-set
1526   %r = add i8 %i1, 42
1527   ret i8 %r
1529 define i8 @add_like_or_t2_extrause(i8 %x) {
1530 ; CHECK-LABEL: @add_like_or_t2_extrause(
1531 ; CHECK-NEXT:    [[I0:%.*]] = shl i8 [[X:%.*]], 4
1532 ; CHECK-NEXT:    [[I1:%.*]] = or disjoint i8 [[I0]], 15
1533 ; CHECK-NEXT:    call void @use(i8 [[I1]])
1534 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[I0]], 57
1535 ; CHECK-NEXT:    ret i8 [[R]]
1537   %i0 = shl i8 %x, 4
1538   %i1 = or i8 %i0, 15 ; no common bits
1539   call void @use(i8 %i1) ; extra use
1540   %r = add i8 %i1, 42
1541   ret i8 %r
1543 define i8 @fold_add_constant_preserve_nsw(i8 %x) {
1544 ; CHECK-LABEL: @fold_add_constant_preserve_nsw(
1545 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X:%.*]], -120
1546 ; CHECK-NEXT:    ret i8 [[ADD]]
1548   %or = or disjoint i8 %x, -128
1549   %add = add nsw i8 %or, 8
1550   ret i8 %add
1552 define i8 @fold_add_constant_no_nsw(i8 %x) {
1553 ; CHECK-LABEL: @fold_add_constant_no_nsw(
1554 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X:%.*]], 120
1555 ; CHECK-NEXT:    ret i8 [[ADD]]
1557   %or = or disjoint i8 %x, -128
1558   %add = add nsw i8 %or, -8
1559   ret i8 %add
1561 define i8 @fold_add_constant_preserve_nuw(i8 %x) {
1562 ; CHECK-LABEL: @fold_add_constant_preserve_nuw(
1563 ; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X:%.*]], -116
1564 ; CHECK-NEXT:    ret i8 [[ADD]]
1566   %or = or disjoint i8 %x, 128
1567   %add = add nuw i8 %or, 12
1568   ret i8 %add
1570 define i32 @sdiv_to_udiv(i32 %arg0, i32 %arg1) {
1571 ; CHECK-LABEL: @sdiv_to_udiv(
1572 ; CHECK-NEXT:    [[T0:%.*]] = shl nuw nsw i32 [[ARG0:%.*]], 8
1573 ; CHECK-NEXT:    [[T2:%.*]] = add nuw nsw i32 [[T0]], 6242049
1574 ; CHECK-NEXT:    [[T3:%.*]] = udiv i32 [[T2]], 192
1575 ; CHECK-NEXT:    ret i32 [[T3]]
1577   %t0 = shl nuw nsw i32 %arg0, 8
1578   %t1 = or disjoint i32 %t0, 1
1579   %t2 = add nuw nsw i32 %t1, 6242048
1580   %t3 = sdiv i32 %t2, 192
1581   ret i32 %t3
1584 define i8 @add_like_or_disjoint(i8 %x) {
1585 ; CHECK-LABEL: @add_like_or_disjoint(
1586 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[X:%.*]], 57
1587 ; CHECK-NEXT:    ret i8 [[R]]
1589   %i1 = or disjoint i8 %x, 15
1590   %r = add i8 %i1, 42
1591   ret i8 %r
1594 define i8 @add_and_xor(i8 noundef %x, i8 %y) {
1595 ; CHECK-LABEL: @add_and_xor(
1596 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
1597 ; CHECK-NEXT:    ret i8 [[ADD]]
1599   %xor = xor i8 %x, -1
1600   %and = and i8 %xor, %y
1601   %add = add i8 %and, %x
1602   ret i8 %add
1605 define i8 @add_and_xor_wrong_const(i8 %x, i8 %y) {
1606 ; CHECK-LABEL: @add_and_xor_wrong_const(
1607 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -2
1608 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]
1609 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[AND]], [[X]]
1610 ; CHECK-NEXT:    ret i8 [[ADD]]
1612   %xor = xor i8 %x, -2
1613   %and = and i8 %xor, %y
1614   %add = add i8 %and, %x
1615   ret i8 %add
1618 define i8 @add_and_xor_wrong_op(i8 %x, i8 %y, i8 %z) {
1619 ; CHECK-LABEL: @add_and_xor_wrong_op(
1620 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[Z:%.*]], -1
1621 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]
1622 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[AND]], [[X:%.*]]
1623 ; CHECK-NEXT:    ret i8 [[ADD]]
1625   %xor = xor i8 %z, -1
1626   %and = and i8 %xor, %y
1627   %add = add i8 %and, %x
1628   ret i8 %add
1631 define i8 @add_and_xor_commuted1(i8 noundef %x, i8 %_y) {
1632 ; CHECK-LABEL: @add_and_xor_commuted1(
1633 ; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1634 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X:%.*]]
1635 ; CHECK-NEXT:    ret i8 [[ADD]]
1637   %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1638   %xor = xor i8 %x, -1
1639   %and = and i8 %y, %xor
1640   %add = add i8 %and, %x
1641   ret i8 %add
1644 define i8 @add_and_xor_commuted2(i8 noundef %_x, i8 %y) {
1645 ; CHECK-LABEL: @add_and_xor_commuted2(
1646 ; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1647 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y:%.*]]
1648 ; CHECK-NEXT:    ret i8 [[ADD]]
1650   %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1651   %xor = xor i8 %x, -1
1652   %and = and i8 %xor, %y
1653   %add = add i8 %x, %and
1654   ret i8 %add
1657 define i8 @add_and_xor_commuted3(i8 noundef %_x, i8 %_y) {
1658 ; CHECK-LABEL: @add_and_xor_commuted3(
1659 ; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1660 ; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1661 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1662 ; CHECK-NEXT:    ret i8 [[ADD]]
1664   %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1665   %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1666   %xor = xor i8 %x, -1
1667   %and = and i8 %y, %xor
1668   %add = add i8 %x, %and
1669   ret i8 %add
1672 define i8 @add_and_xor_extra_use(i8 noundef %x, i8 %y) {
1673 ; CHECK-LABEL: @add_and_xor_extra_use(
1674 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -1
1675 ; CHECK-NEXT:    call void @use(i8 [[XOR]])
1676 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]
1677 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1678 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1679 ; CHECK-NEXT:    ret i8 [[ADD]]
1681   %xor = xor i8 %x, -1
1682   call void @use(i8 %xor)
1683   %and = and i8 %xor, %y
1684   call void @use(i8 %and)
1685   %add = add i8 %and, %x
1686   ret i8 %add
1689 define i8 @add_xor_and_const(i8 noundef %x) {
1690 ; CHECK-LABEL: @add_xor_and_const(
1691 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X:%.*]], 42
1692 ; CHECK-NEXT:    ret i8 [[ADD]]
1694   %and = and i8 %x, 42
1695   %xor = xor i8 %and, 42
1696   %add = add i8 %xor, %x
1697   ret i8 %add
1700 define i8 @add_xor_and_const_wrong_const(i8 %x) {
1701 ; CHECK-LABEL: @add_xor_and_const_wrong_const(
1702 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], 42
1703 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[AND]], 88
1704 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[XOR]], [[X]]
1705 ; CHECK-NEXT:    ret i8 [[ADD]]
1707   %and = and i8 %x, 42
1708   %xor = xor i8 %and, 88
1709   %add = add i8 %xor, %x
1710   ret i8 %add
1713 define i8 @add_xor_and_var(i8 noundef %x, i8 noundef %y) {
1714 ; CHECK-LABEL: @add_xor_and_var(
1715 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1716 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1717 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1718 ; CHECK-NEXT:    ret i8 [[ADD]]
1720   %and = and i8 %x, %y
1721   call void @use(i8 %and)
1722   %xor = xor i8 %and, %y
1723   %add = add i8 %xor, %x
1724   ret i8 %add
1727 define i8 @add_xor_and_var_wrong_op1(i8 %x, i8 %y, i8 %z) {
1728 ; CHECK-LABEL: @add_xor_and_var_wrong_op1(
1729 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1730 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1731 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[AND]], [[Z:%.*]]
1732 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[XOR]], [[X]]
1733 ; CHECK-NEXT:    ret i8 [[ADD]]
1735   %and = and i8 %x, %y
1736   call void @use(i8 %and)
1737   %xor = xor i8 %and, %z
1738   %add = add i8 %xor, %x
1739   ret i8 %add
1742 define i8 @add_xor_and_var_wrong_op2(i8 %x, i8 %y, i8 %z) {
1743 ; CHECK-LABEL: @add_xor_and_var_wrong_op2(
1744 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1745 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1746 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[AND]], [[Y]]
1747 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[XOR]], [[Z:%.*]]
1748 ; CHECK-NEXT:    ret i8 [[ADD]]
1750   %and = and i8 %x, %y
1751   call void @use(i8 %and)
1752   %xor = xor i8 %and, %y
1753   %add = add i8 %xor, %z
1754   ret i8 %add
1757 define i8 @add_xor_and_var_commuted1(i8 noundef %x, i8 noundef %y) {
1758 ; CHECK-LABEL: @add_xor_and_var_commuted1(
1759 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
1760 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1761 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1762 ; CHECK-NEXT:    ret i8 [[ADD]]
1764   %and = and i8 %y, %x
1765   call void @use(i8 %and)
1766   %xor = xor i8 %and, %y
1767   %add = add i8 %xor, %x
1768   ret i8 %add
1771 define i8 @add_xor_and_var_commuted2(i8 noundef %_x, i8 noundef %_y) {
1772 ; CHECK-LABEL: @add_xor_and_var_commuted2(
1773 ; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1774 ; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1775 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y]]
1776 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1777 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1778 ; CHECK-NEXT:    ret i8 [[ADD]]
1780   %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1781   %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1782   %and = and i8 %x, %y
1783   call void @use(i8 %and)
1784   %xor = xor i8 %y, %and
1785   %add = add i8 %xor, %x
1786   ret i8 %add
1789 define i8 @add_xor_and_var_commuted3(i8 noundef %x, i8 noundef %_y) {
1790 ; CHECK-LABEL: @add_xor_and_var_commuted3(
1791 ; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1792 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y]], [[X:%.*]]
1793 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1794 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1795 ; CHECK-NEXT:    ret i8 [[ADD]]
1797   %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1798   %and = and i8 %y, %x
1799   call void @use(i8 %and)
1800   %xor = xor i8 %y, %and
1801   %add = add i8 %xor, %x
1802   ret i8 %add
1805 define i8 @add_xor_and_var_commuted4(i8 noundef %_x, i8 noundef %y) {
1806 ; CHECK-LABEL: @add_xor_and_var_commuted4(
1807 ; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1808 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]
1809 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1810 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1811 ; CHECK-NEXT:    ret i8 [[ADD]]
1813   %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1814   %and = and i8 %x, %y
1815   call void @use(i8 %and)
1816   %xor = xor i8 %and, %y
1817   %add = add i8 %x, %xor
1818   ret i8 %add
1821 define i8 @add_xor_and_var_commuted5(i8 noundef %_x, i8 noundef %_y) {
1822 ; CHECK-LABEL: @add_xor_and_var_commuted5(
1823 ; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1824 ; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1825 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y]], [[X]]
1826 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1827 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1828 ; CHECK-NEXT:    ret i8 [[ADD]]
1830   %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1831   %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1832   %and = and i8 %y, %x
1833   call void @use(i8 %and)
1834   %xor = xor i8 %and, %y
1835   %add = add i8 %x, %xor
1836   ret i8 %add
1839 define i8 @add_xor_and_var_commuted6(i8 noundef %_x, i8 noundef %_y) {
1840 ; CHECK-LABEL: @add_xor_and_var_commuted6(
1841 ; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1842 ; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1843 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y]]
1844 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1845 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1846 ; CHECK-NEXT:    ret i8 [[ADD]]
1848   %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1849   %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1850   %and = and i8 %x, %y
1851   call void @use(i8 %and)
1852   %xor = xor i8 %y, %and
1853   %add = add i8 %x, %xor
1854   ret i8 %add
1857 define i8 @add_xor_and_var_commuted7(i8 noundef %_x, i8 noundef %_y) {
1858 ; CHECK-LABEL: @add_xor_and_var_commuted7(
1859 ; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1860 ; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1861 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y]], [[X]]
1862 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1863 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1864 ; CHECK-NEXT:    ret i8 [[ADD]]
1866   %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1867   %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1868   %and = and i8 %y, %x
1869   call void @use(i8 %and)
1870   %xor = xor i8 %y, %and
1871   %add = add i8 %x, %xor
1872   ret i8 %add
1875 define i8 @add_xor_and_var_extra_use(i8 noundef %x, i8 noundef %y) {
1876 ; CHECK-LABEL: @add_xor_and_var_extra_use(
1877 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1878 ; CHECK-NEXT:    call void @use(i8 [[AND]])
1879 ; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[AND]], [[Y]]
1880 ; CHECK-NEXT:    call void @use(i8 [[XOR]])
1881 ; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1882 ; CHECK-NEXT:    ret i8 [[ADD]]
1884   %and = and i8 %x, %y
1885   call void @use(i8 %and)
1886   %xor = xor i8 %and, %y
1887   call void @use(i8 %xor)
1888   %add = add i8 %xor, %x
1889   ret i8 %add
1892 define i32 @add_add_add(i32 %A, i32 %B, i32 %C, i32 %D) {
1893 ; CHECK-LABEL: @add_add_add(
1894 ; CHECK-NEXT:    [[E:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
1895 ; CHECK-NEXT:    [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1896 ; CHECK-NEXT:    [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1897 ; CHECK-NEXT:    ret i32 [[G]]
1899   %E = add i32 %A, %B
1900   %F = add i32 %E, %C
1901   %G = add i32 %F, %D
1902   ret i32 %G
1905 define i32 @add_add_add_commute1(i32 %A, i32 %B, i32 %C, i32 %D) {
1906 ; CHECK-LABEL: @add_add_add_commute1(
1907 ; CHECK-NEXT:    [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1908 ; CHECK-NEXT:    [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1909 ; CHECK-NEXT:    [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1910 ; CHECK-NEXT:    ret i32 [[G]]
1912   %E = add i32 %B, %A
1913   %F = add i32 %E, %C
1914   %G = add i32 %F, %D
1915   ret i32 %G
1918 define i32 @add_add_add_commute2(i32 %A, i32 %B, i32 %C, i32 %D) {
1919 ; CHECK-LABEL: @add_add_add_commute2(
1920 ; CHECK-NEXT:    [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1921 ; CHECK-NEXT:    [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1922 ; CHECK-NEXT:    [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1923 ; CHECK-NEXT:    ret i32 [[G]]
1925   %E = add i32 %B, %A
1926   %F = add i32 %C, %E
1927   %G = add i32 %F, %D
1928   ret i32 %G
1931 define i32 @add_add_add_commute3(i32 %A, i32 %B, i32 %C, i32 %D) {
1932 ; CHECK-LABEL: @add_add_add_commute3(
1933 ; CHECK-NEXT:    [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1934 ; CHECK-NEXT:    [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1935 ; CHECK-NEXT:    [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1936 ; CHECK-NEXT:    ret i32 [[G]]
1938   %E = add i32 %B, %A
1939   %F = add i32 %C, %E
1940   %G = add i32 %D, %F
1941   ret i32 %G
1944 ; x * y + x --> (y + 1) * x
1946 define i8 @mul_add_common_factor_commute1(i8 %x, i8 %y) {
1947 ; CHECK-LABEL: @mul_add_common_factor_commute1(
1948 ; CHECK-NEXT:    [[X1:%.*]] = add i8 [[Y:%.*]], 1
1949 ; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X1]], [[X:%.*]]
1950 ; CHECK-NEXT:    ret i8 [[A]]
1952   %m = mul nsw i8 %x, %y
1953   %a = add nsw i8 %m, %x
1954   ret i8 %a
1957 define <2 x i8> @mul_add_common_factor_commute2(<2 x i8> %x, <2 x i8> %y) {
1958 ; CHECK-LABEL: @mul_add_common_factor_commute2(
1959 ; CHECK-NEXT:    [[M1:%.*]] = add <2 x i8> [[Y:%.*]], <i8 1, i8 1>
1960 ; CHECK-NEXT:    [[A:%.*]] = mul nuw <2 x i8> [[M1]], [[X:%.*]]
1961 ; CHECK-NEXT:    ret <2 x i8> [[A]]
1963   %m = mul nuw <2 x i8> %y, %x
1964   %a = add nuw <2 x i8> %m, %x
1965   ret <2 x i8> %a
1968 define i8 @mul_add_common_factor_commute3(i8 %p, i8 %y) {
1969 ; CHECK-LABEL: @mul_add_common_factor_commute3(
1970 ; CHECK-NEXT:    [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
1971 ; CHECK-NEXT:    [[M1:%.*]] = add i8 [[Y:%.*]], 1
1972 ; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X]], [[M1]]
1973 ; CHECK-NEXT:    ret i8 [[A]]
1975   %x = mul i8 %p, %p ; thwart complexity-based canonicalization
1976   %m = mul nuw i8 %x, %y
1977   %a = add nsw i8 %x, %m
1978   ret i8 %a
1981 define i8 @mul_add_common_factor_commute4(i8 %p, i8 %q) {
1982 ; CHECK-LABEL: @mul_add_common_factor_commute4(
1983 ; CHECK-NEXT:    [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
1984 ; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[Q:%.*]], [[Q]]
1985 ; CHECK-NEXT:    [[M1:%.*]] = add i8 [[Y]], 1
1986 ; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X]], [[M1]]
1987 ; CHECK-NEXT:    ret i8 [[A]]
1989   %x = mul i8 %p, %p ; thwart complexity-based canonicalization
1990   %y = mul i8 %q, %q ; thwart complexity-based canonicalization
1991   %m = mul nsw i8 %y, %x
1992   %a = add nuw i8 %x, %m
1993   ret i8 %a
1996 ; negative test - uses
1998 define i8 @mul_add_common_factor_use(i8 %x, i8 %y) {
1999 ; CHECK-LABEL: @mul_add_common_factor_use(
2000 ; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]
2001 ; CHECK-NEXT:    call void @use(i8 [[M]])
2002 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[M]], [[X]]
2003 ; CHECK-NEXT:    ret i8 [[A]]
2005   %m = mul i8 %x, %y
2006   call void @use(i8 %m)
2007   %a = add i8 %m, %x
2008   ret i8 %a
2011 define i8 @not_mul(i8 %x) {
2012 ; CHECK-LABEL: @not_mul(
2013 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[X:%.*]], -41
2014 ; CHECK-NEXT:    [[PLUSX:%.*]] = add i8 [[TMP1]], -1
2015 ; CHECK-NEXT:    ret i8 [[PLUSX]]
2017   %mul = mul nsw i8 %x, 42
2018   %not = xor i8 %mul, -1
2019   %plusx = add nsw i8 %not, %x
2020   ret i8 %plusx
2023 define <2 x i8> @not_mul_commute(<2 x i8> %p) {
2024 ; CHECK-LABEL: @not_mul_commute(
2025 ; CHECK-NEXT:    [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2026 ; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i8> [[X]], <i8 43, i8 43>
2027 ; CHECK-NEXT:    [[PLUSX:%.*]] = add <2 x i8> [[TMP1]], <i8 -1, i8 -1>
2028 ; CHECK-NEXT:    ret <2 x i8> [[PLUSX]]
2030   %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2031   %mul = mul nuw <2 x i8> %x, <i8 -42, i8 -42>
2032   %not = xor <2 x i8> %mul, <i8 -1, i8 -1>
2033   %plusx = add nuw <2 x i8> %x, %not
2034   ret <2 x i8> %plusx
2037 ; negative test - need common operand
2039 define i8 @not_mul_wrong_op(i8 %x, i8 %y) {
2040 ; CHECK-LABEL: @not_mul_wrong_op(
2041 ; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 42
2042 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[MUL]], -1
2043 ; CHECK-NEXT:    [[PLUSX:%.*]] = add i8 [[NOT]], [[Y:%.*]]
2044 ; CHECK-NEXT:    ret i8 [[PLUSX]]
2046   %mul = mul i8 %x, 42
2047   %not = xor i8 %mul, -1
2048   %plusx = add i8 %not, %y
2049   ret i8 %plusx
2052 ; negative test - avoid creating an extra mul
2054 define i8 @not_mul_use1(i8 %x) {
2055 ; CHECK-LABEL: @not_mul_use1(
2056 ; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 42
2057 ; CHECK-NEXT:    call void @use(i8 [[MUL]])
2058 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[MUL]], -1
2059 ; CHECK-NEXT:    [[PLUSX:%.*]] = add nsw i8 [[NOT]], [[X]]
2060 ; CHECK-NEXT:    ret i8 [[PLUSX]]
2062   %mul = mul nsw i8 %x, 42
2063   call void @use(i8 %mul)
2064   %not = xor i8 %mul, -1
2065   %plusx = add nsw i8 %not, %x
2066   ret i8 %plusx
2069 ; negative test - too many instructions
2071 define i8 @not_mul_use2(i8 %x) {
2072 ; CHECK-LABEL: @not_mul_use2(
2073 ; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 42
2074 ; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[MUL]], -1
2075 ; CHECK-NEXT:    call void @use(i8 [[NOT]])
2076 ; CHECK-NEXT:    [[PLUSX:%.*]] = add i8 [[NOT]], [[X]]
2077 ; CHECK-NEXT:    ret i8 [[PLUSX]]
2079   %mul = mul i8 %x, 42
2080   %not = xor i8 %mul, -1
2081   call void @use(i8 %not)
2082   %plusx = add i8 %not, %x
2083   ret i8 %plusx
2086 define i8 @full_ashr_inc(i8 %x) {
2087 ; CHECK-LABEL: @full_ashr_inc(
2088 ; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
2089 ; CHECK-NEXT:    [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8
2090 ; CHECK-NEXT:    ret i8 [[R]]
2092   %a = ashr i8 %x, 7
2093   %r = add i8 %a, 1
2094   ret i8 %r
2097 define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) {
2098 ; CHECK-LABEL: @full_ashr_inc_vec(
2099 ; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], <i6 -1, i6 -1>
2100 ; CHECK-NEXT:    [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6>
2101 ; CHECK-NEXT:    ret <2 x i6> [[R]]
2103   %a = ashr <2 x i6> %x, <i6 5, i6 poison>
2104   %r = add <2 x i6> %a, <i6 1, i6 1>
2105   ret <2 x i6> %r
2108 ; negative test - extra use
2110 define i8 @full_ashr_inc_use(i8 %x) {
2111 ; CHECK-LABEL: @full_ashr_inc_use(
2112 ; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 7
2113 ; CHECK-NEXT:    call void @use(i8 [[A]])
2114 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A]], 1
2115 ; CHECK-NEXT:    ret i8 [[R]]
2117   %a = ashr i8 %x, 7
2118   call void @use(i8 %a)
2119   %r = add i8 %a, 1
2120   ret i8 %r
2123 ; negative test - wrong shift amount
2125 define i8 @not_full_ashr_inc(i8 %x) {
2126 ; CHECK-LABEL: @not_full_ashr_inc(
2127 ; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 6
2128 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A]], 1
2129 ; CHECK-NEXT:    ret i8 [[R]]
2131   %a = ashr i8 %x, 6
2132   %r = add i8 %a, 1
2133   ret i8 %r
2136 ; negative test - wrong add amount
2138 define i8 @full_ashr_not_inc(i8 %x) {
2139 ; CHECK-LABEL: @full_ashr_not_inc(
2140 ; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 7
2141 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A]], 2
2142 ; CHECK-NEXT:    ret i8 [[R]]
2144   %a = ashr i8 %x, 7
2145   %r = add i8 %a, 2
2146   ret i8 %r
2149 define i8 @select_negate_or_zero(i1 %b, i8 %x, i8 %y) {
2150 ; CHECK-LABEL: @select_negate_or_zero(
2151 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[X:%.*]]
2152 ; CHECK-NEXT:    [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2153 ; CHECK-NEXT:    ret i8 [[ADD1]]
2155   %negx = sub i8 0, %x
2156   %sel = select i1 %b, i8 0, i8 %negx
2157   %add = add i8 %sel, %y
2158   ret i8 %add
2161 ; commuted add operands - same result
2163 define <2 x i8> @select_negate_or_zero_commute(<2 x i1> %b, <2 x i8> %x, <2 x i8> %p) {
2164 ; CHECK-LABEL: @select_negate_or_zero_commute(
2165 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2166 ; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> zeroinitializer, <2 x i8> [[X:%.*]]
2167 ; CHECK-NEXT:    [[ADD1:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]
2168 ; CHECK-NEXT:    ret <2 x i8> [[ADD1]]
2170   %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2171   %negx = sub <2 x i8> <i8 poison, i8 0>, %x
2172   %sel = select <2 x i1> %b, <2 x i8> <i8 poison, i8 0>, <2 x i8> %negx
2173   %add = add <2 x i8> %y, %sel
2174   ret <2 x i8> %add
2177 ; swapped select operands and extra use are ok
2179 define i8 @select_negate_or_zero_swap(i1 %b, i8 %x, i8 %y) {
2180 ; CHECK-LABEL: @select_negate_or_zero_swap(
2181 ; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2182 ; CHECK-NEXT:    call void @use(i8 [[NEGX]])
2183 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X]], i8 0
2184 ; CHECK-NEXT:    [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2185 ; CHECK-NEXT:    ret i8 [[ADD1]]
2187   %negx = sub i8 0, %x
2188   call void @use(i8 %negx)
2189   %sel = select i1 %b, i8 %negx, i8 0
2190   %add = add i8 %sel, %y
2191   ret i8 %add
2194 ; commuted add operands - same result
2196 define i8 @select_negate_or_zero_swap_commute(i1 %b, i8 %x, i8 %p) {
2197 ; CHECK-LABEL: @select_negate_or_zero_swap_commute(
2198 ; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2199 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X:%.*]], i8 0
2200 ; CHECK-NEXT:    [[ADD1:%.*]] = sub i8 [[Y]], [[TMP1]]
2201 ; CHECK-NEXT:    ret i8 [[ADD1]]
2203   %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2204   %negx = sub i8 0, %x
2205   %sel = select i1 %b, i8 %negx, i8 0
2206   %add = add i8 %y, %sel
2207   ret i8 %add
2210 ; negative test - one arm of the select must simplify
2212 define i8 @select_negate_or_nonzero(i1 %b, i8 %x, i8 %y) {
2213 ; CHECK-LABEL: @select_negate_or_nonzero(
2214 ; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2215 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i8 42, i8 [[NEGX]]
2216 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2217 ; CHECK-NEXT:    ret i8 [[ADD]]
2219   %negx = sub i8 0, %x
2220   %sel = select i1 %b, i8 42, i8 %negx
2221   %add = add i8 %sel, %y
2222   ret i8 %add
2225 ; negative test - must have a negate, not any subtract
2227 define i8 @select_nonnegate_or_zero(i1 %b, i8 %x, i8 %y) {
2228 ; CHECK-LABEL: @select_nonnegate_or_zero(
2229 ; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 42, [[X:%.*]]
2230 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]]
2231 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2232 ; CHECK-NEXT:    ret i8 [[ADD]]
2234   %negx = sub i8 42, %x
2235   %sel = select i1 %b, i8 0, i8 %negx
2236   %add = add i8 %sel, %y
2237   ret i8 %add
2240 ; negative test - don't create an extra instruction
2242 define i8 @select_negate_or_nonzero_use(i1 %b, i8 %x, i8 %y) {
2243 ; CHECK-LABEL: @select_negate_or_nonzero_use(
2244 ; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2245 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]]
2246 ; CHECK-NEXT:    call void @use(i8 [[SEL]])
2247 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2248 ; CHECK-NEXT:    ret i8 [[ADD]]
2250   %negx = sub i8 0, %x
2251   %sel = select i1 %b, i8 0, i8 %negx
2252   call void @use(i8 %sel)
2253   %add = add i8 %sel, %y
2254   ret i8 %add
2257 ; extra reduction because y + ~y -> -1
2259 define i5 @select_negate_not(i1 %b, i5 %x, i5 %y) {
2260 ; CHECK-LABEL: @select_negate_not(
2261 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]]
2262 ; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]]
2263 ; CHECK-NEXT:    ret i5 [[ADD1]]
2265   %negx = sub i5 0, %x
2266   %noty = xor i5 %y, -1
2267   %sel = select i1 %b, i5 %noty, i5 %negx
2268   %add = add i5 %sel, %y
2269   ret i5 %add
2272 define i5 @select_negate_not_commute(i1 %b, i5 %x, i5 %p) {
2273 ; CHECK-LABEL: @select_negate_not_commute(
2274 ; CHECK-NEXT:    [[Y:%.*]] = mul i5 [[P:%.*]], [[P]]
2275 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]]
2276 ; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]]
2277 ; CHECK-NEXT:    ret i5 [[ADD1]]
2279   %y = mul i5 %p, %p ; thwart complexity-based canonicalization
2280   %negx = sub i5 0, %x
2281   %noty = xor i5 %y, -1
2282   %sel = select i1 %b, i5 %noty, i5 %negx
2283   %add = add i5 %y, %sel
2284   ret i5 %add
2287 define i5 @select_negate_not_swap(i1 %b, i5 %x, i5 %y) {
2288 ; CHECK-LABEL: @select_negate_not_swap(
2289 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]]
2290 ; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -1
2291 ; CHECK-NEXT:    ret i5 [[ADD1]]
2293   %negx = sub i5 0, %x
2294   %noty = xor i5 %y, -1
2295   %sel = select i1 %b, i5 %negx, i5 %noty
2296   %add = add i5 %sel, %y
2297   ret i5 %add
2300 define i5 @select_negate_not_swap_commute(i1 %b, i5 %x, i5 %p) {
2301 ; CHECK-LABEL: @select_negate_not_swap_commute(
2302 ; CHECK-NEXT:    [[Y:%.*]] = mul i5 [[P:%.*]], [[P]]
2303 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]]
2304 ; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -1
2305 ; CHECK-NEXT:    ret i5 [[ADD1]]
2307   %y = mul i5 %p, %p ; thwart complexity-based canonicalization
2308   %negx = sub i5 0, %x
2309   %noty = xor i5 %y, -1
2310   %sel = select i1 %b, i5 %negx, i5 %noty
2311   %add = add i5 %y, %sel
2312   ret i5 %add
2315 define i32 @add_select_sub_both_arms_simplify(i1 %b, i32 %a) {
2316 ; CHECK-LABEL: @add_select_sub_both_arms_simplify(
2317 ; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[B:%.*]], i32 [[A:%.*]], i32 99
2318 ; CHECK-NEXT:    ret i32 [[ADD]]
2320   %sub = sub i32 99, %a
2321   %sel = select i1 %b, i32 0, i32 %sub
2322   %add = add i32 %sel, %a
2323   ret i32 %add
2326 define <2 x i8> @add_select_sub_both_arms_simplify_swap(<2 x i1> %b, <2 x i8> %a) {
2327 ; CHECK-LABEL: @add_select_sub_both_arms_simplify_swap(
2328 ; CHECK-NEXT:    [[ADD:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> <i8 42, i8 99>, <2 x i8> [[A:%.*]]
2329 ; CHECK-NEXT:    ret <2 x i8> [[ADD]]
2331   %sub = sub <2 x i8> <i8 42, i8 99>, %a
2332   %sel = select <2 x i1> %b, <2 x i8> %sub, <2 x i8> zeroinitializer
2333   %add = add <2 x i8> %sel, %a
2334   ret <2 x i8> %add
2337 define i8 @add_select_sub_both_arms_simplify_use1(i1 %b, i8 %a) {
2338 ; CHECK-LABEL: @add_select_sub_both_arms_simplify_use1(
2339 ; CHECK-NEXT:    [[SUB:%.*]] = sub i8 42, [[A:%.*]]
2340 ; CHECK-NEXT:    call void @use(i8 [[SUB]])
2341 ; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[B:%.*]], i8 [[A]], i8 42
2342 ; CHECK-NEXT:    ret i8 [[ADD]]
2344   %sub = sub i8 42, %a
2345   call void @use(i8 %sub)
2346   %sel = select i1 %b, i8 0, i8 %sub
2347   %add = add i8 %sel, %a
2348   ret i8 %add
2351 define i8 @add_select_sub_both_arms_simplify_use2(i1 %b, i8 %a) {
2352 ; CHECK-LABEL: @add_select_sub_both_arms_simplify_use2(
2353 ; CHECK-NEXT:    [[SUB:%.*]] = sub i8 42, [[A:%.*]]
2354 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[SUB]]
2355 ; CHECK-NEXT:    call void @use(i8 [[SEL]])
2356 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SEL]], [[A]]
2357 ; CHECK-NEXT:    ret i8 [[ADD]]
2359   %sub = sub i8 42, %a
2360   %sel = select i1 %b, i8 0, i8 %sub
2361   call void @use(i8 %sel)
2362   %add = add i8 %sel, %a
2363   ret i8 %add
2366 define i5 @demand_low_bits_uses(i8 %x, i8 %y) {
2367 ; CHECK-LABEL: @demand_low_bits_uses(
2368 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 [[X:%.*]], 5
2369 ; CHECK-NEXT:    [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2370 ; CHECK-NEXT:    call void @use(i8 [[A]])
2371 ; CHECK-NEXT:    [[R:%.*]] = trunc i8 [[Y]] to i5
2372 ; CHECK-NEXT:    ret i5 [[R]]
2374   %m = mul i8 %x, -32 ; 0xE0
2375   %a = add i8 %m, %y
2376   call void @use(i8 %a)
2377   %r = trunc i8 %a to i5
2378   ret i5 %r
2381 ; negative test - demands one more bit
2383 define i6 @demand_low_bits_uses_extra_bit(i8 %x, i8 %y) {
2384 ; CHECK-LABEL: @demand_low_bits_uses_extra_bit(
2385 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 [[X:%.*]], 5
2386 ; CHECK-NEXT:    [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2387 ; CHECK-NEXT:    call void @use(i8 [[A]])
2388 ; CHECK-NEXT:    [[R:%.*]] = trunc i8 [[A]] to i6
2389 ; CHECK-NEXT:    ret i6 [[R]]
2391   %m = mul i8 %x, -32 ; 0xE0
2392   %a = add i8 %m, %y
2393   call void @use(i8 %a)
2394   %r = trunc i8 %a to i6
2395   ret i6 %r
2398 define i8 @demand_low_bits_uses_commute(i8 %x, i8 %p, i8 %z) {
2399 ; CHECK-LABEL: @demand_low_bits_uses_commute(
2400 ; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2401 ; CHECK-NEXT:    [[M:%.*]] = and i8 [[X:%.*]], -64
2402 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y]], [[M]]
2403 ; CHECK-NEXT:    call void @use(i8 [[A]])
2404 ; CHECK-NEXT:    [[S:%.*]] = sub i8 [[Y]], [[Z:%.*]]
2405 ; CHECK-NEXT:    [[R:%.*]] = shl i8 [[S]], 2
2406 ; CHECK-NEXT:    ret i8 [[R]]
2408   %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2409   %m = and i8 %x, -64 ; 0xC0
2410   %a = add i8 %y, %m
2411   call void @use(i8 %a)
2412   %s = sub i8 %a, %z
2413   %r = shl i8 %s, 2
2414   ret i8 %r
2417 ; negative test - demands one more bit
2419 define i8 @demand_low_bits_uses_commute_extra_bit(i8 %x, i8 %p, i8 %z) {
2420 ; CHECK-LABEL: @demand_low_bits_uses_commute_extra_bit(
2421 ; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2422 ; CHECK-NEXT:    [[M:%.*]] = and i8 [[X:%.*]], -64
2423 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y]], [[M]]
2424 ; CHECK-NEXT:    call void @use(i8 [[A]])
2425 ; CHECK-NEXT:    [[S:%.*]] = sub i8 [[A]], [[Z:%.*]]
2426 ; CHECK-NEXT:    [[R:%.*]] = shl i8 [[S]], 1
2427 ; CHECK-NEXT:    ret i8 [[R]]
2429   %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2430   %m = and i8 %x, -64 ; 0xC0
2431   %a = add i8 %y, %m
2432   call void @use(i8 %a)
2433   %s = sub i8 %a, %z
2434   %r = shl i8 %s, 1
2435   ret i8 %r
2438 define { i64, i64 } @PR57576(i64 noundef %x, i64 noundef %y, i64 noundef %z, i64 noundef %w) {
2439 ; CHECK-LABEL: @PR57576(
2440 ; CHECK-NEXT:    [[ZX:%.*]] = zext i64 [[X:%.*]] to i128
2441 ; CHECK-NEXT:    [[ZY:%.*]] = zext i64 [[Y:%.*]] to i128
2442 ; CHECK-NEXT:    [[ZZ:%.*]] = zext i64 [[Z:%.*]] to i128
2443 ; CHECK-NEXT:    [[SHY:%.*]] = shl nuw i128 [[ZY]], 64
2444 ; CHECK-NEXT:    [[XY:%.*]] = or disjoint i128 [[SHY]], [[ZX]]
2445 ; CHECK-NEXT:    [[SUB:%.*]] = sub i128 [[XY]], [[ZZ]]
2446 ; CHECK-NEXT:    [[T:%.*]] = trunc i128 [[SUB]] to i64
2447 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i128 [[SUB]], 64
2448 ; CHECK-NEXT:    [[DOTTR:%.*]] = trunc nuw i128 [[TMP1]] to i64
2449 ; CHECK-NEXT:    [[DOTNARROW:%.*]] = sub i64 [[DOTTR]], [[W:%.*]]
2450 ; CHECK-NEXT:    [[R1:%.*]] = insertvalue { i64, i64 } poison, i64 [[T]], 0
2451 ; CHECK-NEXT:    [[R2:%.*]] = insertvalue { i64, i64 } [[R1]], i64 [[DOTNARROW]], 1
2452 ; CHECK-NEXT:    ret { i64, i64 } [[R2]]
2454   %zx = zext i64 %x to i128
2455   %zy = zext i64 %y to i128
2456   %zw = zext i64 %w to i128
2457   %zz = zext i64 %z to i128
2458   %shy = shl nuw i128 %zy, 64
2459   %mw = mul i128 %zw, -18446744073709551616
2460   %xy = or i128 %shy, %zx
2461   %sub = sub i128 %xy, %zz
2462   %add = add i128 %sub, %mw
2463   %t = trunc i128 %add to i64
2464   %h = lshr i128 %add, 64
2465   %t2 = trunc i128 %h to i64
2466   %r1 = insertvalue { i64, i64 } poison, i64 %t, 0
2467   %r2 = insertvalue { i64, i64 } %r1, i64 %t2, 1
2468   ret { i64, i64 } %r2
2471 define i8 @mul_negpow2(i8 %x, i8 %y) {
2472 ; CHECK-LABEL: @mul_negpow2(
2473 ; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
2474 ; CHECK-NEXT:    [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2475 ; CHECK-NEXT:    ret i8 [[A]]
2477   %m = mul i8 %x, -2
2478   %a = add i8 %m, %y
2479   ret i8 %a
2482 define <2 x i8> @mul_negpow2_commute_vec(<2 x i8> %x, <2 x i8> %p) {
2483 ; CHECK-LABEL: @mul_negpow2_commute_vec(
2484 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2485 ; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], <i8 3, i8 3>
2486 ; CHECK-NEXT:    [[A:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]
2487 ; CHECK-NEXT:    ret <2 x i8> [[A]]
2489   %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2490   %m = mul <2 x i8> %x, <i8 -8, i8 -8>
2491   %a = add <2 x i8> %y, %m
2492   ret <2 x i8> %a
2495 ; negative test - extra use
2497 define i8 @mul_negpow2_use(i8 %x) {
2498 ; CHECK-LABEL: @mul_negpow2_use(
2499 ; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], -2
2500 ; CHECK-NEXT:    call void @use(i8 [[M]])
2501 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[M]], 42
2502 ; CHECK-NEXT:    ret i8 [[A]]
2504   %m = mul i8 %x, -2
2505   call void @use(i8 %m)
2506   %a = add i8 %m, 42
2507   ret i8 %a
2510 ; negative test - not negative-power-of-2 multiplier
2512 define i8 @mul_not_negpow2(i8 %x) {
2513 ; CHECK-LABEL: @mul_not_negpow2(
2514 ; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], -3
2515 ; CHECK-NEXT:    [[A:%.*]] = add i8 [[M]], 42
2516 ; CHECK-NEXT:    ret i8 [[A]]
2518   %m = mul i8 %x, -3
2519   %a = add i8 %m, 42
2520   ret i8 %a
2523 define i16 @add_sub_zext(i8 %x, i8 %y) {
2524 ; CHECK-LABEL: @add_sub_zext(
2525 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i16
2526 ; CHECK-NEXT:    ret i16 [[TMP1]]
2528   %1 = sub nuw i8 %y, %x
2529   %2 = zext i8 %1 to i16
2530   %3 = zext i8 %x to i16
2531   %4 = add i16 %2, %3
2532   ret i16 %4
2535 define i16 @add_commute_sub_zext(i8 %x, i8 %y) {
2536 ; CHECK-LABEL: @add_commute_sub_zext(
2537 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i16
2538 ; CHECK-NEXT:    ret i16 [[TMP1]]
2540   %1 = sub nuw i8 %y, %x
2541   %2 = zext i8 %1 to i16
2542   %3 = zext i8 %x to i16
2543   %4 = add i16 %3, %2
2544   ret i16 %4
2547 define <2 x i8> @add_sub_2xi5_zext(<2 x i5> %x, <2 x i5> %y) {
2548 ; CHECK-LABEL: @add_sub_2xi5_zext(
2549 ; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i5> [[Y:%.*]] to <2 x i8>
2550 ; CHECK-NEXT:    ret <2 x i8> [[TMP1]]
2552   %1 = sub nuw <2 x i5> %y, %x
2553   %2 = zext <2 x i5> %1 to <2 x i8>
2554   %3 = zext <2 x i5> %x to <2 x i8>
2555   %4 = add <2 x i8> %3, %2
2556   ret <2 x i8> %4
2560 define i3 @add_commute_sub_i2_zext_i3(i2 %x, i2 %y) {
2561 ; CHECK-LABEL: @add_commute_sub_i2_zext_i3(
2562 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i2 [[Y:%.*]] to i3
2563 ; CHECK-NEXT:    ret i3 [[TMP1]]
2565   %1 = sub nuw i2 %y, %x
2566   %2 = zext i2 %1 to i3
2567   %3 = zext i2 %x to i3
2568   %4 = add i3 %3, %2
2569   ret i3 %4
2572 define i16 @add_sub_use_zext(i8 %x, i8 %y) {
2573 ; CHECK-LABEL: @add_sub_use_zext(
2574 ; CHECK-NEXT:    [[TMP1:%.*]] = sub nuw i8 [[Y:%.*]], [[X:%.*]]
2575 ; CHECK-NEXT:    call void @use(i8 [[TMP1]])
2576 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[Y]] to i16
2577 ; CHECK-NEXT:    ret i16 [[TMP2]]
2579   %1 = sub nuw i8 %y, %x
2580   call void @use(i8 %1)
2581   %2 = zext i8 %1 to i16
2582   %3 = zext i8 %x to i16
2583   %4 = add i16 %2, %3
2584   ret i16 %4
2587 ; Negative test: x - y + x  != y
2588 define i16 @add_sub_commute_zext(i8 %x, i8 %y) {
2589 ; CHECK-LABEL: @add_sub_commute_zext(
2590 ; CHECK-NEXT:    [[TMP1:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]]
2591 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2592 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i8 [[X]] to i16
2593 ; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw i16 [[TMP2]], [[TMP3]]
2594 ; CHECK-NEXT:    ret i16 [[TMP4]]
2596   %1 = sub nuw i8 %x, %y
2597   %2 = zext i8 %1 to i16
2598   %3 = zext i8 %x to i16
2599   %4 = add i16 %2, %3
2600   ret i16 %4
2603 ; Negative test: no nuw flags
2604 define i16 @add_no_nuw_sub_zext(i8 %x, i8 %y) {
2605 ; CHECK-LABEL: @add_no_nuw_sub_zext(
2606 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]]
2607 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2608 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i8 [[X]] to i16
2609 ; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]]
2610 ; CHECK-NEXT:    ret i16 [[TMP4]]
2612   %1 = sub i8 %y, %x
2613   %2 = zext i8 %1 to i16
2614   %3 = zext i8 %x to i16
2615   %4 = add i16 %3, %2
2616   ret i16 %4
2619 define i16 @add_no_nuw_sub_commute_zext(i8 %x, i8 %y) {
2620 ; CHECK-LABEL: @add_no_nuw_sub_commute_zext(
2621 ; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
2622 ; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2623 ; CHECK-NEXT:    [[TMP3:%.*]] = zext i8 [[X]] to i16
2624 ; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]]
2625 ; CHECK-NEXT:    ret i16 [[TMP4]]
2627   %1 = sub i8 %x, %y
2628   %2 = zext i8 %1 to i16
2629   %3 = zext i8 %x to i16
2630   %4 = add i16 %3, %2
2631   ret i16 %4
2634 define i16 @add_sub_zext_constant(i8 %x) {
2635 ; CHECK-LABEL: @add_sub_zext_constant(
2636 ; CHECK-NEXT:    ret i16 254
2638   %1 = sub nuw i8 254, %x
2639   %2 = zext i8 %1 to i16
2640   %3 = zext i8 %x to i16
2641   %4 = add i16 %2, %3
2642   ret i16 %4
2645 define <vscale x 1 x i32> @add_to_or_scalable(<vscale x 1 x i32> %in) {
2646 ; CHECK-LABEL: @add_to_or_scalable(
2647 ; CHECK-NEXT:    [[SHL:%.*]] = shl <vscale x 1 x i32> [[IN:%.*]], shufflevector (<vscale x 1 x i32> insertelement (<vscale x 1 x i32> poison, i32 1, i64 0), <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer)
2648 ; CHECK-NEXT:    [[ADD:%.*]] = or disjoint <vscale x 1 x i32> [[SHL]], shufflevector (<vscale x 1 x i32> insertelement (<vscale x 1 x i32> poison, i32 1, i64 0), <vscale x 1 x i32> poison, <vscale x 1 x i32> zeroinitializer)
2649 ; CHECK-NEXT:    ret <vscale x 1 x i32> [[ADD]]
2651   %shl = shl <vscale x 1 x i32> %in, splat (i32 1)
2652   %add = add <vscale x 1 x i32> %shl, splat (i32 1)
2653   ret <vscale x 1 x i32> %add
2656 define i5 @zext_zext_not(i3 noundef %x) {
2657 ; CHECK-LABEL: @zext_zext_not(
2658 ; CHECK-NEXT:    ret i5 7
2660   %zx = zext i3 %x to i5
2661   %notx = xor i3 %x, -1
2662   %znotx = zext i3 %notx to i5
2663   %r = add i5 %zx, %znotx
2664   ret i5 %r
2667 define <2 x i5> @zext_zext_not_commute(<2 x i3> noundef %x) {
2668 ; CHECK-LABEL: @zext_zext_not_commute(
2669 ; CHECK-NEXT:    ret <2 x i5> <i5 7, i5 7>
2671   %zx = zext <2 x i3> %x to <2 x i5>
2672   %notx = xor <2 x i3> %x, <i3 -1, i3 poison>
2673   %znotx = zext <2 x i3> %notx to <2 x i5>
2674   %r = add <2 x i5> %znotx, %zx
2675   ret <2 x i5> %r
2678 define i9 @sext_sext_not(i3 noundef %x) {
2679 ; CHECK-LABEL: @sext_sext_not(
2680 ; CHECK-NEXT:    ret i9 -1
2682   %sx = sext i3 %x to i9
2683   %notx = xor i3 %x, -1
2684   %snotx = sext i3 %notx to i9
2685   %r = add i9 %sx, %snotx
2686   ret i9 %r
2689 define i8 @sext_sext_not_commute(i3 noundef %x) {
2690 ; CHECK-LABEL: @sext_sext_not_commute(
2691 ; CHECK-NEXT:    [[SX:%.*]] = sext i3 [[X:%.*]] to i8
2692 ; CHECK-NEXT:    call void @use(i8 [[SX]])
2693 ; CHECK-NEXT:    ret i8 -1
2696   %sx = sext i3 %x to i8
2697   call void @use(i8 %sx)
2698   %notx = xor i3 %x, -1
2699   %snotx = sext i3 %notx to i8
2700   %r = add i8 %snotx, %sx
2701   ret i8 %r
2704 define i5 @zext_sext_not(i4 noundef %x) {
2705 ; CHECK-LABEL: @zext_sext_not(
2706 ; CHECK-NEXT:    [[ZX:%.*]] = zext i4 [[X:%.*]] to i5
2707 ; CHECK-NEXT:    [[NOTX:%.*]] = xor i4 [[X]], -1
2708 ; CHECK-NEXT:    [[SNOTX:%.*]] = sext i4 [[NOTX]] to i5
2709 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i5 [[ZX]], [[SNOTX]]
2710 ; CHECK-NEXT:    ret i5 [[R]]
2712   %zx = zext i4 %x to i5
2713   %notx = xor i4 %x, -1
2714   %snotx = sext i4 %notx to i5
2715   %r = add i5 %zx, %snotx
2716   ret i5 %r
2719 define i8 @zext_sext_not_commute(i4 noundef %x) {
2720 ; CHECK-LABEL: @zext_sext_not_commute(
2721 ; CHECK-NEXT:    [[ZX:%.*]] = zext i4 [[X:%.*]] to i8
2722 ; CHECK-NEXT:    call void @use(i8 [[ZX]])
2723 ; CHECK-NEXT:    [[NOTX:%.*]] = xor i4 [[X]], -1
2724 ; CHECK-NEXT:    [[SNOTX:%.*]] = sext i4 [[NOTX]] to i8
2725 ; CHECK-NEXT:    call void @use(i8 [[SNOTX]])
2726 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i8 [[SNOTX]], [[ZX]]
2727 ; CHECK-NEXT:    ret i8 [[R]]
2729   %zx = zext i4 %x to i8
2730   call void @use(i8 %zx)
2731   %notx = xor i4 %x, -1
2732   %snotx = sext i4 %notx to i8
2733   call void @use(i8 %snotx)
2734   %r = add i8 %snotx, %zx
2735   ret i8 %r
2738 define i9 @sext_zext_not(i4 noundef %x) {
2739 ; CHECK-LABEL: @sext_zext_not(
2740 ; CHECK-NEXT:    [[SX:%.*]] = sext i4 [[X:%.*]] to i9
2741 ; CHECK-NEXT:    [[NOTX:%.*]] = xor i4 [[X]], -1
2742 ; CHECK-NEXT:    [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
2743 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i9 [[SX]], [[ZNOTX]]
2744 ; CHECK-NEXT:    ret i9 [[R]]
2746   %sx = sext i4 %x to i9
2747   %notx = xor i4 %x, -1
2748   %znotx = zext i4 %notx to i9
2749   %r = add i9 %sx, %znotx
2750   ret i9 %r
2753 define i9 @sext_zext_not_commute(i4 noundef %x) {
2754 ; CHECK-LABEL: @sext_zext_not_commute(
2755 ; CHECK-NEXT:    [[SX:%.*]] = sext i4 [[X:%.*]] to i9
2756 ; CHECK-NEXT:    [[NOTX:%.*]] = xor i4 [[X]], -1
2757 ; CHECK-NEXT:    [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
2758 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i9 [[ZNOTX]], [[SX]]
2759 ; CHECK-NEXT:    ret i9 [[R]]
2761   %sx = sext i4 %x to i9
2762   %notx = xor i4 %x, -1
2763   %znotx = zext i4 %notx to i9
2764   %r = add i9 %znotx, %sx
2765   ret i9 %r
2768 ; PR57741
2770 define i32 @floor_sdiv(i32 %x) {
2771 ; CHECK-LABEL: @floor_sdiv(
2772 ; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X:%.*]], 2
2773 ; CHECK-NEXT:    ret i32 [[R]]
2775   %d = sdiv i32 %x, 4
2776   %a = and i32 %x, -2147483645
2777   %i = icmp ugt i32 %a, -2147483648
2778   %s = sext i1 %i to i32
2779   %r = add i32 %d, %s
2780   ret i32 %r
2783 define i8 @floor_sdiv_by_2(i8 %x) {
2784 ; CHECK-LABEL: @floor_sdiv_by_2(
2785 ; CHECK-NEXT:    [[RV:%.*]] = ashr i8 [[X:%.*]], 1
2786 ; CHECK-NEXT:    ret i8 [[RV]]
2788   %div = sdiv i8 %x, 2
2789   %and = and i8 %x, -127
2790   %icmp = icmp eq i8 %and, -127
2791   %sext = sext i1 %icmp to i8
2792   %rv = add nsw i8 %div, %sext
2793   ret i8 %rv
2796 define i8 @floor_sdiv_by_2_wrong_mask(i8 %x) {
2797 ; CHECK-LABEL: @floor_sdiv_by_2_wrong_mask(
2798 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[X:%.*]], 2
2799 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], 127
2800 ; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i8 [[AND]], 127
2801 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i8
2802 ; CHECK-NEXT:    [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2803 ; CHECK-NEXT:    ret i8 [[RV]]
2805   %div = sdiv i8 %x, 2
2806   %and = and i8 %x, 127
2807   %icmp = icmp eq i8 %and, 127
2808   %sext = sext i1 %icmp to i8
2809   %rv = add nsw i8 %div, %sext
2810   ret i8 %rv
2813 define i8 @floor_sdiv_by_2_wrong_constant(i8 %x) {
2814 ; CHECK-LABEL: @floor_sdiv_by_2_wrong_constant(
2815 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[X:%.*]], 4
2816 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -125
2817 ; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i8 [[AND]], -125
2818 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i8
2819 ; CHECK-NEXT:    [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2820 ; CHECK-NEXT:    ret i8 [[RV]]
2822   %div = sdiv i8 %x, 4
2823   %and = and i8 %x, -125
2824   %icmp = icmp eq i8 %and, -125
2825   %sext = sext i1 %icmp to i8
2826   %rv = add nsw i8 %div, %sext
2827   ret i8 %rv
2830 define i8 @floor_sdiv_by_2_wrong_cast(i8 %x) {
2831 ; CHECK-LABEL: @floor_sdiv_by_2_wrong_cast(
2832 ; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[X:%.*]], 2
2833 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -127
2834 ; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i8 [[AND]], -127
2835 ; CHECK-NEXT:    [[SEXT:%.*]] = zext i1 [[ICMP]] to i8
2836 ; CHECK-NEXT:    [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2837 ; CHECK-NEXT:    ret i8 [[RV]]
2839   %div = sdiv i8 %x, 2
2840   %and = and i8 %x, -127
2841   %icmp = icmp eq i8 %and, -127
2842   %sext = zext i1 %icmp to i8
2843   %rv = add nsw i8 %div, %sext
2844   ret i8 %rv
2847 ; vectors work too and commute is handled by complexity-based canonicalization
2849 define <2 x i32> @floor_sdiv_vec_commute(<2 x i32> %x) {
2850 ; CHECK-LABEL: @floor_sdiv_vec_commute(
2851 ; CHECK-NEXT:    [[R:%.*]] = ashr <2 x i32> [[X:%.*]], <i32 2, i32 2>
2852 ; CHECK-NEXT:    ret <2 x i32> [[R]]
2854   %d = sdiv <2 x i32> %x, <i32 4, i32 4>
2855   %a = and <2 x i32> %x, <i32 -2147483645, i32 -2147483645>
2856   %i = icmp ugt <2 x i32> %a, <i32 -2147483648, i32 -2147483648>
2857   %s = sext <2 x i1> %i to <2 x i32>
2858   %r = add <2 x i32> %s, %d
2859   ret <2 x i32> %r
2862 ; extra uses are ok
2864 define i8 @floor_sdiv_uses(i8 %x) {
2865 ; CHECK-LABEL: @floor_sdiv_uses(
2866 ; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], 16
2867 ; CHECK-NEXT:    call void @use(i8 [[D]])
2868 ; CHECK-NEXT:    [[A:%.*]] = and i8 [[X]], -113
2869 ; CHECK-NEXT:    call void @use(i8 [[A]])
2870 ; CHECK-NEXT:    [[I:%.*]] = icmp ugt i8 [[A]], -128
2871 ; CHECK-NEXT:    [[S:%.*]] = sext i1 [[I]] to i8
2872 ; CHECK-NEXT:    call void @use(i8 [[S]])
2873 ; CHECK-NEXT:    [[R:%.*]] = ashr i8 [[X]], 4
2874 ; CHECK-NEXT:    ret i8 [[R]]
2876   %d = sdiv i8 %x, 16
2877   call void @use(i8 %d)
2878   %a = and i8 %x, 143 ; 128 + 15
2879   call void @use(i8 %a)
2880   %i = icmp ugt i8 %a, 128
2881   %s = sext i1 %i to i8
2882   call void @use(i8 %s)
2883   %r = add i8 %d, %s
2884   ret i8 %r
2887 ; negative test
2889 define i32 @floor_sdiv_wrong_div(i32 %x) {
2890 ; CHECK-LABEL: @floor_sdiv_wrong_div(
2891 ; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 8
2892 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], -2147483645
2893 ; CHECK-NEXT:    [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2894 ; CHECK-NEXT:    [[S:%.*]] = sext i1 [[I]] to i32
2895 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2896 ; CHECK-NEXT:    ret i32 [[R]]
2898   %d = sdiv i32 %x, 8
2899   %a = and i32 %x, -2147483645
2900   %i = icmp ugt i32 %a, -2147483648
2901   %s = sext i1 %i to i32
2902   %r = add i32 %d, %s
2903   ret i32 %r
2906 ; negative test
2908 define i32 @floor_sdiv_wrong_mask(i32 %x) {
2909 ; CHECK-LABEL: @floor_sdiv_wrong_mask(
2910 ; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2911 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], -2147483644
2912 ; CHECK-NEXT:    [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2913 ; CHECK-NEXT:    [[S:%.*]] = sext i1 [[I]] to i32
2914 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2915 ; CHECK-NEXT:    ret i32 [[R]]
2917   %d = sdiv i32 %x, 4
2918   %a = and i32 %x, -2147483644
2919   %i = icmp ugt i32 %a, -2147483648
2920   %s = sext i1 %i to i32
2921   %r = add i32 %d, %s
2922   ret i32 %r
2925 ; negative test
2927 define i32 @floor_sdiv_wrong_cmp(i32 %x) {
2928 ; CHECK-LABEL: @floor_sdiv_wrong_cmp(
2929 ; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2930 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], -2147483646
2931 ; CHECK-NEXT:    [[I:%.*]] = icmp eq i32 [[A]], -2147483646
2932 ; CHECK-NEXT:    [[S:%.*]] = sext i1 [[I]] to i32
2933 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2934 ; CHECK-NEXT:    ret i32 [[R]]
2936   %d = sdiv i32 %x, 4
2937   %a = and i32 %x, -2147483645
2938   %i = icmp ugt i32 %a, -2147483647
2939   %s = sext i1 %i to i32
2940   %r = add i32 %d, %s
2941   ret i32 %r
2944 ; negative test
2946 define i32 @floor_sdiv_wrong_ext(i32 %x) {
2947 ; CHECK-LABEL: @floor_sdiv_wrong_ext(
2948 ; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2949 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], -2147483645
2950 ; CHECK-NEXT:    [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2951 ; CHECK-NEXT:    [[S:%.*]] = zext i1 [[I]] to i32
2952 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2953 ; CHECK-NEXT:    ret i32 [[R]]
2955   %d = sdiv i32 %x, 4
2956   %a = and i32 %x, -2147483645
2957   %i = icmp ugt i32 %a, -2147483648
2958   %s = zext i1 %i to i32
2959   %r = add i32 %d, %s
2960   ret i32 %r
2963 ; negative test
2965 define i32 @floor_sdiv_wrong_op(i32 %x, i32 %y) {
2966 ; CHECK-LABEL: @floor_sdiv_wrong_op(
2967 ; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2968 ; CHECK-NEXT:    [[A:%.*]] = and i32 [[Y:%.*]], -2147483645
2969 ; CHECK-NEXT:    [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2970 ; CHECK-NEXT:    [[S:%.*]] = zext i1 [[I]] to i32
2971 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2972 ; CHECK-NEXT:    ret i32 [[R]]
2974   %d = sdiv i32 %x, 4
2975   %a = and i32 %y, -2147483645
2976   %i = icmp ugt i32 %a, -2147483648
2977   %s = zext i1 %i to i32
2978   %r = add i32 %d, %s
2979   ret i32 %r
2982 ; (X s>> (BW - 1)) + (zext (X s> 0)) --> (X s>> (BW - 1)) | (zext (X != 0))
2984 define i8 @signum_i8_i8(i8 %x) {
2985 ; CHECK-LABEL: @signum_i8_i8(
2986 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7
2987 ; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 0
2988 ; CHECK-NEXT:    [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i8
2989 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
2990 ; CHECK-NEXT:    ret i8 [[R]]
2992   %sgt0 = icmp sgt i8 %x, 0
2993   %zgt0 = zext i1 %sgt0 to i8
2994   %signbit = ashr i8 %x, 7
2995   %r = add i8 %zgt0, %signbit
2996   ret i8 %r
2999 ; extra use of shift is ok
3001 define i8 @signum_i8_i8_use1(i8 %x) {
3002 ; CHECK-LABEL: @signum_i8_i8_use1(
3003 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7
3004 ; CHECK-NEXT:    call void @use(i8 [[SIGNBIT]])
3005 ; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 0
3006 ; CHECK-NEXT:    [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i8
3007 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
3008 ; CHECK-NEXT:    ret i8 [[R]]
3010   %sgt0 = icmp sgt i8 %x, 0
3011   %zgt0 = zext i1 %sgt0 to i8
3012   %signbit = ashr i8 %x, 7
3013   call void @use(i8 %signbit)
3014   %r = add i8 %zgt0, %signbit
3015   ret i8 %r
3018 ; negative test
3020 define i8 @signum_i8_i8_use2(i8 %x) {
3021 ; CHECK-LABEL: @signum_i8_i8_use2(
3022 ; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3023 ; CHECK-NEXT:    [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3024 ; CHECK-NEXT:    call void @use(i8 [[ZGT0]])
3025 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3026 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3027 ; CHECK-NEXT:    ret i8 [[R]]
3029   %sgt0 = icmp sgt i8 %x, 0
3030   %zgt0 = zext i1 %sgt0 to i8
3031   call void @use(i8 %zgt0)
3032   %signbit = ashr i8 %x, 7
3033   %r = add i8 %zgt0, %signbit
3034   ret i8 %r
3037 ; negative test
3039 define i8 @signum_i8_i8_use3(i8 %x) {
3040 ; CHECK-LABEL: @signum_i8_i8_use3(
3041 ; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3042 ; CHECK-NEXT:    call void @use_i1(i1 [[SGT0]])
3043 ; CHECK-NEXT:    [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3044 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3045 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3046 ; CHECK-NEXT:    ret i8 [[R]]
3048   %sgt0 = icmp sgt i8 %x, 0
3049   call void @use_i1(i1 %sgt0)
3050   %zgt0 = zext i1 %sgt0 to i8
3051   %signbit = ashr i8 %x, 7
3052   %r = add i8 %zgt0, %signbit
3053   ret i8 %r
3056 ; poison is ok to propagate in shift amount
3057 ; complexity canonicalization guarantees that shift is op0 of add
3059 define <2 x i5> @signum_v2i5_v2i5(<2 x i5> %x) {
3060 ; CHECK-LABEL: @signum_v2i5_v2i5(
3061 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr <2 x i5> [[X:%.*]], <i5 4, i5 poison>
3062 ; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne <2 x i5> [[X]], zeroinitializer
3063 ; CHECK-NEXT:    [[ISNOTNULL_ZEXT:%.*]] = zext <2 x i1> [[ISNOTNULL]] to <2 x i5>
3064 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i5> [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
3065 ; CHECK-NEXT:    ret <2 x i5> [[R]]
3067   %sgt0 = icmp sgt <2 x i5> %x, zeroinitializer
3068   %zgt0 = zext <2 x i1> %sgt0 to <2 x i5>
3069   %signbit = ashr <2 x i5> %x, <i5 4, i5 poison>
3070   %r = add <2 x i5> %signbit, %zgt0
3071   ret <2 x i5> %r
3074 ; negative test
3076 define i8 @signum_i8_i8_wrong_sh_amt(i8 %x) {
3077 ; CHECK-LABEL: @signum_i8_i8_wrong_sh_amt(
3078 ; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3079 ; CHECK-NEXT:    [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3080 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 6
3081 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3082 ; CHECK-NEXT:    ret i8 [[R]]
3084   %sgt0 = icmp sgt i8 %x, 0
3085   %zgt0 = zext i1 %sgt0 to i8
3086   %signbit = ashr i8 %x, 6
3087   %r = add i8 %zgt0, %signbit
3088   ret i8 %r
3091 ; negative test
3093 define i8 @signum_i8_i8_wrong_ext(i8 %x) {
3094 ; CHECK-LABEL: @signum_i8_i8_wrong_ext(
3095 ; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3096 ; CHECK-NEXT:    [[ZGT0:%.*]] = sext i1 [[SGT0]] to i8
3097 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3098 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3099 ; CHECK-NEXT:    ret i8 [[R]]
3101   %sgt0 = icmp sgt i8 %x, 0
3102   %zgt0 = sext i1 %sgt0 to i8
3103   %signbit = ashr i8 %x, 7
3104   %r = add i8 %zgt0, %signbit
3105   ret i8 %r
3108 ; negative test
3110 define i8 @signum_i8_i8_wrong_pred(i8 %x) {
3111 ; CHECK-LABEL: @signum_i8_i8_wrong_pred(
3112 ; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], -1
3113 ; CHECK-NEXT:    [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3114 ; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3115 ; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3116 ; CHECK-NEXT:    ret i8 [[R]]
3118   %sgt0 = icmp sge i8 %x, 0
3119   %zgt0 = zext i1 %sgt0 to i8
3120   %signbit = ashr i8 %x, 7
3121   %r = add i8 %zgt0, %signbit
3122   ret i8 %r
3125 define i32 @dec_zext_add_assume_nonzero(i8 %x) {
3126 ; CHECK-LABEL: @dec_zext_add_assume_nonzero(
3127 ; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0
3128 ; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
3129 ; CHECK-NEXT:    [[C:%.*]] = zext i8 [[X]] to i32
3130 ; CHECK-NEXT:    ret i32 [[C]]
3132   %z = icmp ne i8 %x, 0
3133   call void @llvm.assume(i1 %z)
3134   %a = add i8 %x, -1
3135   %b = zext i8 %a to i32
3136   %c = add i32 %b, 1
3137   ret i32 %c
3140 define i32 @dec_zext_add_nonzero(i8 %x) {
3141 ; CHECK-LABEL: @dec_zext_add_nonzero(
3142 ; CHECK-NEXT:    [[O:%.*]] = or i8 [[X:%.*]], 4
3143 ; CHECK-NEXT:    [[C:%.*]] = zext i8 [[O]] to i32
3144 ; CHECK-NEXT:    ret i32 [[C]]
3146   %o = or i8 %x, 4
3147   %a = add i8 %o, -1
3148   %b = zext i8 %a to i32
3149   %c = add i32 %b, 1
3150   ret i32 %c
3153 define <2 x i32> @dec_zext_add_nonzero_vec(<2 x i8> %x) {
3154 ; CHECK-LABEL: @dec_zext_add_nonzero_vec(
3155 ; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 8>
3156 ; CHECK-NEXT:    [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3157 ; CHECK-NEXT:    ret <2 x i32> [[C]]
3159   %o = or <2 x i8> %x, <i8 8, i8 8>
3160   %a = add <2 x i8> %o, <i8 -1, i8 -1>
3161   %b = zext <2 x i8> %a to <2 x i32>
3162   %c = add <2 x i32> %b, <i32 1, i32 1>
3163   ret <2 x i32> %c
3166 ; Negative test: Folding this with undef is not safe.
3168 define <2 x i32> @dec_zext_add_nonzero_vec_undef0(<2 x i8> %x) {
3169 ; CHECK-LABEL: @dec_zext_add_nonzero_vec_undef0(
3170 ; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 undef>
3171 ; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[O]], <i8 -1, i8 -1>
3172 ; CHECK-NEXT:    [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>
3173 ; CHECK-NEXT:    [[C:%.*]] = add nuw nsw <2 x i32> [[B]], <i32 1, i32 1>
3174 ; CHECK-NEXT:    ret <2 x i32> [[C]]
3176   %o = or <2 x i8> %x, <i8 8, i8 undef>
3177   %a = add <2 x i8> %o, <i8 -1, i8 -1>
3178   %b = zext <2 x i8> %a to <2 x i32>
3179   %c = add <2 x i32> %b, <i32 1, i32 1>
3180   ret <2 x i32> %c
3183 define <2 x i32> @dec_zext_add_nonzero_poison0(<2 x i8> %x) {
3184 ; CHECK-LABEL: @dec_zext_add_nonzero_poison0(
3185 ; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 poison>
3186 ; CHECK-NEXT:    [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3187 ; CHECK-NEXT:    ret <2 x i32> [[C]]
3189   %o = or <2 x i8> %x, <i8 8, i8 poison>
3190   %a = add <2 x i8> %o, <i8 -1, i8 -1>
3191   %b = zext <2 x i8> %a to <2 x i32>
3192   %c = add <2 x i32> %b, <i32 1, i32 1>
3193   ret <2 x i32> %c
3196 define <2 x i32> @dec_zext_add_nonzero_vec_poison1(<2 x i8> %x) {
3197 ; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison1(
3198 ; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 8>
3199 ; CHECK-NEXT:    [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3200 ; CHECK-NEXT:    ret <2 x i32> [[C]]
3202   %o = or <2 x i8> %x, <i8 8, i8 8>
3203   %a = add <2 x i8> %o, <i8 -1, i8 poison>
3204   %b = zext <2 x i8> %a to <2 x i32>
3205   %c = add <2 x i32> %b, <i32 1, i32 1>
3206   ret <2 x i32> %c
3209 define <2 x i32> @dec_zext_add_nonzero_vec_poison2(<2 x i8> %x) {
3210 ; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison2(
3211 ; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 8>
3212 ; CHECK-NEXT:    [[A:%.*]] = add nsw <2 x i8> [[O]], <i8 -1, i8 -1>
3213 ; CHECK-NEXT:    [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>
3214 ; CHECK-NEXT:    [[C:%.*]] = add nuw nsw <2 x i32> [[B]], <i32 1, i32 poison>
3215 ; CHECK-NEXT:    ret <2 x i32> [[C]]
3217   %o = or <2 x i8> %x, <i8 8, i8 8>
3218   %a = add <2 x i8> %o, <i8 -1, i8 -1>
3219   %b = zext <2 x i8> %a to <2 x i32>
3220   %c = add <2 x i32> %b, <i32 1, i32 poison>
3221   ret <2 x i32> %c
3224 define i32 @add_zext_sext_i1(i1 %a) {
3225 ; CHECK-LABEL: @add_zext_sext_i1(
3226 ; CHECK-NEXT:    ret i32 0
3228   %zext = zext i1 %a to i32
3229   %sext = sext i1 %a to i32
3230   %add = add i32 %zext, %sext
3231   ret i32 %add
3234 define i32 @add_sext_zext_i1(i1 %a) {
3235 ; CHECK-LABEL: @add_sext_zext_i1(
3236 ; CHECK-NEXT:    ret i32 0
3238   %zext = zext i1 %a to i32
3239   %sext = sext i1 %a to i32
3240   %add = add i32 %sext, %zext
3241   ret i32 %add
3244 define <2 x i32> @add_zext_sext_i1_vec(<2 x i1> %a) {
3245 ; CHECK-LABEL: @add_zext_sext_i1_vec(
3246 ; CHECK-NEXT:    ret <2 x i32> zeroinitializer
3248   %zext = zext <2 x i1> %a to <2 x i32>
3249   %sext = sext <2 x i1> %a to <2 x i32>
3250   %add = add <2 x i32> %zext, %sext
3251   ret <2 x i32> %add
3254 define i32 @add_zext_zext_i1(i1 %a) {
3255 ; CHECK-LABEL: @add_zext_zext_i1(
3256 ; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[A:%.*]], i32 2, i32 0
3257 ; CHECK-NEXT:    ret i32 [[ADD]]
3259   %zext = zext i1 %a to i32
3260   %add = add i32 %zext, %zext
3261   ret i32 %add
3264 define i32 @add_sext_sext_i1(i1 %a) {
3265 ; CHECK-LABEL: @add_sext_sext_i1(
3266 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[A:%.*]] to i32
3267 ; CHECK-NEXT:    [[ADD:%.*]] = shl nsw i32 [[SEXT]], 1
3268 ; CHECK-NEXT:    ret i32 [[ADD]]
3270   %sext = sext i1 %a to i32
3271   %add = add i32 %sext, %sext
3272   ret i32 %add
3275 define i32 @add_zext_sext_not_i1(i8 %a) {
3276 ; CHECK-LABEL: @add_zext_sext_not_i1(
3277 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[A:%.*]] to i32
3278 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[A]] to i32
3279 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]
3280 ; CHECK-NEXT:    ret i32 [[ADD]]
3282   %zext = zext i8 %a to i32
3283   %sext = sext i8 %a to i32
3284   %add = add i32 %zext, %sext
3285   ret i32 %add
3288 define i32 @add_zext_sext_i1_different_values(i1 %a, i1 %b) {
3289 ; CHECK-LABEL: @add_zext_sext_i1_different_values(
3290 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i32
3291 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[B:%.*]] to i32
3292 ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]
3293 ; CHECK-NEXT:    ret i32 [[ADD]]
3295   %zext = zext i1 %a to i32
3296   %sext = sext i1 %b to i32
3297   %add = add i32 %zext, %sext
3298   ret i32 %add
3301 define i32 @add_reduce_sqr_sum_nsw(i32 %a, i32 %b) {
3302 ; CHECK-LABEL: @add_reduce_sqr_sum_nsw(
3303 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3304 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3305 ; CHECK-NEXT:    ret i32 [[ADD]]
3307   %a_sq = mul nsw i32 %a, %a
3308   %two_a = shl i32 %a, 1
3309   %two_a_plus_b = add i32 %two_a, %b
3310   %mul = mul i32 %two_a_plus_b, %b
3311   %add = add i32 %mul, %a_sq
3312   ret i32 %add
3315 define i32 @add_reduce_sqr_sum_u(i32 %a, i32 %b) {
3316 ; CHECK-LABEL: @add_reduce_sqr_sum_u(
3317 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3318 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3319 ; CHECK-NEXT:    ret i32 [[ADD]]
3321   %a_sq = mul i32 %a, %a
3322   %two_a = shl i32 %a, 1
3323   %two_a_plus_b = add i32 %two_a, %b
3324   %mul = mul i32 %two_a_plus_b, %b
3325   %add = add i32 %mul, %a_sq
3326   ret i32 %add
3329 define i32 @add_reduce_sqr_sum_nuw(i32 %a, i32 %b) {
3330 ; CHECK-LABEL: @add_reduce_sqr_sum_nuw(
3331 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3332 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3333 ; CHECK-NEXT:    ret i32 [[ADD]]
3335   %a_sq = mul nuw i32 %a, %a
3336   %two_a = mul i32 %a, 2
3337   %two_a_plus_b = add i32 %two_a, %b
3338   %mul = mul nuw i32 %two_a_plus_b, %b
3339   %add = add i32 %mul, %a_sq
3340   ret i32 %add
3343 define i32 @add_reduce_sqr_sum_flipped(i32 %a, i32 %b) {
3344 ; CHECK-LABEL: @add_reduce_sqr_sum_flipped(
3345 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3346 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3347 ; CHECK-NEXT:    ret i32 [[ADD]]
3349   %a_sq = mul nsw i32 %a, %a
3350   %two_a = shl i32 %a, 1
3351   %two_a_plus_b = add i32 %two_a, %b
3352   %mul = mul i32 %two_a_plus_b, %b
3353   %add = add i32 %a_sq, %mul
3354   ret i32 %add
3357 define i32 @add_reduce_sqr_sum_flipped2(i32 %a, i32 %bx) {
3358 ; CHECK-LABEL: @add_reduce_sqr_sum_flipped2(
3359 ; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BX:%.*]], 42
3360 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B]], [[A:%.*]]
3361 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3362 ; CHECK-NEXT:    ret i32 [[ADD]]
3364   %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3365   %a_sq = mul nsw i32 %a, %a
3366   %two_a = shl i32 %a, 1
3367   %two_a_plus_b = add i32 %two_a, %b
3368   %mul = mul i32 %b, %two_a_plus_b
3369   %add = add i32 %mul, %a_sq
3370   ret i32 %add
3373 define i32 @add_reduce_sqr_sum_flipped3(i32 %a, i32 %b) {
3374 ; CHECK-LABEL: @add_reduce_sqr_sum_flipped3(
3375 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3376 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3377 ; CHECK-NEXT:    ret i32 [[ADD]]
3379   %a_sq = mul nsw i32 %a, %a
3380   %two_a = shl i32 %a, 1
3381   %two_a_plus_b = add i32 %b, %two_a
3382   %mul = mul i32 %two_a_plus_b, %b
3383   %add = add i32 %mul, %a_sq
3384   ret i32 %add
3387 define i32 @add_reduce_sqr_sum_order2(i32 %a, i32 %b) {
3388 ; CHECK-LABEL: @add_reduce_sqr_sum_order2(
3389 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3390 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3391 ; CHECK-NEXT:    ret i32 [[AB2]]
3393   %a_sq = mul nsw i32 %a, %a
3394   %twoa = mul i32 %a, 2
3395   %twoab = mul i32 %twoa, %b
3396   %b_sq = mul i32 %b, %b
3397   %twoab_b2 = add i32 %twoab, %b_sq
3398   %ab2 = add i32 %a_sq, %twoab_b2
3399   ret i32 %ab2
3402 define i32 @add_reduce_sqr_sum_order2_flipped(i32 %a, i32 %b) {
3403 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped(
3404 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3405 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3406 ; CHECK-NEXT:    ret i32 [[AB2]]
3408   %a_sq = mul nsw i32 %a, %a
3409   %twoa = mul i32 %a, 2
3410   %twoab = mul i32 %twoa, %b
3411   %b_sq = mul i32 %b, %b
3412   %twoab_b2 = add i32 %twoab, %b_sq
3413   %ab2 = add i32 %twoab_b2, %a_sq
3414   ret i32 %ab2
3417 define i32 @add_reduce_sqr_sum_order2_flipped2(i32 %a, i32 %bx) {
3418 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped2(
3419 ; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BX:%.*]], 42
3420 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B]], [[A:%.*]]
3421 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3422 ; CHECK-NEXT:    ret i32 [[AB2]]
3424   %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3425   %a_sq = mul nsw i32 %a, %a
3426   %twoa = mul i32 %a, 2
3427   %twoab = mul i32 %twoa, %b
3428   %b_sq = mul i32 %b, %b
3429   %twoab_b2 = add i32 %b_sq, %twoab
3430   %ab2 = add i32 %a_sq, %twoab_b2
3431   ret i32 %ab2
3434 define i32 @add_reduce_sqr_sum_order2_flipped3(i32 %a, i32 %bx) {
3435 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped3(
3436 ; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BX:%.*]], 42
3437 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B]], [[A:%.*]]
3438 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3439 ; CHECK-NEXT:    ret i32 [[AB2]]
3441   %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3442   %a_sq = mul nsw i32 %a, %a
3443   %twoa = mul i32 %a, 2
3444   %twoab = mul i32 %b, %twoa
3445   %b_sq = mul i32 %b, %b
3446   %twoab_b2 = add i32 %twoab, %b_sq
3447   %ab2 = add i32 %a_sq, %twoab_b2
3448   ret i32 %ab2
3451 define i32 @add_reduce_sqr_sum_order3(i32 %a, i32 %b) {
3452 ; CHECK-LABEL: @add_reduce_sqr_sum_order3(
3453 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3454 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3455 ; CHECK-NEXT:    ret i32 [[AB2]]
3457   %a_sq = mul nsw i32 %a, %a
3458   %twoa = mul i32 %a, 2
3459   %twoab = mul i32 %twoa, %b
3460   %b_sq = mul i32 %b, %b
3461   %a2_b2 = add i32 %a_sq, %b_sq
3462   %ab2 = add i32 %twoab, %a2_b2
3463   ret i32 %ab2
3466 define i32 @add_reduce_sqr_sum_order3_flipped(i32 %a, i32 %b) {
3467 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped(
3468 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3469 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3470 ; CHECK-NEXT:    ret i32 [[AB2]]
3472   %a_sq = mul nsw i32 %a, %a
3473   %twoa = mul i32 %a, 2
3474   %twoab = mul i32 %twoa, %b
3475   %b_sq = mul i32 %b, %b
3476   %a2_b2 = add i32 %a_sq, %b_sq
3477   %ab2 = add i32 %a2_b2, %twoab
3478   ret i32 %ab2
3481 define i32 @add_reduce_sqr_sum_order3_flipped2(i32 %a, i32 %b) {
3482 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped2(
3483 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3484 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3485 ; CHECK-NEXT:    ret i32 [[AB2]]
3487   %a_sq = mul nsw i32 %a, %a
3488   %twoa = mul i32 %a, 2
3489   %twoab = mul i32 %twoa, %b
3490   %b_sq = mul i32 %b, %b
3491   %a2_b2 = add i32 %b_sq, %a_sq
3492   %ab2 = add i32 %twoab, %a2_b2
3493   ret i32 %ab2
3496 define i32 @add_reduce_sqr_sum_order3_flipped3(i32 %a, i32 %b) {
3497 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped3(
3498 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3499 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3500 ; CHECK-NEXT:    ret i32 [[AB2]]
3502   %a_sq = mul nsw i32 %a, %a
3503   %twoa = mul i32 %a, 2
3504   %twoab = mul i32 %b, %twoa
3505   %b_sq = mul i32 %b, %b
3506   %a2_b2 = add i32 %a_sq, %b_sq
3507   %ab2 = add i32 %twoab, %a2_b2
3508   ret i32 %ab2
3511 define i32 @add_reduce_sqr_sum_order4(i32 %a, i32 %b) {
3512 ; CHECK-LABEL: @add_reduce_sqr_sum_order4(
3513 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3514 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3515 ; CHECK-NEXT:    ret i32 [[AB2]]
3517   %a_sq = mul nsw i32 %a, %a
3518   %ab = mul i32 %a, %b
3519   %twoab = mul i32 %ab, 2
3520   %b_sq = mul i32 %b, %b
3521   %a2_b2 = add i32 %a_sq, %b_sq
3522   %ab2 = add i32 %twoab, %a2_b2
3523   ret i32 %ab2
3526 define i32 @add_reduce_sqr_sum_order4_flipped(i32 %a, i32 %b) {
3527 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped(
3528 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3529 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3530 ; CHECK-NEXT:    ret i32 [[AB2]]
3532   %a_sq = mul nsw i32 %a, %a
3533   %ab = mul i32 %a, %b
3534   %twoab = mul i32 %ab, 2
3535   %b_sq = mul i32 %b, %b
3536   %a2_b2 = add i32 %a_sq, %b_sq
3537   %ab2 = add i32 %a2_b2, %twoab
3538   ret i32 %ab2
3541 define i32 @add_reduce_sqr_sum_order4_flipped2(i32 %a, i32 %b) {
3542 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped2(
3543 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3544 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3545 ; CHECK-NEXT:    ret i32 [[AB2]]
3547   %a_sq = mul nsw i32 %a, %a
3548   %ab = mul i32 %a, %b
3549   %twoab = mul i32 %ab, 2
3550   %b_sq = mul i32 %b, %b
3551   %a2_b2 = add i32 %b_sq, %a_sq
3552   %ab2 = add i32 %twoab, %a2_b2
3553   ret i32 %ab2
3556 define i32 @add_reduce_sqr_sum_order4_flipped3(i32 %a, i32 %b) {
3557 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped3(
3558 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3559 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3560 ; CHECK-NEXT:    ret i32 [[AB2]]
3562   %a_sq = mul nsw i32 %a, %a
3563   %ab = mul i32 %a, %b
3564   %twoab = mul i32 2, %ab
3565   %b_sq = mul i32 %b, %b
3566   %a2_b2 = add i32 %a_sq, %b_sq
3567   %ab2 = add i32 %twoab, %a2_b2
3568   ret i32 %ab2
3571 define i32 @add_reduce_sqr_sum_order4_flipped4(i32 %a, i32 %b) {
3572 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped4(
3573 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3574 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3575 ; CHECK-NEXT:    ret i32 [[AB2]]
3577   %a_sq = mul nsw i32 %a, %a
3578   %ab = mul i32 %b, %a
3579   %twoab = mul i32 %ab, 2
3580   %b_sq = mul i32 %b, %b
3581   %a2_b2 = add i32 %a_sq, %b_sq
3582   %ab2 = add i32 %twoab, %a2_b2
3583   ret i32 %ab2
3586 define i32 @add_reduce_sqr_sum_order5(i32 %a, i32 %b) {
3587 ; CHECK-LABEL: @add_reduce_sqr_sum_order5(
3588 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3589 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3590 ; CHECK-NEXT:    ret i32 [[AB2]]
3592   %a_sq = mul nsw i32 %a, %a
3593   %twob = mul i32 %b, 2
3594   %twoab = mul i32 %twob, %a
3595   %b_sq = mul i32 %b, %b
3596   %a2_b2 = add i32 %a_sq, %b_sq
3597   %ab2 = add i32 %twoab, %a2_b2
3598   ret i32 %ab2
3601 define i32 @add_reduce_sqr_sum_order5_flipped(i32 %a, i32 %b) {
3602 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped(
3603 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3604 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3605 ; CHECK-NEXT:    ret i32 [[AB2]]
3607   %a_sq = mul nsw i32 %a, %a
3608   %twob = mul i32 %b, 2
3609   %twoab = mul i32 %twob, %a
3610   %b_sq = mul i32 %b, %b
3611   %a2_b2 = add i32 %a_sq, %b_sq
3612   %ab2 = add i32 %a2_b2, %twoab
3613   ret i32 %ab2
3616 define i32 @add_reduce_sqr_sum_order5_flipped2(i32 %a, i32 %b) {
3617 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped2(
3618 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3619 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3620 ; CHECK-NEXT:    ret i32 [[AB2]]
3622   %a_sq = mul nsw i32 %a, %a
3623   %twob = mul i32 %b, 2
3624   %twoab = mul i32 %twob, %a
3625   %b_sq = mul i32 %b, %b
3626   %a2_b2 = add i32 %b_sq, %a_sq
3627   %ab2 = add i32 %twoab, %a2_b2
3628   ret i32 %ab2
3631 define i32 @add_reduce_sqr_sum_order5_flipped3(i32 %ax, i32 %b) {
3632 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped3(
3633 ; CHECK-NEXT:    [[A:%.*]] = xor i32 [[AX:%.*]], 42
3634 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A]], [[B:%.*]]
3635 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3636 ; CHECK-NEXT:    ret i32 [[AB2]]
3638   %a = xor i32 %ax, 42 ; thwart complexity-based canonicalization
3639   %a_sq = mul nsw i32 %a, %a
3640   %twob = mul i32 %b, 2
3641   %twoab = mul i32 %a, %twob
3642   %b_sq = mul i32 %b, %b
3643   %a2_b2 = add i32 %a_sq, %b_sq
3644   %ab2 = add i32 %twoab, %a2_b2
3645   ret i32 %ab2
3648 define i32 @add_reduce_sqr_sum_order5_flipped4(i32 %a, i32 %b) {
3649 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped4(
3650 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3651 ; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3652 ; CHECK-NEXT:    ret i32 [[AB2]]
3654   %a_sq = mul nsw i32 %a, %a
3655   %twob = mul i32 2, %b
3656   %twoab = mul i32 %twob, %a
3657   %b_sq = mul i32 %b, %b
3658   %a2_b2 = add i32 %a_sq, %b_sq
3659   %ab2 = add i32 %twoab, %a2_b2
3660   ret i32 %ab2
3663 define i32 @add_reduce_sqr_sum_not_one_use(i32 %a, i32 %b) {
3664 ; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use(
3665 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3666 ; CHECK-NEXT:    [[TWO_A:%.*]] = shl i32 [[A]], 1
3667 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3668 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3669 ; CHECK-NEXT:    tail call void @fake_func(i32 [[MUL]])
3670 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3671 ; CHECK-NEXT:    ret i32 [[ADD]]
3673   %a_sq = mul nsw i32 %a, %a
3674   %two_a = shl i32 %a, 1
3675   %two_a_plus_b = add i32 %two_a, %b
3676   %mul = mul i32 %two_a_plus_b, %b
3677   tail call void @fake_func (i32 %mul)
3678   %add = add i32 %mul, %a_sq
3679   ret i32 %add
3682 define i32 @add_reduce_sqr_sum_not_one_use2(i32 %a, i32 %b) {
3683 ; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use2(
3684 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3685 ; CHECK-NEXT:    [[TWO_A:%.*]] = shl i32 [[A]], 1
3686 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3687 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3688 ; CHECK-NEXT:    tail call void @fake_func(i32 [[A_SQ]])
3689 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3690 ; CHECK-NEXT:    ret i32 [[ADD]]
3692   %a_sq = mul nsw i32 %a, %a
3693   %two_a = shl i32 %a, 1
3694   %two_a_plus_b = add i32 %two_a, %b
3695   %mul = mul i32 %two_a_plus_b, %b
3696   tail call void @fake_func (i32 %a_sq)
3697   %add = add i32 %mul, %a_sq
3698   ret i32 %add
3701 define i32 @add_reduce_sqr_sum_order2_not_one_use(i32 %a, i32 %b) {
3702 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use(
3703 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3704 ; CHECK-NEXT:    [[TWOA:%.*]] = shl i32 [[A]], 1
3705 ; CHECK-NEXT:    [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]]
3706 ; CHECK-NEXT:    [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]]
3707 ; CHECK-NEXT:    tail call void @fake_func(i32 [[TWOAB_B2]])
3708 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]]
3709 ; CHECK-NEXT:    ret i32 [[AB2]]
3711   %a_sq = mul nsw i32 %a, %a
3712   %twoa = mul i32 %a, 2
3713   %twoab = mul i32 %twoa, %b
3714   %b_sq = mul i32 %b, %b
3715   %twoab_b2 = add i32 %twoab, %b_sq
3716   tail call void @fake_func (i32 %twoab_b2)
3717   %ab2 = add i32 %a_sq, %twoab_b2
3718   ret i32 %ab2
3721 define i32 @add_reduce_sqr_sum_order2_not_one_use2(i32 %a, i32 %b) {
3722 ; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use2(
3723 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3724 ; CHECK-NEXT:    [[TWOA:%.*]] = shl i32 [[A]], 1
3725 ; CHECK-NEXT:    [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]]
3726 ; CHECK-NEXT:    [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]]
3727 ; CHECK-NEXT:    tail call void @fake_func(i32 [[A_SQ]])
3728 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]]
3729 ; CHECK-NEXT:    ret i32 [[AB2]]
3731   %a_sq = mul nsw i32 %a, %a
3732   %twoa = mul i32 %a, 2
3733   %twoab = mul i32 %twoa, %b
3734   %b_sq = mul i32 %b, %b
3735   %twoab_b2 = add i32 %twoab, %b_sq
3736   tail call void @fake_func (i32 %a_sq)
3737   %ab2 = add i32 %a_sq, %twoab_b2
3738   ret i32 %ab2
3741 define i32 @add_reduce_sqr_sum_order3_not_one_use(i32 %a, i32 %b) {
3742 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use(
3743 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3744 ; CHECK-NEXT:    [[TWOA:%.*]] = shl i32 [[A]], 1
3745 ; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]]
3746 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3747 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3748 ; CHECK-NEXT:    tail call void @fake_func(i32 [[TWOAB]])
3749 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3750 ; CHECK-NEXT:    ret i32 [[AB2]]
3752   %a_sq = mul nsw i32 %a, %a
3753   %twoa = mul i32 %a, 2
3754   %twoab = mul i32 %twoa, %b
3755   %b_sq = mul i32 %b, %b
3756   %a2_b2 = add i32 %a_sq, %b_sq
3757   tail call void @fake_func (i32 %twoab)
3758   %ab2 = add i32 %twoab, %a2_b2
3759   ret i32 %ab2
3762 define i32 @add_reduce_sqr_sum_order3_not_one_use2(i32 %a, i32 %b) {
3763 ; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use2(
3764 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3765 ; CHECK-NEXT:    [[TWOA:%.*]] = shl i32 [[A]], 1
3766 ; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]]
3767 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3768 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3769 ; CHECK-NEXT:    tail call void @fake_func(i32 [[A2_B2]])
3770 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3771 ; CHECK-NEXT:    ret i32 [[AB2]]
3773   %a_sq = mul nsw i32 %a, %a
3774   %twoa = mul i32 %a, 2
3775   %twoab = mul i32 %twoa, %b
3776   %b_sq = mul i32 %b, %b
3777   %a2_b2 = add i32 %a_sq, %b_sq
3778   tail call void @fake_func (i32 %a2_b2)
3779   %ab2 = add i32 %twoab, %a2_b2
3780   ret i32 %ab2
3783 define i32 @add_reduce_sqr_sum_order4_not_one_use(i32 %a, i32 %b) {
3784 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use(
3785 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3786 ; CHECK-NEXT:    [[AB:%.*]] = mul i32 [[A]], [[B:%.*]]
3787 ; CHECK-NEXT:    [[TWOAB:%.*]] = shl i32 [[AB]], 1
3788 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3789 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3790 ; CHECK-NEXT:    tail call void @fake_func(i32 [[TWOAB]])
3791 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3792 ; CHECK-NEXT:    ret i32 [[AB2]]
3794   %a_sq = mul nsw i32 %a, %a
3795   %ab = mul i32 %a, %b
3796   %twoab = mul i32 %ab, 2
3797   %b_sq = mul i32 %b, %b
3798   %a2_b2 = add i32 %a_sq, %b_sq
3799   tail call void @fake_func (i32 %twoab)
3800   %ab2 = add i32 %twoab, %a2_b2
3801   ret i32 %ab2
3804 define i32 @add_reduce_sqr_sum_order4_not_one_use2(i32 %a, i32 %b) {
3805 ; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use2(
3806 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3807 ; CHECK-NEXT:    [[AB:%.*]] = mul i32 [[A]], [[B:%.*]]
3808 ; CHECK-NEXT:    [[TWOAB:%.*]] = shl i32 [[AB]], 1
3809 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3810 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3811 ; CHECK-NEXT:    tail call void @fake_func(i32 [[A2_B2]])
3812 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3813 ; CHECK-NEXT:    ret i32 [[AB2]]
3815   %a_sq = mul nsw i32 %a, %a
3816   %ab = mul i32 %a, %b
3817   %twoab = mul i32 %ab, 2
3818   %b_sq = mul i32 %b, %b
3819   %a2_b2 = add i32 %a_sq, %b_sq
3820   tail call void @fake_func (i32 %a2_b2)
3821   %ab2 = add i32 %twoab, %a2_b2
3822   ret i32 %ab2
3825 define i32 @add_reduce_sqr_sum_order5_not_one_use(i32 %a, i32 %b) {
3826 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use(
3827 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3828 ; CHECK-NEXT:    [[TWOB:%.*]] = shl i32 [[B:%.*]], 1
3829 ; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]]
3830 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3831 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3832 ; CHECK-NEXT:    tail call void @fake_func(i32 [[TWOAB]])
3833 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3834 ; CHECK-NEXT:    ret i32 [[AB2]]
3836   %a_sq = mul nsw i32 %a, %a
3837   %twob = mul i32 %b, 2
3838   %twoab = mul i32 %twob, %a
3839   %b_sq = mul i32 %b, %b
3840   %a2_b2 = add i32 %a_sq, %b_sq
3841   tail call void @fake_func (i32 %twoab)
3842   %ab2 = add i32 %twoab, %a2_b2
3843   ret i32 %ab2
3846 define i32 @add_reduce_sqr_sum_order5_not_one_use2(i32 %a, i32 %b) {
3847 ; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use2(
3848 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3849 ; CHECK-NEXT:    [[TWOB:%.*]] = shl i32 [[B:%.*]], 1
3850 ; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]]
3851 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3852 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3853 ; CHECK-NEXT:    tail call void @fake_func(i32 [[A2_B2]])
3854 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3855 ; CHECK-NEXT:    ret i32 [[AB2]]
3857   %a_sq = mul nsw i32 %a, %a
3858   %twob = mul i32 %b, 2
3859   %twoab = mul i32 %twob, %a
3860   %b_sq = mul i32 %b, %b
3861   %a2_b2 = add i32 %a_sq, %b_sq
3862   tail call void @fake_func (i32 %a2_b2)
3863   %ab2 = add i32 %twoab, %a2_b2
3864   ret i32 %ab2
3867 define i32 @add_reduce_sqr_sum_invalid0(i32 %a, i32 %b) {
3868 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid0(
3869 ; CHECK-NEXT:    [[TWO_A:%.*]] = shl i32 [[A:%.*]], 1
3870 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3871 ; CHECK-NEXT:    [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A]]
3872 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[MUL1]], [[B]]
3873 ; CHECK-NEXT:    ret i32 [[ADD]]
3875   %not_a_sq = mul nsw i32 %a, %b
3876   %two_a = shl i32 %a, 1
3877   %two_a_plus_b = add i32 %two_a, %b
3878   %mul = mul i32 %two_a_plus_b, %b
3879   %add = add i32 %mul, %not_a_sq
3880   ret i32 %add
3883 define i32 @add_reduce_sqr_sum_invalid1(i32 %a, i32 %b) {
3884 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid1(
3885 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3886 ; CHECK-NEXT:    [[NOT_TWO_A_PLUS_B:%.*]] = mul i32 [[A]], 3
3887 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[NOT_TWO_A_PLUS_B]], [[B:%.*]]
3888 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3889 ; CHECK-NEXT:    ret i32 [[ADD]]
3891   %a_sq = mul nsw i32 %a, %a
3892   %two_a = shl i32 %a, 1
3893   %not_two_a_plus_b = add i32 %two_a, %a
3894   %mul = mul i32 %not_two_a_plus_b, %b
3895   %add = add i32 %mul, %a_sq
3896   ret i32 %add
3899 define i32 @add_reduce_sqr_sum_invalid2(i32 %a, i32 %b) {
3900 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid2(
3901 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3902 ; CHECK-NEXT:    [[NOT_TWO_A:%.*]] = shl i32 [[A]], 2
3903 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = add i32 [[NOT_TWO_A]], [[B:%.*]]
3904 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3905 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3906 ; CHECK-NEXT:    ret i32 [[ADD]]
3908   %a_sq = mul nsw i32 %a, %a
3909   %not_two_a = shl i32 %a, 2
3910   %two_a_plus_b = add i32 %not_two_a, %b
3911   %mul = mul i32 %two_a_plus_b, %b
3912   %add = add i32 %mul, %a_sq
3913   ret i32 %add
3916 define i32 @add_reduce_sqr_sum_invalid3(i32 %a, i32 %b) {
3917 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid3(
3918 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 3
3919 ; CHECK-NEXT:    [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A:%.*]]
3920 ; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[MUL1]], [[A]]
3921 ; CHECK-NEXT:    ret i32 [[ADD]]
3923   %a_sq = mul nsw i32 %a, %a
3924   %not_two_a = shl i32 %b, 1
3925   %two_a_plus_b = add i32 %not_two_a, %b
3926   %mul = mul i32 %two_a_plus_b, %a
3927   %add = add i32 %mul, %a_sq
3928   ret i32 %add
3931 define i32 @add_reduce_sqr_sum_invalid4(i32 %a, i32 %b) {
3932 ; CHECK-LABEL: @add_reduce_sqr_sum_invalid4(
3933 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3934 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 3
3935 ; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3936 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3937 ; CHECK-NEXT:    ret i32 [[ADD]]
3939   %a_sq = mul nsw i32 %a, %a
3940   %not_two_a = shl i32 %b, 1
3941   %two_a_plus_b = add i32 %not_two_a, %b
3942   %mul = mul i32 %two_a_plus_b, %b
3943   %add = add i32 %mul, %a_sq
3944   ret i32 %add
3947 define i32 @add_reduce_sqr_sum_varB_invalid0(i32 %a, i32 %b) {
3948 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid0(
3949 ; CHECK-NEXT:    [[NOT_A_B:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3950 ; CHECK-NEXT:    [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 1
3951 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
3952 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]]
3953 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3954 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3955 ; CHECK-NEXT:    ret i32 [[AB2]]
3957   %not_a_b = mul nsw i32 %a, %a
3958   %twoab = mul i32 %not_a_b, 2
3959   %a_sq = mul i32 %a, %a
3960   %b_sq = mul i32 %b, %b
3961   %a2_b2 = add i32 %a_sq, %b_sq
3962   %ab2 = add i32 %twoab, %a2_b2
3963   ret i32 %ab2
3966 define i32 @add_reduce_sqr_sum_varB_invalid1(i32 %a, i32 %b) {
3967 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid1(
3968 ; CHECK-NEXT:    [[NOT_A_B:%.*]] = mul nsw i32 [[B:%.*]], [[B]]
3969 ; CHECK-NEXT:    [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 1
3970 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]]
3971 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3972 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3973 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3974 ; CHECK-NEXT:    ret i32 [[AB2]]
3976   %not_a_b = mul nsw i32 %b, %b
3977   %twoab = mul i32 %not_a_b, 2
3978   %a_sq = mul i32 %a, %a
3979   %b_sq = mul i32 %b, %b
3980   %a2_b2 = add i32 %a_sq, %b_sq
3981   %ab2 = add i32 %twoab, %a2_b2
3982   ret i32 %ab2
3985 define i32 @add_reduce_sqr_sum_varB_invalid2(i32 %a, i32 %b) {
3986 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid2(
3987 ; CHECK-NEXT:    [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
3988 ; CHECK-NEXT:    [[NOT_TWOAB:%.*]] = shl i32 [[A_B]], 2
3989 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
3990 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3991 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3992 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]]
3993 ; CHECK-NEXT:    ret i32 [[AB2]]
3995   %a_b = mul nsw i32 %a, %b
3996   %not_twoab = mul i32 %a_b, 4
3997   %a_sq = mul i32 %a, %a
3998   %b_sq = mul i32 %b, %b
3999   %a2_b2 = add i32 %a_sq, %b_sq
4000   %ab2 = add i32 %not_twoab, %a2_b2
4001   ret i32 %ab2
4004 define i32 @add_reduce_sqr_sum_varB_invalid3(i32 %a, i32 %b) {
4005 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid3(
4006 ; CHECK-NEXT:    [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
4007 ; CHECK-NEXT:    [[TWOAB:%.*]] = shl i32 [[A_B]], 1
4008 ; CHECK-NEXT:    [[B_SQ1:%.*]] = add i32 [[A]], [[B]]
4009 ; CHECK-NEXT:    [[A2_B2:%.*]] = mul i32 [[B_SQ1]], [[B]]
4010 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4011 ; CHECK-NEXT:    ret i32 [[AB2]]
4013   %a_b = mul nsw i32 %a, %b
4014   %twoab = mul i32 %a_b, 2
4015   %not_a_sq = mul i32 %b, %a
4016   %b_sq = mul i32 %b, %b
4017   %a2_b2 = add i32 %not_a_sq, %b_sq
4018   %ab2 = add i32 %twoab, %a2_b2
4019   ret i32 %ab2
4022 define i32 @add_reduce_sqr_sum_varB_invalid4(i32 %a, i32 %b) {
4023 ; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid4(
4024 ; CHECK-NEXT:    [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
4025 ; CHECK-NEXT:    [[TWOAB:%.*]] = shl i32 [[A_B]], 1
4026 ; CHECK-NEXT:    [[NOT_B_SQ1:%.*]] = add i32 [[A]], [[B]]
4027 ; CHECK-NEXT:    [[A2_B2:%.*]] = mul i32 [[NOT_B_SQ1]], [[A]]
4028 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4029 ; CHECK-NEXT:    ret i32 [[AB2]]
4031   %a_b = mul nsw i32 %a, %b
4032   %twoab = mul i32 %a_b, 2
4033   %a_sq = mul i32 %a, %a
4034   %not_b_sq = mul i32 %b, %a
4035   %a2_b2 = add i32 %a_sq, %not_b_sq
4036   %ab2 = add i32 %twoab, %a2_b2
4037   ret i32 %ab2
4040 define i32 @add_reduce_sqr_sum_varC_invalid0(i32 %a, i32 %b) {
4041 ; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid0(
4042 ; CHECK-NEXT:    [[NOT_TWOA:%.*]] = shl nsw i32 [[B:%.*]], 1
4043 ; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B]]
4044 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]]
4045 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
4046 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4047 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4048 ; CHECK-NEXT:    ret i32 [[AB2]]
4050   %not_twoa = mul nsw i32 %b, 2
4051   %twoab = mul i32 %not_twoa, %b
4052   %a_sq = mul i32 %a, %a
4053   %b_sq = mul i32 %b, %b
4054   %a2_b2 = add i32 %a_sq, %b_sq
4055   %ab2 = add i32 %twoab, %a2_b2
4056   ret i32 %ab2
4059 define i32 @add_reduce_sqr_sum_varC_invalid1(i32 %a, i32 %b) {
4060 ; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid1(
4061 ; CHECK-NEXT:    [[NOT_TWOA:%.*]] = shl nsw i32 [[A:%.*]], 2
4062 ; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B:%.*]]
4063 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
4064 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
4065 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4066 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4067 ; CHECK-NEXT:    ret i32 [[AB2]]
4069   %not_twoa = mul nsw i32 %a, 4
4070   %twoab = mul i32 %not_twoa, %b
4071   %a_sq = mul i32 %a, %a
4072   %b_sq = mul i32 %b, %b
4073   %a2_b2 = add i32 %a_sq, %b_sq
4074   %ab2 = add i32 %twoab, %a2_b2
4075   ret i32 %ab2
4078 define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) {
4079 ; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid2(
4080 ; CHECK-NEXT:    [[TWOA:%.*]] = shl nsw i32 [[A:%.*]], 1
4081 ; CHECK-NEXT:    [[NOT_TWOAB:%.*]] = mul i32 [[TWOA]], [[A]]
4082 ; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
4083 ; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]]
4084 ; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4085 ; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]]
4086 ; CHECK-NEXT:    ret i32 [[AB2]]
4088   %twoa = mul nsw i32 %a, 2
4089   %not_twoab = mul i32 %twoa, %a
4090   %a_sq = mul i32 %a, %a
4091   %b_sq = mul i32 %b, %b
4092   %a2_b2 = add i32 %a_sq, %b_sq
4093   %ab2 = add i32 %not_twoab, %a2_b2
4094   ret i32 %ab2
4097 define i32 @fold_sext_addition_or_disjoint(i8 %x) {
4098 ; CHECK-LABEL: @fold_sext_addition_or_disjoint(
4099 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
4100 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 1246
4101 ; CHECK-NEXT:    ret i32 [[R]]
4103   %xx = or disjoint i8 %x, 12
4104   %se = sext i8 %xx to i32
4105   %r = add i32 %se, 1234
4106   ret i32 %r
4109 define i32 @fold_sext_addition_fail(i8 %x) {
4110 ; CHECK-LABEL: @fold_sext_addition_fail(
4111 ; CHECK-NEXT:    [[XX:%.*]] = or i8 [[X:%.*]], 12
4112 ; CHECK-NEXT:    [[SE:%.*]] = sext i8 [[XX]] to i32
4113 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[SE]], 1234
4114 ; CHECK-NEXT:    ret i32 [[R]]
4116   %xx = or i8 %x, 12
4117   %se = sext i8 %xx to i32
4118   %r = add i32 %se, 1234
4119   ret i32 %r
4122 define i32 @fold_zext_addition_or_disjoint(i8 %x) {
4123 ; CHECK-LABEL: @fold_zext_addition_or_disjoint(
4124 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
4125 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[TMP1]], 1246
4126 ; CHECK-NEXT:    ret i32 [[R]]
4128   %xx = or disjoint i8 %x, 12
4129   %se = zext i8 %xx to i32
4130   %r = add i32 %se, 1234
4131   ret i32 %r
4134 define i32 @fold_zext_addition_or_disjoint2(i8 %x) {
4135 ; CHECK-LABEL: @fold_zext_addition_or_disjoint2(
4136 ; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 4
4137 ; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP1]] to i32
4138 ; CHECK-NEXT:    ret i32 [[R]]
4140   %xx = or disjoint i8 %x, 18
4141   %se = zext i8 %xx to i32
4142   %r = add i32 %se, -14
4143   ret i32 %r
4146 define i32 @fold_zext_addition_fail(i8 %x) {
4147 ; CHECK-LABEL: @fold_zext_addition_fail(
4148 ; CHECK-NEXT:    [[XX:%.*]] = or i8 [[X:%.*]], 12
4149 ; CHECK-NEXT:    [[SE:%.*]] = zext i8 [[XX]] to i32
4150 ; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[SE]], 1234
4151 ; CHECK-NEXT:    ret i32 [[R]]
4153   %xx = or i8 %x, 12
4154   %se = zext i8 %xx to i32
4155   %r = add i32 %se, 1234
4156   ret i32 %r
4159 define i32 @fold_zext_addition_fail2(i8 %x) {
4160 ; CHECK-LABEL: @fold_zext_addition_fail2(
4161 ; CHECK-NEXT:    [[XX:%.*]] = or i8 [[X:%.*]], 18
4162 ; CHECK-NEXT:    [[SE:%.*]] = zext i8 [[XX]] to i32
4163 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[SE]], -14
4164 ; CHECK-NEXT:    ret i32 [[R]]
4166   %xx = or i8 %x, 18
4167   %se = zext i8 %xx to i32
4168   %r = add i32 %se, -14
4169   ret i32 %r
4172 define i32 @fold_zext_nneg_add_const(i8 %x) {
4173 ; CHECK-LABEL: @fold_zext_nneg_add_const(
4174 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
4175 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 98
4176 ; CHECK-NEXT:    ret i32 [[R]]
4178   %xx = add nsw i8 %x, 123
4179   %ze = zext nneg i8 %xx to i32
4180   %r = add nsw i32 %ze, -25
4181   ret i32 %r
4184 define i32 @fold_zext_nneg_add_const_fail1(i8 %x) {
4185 ; CHECK-LABEL: @fold_zext_nneg_add_const_fail1(
4186 ; CHECK-NEXT:    [[XX:%.*]] = add nsw i8 [[X:%.*]], 123
4187 ; CHECK-NEXT:    [[ZE:%.*]] = zext i8 [[XX]] to i32
4188 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[ZE]], -25
4189 ; CHECK-NEXT:    ret i32 [[R]]
4191   %xx = add nsw i8 %x, 123
4192   %ze = zext i8 %xx to i32
4193   %r = add nsw i32 %ze, -25
4194   ret i32 %r
4197 define i32 @fold_zext_nneg_add_const_fail2(i8 %x) {
4198 ; CHECK-LABEL: @fold_zext_nneg_add_const_fail2(
4199 ; CHECK-NEXT:    [[XX:%.*]] = add i8 [[X:%.*]], 123
4200 ; CHECK-NEXT:    [[ZE:%.*]] = zext nneg i8 [[XX]] to i32
4201 ; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[ZE]], -25
4202 ; CHECK-NEXT:    ret i32 [[R]]
4204   %xx = add i8 %x, 123
4205   %ze = zext nneg i8 %xx to i32
4206   %r = add nsw i32 %ze, -25
4207   ret i32 %r
4210 declare void @llvm.assume(i1)
4211 declare void @fake_func(i32)