xref: /llvm-project/llvm/test/Transforms/InstCombine/add.ll (revision bb59eb8ed534da2bd03117cfde594321add4d60c)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3; RUN: opt < %s -passes=instcombine -use-constant-int-for-fixed-length-splat -S | FileCheck %s
4
5declare void @use(i8)
6declare void @use_i1(i1)
7
8define i32 @select_0_or_1_from_bool(i1 %x) {
9; CHECK-LABEL: @select_0_or_1_from_bool(
10; CHECK-NEXT:    [[NOT_X:%.*]] = xor i1 [[X:%.*]], true
11; CHECK-NEXT:    [[ADD:%.*]] = zext i1 [[NOT_X]] to i32
12; CHECK-NEXT:    ret i32 [[ADD]]
13;
14  %ext = sext i1 %x to i32
15  %add = add i32 %ext, 1
16  ret i32 %add
17}
18
19define <2 x i32> @select_0_or_1_from_bool_vec(<2 x i1> %x) {
20; CHECK-LABEL: @select_0_or_1_from_bool_vec(
21; CHECK-NEXT:    [[NOT_X:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true)
22; CHECK-NEXT:    [[ADD:%.*]] = zext <2 x i1> [[NOT_X]] to <2 x i32>
23; CHECK-NEXT:    ret <2 x i32> [[ADD]]
24;
25  %ext = sext <2 x i1> %x to <2 x i32>
26  %add = add <2 x i32> %ext, <i32 1, i32 1>
27  ret <2 x i32> %add
28}
29
30define i32 @select_C_minus_1_or_C_from_bool(i1 %x) {
31; CHECK-LABEL: @select_C_minus_1_or_C_from_bool(
32; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[X:%.*]], i32 41, i32 42
33; CHECK-NEXT:    ret i32 [[ADD]]
34;
35  %ext = sext i1 %x to i32
36  %add = add i32 %ext, 42
37  ret i32 %add
38}
39
40define <2 x i32> @select_C_minus_1_or_C_from_bool_vec(<2 x i1> %x) {
41; CHECK-LABEL: @select_C_minus_1_or_C_from_bool_vec(
42; CHECK-NEXT:    [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 41, i32 42>, <2 x i32> <i32 42, i32 43>
43; CHECK-NEXT:    ret <2 x i32> [[ADD]]
44;
45  %ext = sext <2 x i1> %x to <2 x i32>
46  %add = add <2 x i32> %ext, <i32 42, i32 43>
47  ret <2 x i32> %add
48}
49
50; This is an 'andn' of the low bit.
51
52define i32 @flip_and_mask(i32 %x) {
53; CHECK-LABEL: @flip_and_mask(
54; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], 1
55; CHECK-NEXT:    [[INC:%.*]] = xor i32 [[TMP1]], 1
56; CHECK-NEXT:    ret i32 [[INC]]
57;
58  %shl = shl i32 %x, 31
59  %shr = ashr i32 %shl, 31
60  %inc = add i32 %shr, 1
61  ret i32 %inc
62}
63
64define <2 x i8> @flip_and_mask_splat(<2 x i8> %x) {
65; CHECK-LABEL: @flip_and_mask_splat(
66; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 1)
67; CHECK-NEXT:    [[INC:%.*]] = xor <2 x i8> [[TMP1]], splat (i8 1)
68; CHECK-NEXT:    ret <2 x i8> [[INC]]
69;
70  %shl = shl <2 x i8> %x, <i8 7, i8 7>
71  %shr = ashr <2 x i8> %shl, <i8 7, i8 7>
72  %inc = add <2 x i8> %shr, <i8 1, i8 1>
73  ret <2 x i8> %inc
74}
75
76define i32 @test1(i32 %A) {
77; CHECK-LABEL: @test1(
78; CHECK-NEXT:    ret i32 [[A:%.*]]
79;
80  %B = add i32 %A, 0
81  ret i32 %B
82}
83
84define i32 @test2(i32 %A) {
85; CHECK-LABEL: @test2(
86; CHECK-NEXT:    ret i32 [[A:%.*]]
87;
88  %B = add i32 %A, 5
89  %C = add i32 %B, -5
90  ret i32 %C
91}
92
93define i32 @test3(i32 %A) {
94; CHECK-LABEL: @test3(
95; CHECK-NEXT:    ret i32 [[A:%.*]]
96;
97  %B = add i32 %A, 5
98  %C = sub i32 %B, 5
99  ret i32 %C
100}
101
102; D = B + -A = B - A
103define i32 @test4(i32 %A, i32 %BB) {
104; CHECK-LABEL: @test4(
105; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BB:%.*]], 1
106; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B]], [[A:%.*]]
107; CHECK-NEXT:    ret i32 [[D]]
108;
109  %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization
110  %C = sub i32 0, %A
111  %D = add i32 %B, %C
112  ret i32 %D
113}
114
115define i32 @test4_both_nsw(i32 %A, i32 %BB) {
116; CHECK-LABEL: @test4_both_nsw(
117; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BB:%.*]], 1
118; CHECK-NEXT:    [[D:%.*]] = sub nsw i32 [[B]], [[A:%.*]]
119; CHECK-NEXT:    ret i32 [[D]]
120;
121  %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization
122  %C = sub nsw i32 0, %A
123  %D = add nsw i32 %B, %C
124  ret i32 %D
125}
126
127define i32 @test4_neg_nsw(i32 %A, i32 %BB) {
128; CHECK-LABEL: @test4_neg_nsw(
129; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BB:%.*]], 1
130; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B]], [[A:%.*]]
131; CHECK-NEXT:    ret i32 [[D]]
132;
133  %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization
134  %C = sub nsw i32 0, %A
135  %D = add i32 %B, %C
136  ret i32 %D
137}
138
139define i32 @test4_add_nsw(i32 %A, i32 %BB) {
140; CHECK-LABEL: @test4_add_nsw(
141; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BB:%.*]], 1
142; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B]], [[A:%.*]]
143; CHECK-NEXT:    ret i32 [[D]]
144;
145  %B = xor i32 %BB, 1 ; thwart complexity-based canonicalization
146  %C = sub i32 0, %A
147  %D = add nsw i32 %B, %C
148  ret i32 %D
149}
150
151; D = -A + B = B - A
152define i32 @test5(i32 %A, i32 %B) {
153; CHECK-LABEL: @test5(
154; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
155; CHECK-NEXT:    ret i32 [[D]]
156;
157  %C = sub i32 0, %A
158  %D = add i32 %C, %B
159  ret i32 %D
160}
161
162define i32 @test5_both_nsw(i32 %A, i32 %B) {
163; CHECK-LABEL: @test5_both_nsw(
164; CHECK-NEXT:    [[D:%.*]] = sub nsw i32 [[B:%.*]], [[A:%.*]]
165; CHECK-NEXT:    ret i32 [[D]]
166;
167  %C = sub nsw i32 0, %A
168  %D = add nsw i32 %C, %B
169  ret i32 %D
170}
171
172define i32 @test5_neg_nsw(i32 %A, i32 %B) {
173; CHECK-LABEL: @test5_neg_nsw(
174; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
175; CHECK-NEXT:    ret i32 [[D]]
176;
177  %C = sub nsw i32 0, %A
178  %D = add i32 %C, %B
179  ret i32 %D
180}
181
182define i32 @test5_add_nsw(i32 %A, i32 %B) {
183; CHECK-LABEL: @test5_add_nsw(
184; CHECK-NEXT:    [[D:%.*]] = sub i32 [[B:%.*]], [[A:%.*]]
185; CHECK-NEXT:    ret i32 [[D]]
186;
187  %C = sub i32 0, %A
188  %D = add nsw i32 %C, %B
189  ret i32 %D
190}
191
192define <2 x i8> @neg_op0_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) {
193; CHECK-LABEL: @neg_op0_vec_poison_elt(
194; CHECK-NEXT:    [[R:%.*]] = sub <2 x i8> [[B:%.*]], [[A:%.*]]
195; CHECK-NEXT:    ret <2 x i8> [[R]]
196;
197  %nega = sub <2 x i8> <i8 0, i8 poison>, %a
198  %r = add <2 x i8> %nega, %b
199  ret <2 x i8> %r
200}
201
202define <2 x i8> @neg_neg_vec_poison_elt(<2 x i8> %a, <2 x i8> %b) {
203; CHECK-LABEL: @neg_neg_vec_poison_elt(
204; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i8> [[A:%.*]], [[B:%.*]]
205; CHECK-NEXT:    [[R:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]
206; CHECK-NEXT:    ret <2 x i8> [[R]]
207;
208  %nega = sub <2 x i8> <i8 poison, i8 0>, %a
209  %negb = sub <2 x i8> <i8 poison, i8 0>, %b
210  %r = add <2 x i8> %nega, %negb
211  ret <2 x i8> %r
212}
213
214; C = 7*A+A == 8*A == A << 3
215define i32 @test6(i32 %A) {
216; CHECK-LABEL: @test6(
217; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A:%.*]], 3
218; CHECK-NEXT:    ret i32 [[C]]
219;
220  %B = mul i32 7, %A
221  %C = add i32 %B, %A
222  ret i32 %C
223}
224
225; C = A+7*A == 8*A == A << 3
226define i32 @test7(i32 %A) {
227; CHECK-LABEL: @test7(
228; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A:%.*]], 3
229; CHECK-NEXT:    ret i32 [[C]]
230;
231  %B = mul i32 7, %A
232  %C = add i32 %A, %B
233  ret i32 %C
234}
235
236; (A & C1)+(B & C2) -> (A & C1)|(B & C2) iff C1&C2 == 0
237define i32 @test8(i32 %A, i32 %B) {
238; CHECK-LABEL: @test8(
239; CHECK-NEXT:    [[A1:%.*]] = and i32 [[A:%.*]], 7
240; CHECK-NEXT:    [[B1:%.*]] = and i32 [[B:%.*]], 128
241; CHECK-NEXT:    [[C:%.*]] = or disjoint i32 [[A1]], [[B1]]
242; CHECK-NEXT:    ret i32 [[C]]
243;
244  %A1 = and i32 %A, 7
245  %B1 = and i32 %B, 128
246  %C = add i32 %A1, %B1
247  ret i32 %C
248}
249
250define i32 @test9(i32 %A) {
251; CHECK-LABEL: @test9(
252; CHECK-NEXT:    [[C:%.*]] = shl i32 [[A:%.*]], 5
253; CHECK-NEXT:    ret i32 [[C]]
254;
255  %B = shl i32 %A, 4
256  %C = add i32 %B, %B
257  ret i32 %C
258}
259
260; a != -b
261define i1 @test10(i8 %a, i8 %b) {
262; CHECK-LABEL: @test10(
263; CHECK-NEXT:    [[ADD:%.*]] = sub i8 0, [[B:%.*]]
264; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A:%.*]], [[ADD]]
265; CHECK-NEXT:    ret i1 [[C]]
266;
267  %add = add i8 %a, %b
268  %c = icmp ne i8 %add, 0
269  ret i1 %c
270}
271
272define <2 x i1> @test10vec(<2 x i8> %a, <2 x i8> %b) {
273; CHECK-LABEL: @test10vec(
274; CHECK-NEXT:    [[C:%.*]] = sub <2 x i8> zeroinitializer, [[B:%.*]]
275; CHECK-NEXT:    [[D:%.*]] = icmp ne <2 x i8> [[A:%.*]], [[C]]
276; CHECK-NEXT:    ret <2 x i1> [[D]]
277;
278  %c = add <2 x i8> %a, %b
279  %d = icmp ne <2 x i8> %c, zeroinitializer
280  ret <2 x i1> %d
281}
282
283define i1 @test11(i8 %A) {
284; CHECK-LABEL: @test11(
285; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[A:%.*]], 1
286; CHECK-NEXT:    ret i1 [[C]]
287;
288  %B = add i8 %A, -1
289  %c = icmp ne i8 %B, 0
290  ret i1 %c
291}
292
293define <2 x i1> @test11vec(<2 x i8> %a) {
294; CHECK-LABEL: @test11vec(
295; CHECK-NEXT:    [[C:%.*]] = icmp ne <2 x i8> [[A:%.*]], splat (i8 1)
296; CHECK-NEXT:    ret <2 x i1> [[C]]
297;
298  %b = add <2 x i8> %a, <i8 -1, i8 -1>
299  %c = icmp ne <2 x i8> %b, zeroinitializer
300  ret <2 x i1> %c
301}
302
303define i8 @reassoc_shl1(i8 %x, i8 %y) {
304; CHECK-LABEL: @reassoc_shl1(
305; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl i8 [[X:%.*]], 1
306; CHECK-NEXT:    [[R:%.*]] = add i8 [[Y:%.*]], [[REASS_ADD]]
307; CHECK-NEXT:    ret i8 [[R]]
308;
309  %a = add i8 %y, %x
310  %r = add i8 %a, %x
311  ret i8 %r
312}
313
314define <2 x i8> @reassoc_shl1_commute1(<2 x i8> %x, <2 x i8> %y) {
315; CHECK-LABEL: @reassoc_shl1_commute1(
316; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 1)
317; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[Y:%.*]], [[REASS_ADD]]
318; CHECK-NEXT:    ret <2 x i8> [[R]]
319;
320  %a = add <2 x i8> %x, %y
321  %r = add <2 x i8> %a, %x
322  ret <2 x i8> %r
323}
324
325define i8 @reassoc_shl1_commute2(i8 %px, i8 %py) {
326; CHECK-LABEL: @reassoc_shl1_commute2(
327; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[PX:%.*]]
328; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 43, [[PY:%.*]]
329; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl i8 [[X]], 1
330; CHECK-NEXT:    [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]]
331; CHECK-NEXT:    ret i8 [[R]]
332;
333  %x = sdiv i8 42, %px ; thwart complexity-based canonicalization
334  %y = sdiv i8 43, %py ; thwart complexity-based canonicalization
335  %a = add i8 %y, %x
336  %r = add i8 %x, %a
337  ret i8 %r
338}
339
340define i8 @reassoc_shl1_commute3(i8 %px, i8 %py) {
341; CHECK-LABEL: @reassoc_shl1_commute3(
342; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[PX:%.*]]
343; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 43, [[PY:%.*]]
344; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl i8 [[X]], 1
345; CHECK-NEXT:    [[R:%.*]] = add i8 [[Y]], [[REASS_ADD]]
346; CHECK-NEXT:    ret i8 [[R]]
347;
348  %x = sdiv i8 42, %px ; thwart complexity-based canonicalization
349  %y = sdiv i8 43, %py ; thwart complexity-based canonicalization
350  %a = add i8 %x, %y
351  %r = add i8 %x, %a
352  ret i8 %r
353}
354
355define i8 @reassoc_shl1_extra_use(i8 %x, i8 %y) {
356; CHECK-LABEL: @reassoc_shl1_extra_use(
357; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y:%.*]], [[X:%.*]]
358; CHECK-NEXT:    call void @use(i8 [[A]])
359; CHECK-NEXT:    [[R:%.*]] = add i8 [[A]], [[X]]
360; CHECK-NEXT:    ret i8 [[R]]
361;
362  %a = add i8 %y, %x
363  call void @use(i8 %a)
364  %r = add i8 %a, %x
365  ret i8 %r
366}
367
368;; TODO: shl A, 1?
369define i32 @test13(i32 %A, i32 %B, i32 %C) {
370; CHECK-LABEL: @test13(
371; CHECK-NEXT:    [[D_OK:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
372; CHECK-NEXT:    [[E_OK:%.*]] = add i32 [[D_OK]], [[C:%.*]]
373; CHECK-NEXT:    [[F:%.*]] = add i32 [[E_OK]], [[A]]
374; CHECK-NEXT:    ret i32 [[F]]
375;
376  %D_OK = add i32 %A, %B
377  %E_OK = add i32 %D_OK, %C
378  %F = add i32 %E_OK, %A
379  ret i32 %F
380}
381
382define i32 @test14(i32 %offset, i32 %difference) {
383; CHECK-LABEL: @test14(
384; CHECK-NEXT:    [[TMP_2:%.*]] = and i32 [[DIFFERENCE:%.*]], 3
385; CHECK-NEXT:    [[TMP_3_OK:%.*]] = add i32 [[TMP_2]], [[OFFSET:%.*]]
386; CHECK-NEXT:    [[TMP_5_MASK:%.*]] = and i32 [[DIFFERENCE]], -4
387; CHECK-NEXT:    [[TMP_8:%.*]] = add i32 [[TMP_3_OK]], [[TMP_5_MASK]]
388; CHECK-NEXT:    ret i32 [[TMP_8]]
389;
390  %tmp.2 = and i32 %difference, 3
391  %tmp.3_OK = add i32 %tmp.2, %offset
392  %tmp.5.mask = and i32 %difference, -4
393  ; == add %offset, %difference
394  %tmp.8 = add i32 %tmp.3_OK, %tmp.5.mask
395  ret i32 %tmp.8
396}
397
398; Only one bit set
399define i8 @test15(i8 %A) {
400; CHECK-LABEL: @test15(
401; CHECK-NEXT:    [[C:%.*]] = and i8 [[A:%.*]], 16
402; CHECK-NEXT:    ret i8 [[C]]
403;
404  %B = add i8 %A, -64
405  %C = and i8 %B, 16
406  ret i8 %C
407}
408
409define i32 @test17(i32 %A) {
410; CHECK-LABEL: @test17(
411; CHECK-NEXT:    [[C:%.*]] = sub i32 0, [[A:%.*]]
412; CHECK-NEXT:    ret i32 [[C]]
413;
414  %B = xor i32 %A, -1
415  %C = add i32 %B, 1
416  ret i32 %C
417}
418
419define i8 @test18(i8 %A) {
420; CHECK-LABEL: @test18(
421; CHECK-NEXT:    [[C:%.*]] = sub i8 16, [[A:%.*]]
422; CHECK-NEXT:    ret i8 [[C]]
423;
424  %B = xor i8 %A, -1
425  %C = add i8 %B, 17
426  ret i8 %C
427}
428
429; ~X + -127 and (-128) - X with nsw are equally poisonous
430define i8 @test18_nsw(i8 %A) {
431; CHECK-LABEL: @test18_nsw(
432; CHECK-NEXT:    [[C:%.*]] = sub nsw i8 -128, [[A:%.*]]
433; CHECK-NEXT:    ret i8 [[C]]
434;
435  %B = xor i8 %A, -1
436  %C = add nsw i8 %B, -127
437  ret i8 %C
438}
439
440; nuw couldn't propagate as nsw is.
441define i8 @test18_nuw(i8 %A) {
442; CHECK-LABEL: @test18_nuw(
443; CHECK-NEXT:    [[C:%.*]] = sub i8 -128, [[A:%.*]]
444; CHECK-NEXT:    ret i8 [[C]]
445;
446  %B = xor i8 %A, -1
447  %C = add nuw i8 %B, -127
448  ret i8 %C
449}
450
451; 127 - X with nsw will be more poisonous than ~X + -128 with nsw. (see X = -1)
452define i8 @test18_nsw_overflow(i8 %A) {
453; CHECK-LABEL: @test18_nsw_overflow(
454; CHECK-NEXT:    [[C:%.*]] = sub i8 127, [[A:%.*]]
455; CHECK-NEXT:    ret i8 [[C]]
456;
457  %B = xor i8 %A, -1
458  %C = add nsw i8 %B, -128
459  ret i8 %C
460}
461
462define <2 x i64> @test18vec(<2 x i64> %A) {
463; CHECK-LABEL: @test18vec(
464; CHECK-NEXT:    [[ADD:%.*]] = sub <2 x i64> <i64 1, i64 2>, [[A:%.*]]
465; CHECK-NEXT:    ret <2 x i64> [[ADD]]
466;
467  %xor = xor <2 x i64> %A, <i64 -1, i64 -1>
468  %add = add <2 x i64> %xor, <i64 2, i64 3>
469  ret <2 x i64> %add
470}
471
472define <2 x i8> @test18vec_nsw(<2 x i8> %A) {
473; CHECK-LABEL: @test18vec_nsw(
474; CHECK-NEXT:    [[C:%.*]] = sub nsw <2 x i8> <i8 -124, i8 -125>, [[A:%.*]]
475; CHECK-NEXT:    ret <2 x i8> [[C]]
476;
477  %B = xor <2 x i8> %A, <i8 -1, i8 -1>
478  %C = add nsw <2 x i8> %B, <i8 -123, i8 -124>
479  ret <2 x i8> %C
480}
481
482define <2 x i8> @test18vec_nsw_false(<2 x i8> %A) {
483; CHECK-LABEL: @test18vec_nsw_false(
484; CHECK-NEXT:    [[C:%.*]] = sub nsw <2 x i8> <i8 -125, i8 -126>, [[A:%.*]]
485; CHECK-NEXT:    ret <2 x i8> [[C]]
486;
487  %B = xor <2 x i8> %A, <i8 -1, i8 -1>
488  %C = add nsw <2 x i8> %B, <i8 -124, i8 -125>
489  ret <2 x i8> %C
490}
491
492
493define <2 x i8> @test18vec_nuw(<2 x i8> %A) {
494; CHECK-LABEL: @test18vec_nuw(
495; CHECK-NEXT:    [[C:%.*]] = sub <2 x i8> <i8 -128, i8 -127>, [[A:%.*]]
496; CHECK-NEXT:    ret <2 x i8> [[C]]
497;
498  %B = xor <2 x i8> %A, <i8 -1, i8 -1>
499  %C = add nuw <2 x i8> %B, <i8 -127, i8 -126>
500  ret <2 x i8> %C
501}
502
503define <2 x i8> @test18vec_nsw_overflow(<2 x i8> %A) {
504; CHECK-LABEL: @test18vec_nsw_overflow(
505; CHECK-NEXT:    [[C:%.*]] = sub <2 x i8> <i8 -128, i8 127>, [[A:%.*]]
506; CHECK-NEXT:    ret <2 x i8> [[C]]
507;
508  %B = xor <2 x i8> %A, <i8 -1, i8 -1>
509  %C = add nsw <2 x i8> %B, <i8 -127, i8 -128>
510  ret <2 x i8> %C
511}
512
513define i32 @test19(i1 %C) {
514; CHECK-LABEL: @test19(
515; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
516; CHECK-NEXT:    ret i32 [[V]]
517;
518  %A = select i1 %C, i32 1000, i32 10
519  %V = add i32 %A, 123
520  ret i32 %V
521}
522
523define <2 x i32> @test19vec(i1 %C) {
524; CHECK-LABEL: @test19vec(
525; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1123), <2 x i32> splat (i32 133)
526; CHECK-NEXT:    ret <2 x i32> [[V]]
527;
528  %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
529  %V = add <2 x i32> %A, <i32 123, i32 123>
530  ret <2 x i32> %V
531}
532
533; This is an InstSimplify fold, but test it here to make sure that
534; InstCombine does not prevent the fold.
535; With NSW, add of sign bit -> or of sign bit.
536
537define i32 @test20(i32 %x) {
538; CHECK-LABEL: @test20(
539; CHECK-NEXT:    ret i32 [[X:%.*]]
540;
541  %y = xor i32 %x, -2147483648
542  %z = add nsw i32 %y, -2147483648
543  ret i32 %z
544}
545
546define i32 @xor_sign_bit(i32 %x) {
547; CHECK-LABEL: @xor_sign_bit(
548; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X:%.*]], -2147483606
549; CHECK-NEXT:    ret i32 [[ADD]]
550;
551  %xor = xor i32 %x, 2147483648
552  %add = add i32 %xor, 42
553  ret i32 %add
554}
555
556define <2 x i32> @xor_sign_bit_vec_splat(<2 x i32> %x) {
557; CHECK-LABEL: @xor_sign_bit_vec_splat(
558; CHECK-NEXT:    [[ADD:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 -2147483606)
559; CHECK-NEXT:    ret <2 x i32> [[ADD]]
560;
561  %xor = xor <2 x i32> %x, <i32 2147483648, i32 2147483648>
562  %add = add <2 x i32> %xor, <i32 42, i32 42>
563  ret <2 x i32> %add
564}
565
566; No-wrap info allows converting the add to 'or'.
567
568define i8 @add_nsw_signbit(i8 %x) {
569; CHECK-LABEL: @add_nsw_signbit(
570; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -128
571; CHECK-NEXT:    ret i8 [[Y]]
572;
573  %y = add nsw i8 %x, -128
574  ret i8 %y
575}
576
577; No-wrap info allows converting the add to 'or'.
578
579define i8 @add_nuw_signbit(i8 %x) {
580; CHECK-LABEL: @add_nuw_signbit(
581; CHECK-NEXT:    [[Y:%.*]] = or i8 [[X:%.*]], -128
582; CHECK-NEXT:    ret i8 [[Y]]
583;
584  %y = add nuw i8 %x, 128
585  ret i8 %y
586}
587
588define i32 @add_nsw_sext_add(i8 %x) {
589; CHECK-LABEL: @add_nsw_sext_add(
590; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
591; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 398
592; CHECK-NEXT:    ret i32 [[R]]
593;
594  %add = add nsw i8 %x, 42
595  %ext = sext i8 %add to i32
596  %r = add i32 %ext, 356
597  ret i32 %r
598}
599
600; Negative test - extra use of the sext means increase of instructions.
601
602define i32 @add_nsw_sext_add_extra_use_1(i8 %x, ptr %p) {
603; CHECK-LABEL: @add_nsw_sext_add_extra_use_1(
604; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X:%.*]], 42
605; CHECK-NEXT:    [[EXT:%.*]] = sext i8 [[ADD]] to i32
606; CHECK-NEXT:    store i32 [[EXT]], ptr [[P:%.*]], align 4
607; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[EXT]], 356
608; CHECK-NEXT:    ret i32 [[R]]
609;
610  %add = add nsw i8 %x, 42
611  %ext = sext i8 %add to i32
612  store i32 %ext, ptr %p
613  %r = add i32 %ext, 356
614  ret i32 %r
615}
616
617define <2 x i32> @add_nsw_sext_add_vec_extra_use_2(<2 x i8> %x, ptr %p) {
618; CHECK-LABEL: @add_nsw_sext_add_vec_extra_use_2(
619; CHECK-NEXT:    [[ADD:%.*]] = add nsw <2 x i8> [[X:%.*]], <i8 42, i8 -5>
620; CHECK-NEXT:    store <2 x i8> [[ADD]], ptr [[P:%.*]], align 2
621; CHECK-NEXT:    [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>
622; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 398, i32 7>
623; CHECK-NEXT:    ret <2 x i32> [[R]]
624;
625  %add = add nsw <2 x i8> %x, <i8 42, i8 -5>
626  store <2 x i8> %add, ptr %p
627  %ext = sext <2 x i8> %add to <2 x i32>
628  %r = add <2 x i32> %ext, <i32 356, i32 12>
629  ret <2 x i32> %r
630}
631
632define <2 x i32> @add_nuw_zext_add_vec(<2 x i16> %x) {
633; CHECK-LABEL: @add_nuw_zext_add_vec(
634; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i16> [[X:%.*]] to <2 x i32>
635; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i32> [[TMP1]], <i32 65850, i32 -7>
636; CHECK-NEXT:    ret <2 x i32> [[R]]
637;
638  %add = add nuw <2 x i16> %x, <i16 -42, i16 5>
639  %ext = zext <2 x i16> %add to <2 x i32>
640  %r = add <2 x i32> %ext, <i32 356, i32 -12>
641  ret <2 x i32> %r
642}
643
644; Negative test - extra use of the zext means increase of instructions.
645
646define i64 @add_nuw_zext_add_extra_use_1(i8 %x, ptr %p) {
647; CHECK-LABEL: @add_nuw_zext_add_extra_use_1(
648; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
649; CHECK-NEXT:    [[EXT:%.*]] = zext i8 [[ADD]] to i64
650; CHECK-NEXT:    store i64 [[EXT]], ptr [[P:%.*]], align 4
651; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i64 [[EXT]], 356
652; CHECK-NEXT:    ret i64 [[R]]
653;
654  %add = add nuw i8 %x, 42
655  %ext = zext i8 %add to i64
656  store i64 %ext, ptr %p
657  %r = add i64 %ext, 356
658  ret i64 %r
659}
660
661define i64 @add_nuw_zext_add_extra_use_2(i8 %x, ptr %p) {
662; CHECK-LABEL: @add_nuw_zext_add_extra_use_2(
663; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X:%.*]], 42
664; CHECK-NEXT:    store i8 [[ADD]], ptr [[P:%.*]], align 1
665; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[X]] to i64
666; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i64 [[TMP1]], -314
667; CHECK-NEXT:    ret i64 [[R]]
668;
669  %add = add nuw i8 %x, 42
670  store i8 %add, ptr %p
671  %ext = zext i8 %add to i64
672  %r = add i64 %ext, -356
673  ret i64 %r
674}
675
676define i1 @test21(i32 %x) {
677; CHECK-LABEL: @test21(
678; CHECK-NEXT:    [[Y:%.*]] = icmp eq i32 [[X:%.*]], 119
679; CHECK-NEXT:    ret i1 [[Y]]
680;
681  %t = add i32 %x, 4
682  %y = icmp eq i32 %t, 123
683  ret i1 %y
684}
685
686define <2 x i1> @test21vec(<2 x i32> %x) {
687; CHECK-LABEL: @test21vec(
688; CHECK-NEXT:    [[Y:%.*]] = icmp eq <2 x i32> [[X:%.*]], splat (i32 119)
689; CHECK-NEXT:    ret <2 x i1> [[Y]]
690;
691  %t = add <2 x i32> %x, <i32 4, i32 4>
692  %y = icmp eq <2 x i32> %t, <i32 123, i32 123>
693  ret <2 x i1> %y
694}
695
696define i32 @test22(i32 %V) {
697; CHECK-LABEL: @test22(
698; CHECK-NEXT:    switch i32 [[V:%.*]], label [[DEFAULT:%.*]] [
699; CHECK-NEXT:      i32 10, label [[LAB1:%.*]]
700; CHECK-NEXT:      i32 20, label [[LAB2:%.*]]
701; CHECK-NEXT:    ]
702; CHECK:       Default:
703; CHECK-NEXT:    ret i32 123
704; CHECK:       Lab1:
705; CHECK-NEXT:    ret i32 12312
706; CHECK:       Lab2:
707; CHECK-NEXT:    ret i32 1231231
708;
709  %V2 = add i32 %V, 10
710  switch i32 %V2, label %Default [
711  i32 20, label %Lab1
712  i32 30, label %Lab2
713  ]
714
715Default:                ; preds = %0
716  ret i32 123
717
718Lab1:           ; preds = %0
719  ret i32 12312
720
721Lab2:           ; preds = %0
722  ret i32 1231231
723}
724
725define i32 @test23(i1 %C, i32 %a) {
726; CHECK-LABEL: @test23(
727; CHECK-NEXT:  entry:
728; CHECK-NEXT:    br i1 [[C:%.*]], label [[ENDIF:%.*]], label [[ELSE:%.*]]
729; CHECK:       else:
730; CHECK-NEXT:    br label [[ENDIF]]
731; CHECK:       endif:
732; CHECK-NEXT:    [[B_0:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[ELSE]] ]
733; CHECK-NEXT:    ret i32 [[B_0]]
734;
735entry:
736  br i1 %C, label %endif, label %else
737
738else:           ; preds = %entry
739  br label %endif
740
741endif:          ; preds = %else, %entry
742  %b.0 = phi i32 [ 0, %entry ], [ 1, %else ]
743  %tmp.4 = add i32 %b.0, 1
744  ret i32 %tmp.4
745}
746
747define i32 @test24(i32 %A) {
748; CHECK-LABEL: @test24(
749; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 1
750; CHECK-NEXT:    ret i32 [[B]]
751;
752  %B = add i32 %A, 1
753  %C = shl i32 %B, 1
754  %D = sub i32 %C, 2
755  ret i32 %D
756}
757
758define i64 @test25(i64 %Y) {
759; CHECK-LABEL: @test25(
760; CHECK-NEXT:    [[TMP_8:%.*]] = shl i64 [[Y:%.*]], 3
761; CHECK-NEXT:    ret i64 [[TMP_8]]
762;
763  %tmp.4 = shl i64 %Y, 2
764  %tmp.12 = shl i64 %Y, 2
765  %tmp.8 = add i64 %tmp.4, %tmp.12
766  ret i64 %tmp.8
767}
768
769define i32 @test26(i32 %A, i32 %B) {
770; CHECK-LABEL: @test26(
771; CHECK-NEXT:    ret i32 [[A:%.*]]
772;
773  %C = add i32 %A, %B
774  %D = sub i32 %C, %B
775  ret i32 %D
776}
777
778; Fold add through select.
779define i32 @test27(i1 %C, i32 %X, i32 %Y) {
780; CHECK-LABEL: @test27(
781; CHECK-NEXT:    [[C_UPGRD_1_V:%.*]] = select i1 [[C:%.*]], i32 [[X:%.*]], i32 123
782; CHECK-NEXT:    ret i32 [[C_UPGRD_1_V]]
783;
784  %A = add i32 %X, %Y
785  %B = add i32 %Y, 123
786  %C.upgrd.1 = select i1 %C, i32 %A, i32 %B
787  %D = sub i32 %C.upgrd.1, %Y
788  ret i32 %D
789}
790
791define i32 @test28(i32 %X) {
792; CHECK-LABEL: @test28(
793; CHECK-NEXT:    [[Z:%.*]] = sub i32 -1192, [[X:%.*]]
794; CHECK-NEXT:    ret i32 [[Z]]
795;
796  %Y = add i32 %X, 1234
797  %Z = sub i32 42, %Y
798  ret i32 %Z
799}
800
801define i32 @test29(i32 %x, i32 %y) {
802; CHECK-LABEL: @test29(
803; CHECK-NEXT:    [[TMP_2:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
804; CHECK-NEXT:    [[TMP_7:%.*]] = and i32 [[X]], 63
805; CHECK-NEXT:    [[TMP_9:%.*]] = and i32 [[TMP_2]], -64
806; CHECK-NEXT:    [[TMP_10:%.*]] = or disjoint i32 [[TMP_7]], [[TMP_9]]
807; CHECK-NEXT:    ret i32 [[TMP_10]]
808;
809  %tmp.2 = sub i32 %x, %y
810  %tmp.2.mask = and i32 %tmp.2, 63
811  %tmp.6 = add i32 %tmp.2.mask, %y
812  %tmp.7 = and i32 %tmp.6, 63
813  %tmp.9 = and i32 %tmp.2, -64
814  %tmp.10 = or i32 %tmp.7, %tmp.9
815  ret i32 %tmp.10
816}
817
818; Add of sign bit -> xor of sign bit.
819define i64 @test30(i64 %x) {
820; CHECK-LABEL: @test30(
821; CHECK-NEXT:    ret i64 [[X:%.*]]
822;
823  %tmp.2 = xor i64 %x, -9223372036854775808
824  %tmp.4 = add i64 %tmp.2, -9223372036854775808
825  ret i64 %tmp.4
826}
827
828define i32 @test31(i32 %A) {
829; CHECK-LABEL: @test31(
830; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A:%.*]], 5
831; CHECK-NEXT:    ret i32 [[TMP1]]
832;
833  %B = add i32 %A, 4
834  %C = mul i32 %B, 5
835  %D = sub i32 %C, 20
836  ret i32 %D
837}
838
839define i32 @test32(i32 %A) {
840; CHECK-LABEL: @test32(
841; CHECK-NEXT:    [[B:%.*]] = shl i32 [[A:%.*]], 2
842; CHECK-NEXT:    ret i32 [[B]]
843;
844  %B = add i32 %A, 4
845  %C = shl i32 %B, 2
846  %D = sub i32 %C, 16
847  ret i32 %D
848}
849
850define i8 @test33(i8 %A) {
851; CHECK-LABEL: @test33(
852; CHECK-NEXT:    [[C:%.*]] = or i8 [[A:%.*]], 1
853; CHECK-NEXT:    ret i8 [[C]]
854;
855  %B = and i8 %A, -2
856  %C = add i8 %B, 1
857  ret i8 %C
858}
859
860define i8 @test34(i8 %A) {
861; CHECK-LABEL: @test34(
862; CHECK-NEXT:    [[C:%.*]] = and i8 [[A:%.*]], 12
863; CHECK-NEXT:    ret i8 [[C]]
864;
865  %B = add i8 %A, 64
866  %C = and i8 %B, 12
867  ret i8 %C
868}
869
870; If all bits affected by the add are included
871; in the mask, do the mask op before the add.
872
873define i8 @masked_add(i8 %x) {
874; CHECK-LABEL: @masked_add(
875; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], -16
876; CHECK-NEXT:    [[R:%.*]] = add i8 [[AND]], 96
877; CHECK-NEXT:    ret i8 [[R]]
878;
879  %and = and i8 %x, 240 ; 0xf0
880  %r = add i8 %and, 96  ; 0x60
881  ret i8 %r
882}
883
884define <2 x i8> @masked_add_splat(<2 x i8> %x) {
885; CHECK-LABEL: @masked_add_splat(
886; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 -64)
887; CHECK-NEXT:    [[R:%.*]] = add <2 x i8> [[AND]], splat (i8 64)
888; CHECK-NEXT:    ret <2 x i8> [[R]]
889;
890  %and = and <2 x i8> %x, <i8 192, i8 192> ; 0xc0
891  %r = add <2 x i8> %and, <i8 64, i8 64>  ; 0x40
892  ret <2 x i8> %r
893}
894
895define i8 @not_masked_add(i8 %x) {
896; CHECK-LABEL: @not_masked_add(
897; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], 112
898; CHECK-NEXT:    [[R:%.*]] = add nuw i8 [[AND]], 96
899; CHECK-NEXT:    ret i8 [[R]]
900;
901  %and = and i8 %x, 112 ; 0x70
902  %r = add i8 %and, 96  ; 0x60
903  ret i8 %r
904}
905
906define i8 @masked_add_multi_use(i8 %x) {
907; CHECK-LABEL: @masked_add_multi_use(
908; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], -16
909; CHECK-NEXT:    [[R:%.*]] = add i8 [[AND]], 96
910; CHECK-NEXT:    call void @use(i8 [[AND]])
911; CHECK-NEXT:    ret i8 [[R]]
912;
913  %and = and i8 %x, -16 ; 0xf0
914  %r = add i8 %and, 96  ; 0x60
915  call void @use(i8 %and) ; extra use
916  ret i8 %r
917}
918
919define i32 @test35(i32 %a) {
920; CHECK-LABEL: @test35(
921; CHECK-NEXT:    ret i32 -1
922;
923  %tmpnot = xor i32 %a, -1
924  %tmp2 = add i32 %tmpnot, %a
925  ret i32 %tmp2
926}
927
928define i32 @test36(i32 %a) {
929; CHECK-LABEL: @test36(
930; CHECK-NEXT:    ret i32 0
931;
932  %x = and i32 %a, -2
933  %y = and i32 %a, -126
934  %z = add i32 %x, %y
935  %q = and i32 %z, 1  ; always zero
936  ret i32 %q
937}
938
939define i1 @test37(i32 %a, i32 %b) {
940; CHECK-LABEL: @test37(
941; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
942; CHECK-NEXT:    ret i1 [[CMP]]
943;
944  %add = add i32 %a, %b
945  %cmp = icmp eq i32 %add, %a
946  ret i1 %cmp
947}
948
949define i1 @test38(i32 %a, i32 %b) {
950; CHECK-LABEL: @test38(
951; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
952; CHECK-NEXT:    ret i1 [[CMP]]
953;
954  %add = add i32 %a, %b
955  %cmp = icmp eq i32 %add, %b
956  ret i1 %cmp
957}
958
959define i1 @test39(i32 %a, i32 %b) {
960; CHECK-LABEL: @test39(
961; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[B:%.*]], 0
962; CHECK-NEXT:    ret i1 [[CMP]]
963;
964  %add = add i32 %b, %a
965  %cmp = icmp eq i32 %add, %a
966  ret i1 %cmp
967}
968
969define i1 @test40(i32 %a, i32 %b) {
970; CHECK-LABEL: @test40(
971; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A:%.*]], 0
972; CHECK-NEXT:    ret i1 [[CMP]]
973;
974  %add = add i32 %b, %a
975  %cmp = icmp eq i32 %add, %b
976  ret i1 %cmp
977}
978
979; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
980
981define i64 @test41(i32 %a) {
982; CHECK-LABEL: @test41(
983; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i32 [[A:%.*]], 15
984; CHECK-NEXT:    [[SUB:%.*]] = zext i32 [[TMP1]] to i64
985; CHECK-NEXT:    ret i64 [[SUB]]
986;
987  %add = add nuw i32 %a, 16
988  %zext = zext i32 %add to i64
989  %sub = add i64 %zext, -1
990  ret i64 %sub
991}
992
993define i64 @test41_multiuse_constants_cancel(i32 %a) {
994; CHECK-LABEL: @test41_multiuse_constants_cancel(
995; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[A:%.*]], 1
996; CHECK-NEXT:    [[ZEXT:%.*]] = zext i32 [[ADD]] to i64
997; CHECK-NEXT:    [[SUB:%.*]] = zext i32 [[A]] to i64
998; CHECK-NEXT:    [[EXTRAUSE:%.*]] = add nuw nsw i64 [[ZEXT]], [[SUB]]
999; CHECK-NEXT:    ret i64 [[EXTRAUSE]]
1000;
1001  %add = add nuw i32 %a, 1
1002  %zext = zext i32 %add to i64
1003  %sub = add i64 %zext, -1
1004  %extrause = add i64 %zext, %sub
1005  ret i64 %extrause
1006}
1007
1008; (add (zext (add nuw X, C2)), C) --> (zext (add nuw X, C2 + C))
1009
1010define <2 x i64> @test41vec(<2 x i32> %a) {
1011; CHECK-LABEL: @test41vec(
1012; CHECK-NEXT:    [[TMP1:%.*]] = add nuw <2 x i32> [[A:%.*]], splat (i32 15)
1013; CHECK-NEXT:    [[SUB:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
1014; CHECK-NEXT:    ret <2 x i64> [[SUB]]
1015;
1016  %add = add nuw <2 x i32> %a, <i32 16, i32 16>
1017  %zext = zext <2 x i32> %add to <2 x i64>
1018  %sub = add <2 x i64> %zext, <i64 -1, i64 -1>
1019  ret <2 x i64> %sub
1020}
1021
1022define <2 x i64> @test41vec_and_multiuse(<2 x i32> %a) {
1023; CHECK-LABEL: @test41vec_and_multiuse(
1024; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i32> [[A:%.*]], splat (i32 16)
1025; CHECK-NEXT:    [[ZEXT:%.*]] = zext <2 x i32> [[ADD]] to <2 x i64>
1026; CHECK-NEXT:    [[REASS_ADD:%.*]] = shl nuw nsw <2 x i64> [[ZEXT]], splat (i64 1)
1027; CHECK-NEXT:    [[EXTRAUSE:%.*]] = add nsw <2 x i64> [[REASS_ADD]], splat (i64 -1)
1028; CHECK-NEXT:    ret <2 x i64> [[EXTRAUSE]]
1029;
1030  %add = add nuw <2 x i32> %a, <i32 16, i32 16>
1031  %zext = zext <2 x i32> %add to <2 x i64>
1032  %sub = add <2 x i64> %zext, <i64 -1, i64 -1>
1033  %extrause = add <2 x i64> %zext, %sub
1034  ret <2 x i64> %extrause
1035}
1036
1037define i32 @test42(i1 %C) {
1038; CHECK-LABEL: @test42(
1039; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], i32 1123, i32 133
1040; CHECK-NEXT:    ret i32 [[V]]
1041;
1042  %A = select i1 %C, i32 1000, i32 10
1043  %V = add i32 123, %A
1044  ret i32 %V
1045}
1046
1047define <2 x i32> @test42vec(i1 %C) {
1048; CHECK-LABEL: @test42vec(
1049; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1123), <2 x i32> splat (i32 133)
1050; CHECK-NEXT:    ret <2 x i32> [[V]]
1051;
1052  %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
1053  %V = add <2 x i32> <i32 123, i32 123>, %A
1054  ret <2 x i32> %V
1055}
1056
1057define <2 x i32> @test42vec2(i1 %C) {
1058; CHECK-LABEL: @test42vec2(
1059; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1123, i32 2833>, <2 x i32> <i32 133, i32 363>
1060; CHECK-NEXT:    ret <2 x i32> [[V]]
1061;
1062  %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
1063  %V = add <2 x i32> <i32 123, i32 333>, %A
1064  ret <2 x i32> %V
1065}
1066
1067define i32 @test55(i1 %which) {
1068; CHECK-LABEL: @test55(
1069; CHECK-NEXT:  entry:
1070; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1071; CHECK:       delay:
1072; CHECK-NEXT:    br label [[FINAL]]
1073; CHECK:       final:
1074; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 1123, [[ENTRY:%.*]] ], [ 133, [[DELAY]] ]
1075; CHECK-NEXT:    ret i32 [[A]]
1076;
1077entry:
1078  br i1 %which, label %final, label %delay
1079
1080delay:
1081  br label %final
1082
1083final:
1084  %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
1085  %value = add i32 123, %A
1086  ret i32 %value
1087}
1088
1089define <2 x i32> @test43vec(i1 %which) {
1090; CHECK-LABEL: @test43vec(
1091; CHECK-NEXT:  entry:
1092; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1093; CHECK:       delay:
1094; CHECK-NEXT:    br label [[FINAL]]
1095; CHECK:       final:
1096; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ splat (i32 1123), [[ENTRY:%.*]] ], [ splat (i32 133), [[DELAY]] ]
1097; CHECK-NEXT:    ret <2 x i32> [[A]]
1098;
1099entry:
1100  br i1 %which, label %final, label %delay
1101
1102delay:
1103  br label %final
1104
1105final:
1106  %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
1107  %value = add <2 x i32> <i32 123, i32 123>, %A
1108  ret <2 x i32> %value
1109}
1110
1111define <2 x i32> @test43vec2(i1 %which) {
1112; CHECK-LABEL: @test43vec2(
1113; CHECK-NEXT:  entry:
1114; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1115; CHECK:       delay:
1116; CHECK-NEXT:    br label [[FINAL]]
1117; CHECK:       final:
1118; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 1123, i32 2833>, [[ENTRY:%.*]] ], [ <i32 133, i32 363>, [[DELAY]] ]
1119; CHECK-NEXT:    ret <2 x i32> [[A]]
1120;
1121entry:
1122  br i1 %which, label %final, label %delay
1123
1124delay:
1125  br label %final
1126
1127final:
1128  %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
1129  %value = add <2 x i32> <i32 123, i32 333>, %A
1130  ret <2 x i32> %value
1131}
1132
1133; E = (A + 1) + ~B = A - B
1134define i32 @add_not_increment(i32 %A, i32 %B) {
1135; CHECK-LABEL: @add_not_increment(
1136; CHECK-NEXT:    [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
1137; CHECK-NEXT:    ret i32 [[E]]
1138;
1139  %C = xor i32 %B, -1
1140  %D = add i32 %A, 1
1141  %E = add i32 %D, %C
1142  ret i32 %E
1143}
1144
1145; E = (A + 1) + ~B = A - B
1146define <2 x i32> @add_not_increment_vec(<2 x i32> %A, <2 x i32> %B) {
1147; CHECK-LABEL: @add_not_increment_vec(
1148; CHECK-NEXT:    [[E:%.*]] = sub <2 x i32> [[A:%.*]], [[B:%.*]]
1149; CHECK-NEXT:    ret <2 x i32> [[E]]
1150;
1151  %C = xor <2 x i32> %B, <i32 -1, i32 -1>
1152  %D = add <2 x i32> %A, <i32 1, i32 1>
1153  %E = add <2 x i32> %D, %C
1154  ret <2 x i32> %E
1155}
1156
1157; E = ~B + (1 + A) = A - B
1158define i32 @add_not_increment_commuted(i32 %A, i32 %B) {
1159; CHECK-LABEL: @add_not_increment_commuted(
1160; CHECK-NEXT:    [[E:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
1161; CHECK-NEXT:    ret i32 [[E]]
1162;
1163  %C = xor i32 %B, -1
1164  %D = add i32 %A, 1
1165  %E = add i32 %C, %D
1166  ret i32 %E
1167}
1168
1169; E = (A + ~B) + 1 = A - B
1170define i32 @add_to_sub(i32 %M, i32 %B) {
1171; CHECK-LABEL: @add_to_sub(
1172; CHECK-NEXT:    [[A:%.*]] = mul i32 [[M:%.*]], 42
1173; CHECK-NEXT:    [[E:%.*]] = sub i32 [[A]], [[B:%.*]]
1174; CHECK-NEXT:    ret i32 [[E]]
1175;
1176  %A = mul i32 %M, 42          ; thwart complexity-based ordering
1177  %C = xor i32 %B, -1
1178  %D = add i32 %A, %C
1179  %E = add i32 %D, 1
1180  ret i32 %E
1181}
1182
1183; E = (~B + A) + 1 = A - B
1184define i32 @add_to_sub2(i32 %A, i32 %M) {
1185; CHECK-LABEL: @add_to_sub2(
1186; CHECK-NEXT:    [[B_NEG:%.*]] = mul i32 [[M:%.*]], -42
1187; CHECK-NEXT:    [[E:%.*]] = add i32 [[B_NEG]], [[A:%.*]]
1188; CHECK-NEXT:    ret i32 [[E]]
1189;
1190  %B = mul i32 %M, 42          ; thwart complexity-based ordering
1191  %C = xor i32 %B, -1
1192  %D = add i32 %C, %A
1193  %E = add i32 %D, 1
1194  ret i32 %E
1195}
1196
1197; (X | C1) + C2 --> (X | C1) ^ C1 iff (C1 == -C2)
1198define i32 @test44(i32 %A) {
1199; CHECK-LABEL: @test44(
1200; CHECK-NEXT:    [[C:%.*]] = and i32 [[A:%.*]], -124
1201; CHECK-NEXT:    ret i32 [[C]]
1202;
1203  %B = or i32 %A, 123
1204  %C = add i32 %B, -123
1205  ret i32 %C
1206}
1207
1208define i32 @test44_extra_use(i32 %A) {
1209; CHECK-LABEL: @test44_extra_use(
1210; CHECK-NEXT:    [[B:%.*]] = or i32 [[A:%.*]], 123
1211; CHECK-NEXT:    [[C:%.*]] = and i32 [[A]], -124
1212; CHECK-NEXT:    [[D:%.*]] = mul i32 [[B]], [[C]]
1213; CHECK-NEXT:    ret i32 [[D]]
1214;
1215  %B = or i32 %A, 123
1216  %C = add i32 %B, -123
1217  %D = mul i32 %B, %C
1218  ret i32 %D
1219}
1220
1221define i32 @test44_non_matching(i32 %A) {
1222; CHECK-LABEL: @test44_non_matching(
1223; CHECK-NEXT:    [[B:%.*]] = or i32 [[A:%.*]], 123
1224; CHECK-NEXT:    [[C:%.*]] = add i32 [[B]], -321
1225; CHECK-NEXT:    ret i32 [[C]]
1226;
1227  %B = or i32 %A, 123
1228  %C = add i32 %B, -321
1229  ret i32 %C
1230}
1231
1232define <2 x i32> @test44_vec(<2 x i32> %A) {
1233; CHECK-LABEL: @test44_vec(
1234; CHECK-NEXT:    [[C:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -124)
1235; CHECK-NEXT:    ret <2 x i32> [[C]]
1236;
1237  %B = or <2 x i32> %A, <i32 123, i32 123>
1238  %C = add <2 x i32> %B, <i32 -123, i32 -123>
1239  ret <2 x i32> %C
1240}
1241
1242define <2 x i32> @test44_vec_non_matching(<2 x i32> %A) {
1243; CHECK-LABEL: @test44_vec_non_matching(
1244; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[A:%.*]], splat (i32 123)
1245; CHECK-NEXT:    [[C:%.*]] = add <2 x i32> [[B]], splat (i32 -321)
1246; CHECK-NEXT:    ret <2 x i32> [[C]]
1247;
1248  %B = or <2 x i32> %A, <i32 123, i32 123>
1249  %C = add <2 x i32> %B, <i32 -321, i32 -321>
1250  ret <2 x i32> %C
1251}
1252
1253define <2 x i32> @test44_vec_poison(<2 x i32> %A) {
1254; CHECK-LABEL: @test44_vec_poison(
1255; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 poison>
1256; CHECK-NEXT:    [[C:%.*]] = add nsw <2 x i32> [[B]], <i32 -123, i32 poison>
1257; CHECK-NEXT:    ret <2 x i32> [[C]]
1258;
1259  %B = or <2 x i32> %A, <i32 123, i32 poison>
1260  %C = add <2 x i32> %B, <i32 -123, i32 poison>
1261  ret <2 x i32> %C
1262}
1263
1264define <2 x i32> @test44_vec_non_splat(<2 x i32> %A) {
1265; CHECK-LABEL: @test44_vec_non_splat(
1266; CHECK-NEXT:    [[B:%.*]] = or <2 x i32> [[A:%.*]], <i32 123, i32 456>
1267; CHECK-NEXT:    [[C:%.*]] = add <2 x i32> [[B]], <i32 -123, i32 -456>
1268; CHECK-NEXT:    ret <2 x i32> [[C]]
1269;
1270  %B = or <2 x i32> %A, <i32 123, i32 456>
1271  %C = add <2 x i32> %B, <i32 -123, i32 -456>
1272  ret <2 x i32> %C
1273}
1274
1275define i32 @lshr_add(i1 %x, i1 %y) {
1276; CHECK-LABEL: @lshr_add(
1277; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[X:%.*]], true
1278; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[Y:%.*]], [[TMP1]]
1279; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP2]] to i32
1280; CHECK-NEXT:    ret i32 [[R]]
1281;
1282  %xz = zext i1 %x to i32
1283  %ys = sext i1 %y to i32
1284  %sub = add i32 %xz, %ys
1285  %r = lshr i32 %sub, 31
1286  ret i32 %r
1287}
1288
1289define i5 @and_add(i1 %x, i1 %y) {
1290; CHECK-LABEL: @and_add(
1291; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[X:%.*]], true
1292; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[Y:%.*]], [[TMP1]]
1293; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP2]], i5 -2, i5 0
1294; CHECK-NEXT:    ret i5 [[R]]
1295;
1296  %xz = zext i1 %x to i5
1297  %ys = sext i1 %y to i5
1298  %sub = add i5 %xz, %ys
1299  %r = and i5 %sub, 30
1300  ret i5 %r
1301}
1302
1303define <2 x i8> @ashr_add_commute(<2 x i1> %x, <2 x i1> %y) {
1304; CHECK-LABEL: @ashr_add_commute(
1305; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i1> [[X:%.*]], splat (i1 true)
1306; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i1> [[Y:%.*]], [[TMP1]]
1307; CHECK-NEXT:    [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i8>
1308; CHECK-NEXT:    ret <2 x i8> [[TMP3]]
1309;
1310  %xz = zext <2 x i1> %x to <2 x i8>
1311  %ys = sext <2 x i1> %y to <2 x i8>
1312  %sub = add nsw <2 x i8> %ys, %xz
1313  %r = ashr <2 x i8> %sub, <i8 1, i8 1>
1314  ret <2 x i8> %r
1315}
1316
1317define i32 @cmp_math(i32 %x, i32 %y) {
1318; CHECK-LABEL: @cmp_math(
1319; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]]
1320; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i32
1321; CHECK-NEXT:    ret i32 [[R]]
1322;
1323  %gt = icmp ugt i32 %x, %y
1324  %lt = icmp ult i32 %x, %y
1325  %xz = zext i1 %gt to i32
1326  %yz = zext i1 %lt to i32
1327  %s = sub i32 %xz, %yz
1328  %r = lshr i32 %s, 31
1329  ret i32 %r
1330}
1331
1332; Negative test - wrong type
1333
1334define i32 @lshr_add_nonbool(i2 %x, i1 %y) {
1335; CHECK-LABEL: @lshr_add_nonbool(
1336; CHECK-NEXT:    [[XZ:%.*]] = zext i2 [[X:%.*]] to i32
1337; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1338; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1339; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1340; CHECK-NEXT:    ret i32 [[R]]
1341;
1342  %xz = zext i2 %x to i32
1343  %ys = sext i1 %y to i32
1344  %sub = add i32 %xz, %ys
1345  %r = lshr i32 %sub, 31
1346  ret i32 %r
1347}
1348
1349; Negative test - wrong demand
1350
1351define i32 @and31_add(i1 %x, i1 %y) {
1352; CHECK-LABEL: @and31_add(
1353; CHECK-NEXT:    [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1354; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1355; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1356; CHECK-NEXT:    [[R:%.*]] = and i32 [[SUB]], 31
1357; CHECK-NEXT:    ret i32 [[R]]
1358;
1359  %xz = zext i1 %x to i32
1360  %ys = sext i1 %y to i32
1361  %sub = add i32 %xz, %ys
1362  %r = and i32 %sub, 31
1363  ret i32 %r
1364}
1365
1366; Negative test - extra use
1367
1368define i32 @lshr_add_use(i1 %x, i1 %y, ptr %p) {
1369; CHECK-LABEL: @lshr_add_use(
1370; CHECK-NEXT:    [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1371; CHECK-NEXT:    store i32 [[XZ]], ptr [[P:%.*]], align 4
1372; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1373; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1374; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1375; CHECK-NEXT:    ret i32 [[R]]
1376;
1377  %xz = zext i1 %x to i32
1378  store i32 %xz, ptr %p
1379  %ys = sext i1 %y to i32
1380  %sub = add i32 %xz, %ys
1381  %r = lshr i32 %sub, 31
1382  ret i32 %r
1383}
1384
1385; Negative test - extra use
1386
1387define i32 @lshr_add_use2(i1 %x, i1 %y, ptr %p) {
1388; CHECK-LABEL: @lshr_add_use2(
1389; CHECK-NEXT:    [[XZ:%.*]] = zext i1 [[X:%.*]] to i32
1390; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1391; CHECK-NEXT:    store i32 [[YS]], ptr [[P:%.*]], align 4
1392; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XZ]], [[YS]]
1393; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1394; CHECK-NEXT:    ret i32 [[R]]
1395;
1396  %xz = zext i1 %x to i32
1397  %ys = sext i1 %y to i32
1398  store i32 %ys, ptr %p
1399  %sub = add i32 %xz, %ys
1400  %r = lshr i32 %sub, 31
1401  ret i32 %r
1402}
1403
1404define i32 @lshr_add_sexts(i1 %x, i1 %y) {
1405; CHECK-LABEL: @lshr_add_sexts(
1406; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
1407; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i32
1408; CHECK-NEXT:    ret i32 [[R]]
1409;
1410  %xs = sext i1 %x to i32
1411  %ys = sext i1 %y to i32
1412  %sub = add i32 %xs, %ys
1413  %r = lshr i32 %sub, 31
1414  ret i32 %r
1415}
1416
1417define i5 @and_add_sexts(i1 %x, i1 %y) {
1418; CHECK-LABEL: @and_add_sexts(
1419; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
1420; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i5 -2, i5 0
1421; CHECK-NEXT:    ret i5 [[R]]
1422;
1423  %xs = sext i1 %x to i5
1424  %ys = sext i1 %y to i5
1425  %sub = add i5 %xs, %ys
1426  %r = and i5 %sub, 30
1427  ret i5 %r
1428}
1429
1430define <2 x i8> @ashr_add_sexts(<2 x i1> %x, <2 x i1> %y) {
1431; CHECK-LABEL: @ashr_add_sexts(
1432; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i1> [[Y:%.*]], [[X:%.*]]
1433; CHECK-NEXT:    [[TMP2:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i8>
1434; CHECK-NEXT:    ret <2 x i8> [[TMP2]]
1435;
1436  %xs = sext <2 x i1> %x to <2 x i8>
1437  %ys = sext <2 x i1> %y to <2 x i8>
1438  %sub = add nsw <2 x i8> %ys, %xs
1439  %r = ashr <2 x i8> %sub, <i8 1, i8 1>
1440  ret <2 x i8> %r
1441}
1442
1443define i32 @cmp_math_sexts(i32 %x, i32 %y) {
1444; CHECK-LABEL: @cmp_math_sexts(
1445; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp ne i32 [[X:%.*]], [[Y:%.*]]
1446; CHECK-NEXT:    [[R:%.*]] = zext i1 [[DOTNOT]] to i32
1447; CHECK-NEXT:    ret i32 [[R]]
1448;
1449  %gt = icmp ugt i32 %x, %y
1450  %lt = icmp ult i32 %x, %y
1451  %xz = sext i1 %gt to i32
1452  %yz = zext i1 %lt to i32
1453  %s = sub i32 %xz, %yz
1454  %r = lshr i32 %s, 31
1455  ret i32 %r
1456}
1457
1458; Negative test - wrong type
1459
1460define i32 @lshr_add_nonbool_sexts(i2 %x, i1 %y) {
1461; CHECK-LABEL: @lshr_add_nonbool_sexts(
1462; CHECK-NEXT:    [[XS:%.*]] = sext i2 [[X:%.*]] to i32
1463; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1464; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1465; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1466; CHECK-NEXT:    ret i32 [[R]]
1467;
1468  %xs = sext i2 %x to i32
1469  %ys = sext i1 %y to i32
1470  %sub = add i32 %xs, %ys
1471  %r = lshr i32 %sub, 31
1472  ret i32 %r
1473}
1474
1475; Negative test - wrong demand
1476
1477define i32 @and31_add_sexts(i1 %x, i1 %y) {
1478; CHECK-LABEL: @and31_add_sexts(
1479; CHECK-NEXT:    [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1480; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1481; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1482; CHECK-NEXT:    [[R:%.*]] = and i32 [[SUB]], 31
1483; CHECK-NEXT:    ret i32 [[R]]
1484;
1485  %xs = sext i1 %x to i32
1486  %ys = sext i1 %y to i32
1487  %sub = add i32 %xs, %ys
1488  %r = and i32 %sub, 31
1489  ret i32 %r
1490}
1491
1492define i32 @lshr_add_use_sexts(i1 %x, i1 %y, ptr %p) {
1493; CHECK-LABEL: @lshr_add_use_sexts(
1494; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1495; CHECK-NEXT:    store i32 [[YS]], ptr [[P:%.*]], align 4
1496; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X:%.*]], [[Y]]
1497; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i32
1498; CHECK-NEXT:    ret i32 [[R]]
1499;
1500  %xs = sext i1 %x to i32
1501  %ys = sext i1 %y to i32
1502  store i32 %ys, ptr %p
1503  %sub = add i32 %xs, %ys
1504  %r = lshr i32 %sub, 31
1505  ret i32 %r
1506}
1507
1508define i32 @lshr_add_use_sexts_2(i1 %x, i1 %y, ptr %p) {
1509; CHECK-LABEL: @lshr_add_use_sexts_2(
1510; CHECK-NEXT:    [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1511; CHECK-NEXT:    store i32 [[XS]], ptr [[P:%.*]], align 4
1512; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[X]], [[Y:%.*]]
1513; CHECK-NEXT:    [[R:%.*]] = zext i1 [[TMP1]] to i32
1514; CHECK-NEXT:    ret i32 [[R]]
1515;
1516  %xs = sext i1 %x to i32
1517  store i32 %xs, ptr %p
1518  %ys = sext i1 %y to i32
1519  %sub = add i32 %xs, %ys
1520  %r = lshr i32 %sub, 31
1521  ret i32 %r
1522}
1523
1524; Negative test - extra use
1525
1526declare void @use_sexts(i32, i32)
1527
1528define i32 @lshr_add_use_sexts_both(i1 %x, i1 %y) {
1529; CHECK-LABEL: @lshr_add_use_sexts_both(
1530; CHECK-NEXT:    [[XS:%.*]] = sext i1 [[X:%.*]] to i32
1531; CHECK-NEXT:    [[YS:%.*]] = sext i1 [[Y:%.*]] to i32
1532; CHECK-NEXT:    call void @use_sexts(i32 [[XS]], i32 [[YS]])
1533; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[XS]], [[YS]]
1534; CHECK-NEXT:    [[R:%.*]] = lshr i32 [[SUB]], 31
1535; CHECK-NEXT:    ret i32 [[R]]
1536;
1537  %xs = sext i1 %x to i32
1538  %ys = sext i1 %y to i32
1539  call void @use_sexts(i32 %xs, i32 %ys)
1540  %sub = add i32 %xs, %ys
1541  %r = lshr i32 %sub, 31
1542  ret i32 %r
1543}
1544
1545define i8 @add_like_or_t0(i8 %x) {
1546; CHECK-LABEL: @add_like_or_t0(
1547; CHECK-NEXT:    [[I0:%.*]] = shl i8 [[X:%.*]], 4
1548; CHECK-NEXT:    [[R:%.*]] = add i8 [[I0]], 57
1549; CHECK-NEXT:    ret i8 [[R]]
1550;
1551  %i0 = shl i8 %x, 4
1552  %i1 = or i8 %i0, 15 ; no common bits
1553  %r = add i8 %i1, 42
1554  ret i8 %r
1555}
1556define i8 @add_like_or_n1(i8 %x) {
1557; CHECK-LABEL: @add_like_or_n1(
1558; CHECK-NEXT:    [[I0:%.*]] = shl i8 [[X:%.*]], 4
1559; CHECK-NEXT:    [[I1:%.*]] = or i8 [[I0]], 31
1560; CHECK-NEXT:    [[R:%.*]] = add i8 [[I1]], 42
1561; CHECK-NEXT:    ret i8 [[R]]
1562;
1563  %i0 = shl i8 %x, 4
1564  %i1 = or i8 %i0, 31 ; 4'th bit might be common-set
1565  %r = add i8 %i1, 42
1566  ret i8 %r
1567}
1568define i8 @add_like_or_t2_extrause(i8 %x) {
1569; CHECK-LABEL: @add_like_or_t2_extrause(
1570; CHECK-NEXT:    [[I0:%.*]] = shl i8 [[X:%.*]], 4
1571; CHECK-NEXT:    [[I1:%.*]] = or disjoint i8 [[I0]], 15
1572; CHECK-NEXT:    call void @use(i8 [[I1]])
1573; CHECK-NEXT:    [[R:%.*]] = add i8 [[I0]], 57
1574; CHECK-NEXT:    ret i8 [[R]]
1575;
1576  %i0 = shl i8 %x, 4
1577  %i1 = or i8 %i0, 15 ; no common bits
1578  call void @use(i8 %i1) ; extra use
1579  %r = add i8 %i1, 42
1580  ret i8 %r
1581}
1582define i8 @fold_add_constant_preserve_nsw(i8 %x) {
1583; CHECK-LABEL: @fold_add_constant_preserve_nsw(
1584; CHECK-NEXT:    [[ADD:%.*]] = add nsw i8 [[X:%.*]], -120
1585; CHECK-NEXT:    ret i8 [[ADD]]
1586;
1587  %or = or disjoint i8 %x, -128
1588  %add = add nsw i8 %or, 8
1589  ret i8 %add
1590}
1591define i8 @fold_add_constant_no_nsw(i8 %x) {
1592; CHECK-LABEL: @fold_add_constant_no_nsw(
1593; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[X:%.*]], 120
1594; CHECK-NEXT:    ret i8 [[ADD]]
1595;
1596  %or = or disjoint i8 %x, -128
1597  %add = add nsw i8 %or, -8
1598  ret i8 %add
1599}
1600define i8 @fold_add_constant_preserve_nuw(i8 %x) {
1601; CHECK-LABEL: @fold_add_constant_preserve_nuw(
1602; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[X:%.*]], -116
1603; CHECK-NEXT:    ret i8 [[ADD]]
1604;
1605  %or = or disjoint i8 %x, 128
1606  %add = add nuw i8 %or, 12
1607  ret i8 %add
1608}
1609define i32 @sdiv_to_udiv(i32 %arg0, i32 %arg1) {
1610; CHECK-LABEL: @sdiv_to_udiv(
1611; CHECK-NEXT:    [[T0:%.*]] = shl nuw nsw i32 [[ARG0:%.*]], 8
1612; CHECK-NEXT:    [[T2:%.*]] = add nuw nsw i32 [[T0]], 6242049
1613; CHECK-NEXT:    [[T3:%.*]] = udiv i32 [[T2]], 192
1614; CHECK-NEXT:    ret i32 [[T3]]
1615;
1616  %t0 = shl nuw nsw i32 %arg0, 8
1617  %t1 = or disjoint i32 %t0, 1
1618  %t2 = add nuw nsw i32 %t1, 6242048
1619  %t3 = sdiv i32 %t2, 192
1620  ret i32 %t3
1621}
1622
1623define i8 @add_like_or_disjoint(i8 %x) {
1624; CHECK-LABEL: @add_like_or_disjoint(
1625; CHECK-NEXT:    [[R:%.*]] = add i8 [[X:%.*]], 57
1626; CHECK-NEXT:    ret i8 [[R]]
1627;
1628  %i1 = or disjoint i8 %x, 15
1629  %r = add i8 %i1, 42
1630  ret i8 %r
1631}
1632
1633define i8 @add_and_xor(i8 noundef %x, i8 %y) {
1634; CHECK-LABEL: @add_and_xor(
1635; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y:%.*]], [[X:%.*]]
1636; CHECK-NEXT:    ret i8 [[ADD]]
1637;
1638  %xor = xor i8 %x, -1
1639  %and = and i8 %xor, %y
1640  %add = add i8 %and, %x
1641  ret i8 %add
1642}
1643
1644define i8 @add_and_xor_wrong_const(i8 %x, i8 %y) {
1645; CHECK-LABEL: @add_and_xor_wrong_const(
1646; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -2
1647; CHECK-NEXT:    [[AND:%.*]] = and i8 [[XOR]], [[Y:%.*]]
1648; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[AND]], [[X]]
1649; CHECK-NEXT:    ret i8 [[ADD]]
1650;
1651  %xor = xor i8 %x, -2
1652  %and = and i8 %xor, %y
1653  %add = add i8 %and, %x
1654  ret i8 %add
1655}
1656
1657define i8 @add_and_xor_wrong_op(i8 %x, i8 %y, i8 %z) {
1658; CHECK-LABEL: @add_and_xor_wrong_op(
1659; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[Z:%.*]], -1
1660; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y:%.*]], [[XOR]]
1661; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[AND]], [[X:%.*]]
1662; CHECK-NEXT:    ret i8 [[ADD]]
1663;
1664  %xor = xor i8 %z, -1
1665  %and = and i8 %xor, %y
1666  %add = add i8 %and, %x
1667  ret i8 %add
1668}
1669
1670define i8 @add_and_xor_commuted1(i8 noundef %x, i8 %_y) {
1671; CHECK-LABEL: @add_and_xor_commuted1(
1672; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1673; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X:%.*]]
1674; CHECK-NEXT:    ret i8 [[ADD]]
1675;
1676  %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1677  %xor = xor i8 %x, -1
1678  %and = and i8 %y, %xor
1679  %add = add i8 %and, %x
1680  ret i8 %add
1681}
1682
1683define i8 @add_and_xor_commuted2(i8 noundef %_x, i8 %y) {
1684; CHECK-LABEL: @add_and_xor_commuted2(
1685; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1686; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y:%.*]]
1687; CHECK-NEXT:    ret i8 [[ADD]]
1688;
1689  %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1690  %xor = xor i8 %x, -1
1691  %and = and i8 %xor, %y
1692  %add = add i8 %x, %and
1693  ret i8 %add
1694}
1695
1696define i8 @add_and_xor_commuted3(i8 noundef %_x, i8 %_y) {
1697; CHECK-LABEL: @add_and_xor_commuted3(
1698; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1699; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1700; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1701; CHECK-NEXT:    ret i8 [[ADD]]
1702;
1703  %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1704  %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1705  %xor = xor i8 %x, -1
1706  %and = and i8 %y, %xor
1707  %add = add i8 %x, %and
1708  ret i8 %add
1709}
1710
1711define i8 @add_and_xor_extra_use(i8 noundef %x, i8 %y) {
1712; CHECK-LABEL: @add_and_xor_extra_use(
1713; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[X:%.*]], -1
1714; CHECK-NEXT:    call void @use(i8 [[XOR]])
1715; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y:%.*]], [[XOR]]
1716; CHECK-NEXT:    call void @use(i8 [[AND]])
1717; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1718; CHECK-NEXT:    ret i8 [[ADD]]
1719;
1720  %xor = xor i8 %x, -1
1721  call void @use(i8 %xor)
1722  %and = and i8 %xor, %y
1723  call void @use(i8 %and)
1724  %add = add i8 %and, %x
1725  ret i8 %add
1726}
1727
1728define i8 @add_xor_and_const(i8 noundef %x) {
1729; CHECK-LABEL: @add_xor_and_const(
1730; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X:%.*]], 42
1731; CHECK-NEXT:    ret i8 [[ADD]]
1732;
1733  %and = and i8 %x, 42
1734  %xor = xor i8 %and, 42
1735  %add = add i8 %xor, %x
1736  ret i8 %add
1737}
1738
1739define i8 @add_xor_and_const_wrong_const(i8 %x) {
1740; CHECK-LABEL: @add_xor_and_const_wrong_const(
1741; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], 42
1742; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[AND]], 88
1743; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[XOR]], [[X]]
1744; CHECK-NEXT:    ret i8 [[ADD]]
1745;
1746  %and = and i8 %x, 42
1747  %xor = xor i8 %and, 88
1748  %add = add i8 %xor, %x
1749  ret i8 %add
1750}
1751
1752define i8 @add_xor_and_var(i8 noundef %x, i8 noundef %y) {
1753; CHECK-LABEL: @add_xor_and_var(
1754; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1755; CHECK-NEXT:    call void @use(i8 [[AND]])
1756; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1757; CHECK-NEXT:    ret i8 [[ADD]]
1758;
1759  %and = and i8 %x, %y
1760  call void @use(i8 %and)
1761  %xor = xor i8 %and, %y
1762  %add = add i8 %xor, %x
1763  ret i8 %add
1764}
1765
1766define i8 @add_xor_and_var_wrong_op1(i8 %x, i8 %y, i8 %z) {
1767; CHECK-LABEL: @add_xor_and_var_wrong_op1(
1768; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1769; CHECK-NEXT:    call void @use(i8 [[AND]])
1770; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[AND]], [[Z:%.*]]
1771; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[XOR]], [[X]]
1772; CHECK-NEXT:    ret i8 [[ADD]]
1773;
1774  %and = and i8 %x, %y
1775  call void @use(i8 %and)
1776  %xor = xor i8 %and, %z
1777  %add = add i8 %xor, %x
1778  ret i8 %add
1779}
1780
1781define i8 @add_xor_and_var_wrong_op2(i8 %x, i8 %y, i8 %z) {
1782; CHECK-LABEL: @add_xor_and_var_wrong_op2(
1783; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1784; CHECK-NEXT:    call void @use(i8 [[AND]])
1785; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[AND]], [[Y]]
1786; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[XOR]], [[Z:%.*]]
1787; CHECK-NEXT:    ret i8 [[ADD]]
1788;
1789  %and = and i8 %x, %y
1790  call void @use(i8 %and)
1791  %xor = xor i8 %and, %y
1792  %add = add i8 %xor, %z
1793  ret i8 %add
1794}
1795
1796define i8 @add_xor_and_var_commuted1(i8 noundef %x, i8 noundef %y) {
1797; CHECK-LABEL: @add_xor_and_var_commuted1(
1798; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y:%.*]], [[X:%.*]]
1799; CHECK-NEXT:    call void @use(i8 [[AND]])
1800; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1801; CHECK-NEXT:    ret i8 [[ADD]]
1802;
1803  %and = and i8 %y, %x
1804  call void @use(i8 %and)
1805  %xor = xor i8 %and, %y
1806  %add = add i8 %xor, %x
1807  ret i8 %add
1808}
1809
1810define i8 @add_xor_and_var_commuted2(i8 noundef %_x, i8 noundef %_y) {
1811; CHECK-LABEL: @add_xor_and_var_commuted2(
1812; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1813; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1814; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y]]
1815; CHECK-NEXT:    call void @use(i8 [[AND]])
1816; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1817; CHECK-NEXT:    ret i8 [[ADD]]
1818;
1819  %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1820  %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1821  %and = and i8 %x, %y
1822  call void @use(i8 %and)
1823  %xor = xor i8 %y, %and
1824  %add = add i8 %xor, %x
1825  ret i8 %add
1826}
1827
1828define i8 @add_xor_and_var_commuted3(i8 noundef %x, i8 noundef %_y) {
1829; CHECK-LABEL: @add_xor_and_var_commuted3(
1830; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1831; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y]], [[X:%.*]]
1832; CHECK-NEXT:    call void @use(i8 [[AND]])
1833; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1834; CHECK-NEXT:    ret i8 [[ADD]]
1835;
1836  %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1837  %and = and i8 %y, %x
1838  call void @use(i8 %and)
1839  %xor = xor i8 %y, %and
1840  %add = add i8 %xor, %x
1841  ret i8 %add
1842}
1843
1844define i8 @add_xor_and_var_commuted4(i8 noundef %_x, i8 noundef %y) {
1845; CHECK-LABEL: @add_xor_and_var_commuted4(
1846; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1847; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y:%.*]]
1848; CHECK-NEXT:    call void @use(i8 [[AND]])
1849; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1850; CHECK-NEXT:    ret i8 [[ADD]]
1851;
1852  %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1853  %and = and i8 %x, %y
1854  call void @use(i8 %and)
1855  %xor = xor i8 %and, %y
1856  %add = add i8 %x, %xor
1857  ret i8 %add
1858}
1859
1860define i8 @add_xor_and_var_commuted5(i8 noundef %_x, i8 noundef %_y) {
1861; CHECK-LABEL: @add_xor_and_var_commuted5(
1862; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1863; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1864; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y]], [[X]]
1865; CHECK-NEXT:    call void @use(i8 [[AND]])
1866; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1867; CHECK-NEXT:    ret i8 [[ADD]]
1868;
1869  %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1870  %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1871  %and = and i8 %y, %x
1872  call void @use(i8 %and)
1873  %xor = xor i8 %and, %y
1874  %add = add i8 %x, %xor
1875  ret i8 %add
1876}
1877
1878define i8 @add_xor_and_var_commuted6(i8 noundef %_x, i8 noundef %_y) {
1879; CHECK-LABEL: @add_xor_and_var_commuted6(
1880; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1881; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1882; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[Y]]
1883; CHECK-NEXT:    call void @use(i8 [[AND]])
1884; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1885; CHECK-NEXT:    ret i8 [[ADD]]
1886;
1887  %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1888  %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1889  %and = and i8 %x, %y
1890  call void @use(i8 %and)
1891  %xor = xor i8 %y, %and
1892  %add = add i8 %x, %xor
1893  ret i8 %add
1894}
1895
1896define i8 @add_xor_and_var_commuted7(i8 noundef %_x, i8 noundef %_y) {
1897; CHECK-LABEL: @add_xor_and_var_commuted7(
1898; CHECK-NEXT:    [[X:%.*]] = udiv i8 42, [[_X:%.*]]
1899; CHECK-NEXT:    [[Y:%.*]] = udiv i8 42, [[_Y:%.*]]
1900; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y]], [[X]]
1901; CHECK-NEXT:    call void @use(i8 [[AND]])
1902; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[X]], [[Y]]
1903; CHECK-NEXT:    ret i8 [[ADD]]
1904;
1905  %x = udiv i8 42, %_x ; thwart complexity-based canonicalization
1906  %y = udiv i8 42, %_y ; thwart complexity-based canonicalization
1907  %and = and i8 %y, %x
1908  call void @use(i8 %and)
1909  %xor = xor i8 %y, %and
1910  %add = add i8 %x, %xor
1911  ret i8 %add
1912}
1913
1914define i8 @add_xor_and_var_extra_use(i8 noundef %x, i8 noundef %y) {
1915; CHECK-LABEL: @add_xor_and_var_extra_use(
1916; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X:%.*]], [[Y:%.*]]
1917; CHECK-NEXT:    call void @use(i8 [[AND]])
1918; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[AND]], [[Y]]
1919; CHECK-NEXT:    call void @use(i8 [[XOR]])
1920; CHECK-NEXT:    [[ADD:%.*]] = or i8 [[Y]], [[X]]
1921; CHECK-NEXT:    ret i8 [[ADD]]
1922;
1923  %and = and i8 %x, %y
1924  call void @use(i8 %and)
1925  %xor = xor i8 %and, %y
1926  call void @use(i8 %xor)
1927  %add = add i8 %xor, %x
1928  ret i8 %add
1929}
1930
1931define i32 @add_add_add(i32 %A, i32 %B, i32 %C, i32 %D) {
1932; CHECK-LABEL: @add_add_add(
1933; CHECK-NEXT:    [[E:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
1934; CHECK-NEXT:    [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1935; CHECK-NEXT:    [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1936; CHECK-NEXT:    ret i32 [[G]]
1937;
1938  %E = add i32 %A, %B
1939  %F = add i32 %E, %C
1940  %G = add i32 %F, %D
1941  ret i32 %G
1942}
1943
1944define i32 @add_add_add_commute1(i32 %A, i32 %B, i32 %C, i32 %D) {
1945; CHECK-LABEL: @add_add_add_commute1(
1946; CHECK-NEXT:    [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1947; CHECK-NEXT:    [[F:%.*]] = add i32 [[E]], [[C:%.*]]
1948; CHECK-NEXT:    [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1949; CHECK-NEXT:    ret i32 [[G]]
1950;
1951  %E = add i32 %B, %A
1952  %F = add i32 %E, %C
1953  %G = add i32 %F, %D
1954  ret i32 %G
1955}
1956
1957define i32 @add_add_add_commute2(i32 %A, i32 %B, i32 %C, i32 %D) {
1958; CHECK-LABEL: @add_add_add_commute2(
1959; CHECK-NEXT:    [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1960; CHECK-NEXT:    [[F:%.*]] = add i32 [[C:%.*]], [[E]]
1961; CHECK-NEXT:    [[G:%.*]] = add i32 [[F]], [[D:%.*]]
1962; CHECK-NEXT:    ret i32 [[G]]
1963;
1964  %E = add i32 %B, %A
1965  %F = add i32 %C, %E
1966  %G = add i32 %F, %D
1967  ret i32 %G
1968}
1969
1970define i32 @add_add_add_commute3(i32 %A, i32 %B, i32 %C, i32 %D) {
1971; CHECK-LABEL: @add_add_add_commute3(
1972; CHECK-NEXT:    [[E:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
1973; CHECK-NEXT:    [[F:%.*]] = add i32 [[C:%.*]], [[E]]
1974; CHECK-NEXT:    [[G:%.*]] = add i32 [[D:%.*]], [[F]]
1975; CHECK-NEXT:    ret i32 [[G]]
1976;
1977  %E = add i32 %B, %A
1978  %F = add i32 %C, %E
1979  %G = add i32 %D, %F
1980  ret i32 %G
1981}
1982
1983; x * y + x --> (y + 1) * x
1984
1985define i8 @mul_add_common_factor_commute1(i8 %x, i8 %y) {
1986; CHECK-LABEL: @mul_add_common_factor_commute1(
1987; CHECK-NEXT:    [[X1:%.*]] = add i8 [[Y:%.*]], 1
1988; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X:%.*]], [[X1]]
1989; CHECK-NEXT:    ret i8 [[A]]
1990;
1991  %m = mul nsw i8 %x, %y
1992  %a = add nsw i8 %m, %x
1993  ret i8 %a
1994}
1995
1996define <2 x i8> @mul_add_common_factor_commute2(<2 x i8> %x, <2 x i8> %y) {
1997; CHECK-LABEL: @mul_add_common_factor_commute2(
1998; CHECK-NEXT:    [[M1:%.*]] = add <2 x i8> [[Y:%.*]], splat (i8 1)
1999; CHECK-NEXT:    [[A:%.*]] = mul nuw <2 x i8> [[M1]], [[X:%.*]]
2000; CHECK-NEXT:    ret <2 x i8> [[A]]
2001;
2002  %m = mul nuw <2 x i8> %y, %x
2003  %a = add nuw <2 x i8> %m, %x
2004  ret <2 x i8> %a
2005}
2006
2007define i8 @mul_add_common_factor_commute3(i8 %p, i8 %y) {
2008; CHECK-LABEL: @mul_add_common_factor_commute3(
2009; CHECK-NEXT:    [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
2010; CHECK-NEXT:    [[M1:%.*]] = add i8 [[Y:%.*]], 1
2011; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X]], [[M1]]
2012; CHECK-NEXT:    ret i8 [[A]]
2013;
2014  %x = mul i8 %p, %p ; thwart complexity-based canonicalization
2015  %m = mul nuw i8 %x, %y
2016  %a = add nsw i8 %x, %m
2017  ret i8 %a
2018}
2019
2020define i8 @mul_add_common_factor_commute4(i8 %p, i8 %q) {
2021; CHECK-LABEL: @mul_add_common_factor_commute4(
2022; CHECK-NEXT:    [[X:%.*]] = mul i8 [[P:%.*]], [[P]]
2023; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[Q:%.*]], [[Q]]
2024; CHECK-NEXT:    [[M1:%.*]] = add i8 [[Y]], 1
2025; CHECK-NEXT:    [[A:%.*]] = mul i8 [[X]], [[M1]]
2026; CHECK-NEXT:    ret i8 [[A]]
2027;
2028  %x = mul i8 %p, %p ; thwart complexity-based canonicalization
2029  %y = mul i8 %q, %q ; thwart complexity-based canonicalization
2030  %m = mul nsw i8 %y, %x
2031  %a = add nuw i8 %x, %m
2032  ret i8 %a
2033}
2034
2035; negative test - uses
2036
2037define i8 @mul_add_common_factor_use(i8 %x, i8 %y) {
2038; CHECK-LABEL: @mul_add_common_factor_use(
2039; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], [[Y:%.*]]
2040; CHECK-NEXT:    call void @use(i8 [[M]])
2041; CHECK-NEXT:    [[A:%.*]] = add i8 [[M]], [[X]]
2042; CHECK-NEXT:    ret i8 [[A]]
2043;
2044  %m = mul i8 %x, %y
2045  call void @use(i8 %m)
2046  %a = add i8 %m, %x
2047  ret i8 %a
2048}
2049
2050define i8 @not_mul(i8 %x) {
2051; CHECK-LABEL: @not_mul(
2052; CHECK-NEXT:    [[TMP1:%.*]] = mul i8 [[X:%.*]], -41
2053; CHECK-NEXT:    [[PLUSX:%.*]] = add i8 [[TMP1]], -1
2054; CHECK-NEXT:    ret i8 [[PLUSX]]
2055;
2056  %mul = mul nsw i8 %x, 42
2057  %not = xor i8 %mul, -1
2058  %plusx = add nsw i8 %not, %x
2059  ret i8 %plusx
2060}
2061
2062define <2 x i8> @not_mul_commute(<2 x i8> %p) {
2063; CHECK-LABEL: @not_mul_commute(
2064; CHECK-NEXT:    [[X:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2065; CHECK-NEXT:    [[TMP1:%.*]] = mul <2 x i8> [[X]], splat (i8 43)
2066; CHECK-NEXT:    [[PLUSX:%.*]] = add <2 x i8> [[TMP1]], splat (i8 -1)
2067; CHECK-NEXT:    ret <2 x i8> [[PLUSX]]
2068;
2069  %x = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2070  %mul = mul nuw <2 x i8> %x, <i8 -42, i8 -42>
2071  %not = xor <2 x i8> %mul, <i8 -1, i8 -1>
2072  %plusx = add nuw <2 x i8> %x, %not
2073  ret <2 x i8> %plusx
2074}
2075
2076; negative test - need common operand
2077
2078define i8 @not_mul_wrong_op(i8 %x, i8 %y) {
2079; CHECK-LABEL: @not_mul_wrong_op(
2080; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 42
2081; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[MUL]], -1
2082; CHECK-NEXT:    [[PLUSX:%.*]] = add i8 [[Y:%.*]], [[NOT]]
2083; CHECK-NEXT:    ret i8 [[PLUSX]]
2084;
2085  %mul = mul i8 %x, 42
2086  %not = xor i8 %mul, -1
2087  %plusx = add i8 %not, %y
2088  ret i8 %plusx
2089}
2090
2091; negative test - avoid creating an extra mul
2092
2093define i8 @not_mul_use1(i8 %x) {
2094; CHECK-LABEL: @not_mul_use1(
2095; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i8 [[X:%.*]], 42
2096; CHECK-NEXT:    call void @use(i8 [[MUL]])
2097; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[MUL]], -1
2098; CHECK-NEXT:    [[PLUSX:%.*]] = add nsw i8 [[X]], [[NOT]]
2099; CHECK-NEXT:    ret i8 [[PLUSX]]
2100;
2101  %mul = mul nsw i8 %x, 42
2102  call void @use(i8 %mul)
2103  %not = xor i8 %mul, -1
2104  %plusx = add nsw i8 %not, %x
2105  ret i8 %plusx
2106}
2107
2108; negative test - too many instructions
2109
2110define i8 @not_mul_use2(i8 %x) {
2111; CHECK-LABEL: @not_mul_use2(
2112; CHECK-NEXT:    [[MUL:%.*]] = mul i8 [[X:%.*]], 42
2113; CHECK-NEXT:    [[NOT:%.*]] = xor i8 [[MUL]], -1
2114; CHECK-NEXT:    call void @use(i8 [[NOT]])
2115; CHECK-NEXT:    [[PLUSX:%.*]] = add i8 [[X]], [[NOT]]
2116; CHECK-NEXT:    ret i8 [[PLUSX]]
2117;
2118  %mul = mul i8 %x, 42
2119  %not = xor i8 %mul, -1
2120  call void @use(i8 %not)
2121  %plusx = add i8 %not, %x
2122  ret i8 %plusx
2123}
2124
2125define i8 @full_ashr_inc(i8 %x) {
2126; CHECK-LABEL: @full_ashr_inc(
2127; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt i8 [[X:%.*]], -1
2128; CHECK-NEXT:    [[R:%.*]] = zext i1 [[ISNOTNEG]] to i8
2129; CHECK-NEXT:    ret i8 [[R]]
2130;
2131  %a = ashr i8 %x, 7
2132  %r = add i8 %a, 1
2133  ret i8 %r
2134}
2135
2136define <2 x i6> @full_ashr_inc_vec(<2 x i6> %x) {
2137; CHECK-LABEL: @full_ashr_inc_vec(
2138; CHECK-NEXT:    [[ISNOTNEG:%.*]] = icmp sgt <2 x i6> [[X:%.*]], splat (i6 -1)
2139; CHECK-NEXT:    [[R:%.*]] = zext <2 x i1> [[ISNOTNEG]] to <2 x i6>
2140; CHECK-NEXT:    ret <2 x i6> [[R]]
2141;
2142  %a = ashr <2 x i6> %x, <i6 5, i6 poison>
2143  %r = add <2 x i6> %a, <i6 1, i6 1>
2144  ret <2 x i6> %r
2145}
2146
2147; negative test - extra use
2148
2149define i8 @full_ashr_inc_use(i8 %x) {
2150; CHECK-LABEL: @full_ashr_inc_use(
2151; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 7
2152; CHECK-NEXT:    call void @use(i8 [[A]])
2153; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A]], 1
2154; CHECK-NEXT:    ret i8 [[R]]
2155;
2156  %a = ashr i8 %x, 7
2157  call void @use(i8 %a)
2158  %r = add i8 %a, 1
2159  ret i8 %r
2160}
2161
2162; negative test - wrong shift amount
2163
2164define i8 @not_full_ashr_inc(i8 %x) {
2165; CHECK-LABEL: @not_full_ashr_inc(
2166; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 6
2167; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A]], 1
2168; CHECK-NEXT:    ret i8 [[R]]
2169;
2170  %a = ashr i8 %x, 6
2171  %r = add i8 %a, 1
2172  ret i8 %r
2173}
2174
2175; negative test - wrong add amount
2176
2177define i8 @full_ashr_not_inc(i8 %x) {
2178; CHECK-LABEL: @full_ashr_not_inc(
2179; CHECK-NEXT:    [[A:%.*]] = ashr i8 [[X:%.*]], 7
2180; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[A]], 2
2181; CHECK-NEXT:    ret i8 [[R]]
2182;
2183  %a = ashr i8 %x, 7
2184  %r = add i8 %a, 2
2185  ret i8 %r
2186}
2187
2188define i8 @select_negate_or_zero(i1 %b, i8 %x, i8 %y) {
2189; CHECK-LABEL: @select_negate_or_zero(
2190; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[X:%.*]]
2191; CHECK-NEXT:    [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2192; CHECK-NEXT:    ret i8 [[ADD1]]
2193;
2194  %negx = sub i8 0, %x
2195  %sel = select i1 %b, i8 0, i8 %negx
2196  %add = add i8 %sel, %y
2197  ret i8 %add
2198}
2199
2200; commuted add operands - same result
2201
2202define <2 x i8> @select_negate_or_zero_commute(<2 x i1> %b, <2 x i8> %x, <2 x i8> %p) {
2203; CHECK-LABEL: @select_negate_or_zero_commute(
2204; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2205; CHECK-NEXT:    [[TMP1:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> zeroinitializer, <2 x i8> [[X:%.*]]
2206; CHECK-NEXT:    [[ADD1:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]
2207; CHECK-NEXT:    ret <2 x i8> [[ADD1]]
2208;
2209  %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2210  %negx = sub <2 x i8> <i8 poison, i8 0>, %x
2211  %sel = select <2 x i1> %b, <2 x i8> <i8 poison, i8 0>, <2 x i8> %negx
2212  %add = add <2 x i8> %y, %sel
2213  ret <2 x i8> %add
2214}
2215
2216; swapped select operands and extra use are ok
2217
2218define i8 @select_negate_or_zero_swap(i1 %b, i8 %x, i8 %y) {
2219; CHECK-LABEL: @select_negate_or_zero_swap(
2220; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2221; CHECK-NEXT:    call void @use(i8 [[NEGX]])
2222; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X]], i8 0
2223; CHECK-NEXT:    [[ADD1:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2224; CHECK-NEXT:    ret i8 [[ADD1]]
2225;
2226  %negx = sub i8 0, %x
2227  call void @use(i8 %negx)
2228  %sel = select i1 %b, i8 %negx, i8 0
2229  %add = add i8 %sel, %y
2230  ret i8 %add
2231}
2232
2233; commuted add operands - same result
2234
2235define i8 @select_negate_or_zero_swap_commute(i1 %b, i8 %x, i8 %p) {
2236; CHECK-LABEL: @select_negate_or_zero_swap_commute(
2237; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2238; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[B:%.*]], i8 [[X:%.*]], i8 0
2239; CHECK-NEXT:    [[ADD1:%.*]] = sub i8 [[Y]], [[TMP1]]
2240; CHECK-NEXT:    ret i8 [[ADD1]]
2241;
2242  %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2243  %negx = sub i8 0, %x
2244  %sel = select i1 %b, i8 %negx, i8 0
2245  %add = add i8 %y, %sel
2246  ret i8 %add
2247}
2248
2249; negative test - one arm of the select must simplify
2250
2251define i8 @select_negate_or_nonzero(i1 %b, i8 %x, i8 %y) {
2252; CHECK-LABEL: @select_negate_or_nonzero(
2253; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2254; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i8 42, i8 [[NEGX]]
2255; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2256; CHECK-NEXT:    ret i8 [[ADD]]
2257;
2258  %negx = sub i8 0, %x
2259  %sel = select i1 %b, i8 42, i8 %negx
2260  %add = add i8 %sel, %y
2261  ret i8 %add
2262}
2263
2264; negative test - must have a negate, not any subtract
2265
2266define i8 @select_nonnegate_or_zero(i1 %b, i8 %x, i8 %y) {
2267; CHECK-LABEL: @select_nonnegate_or_zero(
2268; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 42, [[X:%.*]]
2269; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]]
2270; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2271; CHECK-NEXT:    ret i8 [[ADD]]
2272;
2273  %negx = sub i8 42, %x
2274  %sel = select i1 %b, i8 0, i8 %negx
2275  %add = add i8 %sel, %y
2276  ret i8 %add
2277}
2278
2279; negative test - don't create an extra instruction
2280
2281define i8 @select_negate_or_nonzero_use(i1 %b, i8 %x, i8 %y) {
2282; CHECK-LABEL: @select_negate_or_nonzero_use(
2283; CHECK-NEXT:    [[NEGX:%.*]] = sub i8 0, [[X:%.*]]
2284; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[NEGX]]
2285; CHECK-NEXT:    call void @use(i8 [[SEL]])
2286; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SEL]], [[Y:%.*]]
2287; CHECK-NEXT:    ret i8 [[ADD]]
2288;
2289  %negx = sub i8 0, %x
2290  %sel = select i1 %b, i8 0, i8 %negx
2291  call void @use(i8 %sel)
2292  %add = add i8 %sel, %y
2293  ret i8 %add
2294}
2295
2296; extra reduction because y + ~y -> -1
2297
2298define i5 @select_negate_not(i1 %b, i5 %x, i5 %y) {
2299; CHECK-LABEL: @select_negate_not(
2300; CHECK-NEXT:    [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]]
2301; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]]
2302; CHECK-NEXT:    ret i5 [[ADD1]]
2303;
2304  %negx = sub i5 0, %x
2305  %noty = xor i5 %y, -1
2306  %sel = select i1 %b, i5 %noty, i5 %negx
2307  %add = add i5 %sel, %y
2308  ret i5 %add
2309}
2310
2311define i5 @select_negate_not_commute(i1 %b, i5 %x, i5 %p) {
2312; CHECK-LABEL: @select_negate_not_commute(
2313; CHECK-NEXT:    [[Y:%.*]] = mul i5 [[P:%.*]], [[P]]
2314; CHECK-NEXT:    [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]]
2315; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[B:%.*]], i5 -1, i5 [[TMP1]]
2316; CHECK-NEXT:    ret i5 [[ADD1]]
2317;
2318  %y = mul i5 %p, %p ; thwart complexity-based canonicalization
2319  %negx = sub i5 0, %x
2320  %noty = xor i5 %y, -1
2321  %sel = select i1 %b, i5 %noty, i5 %negx
2322  %add = add i5 %y, %sel
2323  ret i5 %add
2324}
2325
2326define i5 @select_negate_not_swap(i1 %b, i5 %x, i5 %y) {
2327; CHECK-LABEL: @select_negate_not_swap(
2328; CHECK-NEXT:    [[TMP1:%.*]] = sub i5 [[Y:%.*]], [[X:%.*]]
2329; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -1
2330; CHECK-NEXT:    ret i5 [[ADD1]]
2331;
2332  %negx = sub i5 0, %x
2333  %noty = xor i5 %y, -1
2334  %sel = select i1 %b, i5 %negx, i5 %noty
2335  %add = add i5 %sel, %y
2336  ret i5 %add
2337}
2338
2339define i5 @select_negate_not_swap_commute(i1 %b, i5 %x, i5 %p) {
2340; CHECK-LABEL: @select_negate_not_swap_commute(
2341; CHECK-NEXT:    [[Y:%.*]] = mul i5 [[P:%.*]], [[P]]
2342; CHECK-NEXT:    [[TMP1:%.*]] = sub i5 [[Y]], [[X:%.*]]
2343; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[B:%.*]], i5 [[TMP1]], i5 -1
2344; CHECK-NEXT:    ret i5 [[ADD1]]
2345;
2346  %y = mul i5 %p, %p ; thwart complexity-based canonicalization
2347  %negx = sub i5 0, %x
2348  %noty = xor i5 %y, -1
2349  %sel = select i1 %b, i5 %negx, i5 %noty
2350  %add = add i5 %y, %sel
2351  ret i5 %add
2352}
2353
2354define i32 @add_select_sub_both_arms_simplify(i1 %b, i32 %a) {
2355; CHECK-LABEL: @add_select_sub_both_arms_simplify(
2356; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[B:%.*]], i32 [[A:%.*]], i32 99
2357; CHECK-NEXT:    ret i32 [[ADD]]
2358;
2359  %sub = sub i32 99, %a
2360  %sel = select i1 %b, i32 0, i32 %sub
2361  %add = add i32 %sel, %a
2362  ret i32 %add
2363}
2364
2365define <2 x i8> @add_select_sub_both_arms_simplify_swap(<2 x i1> %b, <2 x i8> %a) {
2366; CHECK-LABEL: @add_select_sub_both_arms_simplify_swap(
2367; CHECK-NEXT:    [[ADD:%.*]] = select <2 x i1> [[B:%.*]], <2 x i8> <i8 42, i8 99>, <2 x i8> [[A:%.*]]
2368; CHECK-NEXT:    ret <2 x i8> [[ADD]]
2369;
2370  %sub = sub <2 x i8> <i8 42, i8 99>, %a
2371  %sel = select <2 x i1> %b, <2 x i8> %sub, <2 x i8> zeroinitializer
2372  %add = add <2 x i8> %sel, %a
2373  ret <2 x i8> %add
2374}
2375
2376define i8 @add_select_sub_both_arms_simplify_use1(i1 %b, i8 %a) {
2377; CHECK-LABEL: @add_select_sub_both_arms_simplify_use1(
2378; CHECK-NEXT:    [[SUB:%.*]] = sub i8 42, [[A:%.*]]
2379; CHECK-NEXT:    call void @use(i8 [[SUB]])
2380; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[B:%.*]], i8 [[A]], i8 42
2381; CHECK-NEXT:    ret i8 [[ADD]]
2382;
2383  %sub = sub i8 42, %a
2384  call void @use(i8 %sub)
2385  %sel = select i1 %b, i8 0, i8 %sub
2386  %add = add i8 %sel, %a
2387  ret i8 %add
2388}
2389
2390define i8 @add_select_sub_both_arms_simplify_use2(i1 %b, i8 %a) {
2391; CHECK-LABEL: @add_select_sub_both_arms_simplify_use2(
2392; CHECK-NEXT:    [[SUB:%.*]] = sub i8 42, [[A:%.*]]
2393; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[B:%.*]], i8 0, i8 [[SUB]]
2394; CHECK-NEXT:    call void @use(i8 [[SEL]])
2395; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[SEL]], [[A]]
2396; CHECK-NEXT:    ret i8 [[ADD]]
2397;
2398  %sub = sub i8 42, %a
2399  %sel = select i1 %b, i8 0, i8 %sub
2400  call void @use(i8 %sel)
2401  %add = add i8 %sel, %a
2402  ret i8 %add
2403}
2404
2405define i5 @demand_low_bits_uses(i8 %x, i8 %y) {
2406; CHECK-LABEL: @demand_low_bits_uses(
2407; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 [[X:%.*]], 5
2408; CHECK-NEXT:    [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2409; CHECK-NEXT:    call void @use(i8 [[A]])
2410; CHECK-NEXT:    [[R:%.*]] = trunc i8 [[Y]] to i5
2411; CHECK-NEXT:    ret i5 [[R]]
2412;
2413  %m = mul i8 %x, -32 ; 0xE0
2414  %a = add i8 %m, %y
2415  call void @use(i8 %a)
2416  %r = trunc i8 %a to i5
2417  ret i5 %r
2418}
2419
2420; negative test - demands one more bit
2421
2422define i6 @demand_low_bits_uses_extra_bit(i8 %x, i8 %y) {
2423; CHECK-LABEL: @demand_low_bits_uses_extra_bit(
2424; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 [[X:%.*]], 5
2425; CHECK-NEXT:    [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2426; CHECK-NEXT:    call void @use(i8 [[A]])
2427; CHECK-NEXT:    [[R:%.*]] = trunc i8 [[A]] to i6
2428; CHECK-NEXT:    ret i6 [[R]]
2429;
2430  %m = mul i8 %x, -32 ; 0xE0
2431  %a = add i8 %m, %y
2432  call void @use(i8 %a)
2433  %r = trunc i8 %a to i6
2434  ret i6 %r
2435}
2436
2437define i8 @demand_low_bits_uses_commute(i8 %x, i8 %p, i8 %z) {
2438; CHECK-LABEL: @demand_low_bits_uses_commute(
2439; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2440; CHECK-NEXT:    [[M:%.*]] = and i8 [[X:%.*]], -64
2441; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y]], [[M]]
2442; CHECK-NEXT:    call void @use(i8 [[A]])
2443; CHECK-NEXT:    [[S:%.*]] = sub i8 [[Y]], [[Z:%.*]]
2444; CHECK-NEXT:    [[R:%.*]] = shl i8 [[S]], 2
2445; CHECK-NEXT:    ret i8 [[R]]
2446;
2447  %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2448  %m = and i8 %x, -64 ; 0xC0
2449  %a = add i8 %y, %m
2450  call void @use(i8 %a)
2451  %s = sub i8 %a, %z
2452  %r = shl i8 %s, 2
2453  ret i8 %r
2454}
2455
2456; negative test - demands one more bit
2457
2458define i8 @demand_low_bits_uses_commute_extra_bit(i8 %x, i8 %p, i8 %z) {
2459; CHECK-LABEL: @demand_low_bits_uses_commute_extra_bit(
2460; CHECK-NEXT:    [[Y:%.*]] = mul i8 [[P:%.*]], [[P]]
2461; CHECK-NEXT:    [[M:%.*]] = and i8 [[X:%.*]], -64
2462; CHECK-NEXT:    [[A:%.*]] = add i8 [[Y]], [[M]]
2463; CHECK-NEXT:    call void @use(i8 [[A]])
2464; CHECK-NEXT:    [[S:%.*]] = sub i8 [[A]], [[Z:%.*]]
2465; CHECK-NEXT:    [[R:%.*]] = shl i8 [[S]], 1
2466; CHECK-NEXT:    ret i8 [[R]]
2467;
2468  %y = mul i8 %p, %p ; thwart complexity-based canonicalization
2469  %m = and i8 %x, -64 ; 0xC0
2470  %a = add i8 %y, %m
2471  call void @use(i8 %a)
2472  %s = sub i8 %a, %z
2473  %r = shl i8 %s, 1
2474  ret i8 %r
2475}
2476
2477define { i64, i64 } @PR57576(i64 noundef %x, i64 noundef %y, i64 noundef %z, i64 noundef %w) {
2478; CHECK-LABEL: @PR57576(
2479; CHECK-NEXT:    [[ZX:%.*]] = zext i64 [[X:%.*]] to i128
2480; CHECK-NEXT:    [[ZY:%.*]] = zext i64 [[Y:%.*]] to i128
2481; CHECK-NEXT:    [[ZZ:%.*]] = zext i64 [[Z:%.*]] to i128
2482; CHECK-NEXT:    [[SHY:%.*]] = shl nuw i128 [[ZY]], 64
2483; CHECK-NEXT:    [[XY:%.*]] = or disjoint i128 [[SHY]], [[ZX]]
2484; CHECK-NEXT:    [[SUB:%.*]] = sub i128 [[XY]], [[ZZ]]
2485; CHECK-NEXT:    [[T:%.*]] = trunc i128 [[SUB]] to i64
2486; CHECK-NEXT:    [[TMP1:%.*]] = lshr i128 [[SUB]], 64
2487; CHECK-NEXT:    [[DOTTR:%.*]] = trunc nuw i128 [[TMP1]] to i64
2488; CHECK-NEXT:    [[DOTNARROW:%.*]] = sub i64 [[DOTTR]], [[W:%.*]]
2489; CHECK-NEXT:    [[R1:%.*]] = insertvalue { i64, i64 } poison, i64 [[T]], 0
2490; CHECK-NEXT:    [[R2:%.*]] = insertvalue { i64, i64 } [[R1]], i64 [[DOTNARROW]], 1
2491; CHECK-NEXT:    ret { i64, i64 } [[R2]]
2492;
2493  %zx = zext i64 %x to i128
2494  %zy = zext i64 %y to i128
2495  %zw = zext i64 %w to i128
2496  %zz = zext i64 %z to i128
2497  %shy = shl nuw i128 %zy, 64
2498  %mw = mul i128 %zw, -18446744073709551616
2499  %xy = or i128 %shy, %zx
2500  %sub = sub i128 %xy, %zz
2501  %add = add i128 %sub, %mw
2502  %t = trunc i128 %add to i64
2503  %h = lshr i128 %add, 64
2504  %t2 = trunc i128 %h to i64
2505  %r1 = insertvalue { i64, i64 } poison, i64 %t, 0
2506  %r2 = insertvalue { i64, i64 } %r1, i64 %t2, 1
2507  ret { i64, i64 } %r2
2508}
2509
2510define i8 @mul_negpow2(i8 %x, i8 %y) {
2511; CHECK-LABEL: @mul_negpow2(
2512; CHECK-NEXT:    [[TMP1:%.*]] = shl i8 [[X:%.*]], 1
2513; CHECK-NEXT:    [[A:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
2514; CHECK-NEXT:    ret i8 [[A]]
2515;
2516  %m = mul i8 %x, -2
2517  %a = add i8 %m, %y
2518  ret i8 %a
2519}
2520
2521define <2 x i8> @mul_negpow2_commute_vec(<2 x i8> %x, <2 x i8> %p) {
2522; CHECK-LABEL: @mul_negpow2_commute_vec(
2523; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[P:%.*]], [[P]]
2524; CHECK-NEXT:    [[TMP1:%.*]] = shl <2 x i8> [[X:%.*]], splat (i8 3)
2525; CHECK-NEXT:    [[A:%.*]] = sub <2 x i8> [[Y]], [[TMP1]]
2526; CHECK-NEXT:    ret <2 x i8> [[A]]
2527;
2528  %y = mul <2 x i8> %p, %p ; thwart complexity-based canonicalization
2529  %m = mul <2 x i8> %x, <i8 -8, i8 -8>
2530  %a = add <2 x i8> %y, %m
2531  ret <2 x i8> %a
2532}
2533
2534; negative test - extra use
2535
2536define i8 @mul_negpow2_use(i8 %x) {
2537; CHECK-LABEL: @mul_negpow2_use(
2538; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], -2
2539; CHECK-NEXT:    call void @use(i8 [[M]])
2540; CHECK-NEXT:    [[A:%.*]] = add i8 [[M]], 42
2541; CHECK-NEXT:    ret i8 [[A]]
2542;
2543  %m = mul i8 %x, -2
2544  call void @use(i8 %m)
2545  %a = add i8 %m, 42
2546  ret i8 %a
2547}
2548
2549; negative test - not negative-power-of-2 multiplier
2550
2551define i8 @mul_not_negpow2(i8 %x) {
2552; CHECK-LABEL: @mul_not_negpow2(
2553; CHECK-NEXT:    [[M:%.*]] = mul i8 [[X:%.*]], -3
2554; CHECK-NEXT:    [[A:%.*]] = add i8 [[M]], 42
2555; CHECK-NEXT:    ret i8 [[A]]
2556;
2557  %m = mul i8 %x, -3
2558  %a = add i8 %m, 42
2559  ret i8 %a
2560}
2561
2562define i16 @add_sub_zext(i8 %x, i8 %y) {
2563; CHECK-LABEL: @add_sub_zext(
2564; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i16
2565; CHECK-NEXT:    ret i16 [[TMP1]]
2566;
2567  %1 = sub nuw i8 %y, %x
2568  %2 = zext i8 %1 to i16
2569  %3 = zext i8 %x to i16
2570  %4 = add i16 %2, %3
2571  ret i16 %4
2572}
2573
2574define i16 @add_commute_sub_zext(i8 %x, i8 %y) {
2575; CHECK-LABEL: @add_commute_sub_zext(
2576; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[Y:%.*]] to i16
2577; CHECK-NEXT:    ret i16 [[TMP1]]
2578;
2579  %1 = sub nuw i8 %y, %x
2580  %2 = zext i8 %1 to i16
2581  %3 = zext i8 %x to i16
2582  %4 = add i16 %3, %2
2583  ret i16 %4
2584}
2585
2586define <2 x i8> @add_sub_2xi5_zext(<2 x i5> %x, <2 x i5> %y) {
2587; CHECK-LABEL: @add_sub_2xi5_zext(
2588; CHECK-NEXT:    [[TMP1:%.*]] = zext <2 x i5> [[Y:%.*]] to <2 x i8>
2589; CHECK-NEXT:    ret <2 x i8> [[TMP1]]
2590;
2591  %1 = sub nuw <2 x i5> %y, %x
2592  %2 = zext <2 x i5> %1 to <2 x i8>
2593  %3 = zext <2 x i5> %x to <2 x i8>
2594  %4 = add <2 x i8> %3, %2
2595  ret <2 x i8> %4
2596}
2597
2598
2599define i3 @add_commute_sub_i2_zext_i3(i2 %x, i2 %y) {
2600; CHECK-LABEL: @add_commute_sub_i2_zext_i3(
2601; CHECK-NEXT:    [[TMP1:%.*]] = zext i2 [[Y:%.*]] to i3
2602; CHECK-NEXT:    ret i3 [[TMP1]]
2603;
2604  %1 = sub nuw i2 %y, %x
2605  %2 = zext i2 %1 to i3
2606  %3 = zext i2 %x to i3
2607  %4 = add i3 %3, %2
2608  ret i3 %4
2609}
2610
2611define i16 @add_sub_use_zext(i8 %x, i8 %y) {
2612; CHECK-LABEL: @add_sub_use_zext(
2613; CHECK-NEXT:    [[TMP1:%.*]] = sub nuw i8 [[Y:%.*]], [[X:%.*]]
2614; CHECK-NEXT:    call void @use(i8 [[TMP1]])
2615; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[Y]] to i16
2616; CHECK-NEXT:    ret i16 [[TMP2]]
2617;
2618  %1 = sub nuw i8 %y, %x
2619  call void @use(i8 %1)
2620  %2 = zext i8 %1 to i16
2621  %3 = zext i8 %x to i16
2622  %4 = add i16 %2, %3
2623  ret i16 %4
2624}
2625
2626; Negative test: x - y + x  != y
2627define i16 @add_sub_commute_zext(i8 %x, i8 %y) {
2628; CHECK-LABEL: @add_sub_commute_zext(
2629; CHECK-NEXT:    [[TMP1:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]]
2630; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2631; CHECK-NEXT:    [[TMP3:%.*]] = zext i8 [[X]] to i16
2632; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw i16 [[TMP2]], [[TMP3]]
2633; CHECK-NEXT:    ret i16 [[TMP4]]
2634;
2635  %1 = sub nuw i8 %x, %y
2636  %2 = zext i8 %1 to i16
2637  %3 = zext i8 %x to i16
2638  %4 = add i16 %2, %3
2639  ret i16 %4
2640}
2641
2642; Negative test: no nuw flags
2643define i16 @add_no_nuw_sub_zext(i8 %x, i8 %y) {
2644; CHECK-LABEL: @add_no_nuw_sub_zext(
2645; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]]
2646; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2647; CHECK-NEXT:    [[TMP3:%.*]] = zext i8 [[X]] to i16
2648; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]]
2649; CHECK-NEXT:    ret i16 [[TMP4]]
2650;
2651  %1 = sub i8 %y, %x
2652  %2 = zext i8 %1 to i16
2653  %3 = zext i8 %x to i16
2654  %4 = add i16 %3, %2
2655  ret i16 %4
2656}
2657
2658define i16 @add_no_nuw_sub_commute_zext(i8 %x, i8 %y) {
2659; CHECK-LABEL: @add_no_nuw_sub_commute_zext(
2660; CHECK-NEXT:    [[TMP1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
2661; CHECK-NEXT:    [[TMP2:%.*]] = zext i8 [[TMP1]] to i16
2662; CHECK-NEXT:    [[TMP3:%.*]] = zext i8 [[X]] to i16
2663; CHECK-NEXT:    [[TMP4:%.*]] = add nuw nsw i16 [[TMP3]], [[TMP2]]
2664; CHECK-NEXT:    ret i16 [[TMP4]]
2665;
2666  %1 = sub i8 %x, %y
2667  %2 = zext i8 %1 to i16
2668  %3 = zext i8 %x to i16
2669  %4 = add i16 %3, %2
2670  ret i16 %4
2671}
2672
2673define i16 @add_sub_zext_constant(i8 %x) {
2674; CHECK-LABEL: @add_sub_zext_constant(
2675; CHECK-NEXT:    ret i16 254
2676;
2677  %1 = sub nuw i8 254, %x
2678  %2 = zext i8 %1 to i16
2679  %3 = zext i8 %x to i16
2680  %4 = add i16 %2, %3
2681  ret i16 %4
2682}
2683
2684define <vscale x 1 x i32> @add_to_or_scalable(<vscale x 1 x i32> %in) {
2685; CHECK-LABEL: @add_to_or_scalable(
2686; CHECK-NEXT:    [[SHL:%.*]] = shl <vscale x 1 x i32> [[IN:%.*]], splat (i32 1)
2687; CHECK-NEXT:    [[ADD:%.*]] = or disjoint <vscale x 1 x i32> [[SHL]], splat (i32 1)
2688; CHECK-NEXT:    ret <vscale x 1 x i32> [[ADD]]
2689;
2690  %shl = shl <vscale x 1 x i32> %in, splat (i32 1)
2691  %add = add <vscale x 1 x i32> %shl, splat (i32 1)
2692  ret <vscale x 1 x i32> %add
2693}
2694
2695define i5 @zext_zext_not(i3 noundef %x) {
2696; CHECK-LABEL: @zext_zext_not(
2697; CHECK-NEXT:    ret i5 7
2698;
2699  %zx = zext i3 %x to i5
2700  %notx = xor i3 %x, -1
2701  %znotx = zext i3 %notx to i5
2702  %r = add i5 %zx, %znotx
2703  ret i5 %r
2704}
2705
2706define <2 x i5> @zext_zext_not_commute(<2 x i3> noundef %x) {
2707; CHECK-LABEL: @zext_zext_not_commute(
2708; CHECK-NEXT:    ret <2 x i5> splat (i5 7)
2709;
2710  %zx = zext <2 x i3> %x to <2 x i5>
2711  %notx = xor <2 x i3> %x, <i3 -1, i3 poison>
2712  %znotx = zext <2 x i3> %notx to <2 x i5>
2713  %r = add <2 x i5> %znotx, %zx
2714  ret <2 x i5> %r
2715}
2716
2717define i9 @sext_sext_not(i3 noundef %x) {
2718; CHECK-LABEL: @sext_sext_not(
2719; CHECK-NEXT:    ret i9 -1
2720;
2721  %sx = sext i3 %x to i9
2722  %notx = xor i3 %x, -1
2723  %snotx = sext i3 %notx to i9
2724  %r = add i9 %sx, %snotx
2725  ret i9 %r
2726}
2727
2728define i8 @sext_sext_not_commute(i3 noundef %x) {
2729; CHECK-LABEL: @sext_sext_not_commute(
2730; CHECK-NEXT:    [[SX:%.*]] = sext i3 [[X:%.*]] to i8
2731; CHECK-NEXT:    call void @use(i8 [[SX]])
2732; CHECK-NEXT:    ret i8 -1
2733;
2734
2735  %sx = sext i3 %x to i8
2736  call void @use(i8 %sx)
2737  %notx = xor i3 %x, -1
2738  %snotx = sext i3 %notx to i8
2739  %r = add i8 %snotx, %sx
2740  ret i8 %r
2741}
2742
2743define i5 @zext_sext_not(i4 noundef %x) {
2744; CHECK-LABEL: @zext_sext_not(
2745; CHECK-NEXT:    [[ZX:%.*]] = zext i4 [[X:%.*]] to i5
2746; CHECK-NEXT:    [[NOTX:%.*]] = xor i4 [[X]], -1
2747; CHECK-NEXT:    [[SNOTX:%.*]] = sext i4 [[NOTX]] to i5
2748; CHECK-NEXT:    [[R:%.*]] = or disjoint i5 [[ZX]], [[SNOTX]]
2749; CHECK-NEXT:    ret i5 [[R]]
2750;
2751  %zx = zext i4 %x to i5
2752  %notx = xor i4 %x, -1
2753  %snotx = sext i4 %notx to i5
2754  %r = add i5 %zx, %snotx
2755  ret i5 %r
2756}
2757
2758define i8 @zext_sext_not_commute(i4 noundef %x) {
2759; CHECK-LABEL: @zext_sext_not_commute(
2760; CHECK-NEXT:    [[ZX:%.*]] = zext i4 [[X:%.*]] to i8
2761; CHECK-NEXT:    call void @use(i8 [[ZX]])
2762; CHECK-NEXT:    [[NOTX:%.*]] = xor i4 [[X]], -1
2763; CHECK-NEXT:    [[SNOTX:%.*]] = sext i4 [[NOTX]] to i8
2764; CHECK-NEXT:    call void @use(i8 [[SNOTX]])
2765; CHECK-NEXT:    [[R:%.*]] = or disjoint i8 [[SNOTX]], [[ZX]]
2766; CHECK-NEXT:    ret i8 [[R]]
2767;
2768  %zx = zext i4 %x to i8
2769  call void @use(i8 %zx)
2770  %notx = xor i4 %x, -1
2771  %snotx = sext i4 %notx to i8
2772  call void @use(i8 %snotx)
2773  %r = add i8 %snotx, %zx
2774  ret i8 %r
2775}
2776
2777define i9 @sext_zext_not(i4 noundef %x) {
2778; CHECK-LABEL: @sext_zext_not(
2779; CHECK-NEXT:    [[SX:%.*]] = sext i4 [[X:%.*]] to i9
2780; CHECK-NEXT:    [[NOTX:%.*]] = xor i4 [[X]], -1
2781; CHECK-NEXT:    [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
2782; CHECK-NEXT:    [[R:%.*]] = or disjoint i9 [[SX]], [[ZNOTX]]
2783; CHECK-NEXT:    ret i9 [[R]]
2784;
2785  %sx = sext i4 %x to i9
2786  %notx = xor i4 %x, -1
2787  %znotx = zext i4 %notx to i9
2788  %r = add i9 %sx, %znotx
2789  ret i9 %r
2790}
2791
2792define i9 @sext_zext_not_commute(i4 noundef %x) {
2793; CHECK-LABEL: @sext_zext_not_commute(
2794; CHECK-NEXT:    [[SX:%.*]] = sext i4 [[X:%.*]] to i9
2795; CHECK-NEXT:    [[NOTX:%.*]] = xor i4 [[X]], -1
2796; CHECK-NEXT:    [[ZNOTX:%.*]] = zext i4 [[NOTX]] to i9
2797; CHECK-NEXT:    [[R:%.*]] = or disjoint i9 [[ZNOTX]], [[SX]]
2798; CHECK-NEXT:    ret i9 [[R]]
2799;
2800  %sx = sext i4 %x to i9
2801  %notx = xor i4 %x, -1
2802  %znotx = zext i4 %notx to i9
2803  %r = add i9 %znotx, %sx
2804  ret i9 %r
2805}
2806
2807; PR57741
2808
2809define i32 @floor_sdiv(i32 %x) {
2810; CHECK-LABEL: @floor_sdiv(
2811; CHECK-NEXT:    [[R:%.*]] = ashr i32 [[X:%.*]], 2
2812; CHECK-NEXT:    ret i32 [[R]]
2813;
2814  %d = sdiv i32 %x, 4
2815  %a = and i32 %x, -2147483645
2816  %i = icmp ugt i32 %a, -2147483648
2817  %s = sext i1 %i to i32
2818  %r = add i32 %d, %s
2819  ret i32 %r
2820}
2821
2822define i8 @floor_sdiv_by_2(i8 %x) {
2823; CHECK-LABEL: @floor_sdiv_by_2(
2824; CHECK-NEXT:    [[RV:%.*]] = ashr i8 [[X:%.*]], 1
2825; CHECK-NEXT:    ret i8 [[RV]]
2826;
2827  %div = sdiv i8 %x, 2
2828  %and = and i8 %x, -127
2829  %icmp = icmp eq i8 %and, -127
2830  %sext = sext i1 %icmp to i8
2831  %rv = add nsw i8 %div, %sext
2832  ret i8 %rv
2833}
2834
2835define i8 @floor_sdiv_by_2_wrong_mask(i8 %x) {
2836; CHECK-LABEL: @floor_sdiv_by_2_wrong_mask(
2837; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[X:%.*]], 2
2838; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], 127
2839; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i8 [[AND]], 127
2840; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i8
2841; CHECK-NEXT:    [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2842; CHECK-NEXT:    ret i8 [[RV]]
2843;
2844  %div = sdiv i8 %x, 2
2845  %and = and i8 %x, 127
2846  %icmp = icmp eq i8 %and, 127
2847  %sext = sext i1 %icmp to i8
2848  %rv = add nsw i8 %div, %sext
2849  ret i8 %rv
2850}
2851
2852define i8 @floor_sdiv_by_2_wrong_constant(i8 %x) {
2853; CHECK-LABEL: @floor_sdiv_by_2_wrong_constant(
2854; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[X:%.*]], 4
2855; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -125
2856; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i8 [[AND]], -125
2857; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i8
2858; CHECK-NEXT:    [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2859; CHECK-NEXT:    ret i8 [[RV]]
2860;
2861  %div = sdiv i8 %x, 4
2862  %and = and i8 %x, -125
2863  %icmp = icmp eq i8 %and, -125
2864  %sext = sext i1 %icmp to i8
2865  %rv = add nsw i8 %div, %sext
2866  ret i8 %rv
2867}
2868
2869define i8 @floor_sdiv_by_2_wrong_cast(i8 %x) {
2870; CHECK-LABEL: @floor_sdiv_by_2_wrong_cast(
2871; CHECK-NEXT:    [[DIV:%.*]] = sdiv i8 [[X:%.*]], 2
2872; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], -127
2873; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i8 [[AND]], -127
2874; CHECK-NEXT:    [[SEXT:%.*]] = zext i1 [[ICMP]] to i8
2875; CHECK-NEXT:    [[RV:%.*]] = add nsw i8 [[DIV]], [[SEXT]]
2876; CHECK-NEXT:    ret i8 [[RV]]
2877;
2878  %div = sdiv i8 %x, 2
2879  %and = and i8 %x, -127
2880  %icmp = icmp eq i8 %and, -127
2881  %sext = zext i1 %icmp to i8
2882  %rv = add nsw i8 %div, %sext
2883  ret i8 %rv
2884}
2885
2886; vectors work too and commute is handled by complexity-based canonicalization
2887
2888define <2 x i32> @floor_sdiv_vec_commute(<2 x i32> %x) {
2889; CHECK-LABEL: @floor_sdiv_vec_commute(
2890; CHECK-NEXT:    [[R:%.*]] = ashr <2 x i32> [[X:%.*]], splat (i32 2)
2891; CHECK-NEXT:    ret <2 x i32> [[R]]
2892;
2893  %d = sdiv <2 x i32> %x, <i32 4, i32 4>
2894  %a = and <2 x i32> %x, <i32 -2147483645, i32 -2147483645>
2895  %i = icmp ugt <2 x i32> %a, <i32 -2147483648, i32 -2147483648>
2896  %s = sext <2 x i1> %i to <2 x i32>
2897  %r = add <2 x i32> %s, %d
2898  ret <2 x i32> %r
2899}
2900
2901; extra uses are ok
2902
2903define i8 @floor_sdiv_uses(i8 %x) {
2904; CHECK-LABEL: @floor_sdiv_uses(
2905; CHECK-NEXT:    [[D:%.*]] = sdiv i8 [[X:%.*]], 16
2906; CHECK-NEXT:    call void @use(i8 [[D]])
2907; CHECK-NEXT:    [[A:%.*]] = and i8 [[X]], -113
2908; CHECK-NEXT:    call void @use(i8 [[A]])
2909; CHECK-NEXT:    [[I:%.*]] = icmp ugt i8 [[A]], -128
2910; CHECK-NEXT:    [[S:%.*]] = sext i1 [[I]] to i8
2911; CHECK-NEXT:    call void @use(i8 [[S]])
2912; CHECK-NEXT:    [[R:%.*]] = ashr i8 [[X]], 4
2913; CHECK-NEXT:    ret i8 [[R]]
2914;
2915  %d = sdiv i8 %x, 16
2916  call void @use(i8 %d)
2917  %a = and i8 %x, 143 ; 128 + 15
2918  call void @use(i8 %a)
2919  %i = icmp ugt i8 %a, 128
2920  %s = sext i1 %i to i8
2921  call void @use(i8 %s)
2922  %r = add i8 %d, %s
2923  ret i8 %r
2924}
2925
2926; negative test
2927
2928define i32 @floor_sdiv_wrong_div(i32 %x) {
2929; CHECK-LABEL: @floor_sdiv_wrong_div(
2930; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 8
2931; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], -2147483645
2932; CHECK-NEXT:    [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2933; CHECK-NEXT:    [[S:%.*]] = sext i1 [[I]] to i32
2934; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2935; CHECK-NEXT:    ret i32 [[R]]
2936;
2937  %d = sdiv i32 %x, 8
2938  %a = and i32 %x, -2147483645
2939  %i = icmp ugt i32 %a, -2147483648
2940  %s = sext i1 %i to i32
2941  %r = add i32 %d, %s
2942  ret i32 %r
2943}
2944
2945; negative test
2946
2947define i32 @floor_sdiv_wrong_mask(i32 %x) {
2948; CHECK-LABEL: @floor_sdiv_wrong_mask(
2949; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2950; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], -2147483644
2951; CHECK-NEXT:    [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2952; CHECK-NEXT:    [[S:%.*]] = sext i1 [[I]] to i32
2953; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2954; CHECK-NEXT:    ret i32 [[R]]
2955;
2956  %d = sdiv i32 %x, 4
2957  %a = and i32 %x, -2147483644
2958  %i = icmp ugt i32 %a, -2147483648
2959  %s = sext i1 %i to i32
2960  %r = add i32 %d, %s
2961  ret i32 %r
2962}
2963
2964; negative test
2965
2966define i32 @floor_sdiv_wrong_cmp(i32 %x) {
2967; CHECK-LABEL: @floor_sdiv_wrong_cmp(
2968; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2969; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], -2147483646
2970; CHECK-NEXT:    [[I:%.*]] = icmp eq i32 [[A]], -2147483646
2971; CHECK-NEXT:    [[S:%.*]] = sext i1 [[I]] to i32
2972; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2973; CHECK-NEXT:    ret i32 [[R]]
2974;
2975  %d = sdiv i32 %x, 4
2976  %a = and i32 %x, -2147483645
2977  %i = icmp ugt i32 %a, -2147483647
2978  %s = sext i1 %i to i32
2979  %r = add i32 %d, %s
2980  ret i32 %r
2981}
2982
2983; negative test
2984
2985define i32 @floor_sdiv_wrong_ext(i32 %x) {
2986; CHECK-LABEL: @floor_sdiv_wrong_ext(
2987; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 4
2988; CHECK-NEXT:    [[A:%.*]] = and i32 [[X]], -2147483645
2989; CHECK-NEXT:    [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
2990; CHECK-NEXT:    [[S:%.*]] = zext i1 [[I]] to i32
2991; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
2992; CHECK-NEXT:    ret i32 [[R]]
2993;
2994  %d = sdiv i32 %x, 4
2995  %a = and i32 %x, -2147483645
2996  %i = icmp ugt i32 %a, -2147483648
2997  %s = zext i1 %i to i32
2998  %r = add i32 %d, %s
2999  ret i32 %r
3000}
3001
3002; negative test
3003
3004define i32 @floor_sdiv_wrong_op(i32 %x, i32 %y) {
3005; CHECK-LABEL: @floor_sdiv_wrong_op(
3006; CHECK-NEXT:    [[D:%.*]] = sdiv i32 [[X:%.*]], 4
3007; CHECK-NEXT:    [[A:%.*]] = and i32 [[Y:%.*]], -2147483645
3008; CHECK-NEXT:    [[I:%.*]] = icmp ugt i32 [[A]], -2147483648
3009; CHECK-NEXT:    [[S:%.*]] = zext i1 [[I]] to i32
3010; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[D]], [[S]]
3011; CHECK-NEXT:    ret i32 [[R]]
3012;
3013  %d = sdiv i32 %x, 4
3014  %a = and i32 %y, -2147483645
3015  %i = icmp ugt i32 %a, -2147483648
3016  %s = zext i1 %i to i32
3017  %r = add i32 %d, %s
3018  ret i32 %r
3019}
3020
3021define i32 @floor_sdiv_using_srem_by_8(i32 %x) {
3022; CHECK-LABEL: @floor_sdiv_using_srem_by_8(
3023; CHECK-NEXT:    [[F:%.*]] = ashr i32 [[X:%.*]], 3
3024; CHECK-NEXT:    ret i32 [[F]]
3025;
3026  %d = sdiv i32 %x, 8
3027  %r = srem i32 %x, 8
3028  %i = icmp ugt i32 %r, -2147483648
3029  %s = sext i1 %i to i32
3030  %f = add i32 %d, %s
3031  ret i32 %f
3032}
3033
3034define i32 @floor_sdiv_using_srem_by_2(i32 %x) {
3035; CHECK-LABEL: @floor_sdiv_using_srem_by_2(
3036; CHECK-NEXT:    [[F:%.*]] = ashr i32 [[X:%.*]], 1
3037; CHECK-NEXT:    ret i32 [[F]]
3038;
3039  %d = sdiv i32 %x, 2
3040  %r = srem i32 %x, 2
3041  %i = icmp ugt i32 %r, -2147483648
3042  %s = sext i1 %i to i32
3043  %f = add i32 %d, %s
3044  ret i32 %f
3045}
3046
3047; (X s>> (BW - 1)) + (zext (X s> 0)) --> (X s>> (BW - 1)) | (zext (X != 0))
3048
3049define i8 @signum_i8_i8(i8 %x) {
3050; CHECK-LABEL: @signum_i8_i8(
3051; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7
3052; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 0
3053; CHECK-NEXT:    [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i8
3054; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
3055; CHECK-NEXT:    ret i8 [[R]]
3056;
3057  %sgt0 = icmp sgt i8 %x, 0
3058  %zgt0 = zext i1 %sgt0 to i8
3059  %signbit = ashr i8 %x, 7
3060  %r = add i8 %zgt0, %signbit
3061  ret i8 %r
3062}
3063
3064; extra use of shift is ok
3065
3066define i8 @signum_i8_i8_use1(i8 %x) {
3067; CHECK-LABEL: @signum_i8_i8_use1(
3068; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7
3069; CHECK-NEXT:    call void @use(i8 [[SIGNBIT]])
3070; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne i8 [[X]], 0
3071; CHECK-NEXT:    [[ISNOTNULL_ZEXT:%.*]] = zext i1 [[ISNOTNULL]] to i8
3072; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
3073; CHECK-NEXT:    ret i8 [[R]]
3074;
3075  %sgt0 = icmp sgt i8 %x, 0
3076  %zgt0 = zext i1 %sgt0 to i8
3077  %signbit = ashr i8 %x, 7
3078  call void @use(i8 %signbit)
3079  %r = add i8 %zgt0, %signbit
3080  ret i8 %r
3081}
3082
3083; negative test
3084
3085define i8 @signum_i8_i8_use2(i8 %x) {
3086; CHECK-LABEL: @signum_i8_i8_use2(
3087; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3088; CHECK-NEXT:    [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3089; CHECK-NEXT:    call void @use(i8 [[ZGT0]])
3090; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3091; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3092; CHECK-NEXT:    ret i8 [[R]]
3093;
3094  %sgt0 = icmp sgt i8 %x, 0
3095  %zgt0 = zext i1 %sgt0 to i8
3096  call void @use(i8 %zgt0)
3097  %signbit = ashr i8 %x, 7
3098  %r = add i8 %zgt0, %signbit
3099  ret i8 %r
3100}
3101
3102; negative test
3103
3104define i8 @signum_i8_i8_use3(i8 %x) {
3105; CHECK-LABEL: @signum_i8_i8_use3(
3106; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3107; CHECK-NEXT:    call void @use_i1(i1 [[SGT0]])
3108; CHECK-NEXT:    [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3109; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3110; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3111; CHECK-NEXT:    ret i8 [[R]]
3112;
3113  %sgt0 = icmp sgt i8 %x, 0
3114  call void @use_i1(i1 %sgt0)
3115  %zgt0 = zext i1 %sgt0 to i8
3116  %signbit = ashr i8 %x, 7
3117  %r = add i8 %zgt0, %signbit
3118  ret i8 %r
3119}
3120
3121; poison is ok to propagate in shift amount
3122; complexity canonicalization guarantees that shift is op0 of add
3123
3124define <2 x i5> @signum_v2i5_v2i5(<2 x i5> %x) {
3125; CHECK-LABEL: @signum_v2i5_v2i5(
3126; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr <2 x i5> [[X:%.*]], <i5 4, i5 poison>
3127; CHECK-NEXT:    [[ISNOTNULL:%.*]] = icmp ne <2 x i5> [[X]], zeroinitializer
3128; CHECK-NEXT:    [[ISNOTNULL_ZEXT:%.*]] = zext <2 x i1> [[ISNOTNULL]] to <2 x i5>
3129; CHECK-NEXT:    [[R:%.*]] = or <2 x i5> [[SIGNBIT]], [[ISNOTNULL_ZEXT]]
3130; CHECK-NEXT:    ret <2 x i5> [[R]]
3131;
3132  %sgt0 = icmp sgt <2 x i5> %x, zeroinitializer
3133  %zgt0 = zext <2 x i1> %sgt0 to <2 x i5>
3134  %signbit = ashr <2 x i5> %x, <i5 4, i5 poison>
3135  %r = add <2 x i5> %signbit, %zgt0
3136  ret <2 x i5> %r
3137}
3138
3139; negative test
3140
3141define i8 @signum_i8_i8_wrong_sh_amt(i8 %x) {
3142; CHECK-LABEL: @signum_i8_i8_wrong_sh_amt(
3143; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3144; CHECK-NEXT:    [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3145; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 6
3146; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3147; CHECK-NEXT:    ret i8 [[R]]
3148;
3149  %sgt0 = icmp sgt i8 %x, 0
3150  %zgt0 = zext i1 %sgt0 to i8
3151  %signbit = ashr i8 %x, 6
3152  %r = add i8 %zgt0, %signbit
3153  ret i8 %r
3154}
3155
3156; negative test
3157
3158define i8 @signum_i8_i8_wrong_ext(i8 %x) {
3159; CHECK-LABEL: @signum_i8_i8_wrong_ext(
3160; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], 0
3161; CHECK-NEXT:    [[ZGT0:%.*]] = sext i1 [[SGT0]] to i8
3162; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3163; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3164; CHECK-NEXT:    ret i8 [[R]]
3165;
3166  %sgt0 = icmp sgt i8 %x, 0
3167  %zgt0 = sext i1 %sgt0 to i8
3168  %signbit = ashr i8 %x, 7
3169  %r = add i8 %zgt0, %signbit
3170  ret i8 %r
3171}
3172
3173; negative test
3174
3175define i8 @signum_i8_i8_wrong_pred(i8 %x) {
3176; CHECK-LABEL: @signum_i8_i8_wrong_pred(
3177; CHECK-NEXT:    [[SGT0:%.*]] = icmp sgt i8 [[X:%.*]], -1
3178; CHECK-NEXT:    [[ZGT0:%.*]] = zext i1 [[SGT0]] to i8
3179; CHECK-NEXT:    [[SIGNBIT:%.*]] = ashr i8 [[X]], 7
3180; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[SIGNBIT]], [[ZGT0]]
3181; CHECK-NEXT:    ret i8 [[R]]
3182;
3183  %sgt0 = icmp sge i8 %x, 0
3184  %zgt0 = zext i1 %sgt0 to i8
3185  %signbit = ashr i8 %x, 7
3186  %r = add i8 %zgt0, %signbit
3187  ret i8 %r
3188}
3189
3190define i32 @dec_zext_add_assume_nonzero(i8 %x) {
3191; CHECK-LABEL: @dec_zext_add_assume_nonzero(
3192; CHECK-NEXT:    [[Z:%.*]] = icmp ne i8 [[X:%.*]], 0
3193; CHECK-NEXT:    call void @llvm.assume(i1 [[Z]])
3194; CHECK-NEXT:    [[C:%.*]] = zext i8 [[X]] to i32
3195; CHECK-NEXT:    ret i32 [[C]]
3196;
3197  %z = icmp ne i8 %x, 0
3198  call void @llvm.assume(i1 %z)
3199  %a = add i8 %x, -1
3200  %b = zext i8 %a to i32
3201  %c = add i32 %b, 1
3202  ret i32 %c
3203}
3204
3205define i32 @dec_zext_add_nonzero(i8 %x) {
3206; CHECK-LABEL: @dec_zext_add_nonzero(
3207; CHECK-NEXT:    [[O:%.*]] = or i8 [[X:%.*]], 4
3208; CHECK-NEXT:    [[C:%.*]] = zext i8 [[O]] to i32
3209; CHECK-NEXT:    ret i32 [[C]]
3210;
3211  %o = or i8 %x, 4
3212  %a = add i8 %o, -1
3213  %b = zext i8 %a to i32
3214  %c = add i32 %b, 1
3215  ret i32 %c
3216}
3217
3218define <2 x i32> @dec_zext_add_nonzero_vec(<2 x i8> %x) {
3219; CHECK-LABEL: @dec_zext_add_nonzero_vec(
3220; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8)
3221; CHECK-NEXT:    [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3222; CHECK-NEXT:    ret <2 x i32> [[C]]
3223;
3224  %o = or <2 x i8> %x, <i8 8, i8 8>
3225  %a = add <2 x i8> %o, <i8 -1, i8 -1>
3226  %b = zext <2 x i8> %a to <2 x i32>
3227  %c = add <2 x i32> %b, <i32 1, i32 1>
3228  ret <2 x i32> %c
3229}
3230
3231; Negative test: Folding this with undef is not safe.
3232
3233define <2 x i32> @dec_zext_add_nonzero_vec_undef0(<2 x i8> %x) {
3234; CHECK-LABEL: @dec_zext_add_nonzero_vec_undef0(
3235; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 undef>
3236; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[O]], splat (i8 -1)
3237; CHECK-NEXT:    [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>
3238; CHECK-NEXT:    [[C:%.*]] = add nuw nsw <2 x i32> [[B]], splat (i32 1)
3239; CHECK-NEXT:    ret <2 x i32> [[C]]
3240;
3241  %o = or <2 x i8> %x, <i8 8, i8 undef>
3242  %a = add <2 x i8> %o, <i8 -1, i8 -1>
3243  %b = zext <2 x i8> %a to <2 x i32>
3244  %c = add <2 x i32> %b, <i32 1, i32 1>
3245  ret <2 x i32> %c
3246}
3247
3248define <2 x i32> @dec_zext_add_nonzero_poison0(<2 x i8> %x) {
3249; CHECK-LABEL: @dec_zext_add_nonzero_poison0(
3250; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 poison>
3251; CHECK-NEXT:    [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3252; CHECK-NEXT:    ret <2 x i32> [[C]]
3253;
3254  %o = or <2 x i8> %x, <i8 8, i8 poison>
3255  %a = add <2 x i8> %o, <i8 -1, i8 -1>
3256  %b = zext <2 x i8> %a to <2 x i32>
3257  %c = add <2 x i32> %b, <i32 1, i32 1>
3258  ret <2 x i32> %c
3259}
3260
3261define <2 x i32> @dec_zext_add_nonzero_vec_poison1(<2 x i8> %x) {
3262; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison1(
3263; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8)
3264; CHECK-NEXT:    [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
3265; CHECK-NEXT:    ret <2 x i32> [[C]]
3266;
3267  %o = or <2 x i8> %x, <i8 8, i8 8>
3268  %a = add <2 x i8> %o, <i8 -1, i8 poison>
3269  %b = zext <2 x i8> %a to <2 x i32>
3270  %c = add <2 x i32> %b, <i32 1, i32 1>
3271  ret <2 x i32> %c
3272}
3273
3274define <2 x i32> @dec_zext_add_nonzero_vec_poison2(<2 x i8> %x) {
3275; CHECK-LABEL: @dec_zext_add_nonzero_vec_poison2(
3276; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], splat (i8 8)
3277; CHECK-NEXT:    [[A:%.*]] = add nsw <2 x i8> [[O]], splat (i8 -1)
3278; CHECK-NEXT:    [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>
3279; CHECK-NEXT:    [[C:%.*]] = add nuw nsw <2 x i32> [[B]], <i32 1, i32 poison>
3280; CHECK-NEXT:    ret <2 x i32> [[C]]
3281;
3282  %o = or <2 x i8> %x, <i8 8, i8 8>
3283  %a = add <2 x i8> %o, <i8 -1, i8 -1>
3284  %b = zext <2 x i8> %a to <2 x i32>
3285  %c = add <2 x i32> %b, <i32 1, i32 poison>
3286  ret <2 x i32> %c
3287}
3288
3289define i32 @add_zext_sext_i1(i1 %a) {
3290; CHECK-LABEL: @add_zext_sext_i1(
3291; CHECK-NEXT:    ret i32 0
3292;
3293  %zext = zext i1 %a to i32
3294  %sext = sext i1 %a to i32
3295  %add = add i32 %zext, %sext
3296  ret i32 %add
3297}
3298
3299define i32 @add_sext_zext_i1(i1 %a) {
3300; CHECK-LABEL: @add_sext_zext_i1(
3301; CHECK-NEXT:    ret i32 0
3302;
3303  %zext = zext i1 %a to i32
3304  %sext = sext i1 %a to i32
3305  %add = add i32 %sext, %zext
3306  ret i32 %add
3307}
3308
3309define <2 x i32> @add_zext_sext_i1_vec(<2 x i1> %a) {
3310; CHECK-LABEL: @add_zext_sext_i1_vec(
3311; CHECK-NEXT:    ret <2 x i32> zeroinitializer
3312;
3313  %zext = zext <2 x i1> %a to <2 x i32>
3314  %sext = sext <2 x i1> %a to <2 x i32>
3315  %add = add <2 x i32> %zext, %sext
3316  ret <2 x i32> %add
3317}
3318
3319define i32 @add_zext_zext_i1(i1 %a) {
3320; CHECK-LABEL: @add_zext_zext_i1(
3321; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[A:%.*]], i32 2, i32 0
3322; CHECK-NEXT:    ret i32 [[ADD]]
3323;
3324  %zext = zext i1 %a to i32
3325  %add = add i32 %zext, %zext
3326  ret i32 %add
3327}
3328
3329define i32 @add_sext_sext_i1(i1 %a) {
3330; CHECK-LABEL: @add_sext_sext_i1(
3331; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[A:%.*]] to i32
3332; CHECK-NEXT:    [[ADD:%.*]] = shl nsw i32 [[SEXT]], 1
3333; CHECK-NEXT:    ret i32 [[ADD]]
3334;
3335  %sext = sext i1 %a to i32
3336  %add = add i32 %sext, %sext
3337  ret i32 %add
3338}
3339
3340define i32 @add_zext_sext_not_i1(i8 %a) {
3341; CHECK-LABEL: @add_zext_sext_not_i1(
3342; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[A:%.*]] to i32
3343; CHECK-NEXT:    [[SEXT:%.*]] = sext i8 [[A]] to i32
3344; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]
3345; CHECK-NEXT:    ret i32 [[ADD]]
3346;
3347  %zext = zext i8 %a to i32
3348  %sext = sext i8 %a to i32
3349  %add = add i32 %zext, %sext
3350  ret i32 %add
3351}
3352
3353define i32 @add_zext_sext_i1_different_values(i1 %a, i1 %b) {
3354; CHECK-LABEL: @add_zext_sext_i1_different_values(
3355; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i32
3356; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[B:%.*]] to i32
3357; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[ZEXT]], [[SEXT]]
3358; CHECK-NEXT:    ret i32 [[ADD]]
3359;
3360  %zext = zext i1 %a to i32
3361  %sext = sext i1 %b to i32
3362  %add = add i32 %zext, %sext
3363  ret i32 %add
3364}
3365
3366define i32 @add_reduce_sqr_sum_nsw(i32 %a, i32 %b) {
3367; CHECK-LABEL: @add_reduce_sqr_sum_nsw(
3368; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3369; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3370; CHECK-NEXT:    ret i32 [[ADD]]
3371;
3372  %a_sq = mul nsw i32 %a, %a
3373  %two_a = shl i32 %a, 1
3374  %two_a_plus_b = add i32 %two_a, %b
3375  %mul = mul i32 %two_a_plus_b, %b
3376  %add = add i32 %mul, %a_sq
3377  ret i32 %add
3378}
3379
3380define i32 @add_reduce_sqr_sum_u(i32 %a, i32 %b) {
3381; CHECK-LABEL: @add_reduce_sqr_sum_u(
3382; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3383; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3384; CHECK-NEXT:    ret i32 [[ADD]]
3385;
3386  %a_sq = mul i32 %a, %a
3387  %two_a = shl i32 %a, 1
3388  %two_a_plus_b = add i32 %two_a, %b
3389  %mul = mul i32 %two_a_plus_b, %b
3390  %add = add i32 %mul, %a_sq
3391  ret i32 %add
3392}
3393
3394define i32 @add_reduce_sqr_sum_nuw(i32 %a, i32 %b) {
3395; CHECK-LABEL: @add_reduce_sqr_sum_nuw(
3396; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3397; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3398; CHECK-NEXT:    ret i32 [[ADD]]
3399;
3400  %a_sq = mul nuw i32 %a, %a
3401  %two_a = mul i32 %a, 2
3402  %two_a_plus_b = add i32 %two_a, %b
3403  %mul = mul nuw i32 %two_a_plus_b, %b
3404  %add = add i32 %mul, %a_sq
3405  ret i32 %add
3406}
3407
3408define i32 @add_reduce_sqr_sum_flipped(i32 %a, i32 %b) {
3409; CHECK-LABEL: @add_reduce_sqr_sum_flipped(
3410; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3411; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3412; CHECK-NEXT:    ret i32 [[ADD]]
3413;
3414  %a_sq = mul nsw i32 %a, %a
3415  %two_a = shl i32 %a, 1
3416  %two_a_plus_b = add i32 %two_a, %b
3417  %mul = mul i32 %two_a_plus_b, %b
3418  %add = add i32 %a_sq, %mul
3419  ret i32 %add
3420}
3421
3422define i32 @add_reduce_sqr_sum_flipped2(i32 %a, i32 %bx) {
3423; CHECK-LABEL: @add_reduce_sqr_sum_flipped2(
3424; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BX:%.*]], 42
3425; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]]
3426; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3427; CHECK-NEXT:    ret i32 [[ADD]]
3428;
3429  %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3430  %a_sq = mul nsw i32 %a, %a
3431  %two_a = shl i32 %a, 1
3432  %two_a_plus_b = add i32 %two_a, %b
3433  %mul = mul i32 %b, %two_a_plus_b
3434  %add = add i32 %mul, %a_sq
3435  ret i32 %add
3436}
3437
3438define i32 @add_reduce_sqr_sum_flipped3(i32 %a, i32 %b) {
3439; CHECK-LABEL: @add_reduce_sqr_sum_flipped3(
3440; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3441; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3442; CHECK-NEXT:    ret i32 [[ADD]]
3443;
3444  %a_sq = mul nsw i32 %a, %a
3445  %two_a = shl i32 %a, 1
3446  %two_a_plus_b = add i32 %b, %two_a
3447  %mul = mul i32 %two_a_plus_b, %b
3448  %add = add i32 %mul, %a_sq
3449  ret i32 %add
3450}
3451
3452define i32 @add_reduce_sqr_sum_order2(i32 %a, i32 %b) {
3453; CHECK-LABEL: @add_reduce_sqr_sum_order2(
3454; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3455; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3456; CHECK-NEXT:    ret i32 [[AB2]]
3457;
3458  %a_sq = mul nsw i32 %a, %a
3459  %twoa = mul i32 %a, 2
3460  %twoab = mul i32 %twoa, %b
3461  %b_sq = mul i32 %b, %b
3462  %twoab_b2 = add i32 %twoab, %b_sq
3463  %ab2 = add i32 %a_sq, %twoab_b2
3464  ret i32 %ab2
3465}
3466
3467define i32 @add_reduce_sqr_sum_order2_flipped(i32 %a, i32 %b) {
3468; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped(
3469; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3470; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3471; CHECK-NEXT:    ret i32 [[AB2]]
3472;
3473  %a_sq = mul nsw i32 %a, %a
3474  %twoa = mul i32 %a, 2
3475  %twoab = mul i32 %twoa, %b
3476  %b_sq = mul i32 %b, %b
3477  %twoab_b2 = add i32 %twoab, %b_sq
3478  %ab2 = add i32 %twoab_b2, %a_sq
3479  ret i32 %ab2
3480}
3481
3482define i32 @add_reduce_sqr_sum_order2_flipped2(i32 %a, i32 %bx) {
3483; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped2(
3484; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BX:%.*]], 42
3485; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]]
3486; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3487; CHECK-NEXT:    ret i32 [[AB2]]
3488;
3489  %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3490  %a_sq = mul nsw i32 %a, %a
3491  %twoa = mul i32 %a, 2
3492  %twoab = mul i32 %twoa, %b
3493  %b_sq = mul i32 %b, %b
3494  %twoab_b2 = add i32 %b_sq, %twoab
3495  %ab2 = add i32 %a_sq, %twoab_b2
3496  ret i32 %ab2
3497}
3498
3499define i32 @add_reduce_sqr_sum_order2_flipped3(i32 %a, i32 %bx) {
3500; CHECK-LABEL: @add_reduce_sqr_sum_order2_flipped3(
3501; CHECK-NEXT:    [[B:%.*]] = xor i32 [[BX:%.*]], 42
3502; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B]]
3503; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3504; CHECK-NEXT:    ret i32 [[AB2]]
3505;
3506  %b = xor i32 %bx, 42 ; thwart complexity-based canonicalization
3507  %a_sq = mul nsw i32 %a, %a
3508  %twoa = mul i32 %a, 2
3509  %twoab = mul i32 %b, %twoa
3510  %b_sq = mul i32 %b, %b
3511  %twoab_b2 = add i32 %twoab, %b_sq
3512  %ab2 = add i32 %a_sq, %twoab_b2
3513  ret i32 %ab2
3514}
3515
3516define i32 @add_reduce_sqr_sum_order3(i32 %a, i32 %b) {
3517; CHECK-LABEL: @add_reduce_sqr_sum_order3(
3518; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3519; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3520; CHECK-NEXT:    ret i32 [[AB2]]
3521;
3522  %a_sq = mul nsw i32 %a, %a
3523  %twoa = mul i32 %a, 2
3524  %twoab = mul i32 %twoa, %b
3525  %b_sq = mul i32 %b, %b
3526  %a2_b2 = add i32 %a_sq, %b_sq
3527  %ab2 = add i32 %twoab, %a2_b2
3528  ret i32 %ab2
3529}
3530
3531define i32 @add_reduce_sqr_sum_order3_flipped(i32 %a, i32 %b) {
3532; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped(
3533; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3534; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3535; CHECK-NEXT:    ret i32 [[AB2]]
3536;
3537  %a_sq = mul nsw i32 %a, %a
3538  %twoa = mul i32 %a, 2
3539  %twoab = mul i32 %twoa, %b
3540  %b_sq = mul i32 %b, %b
3541  %a2_b2 = add i32 %a_sq, %b_sq
3542  %ab2 = add i32 %a2_b2, %twoab
3543  ret i32 %ab2
3544}
3545
3546define i32 @add_reduce_sqr_sum_order3_flipped2(i32 %a, i32 %b) {
3547; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped2(
3548; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3549; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3550; CHECK-NEXT:    ret i32 [[AB2]]
3551;
3552  %a_sq = mul nsw i32 %a, %a
3553  %twoa = mul i32 %a, 2
3554  %twoab = mul i32 %twoa, %b
3555  %b_sq = mul i32 %b, %b
3556  %a2_b2 = add i32 %b_sq, %a_sq
3557  %ab2 = add i32 %twoab, %a2_b2
3558  ret i32 %ab2
3559}
3560
3561define i32 @add_reduce_sqr_sum_order3_flipped3(i32 %a, i32 %b) {
3562; CHECK-LABEL: @add_reduce_sqr_sum_order3_flipped3(
3563; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3564; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3565; CHECK-NEXT:    ret i32 [[AB2]]
3566;
3567  %a_sq = mul nsw i32 %a, %a
3568  %twoa = mul i32 %a, 2
3569  %twoab = mul i32 %b, %twoa
3570  %b_sq = mul i32 %b, %b
3571  %a2_b2 = add i32 %a_sq, %b_sq
3572  %ab2 = add i32 %twoab, %a2_b2
3573  ret i32 %ab2
3574}
3575
3576define i32 @add_reduce_sqr_sum_order4(i32 %a, i32 %b) {
3577; CHECK-LABEL: @add_reduce_sqr_sum_order4(
3578; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3579; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3580; CHECK-NEXT:    ret i32 [[AB2]]
3581;
3582  %a_sq = mul nsw i32 %a, %a
3583  %ab = mul i32 %a, %b
3584  %twoab = mul i32 %ab, 2
3585  %b_sq = mul i32 %b, %b
3586  %a2_b2 = add i32 %a_sq, %b_sq
3587  %ab2 = add i32 %twoab, %a2_b2
3588  ret i32 %ab2
3589}
3590
3591define i32 @add_reduce_sqr_sum_order4_flipped(i32 %a, i32 %b) {
3592; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped(
3593; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3594; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3595; CHECK-NEXT:    ret i32 [[AB2]]
3596;
3597  %a_sq = mul nsw i32 %a, %a
3598  %ab = mul i32 %a, %b
3599  %twoab = mul i32 %ab, 2
3600  %b_sq = mul i32 %b, %b
3601  %a2_b2 = add i32 %a_sq, %b_sq
3602  %ab2 = add i32 %a2_b2, %twoab
3603  ret i32 %ab2
3604}
3605
3606define i32 @add_reduce_sqr_sum_order4_flipped2(i32 %a, i32 %b) {
3607; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped2(
3608; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3609; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3610; CHECK-NEXT:    ret i32 [[AB2]]
3611;
3612  %a_sq = mul nsw i32 %a, %a
3613  %ab = mul i32 %a, %b
3614  %twoab = mul i32 %ab, 2
3615  %b_sq = mul i32 %b, %b
3616  %a2_b2 = add i32 %b_sq, %a_sq
3617  %ab2 = add i32 %twoab, %a2_b2
3618  ret i32 %ab2
3619}
3620
3621define i32 @add_reduce_sqr_sum_order4_flipped3(i32 %a, i32 %b) {
3622; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped3(
3623; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
3624; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3625; CHECK-NEXT:    ret i32 [[AB2]]
3626;
3627  %a_sq = mul nsw i32 %a, %a
3628  %ab = mul i32 %a, %b
3629  %twoab = mul i32 2, %ab
3630  %b_sq = mul i32 %b, %b
3631  %a2_b2 = add i32 %a_sq, %b_sq
3632  %ab2 = add i32 %twoab, %a2_b2
3633  ret i32 %ab2
3634}
3635
3636define i32 @add_reduce_sqr_sum_order4_flipped4(i32 %a, i32 %b) {
3637; CHECK-LABEL: @add_reduce_sqr_sum_order4_flipped4(
3638; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3639; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3640; CHECK-NEXT:    ret i32 [[AB2]]
3641;
3642  %a_sq = mul nsw i32 %a, %a
3643  %ab = mul i32 %b, %a
3644  %twoab = mul i32 %ab, 2
3645  %b_sq = mul i32 %b, %b
3646  %a2_b2 = add i32 %a_sq, %b_sq
3647  %ab2 = add i32 %twoab, %a2_b2
3648  ret i32 %ab2
3649}
3650
3651define i32 @add_reduce_sqr_sum_order5(i32 %a, i32 %b) {
3652; CHECK-LABEL: @add_reduce_sqr_sum_order5(
3653; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3654; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3655; CHECK-NEXT:    ret i32 [[AB2]]
3656;
3657  %a_sq = mul nsw i32 %a, %a
3658  %twob = mul i32 %b, 2
3659  %twoab = mul i32 %twob, %a
3660  %b_sq = mul i32 %b, %b
3661  %a2_b2 = add i32 %a_sq, %b_sq
3662  %ab2 = add i32 %twoab, %a2_b2
3663  ret i32 %ab2
3664}
3665
3666define i32 @add_reduce_sqr_sum_order5_flipped(i32 %a, i32 %b) {
3667; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped(
3668; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3669; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3670; CHECK-NEXT:    ret i32 [[AB2]]
3671;
3672  %a_sq = mul nsw i32 %a, %a
3673  %twob = mul i32 %b, 2
3674  %twoab = mul i32 %twob, %a
3675  %b_sq = mul i32 %b, %b
3676  %a2_b2 = add i32 %a_sq, %b_sq
3677  %ab2 = add i32 %a2_b2, %twoab
3678  ret i32 %ab2
3679}
3680
3681define i32 @add_reduce_sqr_sum_order5_flipped2(i32 %a, i32 %b) {
3682; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped2(
3683; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3684; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3685; CHECK-NEXT:    ret i32 [[AB2]]
3686;
3687  %a_sq = mul nsw i32 %a, %a
3688  %twob = mul i32 %b, 2
3689  %twoab = mul i32 %twob, %a
3690  %b_sq = mul i32 %b, %b
3691  %a2_b2 = add i32 %b_sq, %a_sq
3692  %ab2 = add i32 %twoab, %a2_b2
3693  ret i32 %ab2
3694}
3695
3696define i32 @add_reduce_sqr_sum_order5_flipped3(i32 %ax, i32 %b) {
3697; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped3(
3698; CHECK-NEXT:    [[A:%.*]] = xor i32 [[AX:%.*]], 42
3699; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A]]
3700; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3701; CHECK-NEXT:    ret i32 [[AB2]]
3702;
3703  %a = xor i32 %ax, 42 ; thwart complexity-based canonicalization
3704  %a_sq = mul nsw i32 %a, %a
3705  %twob = mul i32 %b, 2
3706  %twoab = mul i32 %a, %twob
3707  %b_sq = mul i32 %b, %b
3708  %a2_b2 = add i32 %a_sq, %b_sq
3709  %ab2 = add i32 %twoab, %a2_b2
3710  ret i32 %ab2
3711}
3712
3713define i32 @add_reduce_sqr_sum_order5_flipped4(i32 %a, i32 %b) {
3714; CHECK-LABEL: @add_reduce_sqr_sum_order5_flipped4(
3715; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[B:%.*]], [[A:%.*]]
3716; CHECK-NEXT:    [[AB2:%.*]] = mul i32 [[TMP1]], [[TMP1]]
3717; CHECK-NEXT:    ret i32 [[AB2]]
3718;
3719  %a_sq = mul nsw i32 %a, %a
3720  %twob = mul i32 2, %b
3721  %twoab = mul i32 %twob, %a
3722  %b_sq = mul i32 %b, %b
3723  %a2_b2 = add i32 %a_sq, %b_sq
3724  %ab2 = add i32 %twoab, %a2_b2
3725  ret i32 %ab2
3726}
3727
3728define i32 @add_reduce_sqr_sum_not_one_use(i32 %a, i32 %b) {
3729; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use(
3730; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3731; CHECK-NEXT:    [[TWO_A:%.*]] = shl i32 [[A]], 1
3732; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3733; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3734; CHECK-NEXT:    tail call void @fake_func(i32 [[MUL]])
3735; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3736; CHECK-NEXT:    ret i32 [[ADD]]
3737;
3738  %a_sq = mul nsw i32 %a, %a
3739  %two_a = shl i32 %a, 1
3740  %two_a_plus_b = add i32 %two_a, %b
3741  %mul = mul i32 %two_a_plus_b, %b
3742  tail call void @fake_func (i32 %mul)
3743  %add = add i32 %mul, %a_sq
3744  ret i32 %add
3745}
3746
3747define i32 @add_reduce_sqr_sum_not_one_use2(i32 %a, i32 %b) {
3748; CHECK-LABEL: @add_reduce_sqr_sum_not_one_use2(
3749; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3750; CHECK-NEXT:    [[TWO_A:%.*]] = shl i32 [[A]], 1
3751; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3752; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3753; CHECK-NEXT:    tail call void @fake_func(i32 [[A_SQ]])
3754; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3755; CHECK-NEXT:    ret i32 [[ADD]]
3756;
3757  %a_sq = mul nsw i32 %a, %a
3758  %two_a = shl i32 %a, 1
3759  %two_a_plus_b = add i32 %two_a, %b
3760  %mul = mul i32 %two_a_plus_b, %b
3761  tail call void @fake_func (i32 %a_sq)
3762  %add = add i32 %mul, %a_sq
3763  ret i32 %add
3764}
3765
3766define i32 @add_reduce_sqr_sum_order2_not_one_use(i32 %a, i32 %b) {
3767; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use(
3768; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3769; CHECK-NEXT:    [[TWOA:%.*]] = shl i32 [[A]], 1
3770; CHECK-NEXT:    [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]]
3771; CHECK-NEXT:    [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]]
3772; CHECK-NEXT:    tail call void @fake_func(i32 [[TWOAB_B2]])
3773; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]]
3774; CHECK-NEXT:    ret i32 [[AB2]]
3775;
3776  %a_sq = mul nsw i32 %a, %a
3777  %twoa = mul i32 %a, 2
3778  %twoab = mul i32 %twoa, %b
3779  %b_sq = mul i32 %b, %b
3780  %twoab_b2 = add i32 %twoab, %b_sq
3781  tail call void @fake_func (i32 %twoab_b2)
3782  %ab2 = add i32 %a_sq, %twoab_b2
3783  ret i32 %ab2
3784}
3785
3786define i32 @add_reduce_sqr_sum_order2_not_one_use2(i32 %a, i32 %b) {
3787; CHECK-LABEL: @add_reduce_sqr_sum_order2_not_one_use2(
3788; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3789; CHECK-NEXT:    [[TWOA:%.*]] = shl i32 [[A]], 1
3790; CHECK-NEXT:    [[TWOAB1:%.*]] = add i32 [[TWOA]], [[B:%.*]]
3791; CHECK-NEXT:    [[TWOAB_B2:%.*]] = mul i32 [[TWOAB1]], [[B]]
3792; CHECK-NEXT:    tail call void @fake_func(i32 [[A_SQ]])
3793; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[A_SQ]], [[TWOAB_B2]]
3794; CHECK-NEXT:    ret i32 [[AB2]]
3795;
3796  %a_sq = mul nsw i32 %a, %a
3797  %twoa = mul i32 %a, 2
3798  %twoab = mul i32 %twoa, %b
3799  %b_sq = mul i32 %b, %b
3800  %twoab_b2 = add i32 %twoab, %b_sq
3801  tail call void @fake_func (i32 %a_sq)
3802  %ab2 = add i32 %a_sq, %twoab_b2
3803  ret i32 %ab2
3804}
3805
3806define i32 @add_reduce_sqr_sum_order3_not_one_use(i32 %a, i32 %b) {
3807; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use(
3808; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3809; CHECK-NEXT:    [[TWOA:%.*]] = shl i32 [[A]], 1
3810; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]]
3811; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3812; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3813; CHECK-NEXT:    tail call void @fake_func(i32 [[TWOAB]])
3814; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3815; CHECK-NEXT:    ret i32 [[AB2]]
3816;
3817  %a_sq = mul nsw i32 %a, %a
3818  %twoa = mul i32 %a, 2
3819  %twoab = mul i32 %twoa, %b
3820  %b_sq = mul i32 %b, %b
3821  %a2_b2 = add i32 %a_sq, %b_sq
3822  tail call void @fake_func (i32 %twoab)
3823  %ab2 = add i32 %twoab, %a2_b2
3824  ret i32 %ab2
3825}
3826
3827define i32 @add_reduce_sqr_sum_order3_not_one_use2(i32 %a, i32 %b) {
3828; CHECK-LABEL: @add_reduce_sqr_sum_order3_not_one_use2(
3829; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3830; CHECK-NEXT:    [[TWOA:%.*]] = shl i32 [[A]], 1
3831; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[TWOA]], [[B:%.*]]
3832; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3833; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3834; CHECK-NEXT:    tail call void @fake_func(i32 [[A2_B2]])
3835; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3836; CHECK-NEXT:    ret i32 [[AB2]]
3837;
3838  %a_sq = mul nsw i32 %a, %a
3839  %twoa = mul i32 %a, 2
3840  %twoab = mul i32 %twoa, %b
3841  %b_sq = mul i32 %b, %b
3842  %a2_b2 = add i32 %a_sq, %b_sq
3843  tail call void @fake_func (i32 %a2_b2)
3844  %ab2 = add i32 %twoab, %a2_b2
3845  ret i32 %ab2
3846}
3847
3848define i32 @add_reduce_sqr_sum_order4_not_one_use(i32 %a, i32 %b) {
3849; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use(
3850; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3851; CHECK-NEXT:    [[AB:%.*]] = mul i32 [[A]], [[B:%.*]]
3852; CHECK-NEXT:    [[TWOAB:%.*]] = shl i32 [[AB]], 1
3853; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3854; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3855; CHECK-NEXT:    tail call void @fake_func(i32 [[TWOAB]])
3856; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3857; CHECK-NEXT:    ret i32 [[AB2]]
3858;
3859  %a_sq = mul nsw i32 %a, %a
3860  %ab = mul i32 %a, %b
3861  %twoab = mul i32 %ab, 2
3862  %b_sq = mul i32 %b, %b
3863  %a2_b2 = add i32 %a_sq, %b_sq
3864  tail call void @fake_func (i32 %twoab)
3865  %ab2 = add i32 %twoab, %a2_b2
3866  ret i32 %ab2
3867}
3868
3869define i32 @add_reduce_sqr_sum_order4_not_one_use2(i32 %a, i32 %b) {
3870; CHECK-LABEL: @add_reduce_sqr_sum_order4_not_one_use2(
3871; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3872; CHECK-NEXT:    [[AB:%.*]] = mul i32 [[A]], [[B:%.*]]
3873; CHECK-NEXT:    [[TWOAB:%.*]] = shl i32 [[AB]], 1
3874; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3875; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3876; CHECK-NEXT:    tail call void @fake_func(i32 [[A2_B2]])
3877; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3878; CHECK-NEXT:    ret i32 [[AB2]]
3879;
3880  %a_sq = mul nsw i32 %a, %a
3881  %ab = mul i32 %a, %b
3882  %twoab = mul i32 %ab, 2
3883  %b_sq = mul i32 %b, %b
3884  %a2_b2 = add i32 %a_sq, %b_sq
3885  tail call void @fake_func (i32 %a2_b2)
3886  %ab2 = add i32 %twoab, %a2_b2
3887  ret i32 %ab2
3888}
3889
3890define i32 @add_reduce_sqr_sum_order5_not_one_use(i32 %a, i32 %b) {
3891; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use(
3892; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3893; CHECK-NEXT:    [[TWOB:%.*]] = shl i32 [[B:%.*]], 1
3894; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]]
3895; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3896; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3897; CHECK-NEXT:    tail call void @fake_func(i32 [[TWOAB]])
3898; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3899; CHECK-NEXT:    ret i32 [[AB2]]
3900;
3901  %a_sq = mul nsw i32 %a, %a
3902  %twob = mul i32 %b, 2
3903  %twoab = mul i32 %twob, %a
3904  %b_sq = mul i32 %b, %b
3905  %a2_b2 = add i32 %a_sq, %b_sq
3906  tail call void @fake_func (i32 %twoab)
3907  %ab2 = add i32 %twoab, %a2_b2
3908  ret i32 %ab2
3909}
3910
3911define i32 @add_reduce_sqr_sum_order5_not_one_use2(i32 %a, i32 %b) {
3912; CHECK-LABEL: @add_reduce_sqr_sum_order5_not_one_use2(
3913; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3914; CHECK-NEXT:    [[TWOB:%.*]] = shl i32 [[B:%.*]], 1
3915; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[TWOB]], [[A]]
3916; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
3917; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
3918; CHECK-NEXT:    tail call void @fake_func(i32 [[A2_B2]])
3919; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
3920; CHECK-NEXT:    ret i32 [[AB2]]
3921;
3922  %a_sq = mul nsw i32 %a, %a
3923  %twob = mul i32 %b, 2
3924  %twoab = mul i32 %twob, %a
3925  %b_sq = mul i32 %b, %b
3926  %a2_b2 = add i32 %a_sq, %b_sq
3927  tail call void @fake_func (i32 %a2_b2)
3928  %ab2 = add i32 %twoab, %a2_b2
3929  ret i32 %ab2
3930}
3931
3932define i32 @add_reduce_sqr_sum_invalid0(i32 %a, i32 %b) {
3933; CHECK-LABEL: @add_reduce_sqr_sum_invalid0(
3934; CHECK-NEXT:    [[TWO_A:%.*]] = shl i32 [[A:%.*]], 1
3935; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = add i32 [[TWO_A]], [[B:%.*]]
3936; CHECK-NEXT:    [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A]]
3937; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[MUL1]], [[B]]
3938; CHECK-NEXT:    ret i32 [[ADD]]
3939;
3940  %not_a_sq = mul nsw i32 %a, %b
3941  %two_a = shl i32 %a, 1
3942  %two_a_plus_b = add i32 %two_a, %b
3943  %mul = mul i32 %two_a_plus_b, %b
3944  %add = add i32 %mul, %not_a_sq
3945  ret i32 %add
3946}
3947
3948define i32 @add_reduce_sqr_sum_invalid1(i32 %a, i32 %b) {
3949; CHECK-LABEL: @add_reduce_sqr_sum_invalid1(
3950; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3951; CHECK-NEXT:    [[NOT_TWO_A_PLUS_B:%.*]] = mul i32 [[A]], 3
3952; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[NOT_TWO_A_PLUS_B]], [[B:%.*]]
3953; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3954; CHECK-NEXT:    ret i32 [[ADD]]
3955;
3956  %a_sq = mul nsw i32 %a, %a
3957  %two_a = shl i32 %a, 1
3958  %not_two_a_plus_b = add i32 %two_a, %a
3959  %mul = mul i32 %not_two_a_plus_b, %b
3960  %add = add i32 %mul, %a_sq
3961  ret i32 %add
3962}
3963
3964define i32 @add_reduce_sqr_sum_invalid2(i32 %a, i32 %b) {
3965; CHECK-LABEL: @add_reduce_sqr_sum_invalid2(
3966; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3967; CHECK-NEXT:    [[NOT_TWO_A:%.*]] = shl i32 [[A]], 2
3968; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = add i32 [[NOT_TWO_A]], [[B:%.*]]
3969; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
3970; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
3971; CHECK-NEXT:    ret i32 [[ADD]]
3972;
3973  %a_sq = mul nsw i32 %a, %a
3974  %not_two_a = shl i32 %a, 2
3975  %two_a_plus_b = add i32 %not_two_a, %b
3976  %mul = mul i32 %two_a_plus_b, %b
3977  %add = add i32 %mul, %a_sq
3978  ret i32 %add
3979}
3980
3981define i32 @add_reduce_sqr_sum_invalid3(i32 %a, i32 %b) {
3982; CHECK-LABEL: @add_reduce_sqr_sum_invalid3(
3983; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 3
3984; CHECK-NEXT:    [[MUL1:%.*]] = add i32 [[TWO_A_PLUS_B]], [[A:%.*]]
3985; CHECK-NEXT:    [[ADD:%.*]] = mul i32 [[MUL1]], [[A]]
3986; CHECK-NEXT:    ret i32 [[ADD]]
3987;
3988  %a_sq = mul nsw i32 %a, %a
3989  %not_two_a = shl i32 %b, 1
3990  %two_a_plus_b = add i32 %not_two_a, %b
3991  %mul = mul i32 %two_a_plus_b, %a
3992  %add = add i32 %mul, %a_sq
3993  ret i32 %add
3994}
3995
3996define i32 @add_reduce_sqr_sum_invalid4(i32 %a, i32 %b) {
3997; CHECK-LABEL: @add_reduce_sqr_sum_invalid4(
3998; CHECK-NEXT:    [[A_SQ:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
3999; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = mul i32 [[B:%.*]], 3
4000; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TWO_A_PLUS_B]], [[B]]
4001; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[MUL]], [[A_SQ]]
4002; CHECK-NEXT:    ret i32 [[ADD]]
4003;
4004  %a_sq = mul nsw i32 %a, %a
4005  %not_two_a = shl i32 %b, 1
4006  %two_a_plus_b = add i32 %not_two_a, %b
4007  %mul = mul i32 %two_a_plus_b, %b
4008  %add = add i32 %mul, %a_sq
4009  ret i32 %add
4010}
4011
4012define i32 @add_reduce_sqr_sum_varB_invalid0(i32 %a, i32 %b) {
4013; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid0(
4014; CHECK-NEXT:    [[NOT_A_B:%.*]] = mul nsw i32 [[A:%.*]], [[A]]
4015; CHECK-NEXT:    [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 1
4016; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
4017; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]]
4018; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4019; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4020; CHECK-NEXT:    ret i32 [[AB2]]
4021;
4022  %not_a_b = mul nsw i32 %a, %a
4023  %twoab = mul i32 %not_a_b, 2
4024  %a_sq = mul i32 %a, %a
4025  %b_sq = mul i32 %b, %b
4026  %a2_b2 = add i32 %a_sq, %b_sq
4027  %ab2 = add i32 %twoab, %a2_b2
4028  ret i32 %ab2
4029}
4030
4031define i32 @add_reduce_sqr_sum_varB_invalid1(i32 %a, i32 %b) {
4032; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid1(
4033; CHECK-NEXT:    [[NOT_A_B:%.*]] = mul nsw i32 [[B:%.*]], [[B]]
4034; CHECK-NEXT:    [[TWOAB:%.*]] = shl nuw i32 [[NOT_A_B]], 1
4035; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]]
4036; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
4037; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4038; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4039; CHECK-NEXT:    ret i32 [[AB2]]
4040;
4041  %not_a_b = mul nsw i32 %b, %b
4042  %twoab = mul i32 %not_a_b, 2
4043  %a_sq = mul i32 %a, %a
4044  %b_sq = mul i32 %b, %b
4045  %a2_b2 = add i32 %a_sq, %b_sq
4046  %ab2 = add i32 %twoab, %a2_b2
4047  ret i32 %ab2
4048}
4049
4050define i32 @add_reduce_sqr_sum_varB_invalid2(i32 %a, i32 %b) {
4051; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid2(
4052; CHECK-NEXT:    [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
4053; CHECK-NEXT:    [[NOT_TWOAB:%.*]] = shl i32 [[A_B]], 2
4054; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
4055; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
4056; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4057; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]]
4058; CHECK-NEXT:    ret i32 [[AB2]]
4059;
4060  %a_b = mul nsw i32 %a, %b
4061  %not_twoab = mul i32 %a_b, 4
4062  %a_sq = mul i32 %a, %a
4063  %b_sq = mul i32 %b, %b
4064  %a2_b2 = add i32 %a_sq, %b_sq
4065  %ab2 = add i32 %not_twoab, %a2_b2
4066  ret i32 %ab2
4067}
4068
4069define i32 @add_reduce_sqr_sum_varB_invalid3(i32 %a, i32 %b) {
4070; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid3(
4071; CHECK-NEXT:    [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
4072; CHECK-NEXT:    [[TWOAB:%.*]] = shl i32 [[A_B]], 1
4073; CHECK-NEXT:    [[B_SQ1:%.*]] = add i32 [[A]], [[B]]
4074; CHECK-NEXT:    [[A2_B2:%.*]] = mul i32 [[B]], [[B_SQ1]]
4075; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4076; CHECK-NEXT:    ret i32 [[AB2]]
4077;
4078  %a_b = mul nsw i32 %a, %b
4079  %twoab = mul i32 %a_b, 2
4080  %not_a_sq = mul i32 %b, %a
4081  %b_sq = mul i32 %b, %b
4082  %a2_b2 = add i32 %not_a_sq, %b_sq
4083  %ab2 = add i32 %twoab, %a2_b2
4084  ret i32 %ab2
4085}
4086
4087define i32 @add_reduce_sqr_sum_varB_invalid4(i32 %a, i32 %b) {
4088; CHECK-LABEL: @add_reduce_sqr_sum_varB_invalid4(
4089; CHECK-NEXT:    [[A_B:%.*]] = mul nsw i32 [[A:%.*]], [[B:%.*]]
4090; CHECK-NEXT:    [[TWOAB:%.*]] = shl i32 [[A_B]], 1
4091; CHECK-NEXT:    [[NOT_B_SQ1:%.*]] = add i32 [[A]], [[B]]
4092; CHECK-NEXT:    [[A2_B2:%.*]] = mul i32 [[A]], [[NOT_B_SQ1]]
4093; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4094; CHECK-NEXT:    ret i32 [[AB2]]
4095;
4096  %a_b = mul nsw i32 %a, %b
4097  %twoab = mul i32 %a_b, 2
4098  %a_sq = mul i32 %a, %a
4099  %not_b_sq = mul i32 %b, %a
4100  %a2_b2 = add i32 %a_sq, %not_b_sq
4101  %ab2 = add i32 %twoab, %a2_b2
4102  ret i32 %ab2
4103}
4104
4105define i32 @add_reduce_sqr_sum_varC_invalid0(i32 %a, i32 %b) {
4106; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid0(
4107; CHECK-NEXT:    [[NOT_TWOA:%.*]] = shl nsw i32 [[B:%.*]], 1
4108; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B]]
4109; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A:%.*]], [[A]]
4110; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
4111; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4112; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4113; CHECK-NEXT:    ret i32 [[AB2]]
4114;
4115  %not_twoa = mul nsw i32 %b, 2
4116  %twoab = mul i32 %not_twoa, %b
4117  %a_sq = mul i32 %a, %a
4118  %b_sq = mul i32 %b, %b
4119  %a2_b2 = add i32 %a_sq, %b_sq
4120  %ab2 = add i32 %twoab, %a2_b2
4121  ret i32 %ab2
4122}
4123
4124define i32 @add_reduce_sqr_sum_varC_invalid1(i32 %a, i32 %b) {
4125; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid1(
4126; CHECK-NEXT:    [[NOT_TWOA:%.*]] = shl nsw i32 [[A:%.*]], 2
4127; CHECK-NEXT:    [[TWOAB:%.*]] = mul i32 [[NOT_TWOA]], [[B:%.*]]
4128; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
4129; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B]], [[B]]
4130; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4131; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[TWOAB]], [[A2_B2]]
4132; CHECK-NEXT:    ret i32 [[AB2]]
4133;
4134  %not_twoa = mul nsw i32 %a, 4
4135  %twoab = mul i32 %not_twoa, %b
4136  %a_sq = mul i32 %a, %a
4137  %b_sq = mul i32 %b, %b
4138  %a2_b2 = add i32 %a_sq, %b_sq
4139  %ab2 = add i32 %twoab, %a2_b2
4140  ret i32 %ab2
4141}
4142
4143define i32 @add_reduce_sqr_sum_varC_invalid2(i32 %a, i32 %b) {
4144; CHECK-LABEL: @add_reduce_sqr_sum_varC_invalid2(
4145; CHECK-NEXT:    [[TWOA:%.*]] = shl nsw i32 [[A:%.*]], 1
4146; CHECK-NEXT:    [[NOT_TWOAB:%.*]] = mul i32 [[TWOA]], [[A]]
4147; CHECK-NEXT:    [[A_SQ:%.*]] = mul i32 [[A]], [[A]]
4148; CHECK-NEXT:    [[B_SQ:%.*]] = mul i32 [[B:%.*]], [[B]]
4149; CHECK-NEXT:    [[A2_B2:%.*]] = add i32 [[A_SQ]], [[B_SQ]]
4150; CHECK-NEXT:    [[AB2:%.*]] = add i32 [[NOT_TWOAB]], [[A2_B2]]
4151; CHECK-NEXT:    ret i32 [[AB2]]
4152;
4153  %twoa = mul nsw i32 %a, 2
4154  %not_twoab = mul i32 %twoa, %a
4155  %a_sq = mul i32 %a, %a
4156  %b_sq = mul i32 %b, %b
4157  %a2_b2 = add i32 %a_sq, %b_sq
4158  %ab2 = add i32 %not_twoab, %a2_b2
4159  ret i32 %ab2
4160}
4161
4162define i32 @fold_sext_addition_or_disjoint(i8 %x) {
4163; CHECK-LABEL: @fold_sext_addition_or_disjoint(
4164; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
4165; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 1246
4166; CHECK-NEXT:    ret i32 [[R]]
4167;
4168  %xx = or disjoint i8 %x, 12
4169  %se = sext i8 %xx to i32
4170  %r = add i32 %se, 1234
4171  ret i32 %r
4172}
4173
4174define i32 @fold_sext_addition_fail(i8 %x) {
4175; CHECK-LABEL: @fold_sext_addition_fail(
4176; CHECK-NEXT:    [[XX:%.*]] = or i8 [[X:%.*]], 12
4177; CHECK-NEXT:    [[SE:%.*]] = sext i8 [[XX]] to i32
4178; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[SE]], 1234
4179; CHECK-NEXT:    ret i32 [[R]]
4180;
4181  %xx = or i8 %x, 12
4182  %se = sext i8 %xx to i32
4183  %r = add i32 %se, 1234
4184  ret i32 %r
4185}
4186
4187define i32 @fold_zext_addition_or_disjoint(i8 %x) {
4188; CHECK-LABEL: @fold_zext_addition_or_disjoint(
4189; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
4190; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[TMP1]], 1246
4191; CHECK-NEXT:    ret i32 [[R]]
4192;
4193  %xx = or disjoint i8 %x, 12
4194  %se = zext i8 %xx to i32
4195  %r = add i32 %se, 1234
4196  ret i32 %r
4197}
4198
4199define i32 @fold_zext_addition_or_disjoint2(i8 %x) {
4200; CHECK-LABEL: @fold_zext_addition_or_disjoint2(
4201; CHECK-NEXT:    [[TMP1:%.*]] = add nuw i8 [[X:%.*]], 4
4202; CHECK-NEXT:    [[R:%.*]] = zext i8 [[TMP1]] to i32
4203; CHECK-NEXT:    ret i32 [[R]]
4204;
4205  %xx = or disjoint i8 %x, 18
4206  %se = zext i8 %xx to i32
4207  %r = add i32 %se, -14
4208  ret i32 %r
4209}
4210
4211define i32 @fold_zext_addition_fail(i8 %x) {
4212; CHECK-LABEL: @fold_zext_addition_fail(
4213; CHECK-NEXT:    [[XX:%.*]] = or i8 [[X:%.*]], 12
4214; CHECK-NEXT:    [[SE:%.*]] = zext i8 [[XX]] to i32
4215; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[SE]], 1234
4216; CHECK-NEXT:    ret i32 [[R]]
4217;
4218  %xx = or i8 %x, 12
4219  %se = zext i8 %xx to i32
4220  %r = add i32 %se, 1234
4221  ret i32 %r
4222}
4223
4224define i32 @fold_zext_addition_fail2(i8 %x) {
4225; CHECK-LABEL: @fold_zext_addition_fail2(
4226; CHECK-NEXT:    [[XX:%.*]] = or i8 [[X:%.*]], 18
4227; CHECK-NEXT:    [[SE:%.*]] = zext i8 [[XX]] to i32
4228; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[SE]], -14
4229; CHECK-NEXT:    ret i32 [[R]]
4230;
4231  %xx = or i8 %x, 18
4232  %se = zext i8 %xx to i32
4233  %r = add i32 %se, -14
4234  ret i32 %r
4235}
4236
4237define i32 @fold_zext_nneg_add_const(i8 %x) {
4238; CHECK-LABEL: @fold_zext_nneg_add_const(
4239; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
4240; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 98
4241; CHECK-NEXT:    ret i32 [[R]]
4242;
4243  %xx = add nsw i8 %x, 123
4244  %ze = zext nneg i8 %xx to i32
4245  %r = add nsw i32 %ze, -25
4246  ret i32 %r
4247}
4248
4249define i32 @fold_zext_nneg_add_const_fail1(i8 %x) {
4250; CHECK-LABEL: @fold_zext_nneg_add_const_fail1(
4251; CHECK-NEXT:    [[XX:%.*]] = add nsw i8 [[X:%.*]], 123
4252; CHECK-NEXT:    [[ZE:%.*]] = zext i8 [[XX]] to i32
4253; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[ZE]], -25
4254; CHECK-NEXT:    ret i32 [[R]]
4255;
4256  %xx = add nsw i8 %x, 123
4257  %ze = zext i8 %xx to i32
4258  %r = add nsw i32 %ze, -25
4259  ret i32 %r
4260}
4261
4262define i32 @fold_zext_nneg_add_const_fail2(i8 %x) {
4263; CHECK-LABEL: @fold_zext_nneg_add_const_fail2(
4264; CHECK-NEXT:    [[XX:%.*]] = add i8 [[X:%.*]], 123
4265; CHECK-NEXT:    [[ZE:%.*]] = zext nneg i8 [[XX]] to i32
4266; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[ZE]], -25
4267; CHECK-NEXT:    ret i32 [[R]]
4268;
4269  %xx = add i8 %x, 123
4270  %ze = zext nneg i8 %xx to i32
4271  %r = add nsw i32 %ze, -25
4272  ret i32 %r
4273}
4274
4275declare void @llvm.assume(i1)
4276declare void @fake_func(i32)
4277