xref: /llvm-project/llvm/test/Transforms/InstCombine/sub-of-negatible.ll (revision ff07df6620c32571c7e13ff96ec7976c63ed0ab8)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4declare void @use4(i4)
5declare void @use8(i8)
6declare void @use_v2i4(<2 x i4>)
7declare i1 @use32gen1(i32)
8
9; Constant can be freely negated.
10define i8 @t0(i8 %x) {
11; CHECK-LABEL: @t0(
12; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42
13; CHECK-NEXT:    ret i8 [[T0]]
14;
15  %t0 = sub i8 %x, -42
16  ret i8 %t0
17}
18
19; Negation can be negated for free
20define i8 @t1(i8 %x, i8 %y) {
21; CHECK-LABEL: @t1(
22; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
23; CHECK-NEXT:    call void @use8(i8 [[T0]])
24; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X:%.*]], [[Y]]
25; CHECK-NEXT:    ret i8 [[T1]]
26;
27  %t0 = sub i8 0, %y
28  call void @use8(i8 %t0)
29  %t1 = sub i8 %x, %t0
30  ret i8 %t1
31}
32
33; Shift-left can be negated if all uses can be updated
34define i8 @t2(i8 %x, i8 %y) {
35; CHECK-LABEL: @t2(
36; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i8 42, [[Y:%.*]]
37; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
38; CHECK-NEXT:    ret i8 [[T1]]
39;
40  %t0 = shl i8 -42, %y
41  %t1 = sub i8 %x, %t0
42  ret i8 %t1
43}
44define i8 @n2(i8 %x, i8 %y) {
45; CHECK-LABEL: @n2(
46; CHECK-NEXT:    [[T0:%.*]] = shl i8 -42, [[Y:%.*]]
47; CHECK-NEXT:    call void @use8(i8 [[T0]])
48; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
49; CHECK-NEXT:    ret i8 [[T1]]
50;
51  %t0 = shl i8 -42, %y
52  call void @use8(i8 %t0)
53  %t1 = sub i8 %x, %t0
54  ret i8 %t1
55}
56define i8 @t3(i8 %x, i8 %y, i8 %z) {
57; CHECK-LABEL: @t3(
58; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
59; CHECK-NEXT:    call void @use8(i8 [[T0]])
60; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Z]], [[Y:%.*]]
61; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
62; CHECK-NEXT:    ret i8 [[T2]]
63;
64  %t0 = sub i8 0, %z
65  call void @use8(i8 %t0)
66  %t1 = shl i8 %t0, %y
67  %t2 = sub i8 %x, %t1
68  ret i8 %t2
69}
70define i8 @n3(i8 %x, i8 %y, i8 %z) {
71; CHECK-LABEL: @n3(
72; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
73; CHECK-NEXT:    call void @use8(i8 [[T0]])
74; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], [[Y:%.*]]
75; CHECK-NEXT:    call void @use8(i8 [[T1]])
76; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
77; CHECK-NEXT:    ret i8 [[T2]]
78;
79  %t0 = sub i8 0, %z
80  call void @use8(i8 %t0)
81  %t1 = shl i8 %t0, %y
82  call void @use8(i8 %t1)
83  %t2 = sub i8 %x, %t1
84  ret i8 %t2
85}
86
87; Select can be negated if all it's operands can be negated and all the users of select can be updated
88define i8 @t4(i8 %x, i1 %y) {
89; CHECK-LABEL: @t4(
90; CHECK-NEXT:    [[T0_NEG:%.*]] = select i1 [[Y:%.*]], i8 42, i8 -44
91; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
92; CHECK-NEXT:    ret i8 [[T1]]
93;
94  %t0 = select i1 %y, i8 -42, i8 44
95  %t1 = sub i8 %x, %t0
96  ret i8 %t1
97}
98
99define i8 @select_of_constants_multi_use(i1 %b) {
100; CHECK-LABEL: @select_of_constants_multi_use(
101; CHECK-NEXT:    [[S_NEG:%.*]] = select i1 [[B:%.*]], i8 -42, i8 2
102; CHECK-NEXT:    [[S:%.*]] = select i1 [[B]], i8 42, i8 -2
103; CHECK-NEXT:    call void @use8(i8 [[S]])
104; CHECK-NEXT:    ret i8 [[S_NEG]]
105;
106  %s = select i1 %b, i8 42, i8 -2
107  call void @use8(i8 %s)
108  %n = sub i8 0, %s
109  ret i8 %n
110}
111
112define i32 @PR52261(i1 %b) {
113; CHECK-LABEL: @PR52261(
114; CHECK-NEXT:    ret i32 2
115;
116  %s = select i1 %b, i32 2, i32 -2
117  %n = sub nsw i32 0, %s
118  %a = and i32 %s, %n
119  ret i32 %a
120}
121
122define i8 @n4(i8 %x, i1 %y) {
123; CHECK-LABEL: @n4(
124; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 44
125; CHECK-NEXT:    call void @use8(i8 [[T0]])
126; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
127; CHECK-NEXT:    ret i8 [[T1]]
128;
129  %t0 = select i1 %y, i8 -42, i8 44
130  call void @use8(i8 %t0)
131  %t1 = sub i8 %x, %t0
132  ret i8 %t1
133}
134define i8 @n5(i8 %x, i1 %y, i8 %z) {
135; CHECK-LABEL: @n5(
136; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 [[Z:%.*]]
137; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
138; CHECK-NEXT:    ret i8 [[T1]]
139;
140  %t0 = select i1 %y, i8 -42, i8 %z
141  %t1 = sub i8 %x, %t0
142  ret i8 %t1
143}
144define i8 @t6(i8 %x, i1 %y, i8 %z) {
145; CHECK-LABEL: @t6(
146; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
147; CHECK-NEXT:    call void @use8(i8 [[T0]])
148; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 42, i8 [[Z]]
149; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
150; CHECK-NEXT:    ret i8 [[T2]]
151;
152  %t0 = sub i8 0, %z
153  call void @use8(i8 %t0)
154  %t1 = select i1 %y, i8 -42, i8 %t0
155  %t2 = sub i8 %x, %t1
156  ret i8 %t2
157}
158define i8 @t7(i8 %x, i1 %y, i8 %z) {
159; CHECK-LABEL: @t7(
160; CHECK-NEXT:    [[T0_NEG:%.*]] = shl nsw i8 -1, [[Z:%.*]]
161; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0_NEG]]
162; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
163; CHECK-NEXT:    ret i8 [[T2]]
164;
165  %t0 = shl i8 1, %z
166  %t1 = select i1 %y, i8 0, i8 %t0
167  %t2 = sub i8 %x, %t1
168  ret i8 %t2
169}
170define i8 @n8(i8 %x, i1 %y, i8 %z) {
171; CHECK-LABEL: @n8(
172; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[Z:%.*]]
173; CHECK-NEXT:    call void @use8(i8 [[T0]])
174; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]]
175; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
176; CHECK-NEXT:    ret i8 [[T2]]
177;
178  %t0 = shl i8 1, %z
179  call void @use8(i8 %t0)
180  %t1 = select i1 %y, i8 0, i8 %t0
181  %t2 = sub i8 %x, %t1
182  ret i8 %t2
183}
184
185; Subtraction can be negated by swapping its operands.
186; x - (y - z) -> x - y + z -> x + (z - y)
187define i8 @t9(i8 %x, i8 %y) {
188; CHECK-LABEL: @t9(
189; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
190; CHECK-NEXT:    ret i8 [[T0_NEG]]
191;
192  %t0 = sub i8 %y, %x
193  %t1 = sub i8 0, %t0
194  ret i8 %t1
195}
196
197define i8 @n10(i8 %x, i8 %y, i8 %z) {
198; CHECK-LABEL: @n10(
199; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]]
200; CHECK-NEXT:    call void @use8(i8 [[T0]])
201; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[T0]]
202; CHECK-NEXT:    ret i8 [[T1]]
203;
204  %t0 = sub i8 %y, %x
205  call void @use8(i8 %t0)
206  %t1 = sub i8 0, %t0
207  ret i8 %t1
208}
209
210define i8 @neg_of_sub_from_constant(i8 %x) {
211; CHECK-LABEL: @neg_of_sub_from_constant(
212; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42
213; CHECK-NEXT:    ret i8 [[S_NEG]]
214;
215  %s = sub i8 42, %x
216  %r = sub i8 0, %s
217  ret i8 %r
218}
219
220define i8 @neg_of_sub_from_constant_multi_use(i8 %x) {
221; CHECK-LABEL: @neg_of_sub_from_constant_multi_use(
222; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42
223; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]]
224; CHECK-NEXT:    call void @use8(i8 [[S]])
225; CHECK-NEXT:    ret i8 [[S_NEG]]
226;
227  %s = sub i8 42, %x
228  call void @use8(i8 %s)
229  %r = sub i8 0, %s
230  ret i8 %r
231}
232
233define i8 @sub_from_constant_of_sub_from_constant(i8 %x) {
234; CHECK-LABEL: @sub_from_constant_of_sub_from_constant(
235; CHECK-NEXT:    [[R:%.*]] = add i8 [[X:%.*]], -31
236; CHECK-NEXT:    ret i8 [[R]]
237;
238  %s = sub i8 42, %x
239  %r = sub i8 11, %s
240  ret i8 %r
241}
242
243define i8 @sub_from_constant_of_sub_from_constant_multi_use(i8 %x) {
244; CHECK-LABEL: @sub_from_constant_of_sub_from_constant_multi_use(
245; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X:%.*]]
246; CHECK-NEXT:    call void @use8(i8 [[S]])
247; CHECK-NEXT:    [[R:%.*]] = add i8 [[X]], -31
248; CHECK-NEXT:    ret i8 [[R]]
249;
250  %s = sub i8 42, %x
251  call void @use8(i8 %s)
252  %r = sub i8 11, %s
253  ret i8 %r
254}
255
256define i8 @sub_from_variable_of_sub_from_constant(i8 %x, i8 %y) {
257; CHECK-LABEL: @sub_from_variable_of_sub_from_constant(
258; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42
259; CHECK-NEXT:    [[R:%.*]] = add i8 [[S_NEG]], [[Y:%.*]]
260; CHECK-NEXT:    ret i8 [[R]]
261;
262  %s = sub i8 42, %x
263  %r = sub i8 %y, %s
264  ret i8 %r
265}
266
267define i8 @sub_from_variable_of_sub_from_constant_multi_use(i8 %x, i8 %y) {
268; CHECK-LABEL: @sub_from_variable_of_sub_from_constant_multi_use(
269; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X:%.*]]
270; CHECK-NEXT:    call void @use8(i8 [[S]])
271; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y:%.*]], [[S]]
272; CHECK-NEXT:    ret i8 [[R]]
273;
274  %s = sub i8 42, %x
275  call void @use8(i8 %s)
276  %r = sub i8 %y, %s
277  ret i8 %r
278}
279
280; Addition can be negated if both operands can be negated
281; x - (y + z) -> x - y - z -> x + ((-y) + (-z)))
282define i8 @t12(i8 %x, i8 %y, i8 %z) {
283; CHECK-LABEL: @t12(
284; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
285; CHECK-NEXT:    call void @use8(i8 [[T0]])
286; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]]
287; CHECK-NEXT:    call void @use8(i8 [[T1]])
288; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]
289; CHECK-NEXT:    [[T3:%.*]] = add i8 [[X:%.*]], [[TMP1]]
290; CHECK-NEXT:    ret i8 [[T3]]
291;
292  %t0 = sub i8 0, %y
293  call void @use8(i8 %t0)
294  %t1 = sub i8 0, %z
295  call void @use8(i8 %t1)
296  %t2 = add i8 %t0, %t1
297  %t3 = sub i8 %x, %t2
298  ret i8 %t3
299}
300define i8 @n13(i8 %x, i8 %y, i8 %z) {
301; CHECK-LABEL: @n13(
302; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
303; CHECK-NEXT:    call void @use8(i8 [[T0]])
304; CHECK-NEXT:    [[T1_NEG:%.*]] = sub i8 [[Y]], [[Z:%.*]]
305; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
306; CHECK-NEXT:    ret i8 [[T2]]
307;
308  %t0 = sub i8 0, %y
309  call void @use8(i8 %t0)
310  %t1 = add i8 %t0, %z
311  %t2 = sub i8 %x, %t1
312  ret i8 %t2
313}
314define i8 @n14(i8 %x, i8 %y, i8 %z) {
315; CHECK-LABEL: @n14(
316; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
317; CHECK-NEXT:    call void @use8(i8 [[T0]])
318; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]]
319; CHECK-NEXT:    call void @use8(i8 [[T1]])
320; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]
321; CHECK-NEXT:    [[T2:%.*]] = sub i8 0, [[TMP1]]
322; CHECK-NEXT:    call void @use8(i8 [[T2]])
323; CHECK-NEXT:    [[T3:%.*]] = add i8 [[X:%.*]], [[TMP1]]
324; CHECK-NEXT:    ret i8 [[T3]]
325;
326  %t0 = sub i8 0, %y
327  call void @use8(i8 %t0)
328  %t1 = sub i8 0, %z
329  call void @use8(i8 %t1)
330  %t2 = add i8 %t0, %t1
331  call void @use8(i8 %t2)
332  %t3 = sub i8 %x, %t2
333  ret i8 %t3
334}
335
336define i8 @neg_of_add_with_constant(i8 %x) {
337; CHECK-LABEL: @neg_of_add_with_constant(
338; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X:%.*]]
339; CHECK-NEXT:    ret i8 [[R]]
340;
341  %s = add i8 %x, 42
342  %r = sub i8 0, %s
343  ret i8 %r
344}
345
346define i8 @neg_of_add_with_constant_multi_use(i8 %x) {
347; CHECK-LABEL: @neg_of_add_with_constant_multi_use(
348; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42
349; CHECK-NEXT:    call void @use8(i8 [[S]])
350; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X]]
351; CHECK-NEXT:    ret i8 [[R]]
352;
353  %s = add i8 %x, 42
354  call void @use8(i8 %s)
355  %r = sub i8 0, %s
356  ret i8 %r
357}
358
359define i8 @sub_from_constant_of_add_with_constant(i8 %x) {
360; CHECK-LABEL: @sub_from_constant_of_add_with_constant(
361; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X:%.*]]
362; CHECK-NEXT:    ret i8 [[R]]
363;
364  %s = add i8 %x, 42
365  %r = sub i8 11, %s
366  ret i8 %r
367}
368
369define i8 @sub_from_constant_of_add_with_constant_multi_use(i8 %x) {
370; CHECK-LABEL: @sub_from_constant_of_add_with_constant_multi_use(
371; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42
372; CHECK-NEXT:    call void @use8(i8 [[S]])
373; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X]]
374; CHECK-NEXT:    ret i8 [[R]]
375;
376  %s = add i8 %x, 42
377  call void @use8(i8 %s)
378  %r = sub i8 11, %s
379  ret i8 %r
380}
381
382define i8 @sub_from_variable_of_add_with_constant(i8 %x, i8 %y) {
383; CHECK-LABEL: @sub_from_variable_of_add_with_constant(
384; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42
385; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y:%.*]], [[S]]
386; CHECK-NEXT:    ret i8 [[R]]
387;
388  %s = add i8 %x, 42
389  %r = sub i8 %y, %s
390  ret i8 %r
391}
392
393define i8 @sub_from_variable_of_add_with_constant_multi_use(i8 %x, i8 %y) {
394; CHECK-LABEL: @sub_from_variable_of_add_with_constant_multi_use(
395; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42
396; CHECK-NEXT:    call void @use8(i8 [[S]])
397; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y:%.*]], [[S]]
398; CHECK-NEXT:    ret i8 [[R]]
399;
400  %s = add i8 %x, 42
401  call void @use8(i8 %s)
402  %r = sub i8 %y, %s
403  ret i8 %r
404}
405
406; Multiplication can be negated if either one of operands can be negated
407; x - (y * z) -> x + ((-y) * z) or  x + ((-z) * y)
408define i8 @t15(i8 %x, i8 %y, i8 %z) {
409; CHECK-LABEL: @t15(
410; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
411; CHECK-NEXT:    call void @use8(i8 [[T0]])
412; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[Y]], [[Z:%.*]]
413; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
414; CHECK-NEXT:    ret i8 [[T2]]
415;
416  %t0 = sub i8 0, %y
417  call void @use8(i8 %t0)
418  %t1 = mul i8 %t0, %z
419  %t2 = sub i8 %x, %t1
420  ret i8 %t2
421}
422define i8 @n16(i8 %x, i8 %y, i8 %z) {
423; CHECK-LABEL: @n16(
424; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
425; CHECK-NEXT:    call void @use8(i8 [[T0]])
426; CHECK-NEXT:    [[T1:%.*]] = mul i8 [[Z:%.*]], [[T0]]
427; CHECK-NEXT:    call void @use8(i8 [[T1]])
428; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
429; CHECK-NEXT:    ret i8 [[T2]]
430;
431  %t0 = sub i8 0, %y
432  call void @use8(i8 %t0)
433  %t1 = mul i8 %t0, %z
434  call void @use8(i8 %t1)
435  %t2 = sub i8 %x, %t1
436  ret i8 %t2
437}
438
439; Phi can be negated if all incoming values can be negated
440define i8 @t16(i1 %c, i8 %x) {
441; CHECK-LABEL: @t16(
442; CHECK-NEXT:  begin:
443; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
444; CHECK:       then:
445; CHECK-NEXT:    br label [[END:%.*]]
446; CHECK:       else:
447; CHECK-NEXT:    br label [[END]]
448; CHECK:       end:
449; CHECK-NEXT:    [[Z_NEG:%.*]] = phi i8 [ [[X:%.*]], [[THEN]] ], [ 42, [[ELSE]] ]
450; CHECK-NEXT:    ret i8 [[Z_NEG]]
451;
452begin:
453  br i1 %c, label %then, label %else
454then:
455  %y = sub i8 0, %x
456  br label %end
457else:
458  br label %end
459end:
460  %z = phi i8 [ %y, %then], [ -42, %else ]
461  %n = sub i8 0, %z
462  ret i8 %n
463}
464define i8 @n17(i1 %c, i8 %x) {
465; CHECK-LABEL: @n17(
466; CHECK-NEXT:  begin:
467; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
468; CHECK:       then:
469; CHECK-NEXT:    [[Y:%.*]] = sub i8 0, [[X:%.*]]
470; CHECK-NEXT:    br label [[END:%.*]]
471; CHECK:       else:
472; CHECK-NEXT:    br label [[END]]
473; CHECK:       end:
474; CHECK-NEXT:    [[Z:%.*]] = phi i8 [ [[Y]], [[THEN]] ], [ -42, [[ELSE]] ]
475; CHECK-NEXT:    call void @use8(i8 [[Z]])
476; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[Z]]
477; CHECK-NEXT:    ret i8 [[N]]
478;
479begin:
480  br i1 %c, label %then, label %else
481then:
482  %y = sub i8 0, %x
483  br label %end
484else:
485  br label %end
486end:
487  %z = phi i8 [ %y, %then], [ -42, %else ]
488  call void @use8(i8 %z)
489  %n = sub i8 0, %z
490  ret i8 %n
491}
492define i8 @n19(i1 %c, i8 %x, i8 %y) {
493; CHECK-LABEL: @n19(
494; CHECK-NEXT:  begin:
495; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
496; CHECK:       then:
497; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[X:%.*]]
498; CHECK-NEXT:    br label [[END:%.*]]
499; CHECK:       else:
500; CHECK-NEXT:    br label [[END]]
501; CHECK:       end:
502; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[Z]], [[THEN]] ], [ [[Y:%.*]], [[ELSE]] ]
503; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[R]]
504; CHECK-NEXT:    ret i8 [[N]]
505;
506begin:
507  br i1 %c, label %then, label %else
508then:
509  %z = sub i8 0, %x
510  br label %end
511else:
512  br label %end
513end:
514  %r = phi i8 [ %z, %then], [ %y, %else ]
515  %n = sub i8 0, %r
516  ret i8 %n
517}
518define void @phi_with_duplicate_incoming_basic_blocks(i32 %x, i32 %y, i1 %should_lookup, i32 %z) {
519; CHECK-LABEL: @phi_with_duplicate_incoming_basic_blocks(
520; CHECK-NEXT:  entry:
521; CHECK-NEXT:    [[X_INC_NEG:%.*]] = xor i32 [[X:%.*]], -1
522; CHECK-NEXT:    br i1 [[SHOULD_LOOKUP:%.*]], label [[LOOKUP:%.*]], label [[LOOP:%.*]]
523; CHECK:       lookup:
524; CHECK-NEXT:    [[TO_LOOKUP:%.*]] = phi i32 [ [[Y:%.*]], [[ENTRY:%.*]] ], [ [[METAVAL_NEG:%.*]], [[LOOP]] ]
525; CHECK-NEXT:    switch i32 [[TO_LOOKUP]], label [[END:%.*]] [
526; CHECK-NEXT:      i32 0, label [[LOOP]]
527; CHECK-NEXT:      i32 42, label [[LOOP]]
528; CHECK-NEXT:    ]
529; CHECK:       loop:
530; CHECK-NEXT:    [[METAVAL_NEG]] = phi i32 [ [[X_INC_NEG]], [[LOOKUP]] ], [ [[X_INC_NEG]], [[LOOKUP]] ], [ -84, [[ENTRY]] ]
531; CHECK-NEXT:    [[REPEAT:%.*]] = call i1 @use32gen1(i32 [[METAVAL_NEG]])
532; CHECK-NEXT:    br i1 [[REPEAT]], label [[LOOKUP]], label [[END]]
533; CHECK:       end:
534; CHECK-NEXT:    ret void
535;
536entry:
537  %x_inc = add i32 %x, 1
538  br i1 %should_lookup, label %lookup, label %loop
539
540lookup:
541  %to_lookup = phi i32 [ %y, %entry ], [ %negated_metaval, %loop ]
542  switch i32 %to_lookup, label %end [
543  i32 0, label %loop
544  i32 42, label %loop
545  ]
546
547loop:
548  %metaval = phi i32 [ %x_inc, %lookup ], [ %x_inc, %lookup ], [ 84, %entry ]
549  %negated_metaval = sub i32 0, %metaval
550  %repeat = call i1 @use32gen1(i32 %negated_metaval)
551  br i1 %repeat, label %lookup, label %end
552
553end:
554  ret void
555}
556
557; truncation can be negated if it's operand can be negated
558define i8 @t20(i8 %x, i16 %y) {
559; CHECK-LABEL: @t20(
560; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i16 42, [[Y:%.*]]
561; CHECK-NEXT:    [[T1_NEG:%.*]] = trunc i16 [[T0_NEG]] to i8
562; CHECK-NEXT:    [[T2:%.*]] = add i8 [[X:%.*]], [[T1_NEG]]
563; CHECK-NEXT:    ret i8 [[T2]]
564;
565  %t0 = shl i16 -42, %y
566  %t1 = trunc i16 %t0 to i8
567  %t2 = sub i8 %x, %t1
568  ret i8 %t2
569}
570define i8 @n21(i8 %x, i16 %y) {
571; CHECK-LABEL: @n21(
572; CHECK-NEXT:    [[T0:%.*]] = shl i16 -42, [[Y:%.*]]
573; CHECK-NEXT:    [[T1:%.*]] = trunc i16 [[T0]] to i8
574; CHECK-NEXT:    call void @use8(i8 [[T1]])
575; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
576; CHECK-NEXT:    ret i8 [[T2]]
577;
578  %t0 = shl i16 -42, %y
579  %t1 = trunc i16 %t0 to i8
580  call void @use8(i8 %t1)
581  %t2 = sub i8 %x, %t1
582  ret i8 %t2
583}
584
585define i4 @negate_xor(i4 %x) {
586; CHECK-LABEL: @negate_xor(
587; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], -6
588; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1
589; CHECK-NEXT:    ret i4 [[O_NEG]]
590;
591  %o = xor i4 %x, 5
592  %r = sub i4 0, %o
593  ret i4 %r
594}
595
596define <2 x i4> @negate_xor_vec(<2 x i4> %x) {
597; CHECK-LABEL: @negate_xor_vec(
598; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[X:%.*]], <i4 -6, i4 5>
599; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[TMP1]], splat (i4 1)
600; CHECK-NEXT:    ret <2 x i4> [[O_NEG]]
601;
602  %o = xor <2 x i4> %x, <i4 5, i4 10>
603  %r = sub <2 x i4> zeroinitializer, %o
604  ret <2 x i4> %r
605}
606
607define i8 @negate_xor_use(i8 %x) {
608; CHECK-LABEL: @negate_xor_use(
609; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X:%.*]], 5
610; CHECK-NEXT:    call void @use8(i8 [[O]])
611; CHECK-NEXT:    [[R:%.*]] = sub i8 0, [[O]]
612; CHECK-NEXT:    ret i8 [[R]]
613;
614  %o = xor i8 %x, 5
615  call void @use8(i8 %o)
616  %r = sub i8 0, %o
617  ret i8 %r
618}
619
620define i4 @negate_shl_xor(i4 %x, i4 %y) {
621; CHECK-LABEL: @negate_shl_xor(
622; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], -6
623; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1
624; CHECK-NEXT:    [[S_NEG:%.*]] = shl i4 [[O_NEG]], [[Y:%.*]]
625; CHECK-NEXT:    ret i4 [[S_NEG]]
626;
627  %o = xor i4 %x, 5
628  %s = shl i4 %o, %y
629  %r = sub i4 0, %s
630  ret i4 %r
631}
632
633define i8 @negate_shl_not_uses(i8 %x, i8 %y) {
634; CHECK-LABEL: @negate_shl_not_uses(
635; CHECK-NEXT:    [[O_NEG:%.*]] = add i8 [[X:%.*]], 1
636; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X]], -1
637; CHECK-NEXT:    call void @use8(i8 [[O]])
638; CHECK-NEXT:    [[S_NEG:%.*]] = shl i8 [[O_NEG]], [[Y:%.*]]
639; CHECK-NEXT:    ret i8 [[S_NEG]]
640;
641  %o = xor i8 %x, -1
642  call void @use8(i8 %o)
643  %s = shl i8 %o, %y
644  %r = sub i8 0, %s
645  ret i8 %r
646}
647
648define <2 x i4> @negate_mul_not_uses_vec(<2 x i4> %x, <2 x i4> %y) {
649; CHECK-LABEL: @negate_mul_not_uses_vec(
650; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[X:%.*]], splat (i4 1)
651; CHECK-NEXT:    [[O:%.*]] = xor <2 x i4> [[X]], splat (i4 -1)
652; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[O]])
653; CHECK-NEXT:    [[S_NEG:%.*]] = mul <2 x i4> [[O_NEG]], [[Y:%.*]]
654; CHECK-NEXT:    ret <2 x i4> [[S_NEG]]
655;
656  %o = xor <2 x i4> %x, <i4 -1, i4 -1>
657  call void @use_v2i4(<2 x i4> %o)
658  %s = mul <2 x i4> %o, %y
659  %r = sub <2 x i4> zeroinitializer, %s
660  ret <2 x i4> %r
661}
662
663; signed division can be negated if divisor can be negated and is not 1/-1
664define i8 @negate_sdiv(i8 %x, i8 %y) {
665; CHECK-LABEL: @negate_sdiv(
666; CHECK-NEXT:    [[T0_NEG:%.*]] = sdiv i8 [[Y:%.*]], -42
667; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
668; CHECK-NEXT:    ret i8 [[T1]]
669;
670  %t0 = sdiv i8 %y, 42
671  %t1 = sub i8 %x, %t0
672  ret i8 %t1
673}
674define i8 @negate_sdiv_extrause(i8 %x, i8 %y) {
675; CHECK-LABEL: @negate_sdiv_extrause(
676; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y:%.*]], 42
677; CHECK-NEXT:    call void @use8(i8 [[T0]])
678; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
679; CHECK-NEXT:    ret i8 [[T1]]
680;
681  %t0 = sdiv i8 %y, 42
682  call void @use8(i8 %t0)
683  %t1 = sub i8 %x, %t0
684  ret i8 %t1
685}
686define i8 @negate_sdiv_extrause2(i8 %x, i8 %y) {
687; CHECK-LABEL: @negate_sdiv_extrause2(
688; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y:%.*]], 42
689; CHECK-NEXT:    call void @use8(i8 [[T0]])
690; CHECK-NEXT:    [[T1:%.*]] = sub nsw i8 0, [[T0]]
691; CHECK-NEXT:    ret i8 [[T1]]
692;
693  %t0 = sdiv i8 %y, 42
694  call void @use8(i8 %t0)
695  %t1 = sub i8 0, %t0
696  ret i8 %t1
697}
698
699; Right-shift sign bit smear is negatible.
700define i8 @negate_ashr(i8 %x, i8 %y) {
701; CHECK-LABEL: @negate_ashr(
702; CHECK-NEXT:    [[T0_NEG:%.*]] = lshr i8 [[Y:%.*]], 7
703; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
704; CHECK-NEXT:    ret i8 [[T1]]
705;
706  %t0 = ashr i8 %y, 7
707  %t1 = sub i8 %x, %t0
708  ret i8 %t1
709}
710define i8 @negate_lshr(i8 %x, i8 %y) {
711; CHECK-LABEL: @negate_lshr(
712; CHECK-NEXT:    [[T0_NEG:%.*]] = ashr i8 [[Y:%.*]], 7
713; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
714; CHECK-NEXT:    ret i8 [[T1]]
715;
716  %t0 = lshr i8 %y, 7
717  %t1 = sub i8 %x, %t0
718  ret i8 %t1
719}
720define i8 @negate_ashr_extrause(i8 %x, i8 %y) {
721; CHECK-LABEL: @negate_ashr_extrause(
722; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y:%.*]], 7
723; CHECK-NEXT:    call void @use8(i8 [[T0]])
724; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
725; CHECK-NEXT:    ret i8 [[T1]]
726;
727  %t0 = ashr i8 %y, 7
728  call void @use8(i8 %t0)
729  %t1 = sub i8 %x, %t0
730  ret i8 %t1
731}
732define i8 @negate_lshr_extrause(i8 %x, i8 %y) {
733; CHECK-LABEL: @negate_lshr_extrause(
734; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y:%.*]], 7
735; CHECK-NEXT:    call void @use8(i8 [[T0]])
736; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
737; CHECK-NEXT:    ret i8 [[T1]]
738;
739  %t0 = lshr i8 %y, 7
740  call void @use8(i8 %t0)
741  %t1 = sub i8 %x, %t0
742  ret i8 %t1
743}
744define i8 @negate_ashr_wrongshift(i8 %x, i8 %y) {
745; CHECK-LABEL: @negate_ashr_wrongshift(
746; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y:%.*]], 6
747; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
748; CHECK-NEXT:    ret i8 [[T1]]
749;
750  %t0 = ashr i8 %y, 6
751  %t1 = sub i8 %x, %t0
752  ret i8 %t1
753}
754define i8 @negate_lshr_wrongshift(i8 %x, i8 %y) {
755; CHECK-LABEL: @negate_lshr_wrongshift(
756; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y:%.*]], 6
757; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
758; CHECK-NEXT:    ret i8 [[T1]]
759;
760  %t0 = lshr i8 %y, 6
761  %t1 = sub i8 %x, %t0
762  ret i8 %t1
763}
764
765; *ext of i1 is always negatible
766define i8 @negate_sext(i8 %x, i1 %y) {
767; CHECK-LABEL: @negate_sext(
768; CHECK-NEXT:    [[T0_NEG:%.*]] = zext i1 [[Y:%.*]] to i8
769; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X:%.*]], [[T0_NEG]]
770; CHECK-NEXT:    ret i8 [[T1]]
771;
772  %t0 = sext i1 %y to i8
773  %t1 = sub i8 %x, %t0
774  ret i8 %t1
775}
776define i8 @negate_zext(i8 %x, i1 %y) {
777; CHECK-LABEL: @negate_zext(
778; CHECK-NEXT:    [[T0_NEG:%.*]] = sext i1 [[Y:%.*]] to i8
779; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X:%.*]], [[T0_NEG]]
780; CHECK-NEXT:    ret i8 [[T1]]
781;
782  %t0 = zext i1 %y to i8
783  %t1 = sub i8 %x, %t0
784  ret i8 %t1
785}
786define i8 @negate_sext_extrause(i8 %x, i1 %y) {
787; CHECK-LABEL: @negate_sext_extrause(
788; CHECK-NEXT:    [[T0:%.*]] = sext i1 [[Y:%.*]] to i8
789; CHECK-NEXT:    call void @use8(i8 [[T0]])
790; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
791; CHECK-NEXT:    ret i8 [[T1]]
792;
793  %t0 = sext i1 %y to i8
794  call void @use8(i8 %t0)
795  %t1 = sub i8 %x, %t0
796  ret i8 %t1
797}
798define i8 @negate_zext_extrause(i8 %x, i1 %y) {
799; CHECK-LABEL: @negate_zext_extrause(
800; CHECK-NEXT:    [[T0:%.*]] = zext i1 [[Y:%.*]] to i8
801; CHECK-NEXT:    call void @use8(i8 [[T0]])
802; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
803; CHECK-NEXT:    ret i8 [[T1]]
804;
805  %t0 = zext i1 %y to i8
806  call void @use8(i8 %t0)
807  %t1 = sub i8 %x, %t0
808  ret i8 %t1
809}
810define i8 @negate_sext_wrongwidth(i8 %x, i2 %y) {
811; CHECK-LABEL: @negate_sext_wrongwidth(
812; CHECK-NEXT:    [[T0:%.*]] = sext i2 [[Y:%.*]] to i8
813; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
814; CHECK-NEXT:    ret i8 [[T1]]
815;
816  %t0 = sext i2 %y to i8
817  %t1 = sub i8 %x, %t0
818  ret i8 %t1
819}
820define i8 @negate_zext_wrongwidth(i8 %x, i2 %y) {
821; CHECK-LABEL: @negate_zext_wrongwidth(
822; CHECK-NEXT:    [[T0:%.*]] = zext i2 [[Y:%.*]] to i8
823; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
824; CHECK-NEXT:    ret i8 [[T1]]
825;
826  %t0 = zext i2 %y to i8
827  %t1 = sub i8 %x, %t0
828  ret i8 %t1
829}
830
831define <2 x i4> @negate_shufflevector_oneinput_reverse(<2 x i4> %x, <2 x i4> %y) {
832; CHECK-LABEL: @negate_shufflevector_oneinput_reverse(
833; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
834; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> poison, <2 x i32> <i32 1, i32 0>
835; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y:%.*]]
836; CHECK-NEXT:    ret <2 x i4> [[T2]]
837;
838  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
839  %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 1, i32 0>
840  %t2 = sub <2 x i4> %y, %t1
841  ret <2 x i4> %t2
842}
843define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(<2 x i4> %x, <2 x i4> %y) {
844; CHECK-LABEL: @negate_shufflevector_oneinput_second_lane_is_undef(
845; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
846; CHECK-NEXT:    [[T11_NEG:%.*]] = insertelement <2 x i4> [[T0_NEG]], i4 undef, i64 1
847; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T11_NEG]], [[Y:%.*]]
848; CHECK-NEXT:    ret <2 x i4> [[T2]]
849;
850  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
851  %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 0, i32 2>
852  %t2 = sub <2 x i4> %y, %t1
853  ret <2 x i4> %t2
854}
855define <2 x i4> @negate_shufflevector_twoinputs(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
856; CHECK-LABEL: @negate_shufflevector_twoinputs(
857; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
858; CHECK-NEXT:    [[T1_NEG:%.*]] = add <2 x i4> [[Y:%.*]], <i4 poison, i4 1>
859; CHECK-NEXT:    [[T2_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> [[T1_NEG]], <2 x i32> <i32 0, i32 3>
860; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[Z:%.*]]
861; CHECK-NEXT:    ret <2 x i4> [[T3]]
862;
863  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
864  %t1 = xor <2 x i4> %y, <i4 -1, i4 -1>
865  %t2 = shufflevector <2 x i4> %t0, <2 x i4> %t1, <2 x i32> <i32 0, i32 3>
866  %t3 = sub <2 x i4> %z, %t2
867  ret <2 x i4> %t3
868}
869define <2 x i4> @negate_shufflevector_oneinput_extrause(<2 x i4> %x, <2 x i4> %y) {
870; CHECK-LABEL: @negate_shufflevector_oneinput_extrause(
871; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X:%.*]]
872; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> poison, <2 x i32> <i32 1, i32 0>
873; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T1]])
874; CHECK-NEXT:    [[T2:%.*]] = sub <2 x i4> [[Y:%.*]], [[T1]]
875; CHECK-NEXT:    ret <2 x i4> [[T2]]
876;
877  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
878  %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 1, i32 0>
879  call void @use_v2i4(<2 x i4> %t1)
880  %t2 = sub <2 x i4> %y, %t1
881  ret <2 x i4> %t2
882}
883
884; zext of non-negative can be negated
885; sext of non-positive can be negated
886define i16 @negation_of_zeroext_of_nonnegative(i8 %x) {
887; CHECK-LABEL: @negation_of_zeroext_of_nonnegative(
888; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
889; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -1
890; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]]
891; CHECK:       nonneg_bb:
892; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i16
893; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
894; CHECK-NEXT:    ret i16 [[T3]]
895; CHECK:       neg_bb:
896; CHECK-NEXT:    ret i16 0
897;
898  %t0 = sub i8 0, %x
899  %t1 = icmp sge i8 %t0, 0
900  br i1 %t1, label %nonneg_bb, label %neg_bb
901
902nonneg_bb:
903  %t2 = zext i8 %t0 to i16
904  %t3 = sub i16 0, %t2
905  ret i16 %t3
906
907neg_bb:
908  ret i16 0
909}
910define i16 @negation_of_zeroext_of_positive(i8 %x) {
911; CHECK-LABEL: @negation_of_zeroext_of_positive(
912; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
913; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], 0
914; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]]
915; CHECK:       nonneg_bb:
916; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i16
917; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
918; CHECK-NEXT:    ret i16 [[T3]]
919; CHECK:       neg_bb:
920; CHECK-NEXT:    ret i16 0
921;
922  %t0 = sub i8 0, %x
923  %t1 = icmp sgt i8 %t0, 0
924  br i1 %t1, label %nonneg_bb, label %neg_bb
925
926nonneg_bb:
927  %t2 = zext i8 %t0 to i16
928  %t3 = sub i16 0, %t2
929  ret i16 %t3
930
931neg_bb:
932  ret i16 0
933}
934define i16 @negation_of_signext_of_negative(i8 %x) {
935; CHECK-LABEL: @negation_of_signext_of_negative(
936; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
937; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 0
938; CHECK-NEXT:    br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]]
939; CHECK:       neg_bb:
940; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i16
941; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
942; CHECK-NEXT:    ret i16 [[T3]]
943; CHECK:       nonneg_bb:
944; CHECK-NEXT:    ret i16 0
945;
946  %t0 = sub i8 0, %x
947  %t1 = icmp slt i8 %t0, 0
948  br i1 %t1, label %neg_bb, label %nonneg_bb
949
950neg_bb:
951  %t2 = sext i8 %t0 to i16
952  %t3 = sub i16 0, %t2
953  ret i16 %t3
954
955nonneg_bb:
956  ret i16 0
957}
958define i16 @negation_of_signext_of_nonpositive(i8 %x) {
959; CHECK-LABEL: @negation_of_signext_of_nonpositive(
960; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
961; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 1
962; CHECK-NEXT:    br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]]
963; CHECK:       neg_bb:
964; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i16
965; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
966; CHECK-NEXT:    ret i16 [[T3]]
967; CHECK:       nonneg_bb:
968; CHECK-NEXT:    ret i16 0
969;
970  %t0 = sub i8 0, %x
971  %t1 = icmp sle i8 %t0, 0
972  br i1 %t1, label %neg_bb, label %nonneg_bb
973
974neg_bb:
975  %t2 = sext i8 %t0 to i16
976  %t3 = sub i16 0, %t2
977  ret i16 %t3
978
979nonneg_bb:
980  ret i16 0
981}
982define i16 @negation_of_signext_of_nonnegative__wrong_cast(i8 %x) {
983; CHECK-LABEL: @negation_of_signext_of_nonnegative__wrong_cast(
984; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
985; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -1
986; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]]
987; CHECK:       nonneg_bb:
988; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i16
989; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
990; CHECK-NEXT:    ret i16 [[T3]]
991; CHECK:       neg_bb:
992; CHECK-NEXT:    ret i16 0
993;
994  %t0 = sub i8 0, %x
995  %t1 = icmp sge i8 %t0, 0
996  br i1 %t1, label %nonneg_bb, label %neg_bb
997
998nonneg_bb:
999  %t2 = sext i8 %t0 to i16
1000  %t3 = sub i16 0, %t2
1001  ret i16 %t3
1002
1003neg_bb:
1004  ret i16 0
1005}
1006define i16 @negation_of_zeroext_of_negative_wrongcast(i8 %x) {
1007; CHECK-LABEL: @negation_of_zeroext_of_negative_wrongcast(
1008; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1009; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 0
1010; CHECK-NEXT:    br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]]
1011; CHECK:       neg_bb:
1012; CHECK-NEXT:    [[T2:%.*]] = zext i8 [[T0]] to i16
1013; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
1014; CHECK-NEXT:    ret i16 [[T3]]
1015; CHECK:       nonneg_bb:
1016; CHECK-NEXT:    ret i16 0
1017;
1018  %t0 = sub i8 0, %x
1019  %t1 = icmp slt i8 %t0, 0
1020  br i1 %t1, label %neg_bb, label %nonneg_bb
1021
1022neg_bb:
1023  %t2 = zext i8 %t0 to i16
1024  %t3 = sub i16 0, %t2
1025  ret i16 %t3
1026
1027nonneg_bb:
1028  ret i16 0
1029}
1030
1031; 'or' of 1 and operand with no lowest bit set is 'inc'
1032define i8 @negation_of_increment_via_or_with_no_common_bits_set(i8 %x, i8 %y) {
1033; CHECK-LABEL: @negation_of_increment_via_or_with_no_common_bits_set(
1034; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1
1035; CHECK-NEXT:    [[T1_NEG:%.*]] = xor i8 [[T0]], -1
1036; CHECK-NEXT:    [[T2:%.*]] = add i8 [[X:%.*]], [[T1_NEG]]
1037; CHECK-NEXT:    ret i8 [[T2]]
1038;
1039  %t0 = shl i8 %y, 1
1040  %t1 = or i8 %t0, 1
1041  %t2 = sub i8 %x, %t1
1042  ret i8 %t2
1043}
1044define i8 @negation_of_increment_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) {
1045; CHECK-LABEL: @negation_of_increment_via_or_with_no_common_bits_set_extrause(
1046; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1
1047; CHECK-NEXT:    [[T1:%.*]] = or disjoint i8 [[T0]], 1
1048; CHECK-NEXT:    call void @use8(i8 [[T1]])
1049; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1050; CHECK-NEXT:    ret i8 [[T2]]
1051;
1052  %t0 = shl i8 %y, 1
1053  %t1 = or i8 %t0, 1
1054  call void @use8(i8 %t1)
1055  %t2 = sub i8 %x, %t1
1056  ret i8 %t2
1057}
1058define i8 @negation_of_increment_via_or_common_bits_set(i8 %x, i8 %y) {
1059; CHECK-LABEL: @negation_of_increment_via_or_common_bits_set(
1060; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1
1061; CHECK-NEXT:    [[T1:%.*]] = or i8 [[T0]], 3
1062; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1063; CHECK-NEXT:    ret i8 [[T2]]
1064;
1065  %t0 = shl i8 %y, 1
1066  %t1 = or i8 %t0, 3
1067  %t2 = sub i8 %x, %t1
1068  ret i8 %t2
1069}
1070
1071define i8 @negation_of_increment_via_or_disjoint(i8 %x, i8 %y) {
1072; CHECK-LABEL: @negation_of_increment_via_or_disjoint(
1073; CHECK-NEXT:    [[T1_NEG:%.*]] = xor i8 [[Y:%.*]], -1
1074; CHECK-NEXT:    [[T2:%.*]] = add i8 [[X:%.*]], [[T1_NEG]]
1075; CHECK-NEXT:    ret i8 [[T2]]
1076;
1077  %t1 = or disjoint i8 %y, 1
1078  %t2 = sub i8 %x, %t1
1079  ret i8 %t2
1080}
1081
1082; 'or' of operands with no common bits set is 'add'
1083define i8 @add_via_or_with_no_common_bits_set(i8 %x, i8 %y) {
1084; CHECK-LABEL: @add_via_or_with_no_common_bits_set(
1085; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
1086; CHECK-NEXT:    call void @use8(i8 [[T0]])
1087; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Y]], 2
1088; CHECK-NEXT:    [[T2_NEG:%.*]] = add i8 [[T1_NEG]], -3
1089; CHECK-NEXT:    [[T3:%.*]] = add i8 [[T2_NEG]], [[X:%.*]]
1090; CHECK-NEXT:    ret i8 [[T3]]
1091;
1092  %t0 = sub i8 0, %y
1093  call void @use8(i8 %t0)
1094  %t1 = shl i8 %t0, 2
1095  %t2 = or i8 %t1, 3
1096  %t3 = sub i8 %x, %t2
1097  ret i8 %t3
1098}
1099define i8 @add_via_or_with_common_bit_maybe_set(i8 %x, i8 %y) {
1100; CHECK-LABEL: @add_via_or_with_common_bit_maybe_set(
1101; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
1102; CHECK-NEXT:    call void @use8(i8 [[T0]])
1103; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 2
1104; CHECK-NEXT:    [[T2:%.*]] = or i8 [[T1]], 4
1105; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X:%.*]], [[T2]]
1106; CHECK-NEXT:    ret i8 [[T3]]
1107;
1108  %t0 = sub i8 0, %y
1109  call void @use8(i8 %t0)
1110  %t1 = shl i8 %t0, 2
1111  %t2 = or i8 %t1, 4
1112  %t3 = sub i8 %x, %t2
1113  ret i8 %t3
1114}
1115define i8 @add_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) {
1116; CHECK-LABEL: @add_via_or_with_no_common_bits_set_extrause(
1117; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
1118; CHECK-NEXT:    call void @use8(i8 [[T0]])
1119; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 2
1120; CHECK-NEXT:    [[T2:%.*]] = or disjoint i8 [[T1]], 3
1121; CHECK-NEXT:    call void @use8(i8 [[T2]])
1122; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X:%.*]], [[T2]]
1123; CHECK-NEXT:    ret i8 [[T3]]
1124;
1125  %t0 = sub i8 0, %y
1126  call void @use8(i8 %t0)
1127  %t1 = shl i8 %t0, 2
1128  %t2 = or i8 %t1, 3
1129  call void @use8(i8 %t2)
1130  %t3 = sub i8 %x, %t2
1131  ret i8 %t3
1132}
1133
1134; `extractelement` is negatible if source operand is negatible.
1135define i4 @negate_extractelement(<2 x i4> %x, i32 %y, i4 %z) {
1136; CHECK-LABEL: @negate_extractelement(
1137; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X:%.*]]
1138; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]])
1139; CHECK-NEXT:    [[T1_NEG:%.*]] = extractelement <2 x i4> [[X]], i32 [[Y:%.*]]
1140; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]]
1141; CHECK-NEXT:    ret i4 [[T2]]
1142;
1143  %t0 = sub <2 x i4> zeroinitializer, %x
1144  call void @use_v2i4(<2 x i4> %t0)
1145  %t1 = extractelement <2 x i4> %t0, i32 %y
1146  %t2 = sub i4 %z, %t1
1147  ret i4 %t2
1148}
1149define i4 @negate_extractelement_extrause(<2 x i4> %x, i32 %y, i4 %z) {
1150; CHECK-LABEL: @negate_extractelement_extrause(
1151; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X:%.*]]
1152; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]])
1153; CHECK-NEXT:    [[T1:%.*]] = extractelement <2 x i4> [[T0]], i32 [[Y:%.*]]
1154; CHECK-NEXT:    call void @use4(i4 [[T1]])
1155; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]]
1156; CHECK-NEXT:    ret i4 [[T2]]
1157;
1158  %t0 = sub <2 x i4> zeroinitializer, %x
1159  call void @use_v2i4(<2 x i4> %t0)
1160  %t1 = extractelement <2 x i4> %t0, i32 %y
1161  call void @use4(i4 %t1)
1162  %t2 = sub i4 %z, %t1
1163  ret i4 %t2
1164}
1165
1166; `insertelement` is negatible if both source vector and element-to-be-inserted are negatible.
1167define <2 x i4> @negate_insertelement(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
1168; CHECK-LABEL: @negate_insertelement(
1169; CHECK-NEXT:    [[T2_NEG:%.*]] = insertelement <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]]
1170; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[B:%.*]]
1171; CHECK-NEXT:    ret <2 x i4> [[T3]]
1172;
1173  %t0 = sub <2 x i4> zeroinitializer, %src
1174  %t1 = sub i4 zeroinitializer, %a
1175  %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x
1176  %t3 = sub <2 x i4> %b, %t2
1177  ret <2 x i4> %t3
1178}
1179define <2 x i4> @negate_insertelement_extrause(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
1180; CHECK-LABEL: @negate_insertelement_extrause(
1181; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC:%.*]]
1182; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A:%.*]]
1183; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[T1]], i32 [[X:%.*]]
1184; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T2]])
1185; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]]
1186; CHECK-NEXT:    ret <2 x i4> [[T3]]
1187;
1188  %t0 = sub <2 x i4> zeroinitializer, %src
1189  %t1 = sub i4 zeroinitializer, %a
1190  %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x
1191  call void @use_v2i4(<2 x i4> %t2)
1192  %t3 = sub <2 x i4> %b, %t2
1193  ret <2 x i4> %t3
1194}
1195define <2 x i4> @negate_insertelement_nonnegatible_base(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
1196; CHECK-LABEL: @negate_insertelement_nonnegatible_base(
1197; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A:%.*]]
1198; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[SRC:%.*]], i4 [[T1]], i32 [[X:%.*]]
1199; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]]
1200; CHECK-NEXT:    ret <2 x i4> [[T3]]
1201;
1202  %t1 = sub i4 zeroinitializer, %a
1203  %t2 = insertelement <2 x i4> %src, i4 %t1, i32 %x
1204  %t3 = sub <2 x i4> %b, %t2
1205  ret <2 x i4> %t3
1206}
1207define <2 x i4> @negate_insertelement_nonnegatible_insert(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
1208; CHECK-LABEL: @negate_insertelement_nonnegatible_insert(
1209; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC:%.*]]
1210; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[A:%.*]], i32 [[X:%.*]]
1211; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]]
1212; CHECK-NEXT:    ret <2 x i4> [[T3]]
1213;
1214  %t0 = sub <2 x i4> zeroinitializer, %src
1215  %t2 = insertelement <2 x i4> %t0, i4 %a, i32 %x
1216  %t3 = sub <2 x i4> %b, %t2
1217  ret <2 x i4> %t3
1218}
1219
1220; left-shift by constant can always be negated
1221define i8 @negate_left_shift_by_constant_prefer_keeping_shl(i8 %x, i8 %y, i8 %z) {
1222; CHECK-LABEL: @negate_left_shift_by_constant_prefer_keeping_shl(
1223; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
1224; CHECK-NEXT:    call void @use8(i8 [[T0]])
1225; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Z]], 4
1226; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
1227; CHECK-NEXT:    ret i8 [[T2]]
1228;
1229  %t0 = sub i8 0, %z
1230  call void @use8(i8 %t0)
1231  %t1 = shl i8 %t0, 4
1232  %t2 = sub i8 %x, %t1
1233  ret i8 %t2
1234}
1235define i8 @negate_left_shift_by_constant_prefer_keeping_shl_extrause(i8 %x, i8 %y, i8 %z) {
1236; CHECK-LABEL: @negate_left_shift_by_constant_prefer_keeping_shl_extrause(
1237; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
1238; CHECK-NEXT:    call void @use8(i8 [[T0]])
1239; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 4
1240; CHECK-NEXT:    call void @use8(i8 [[T1]])
1241; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1242; CHECK-NEXT:    ret i8 [[T2]]
1243;
1244  %t0 = sub i8 0, %z
1245  call void @use8(i8 %t0)
1246  %t1 = shl i8 %t0, 4
1247  call void @use8(i8 %t1)
1248  %t2 = sub i8 %x, %t1
1249  ret i8 %t2
1250}
1251define i8 @negate_left_shift_by_constant(i8 %x, i8 %y, i8 %z, i8 %k) {
1252; CHECK-LABEL: @negate_left_shift_by_constant(
1253; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]]
1254; CHECK-NEXT:    call void @use8(i8 [[T0]])
1255; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 4
1256; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1257; CHECK-NEXT:    ret i8 [[T2]]
1258;
1259  %t0 = sub i8 %k, %z
1260  call void @use8(i8 %t0)
1261  %t1 = shl i8 %t0, 4
1262  %t2 = sub i8 %x, %t1
1263  ret i8 %t2
1264}
1265define i8 @negate_left_shift_by_constant_extrause(i8 %x, i8 %y, i8 %z, i8 %k) {
1266; CHECK-LABEL: @negate_left_shift_by_constant_extrause(
1267; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]]
1268; CHECK-NEXT:    call void @use8(i8 [[T0]])
1269; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 4
1270; CHECK-NEXT:    call void @use8(i8 [[T1]])
1271; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1272; CHECK-NEXT:    ret i8 [[T2]]
1273;
1274  %t0 = sub i8 %k, %z
1275  call void @use8(i8 %t0)
1276  %t1 = shl i8 %t0, 4
1277  call void @use8(i8 %t1)
1278  %t2 = sub i8 %x, %t1
1279  ret i8 %t2
1280}
1281
1282; `add` with single negatible operand is still negatible
1283define i8 @negate_add_with_single_negatible_operand(i8 %x, i8 %y) {
1284; CHECK-LABEL: @negate_add_with_single_negatible_operand(
1285; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X:%.*]]
1286; CHECK-NEXT:    ret i8 [[T1]]
1287;
1288  %t0 = add i8 %x, 42
1289  %t1 = sub i8 0, %t0
1290  ret i8 %t1
1291}
1292; do so even if we are two levels deep
1293define i8 @negate_add_with_single_negatible_operand_depth2(i8 %x, i8 %y) {
1294; CHECK-LABEL: @negate_add_with_single_negatible_operand_depth2(
1295; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 -21, [[X:%.*]]
1296; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[T0_NEG]], [[Y:%.*]]
1297; CHECK-NEXT:    ret i8 [[T1_NEG]]
1298;
1299  %t0 = add i8 %x, 21
1300  %t1 = mul i8 %t0, %y
1301  %t2 = sub i8 0, %t1
1302  ret i8 %t2
1303}
1304
1305define i8 @negate_add_with_single_negatible_operand_extrause(i8 %x, i8 %y) {
1306; CHECK-LABEL: @negate_add_with_single_negatible_operand_extrause(
1307; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42
1308; CHECK-NEXT:    call void @use8(i8 [[T0]])
1309; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X]]
1310; CHECK-NEXT:    ret i8 [[T1]]
1311;
1312  %t0 = add i8 %x, 42
1313  call void @use8(i8 %t0)
1314  %t1 = sub i8 0, %t0
1315  ret i8 %t1
1316}
1317; But don't do this if that means just sinking the negation.
1318define i8 @negate_add_with_single_negatible_operand_non_negation(i8 %x, i8 %y) {
1319; CHECK-LABEL: @negate_add_with_single_negatible_operand_non_negation(
1320; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42
1321; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Y:%.*]], [[T0]]
1322; CHECK-NEXT:    ret i8 [[T1]]
1323;
1324  %t0 = add i8 %x, 42
1325  %t1 = sub i8 %y, %t0
1326  ret i8 %t1
1327}
1328
1329; abs/nabs can be negated
1330define i8 @negate_abs(i8 %x, i8 %y) {
1331; CHECK-LABEL: @negate_abs(
1332; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1333; CHECK-NEXT:    call void @use8(i8 [[T0]])
1334; CHECK-NEXT:    [[T2:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)
1335; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[Y:%.*]], [[T2]]
1336; CHECK-NEXT:    ret i8 [[T3]]
1337;
1338  %t0 = sub i8 0, %x
1339  call void @use8(i8 %t0)
1340  %t1 = icmp slt i8 %x, 0
1341  %t2 = select i1 %t1, i8 %t0, i8 %x, !prof !0
1342  %t3 = sub i8 %y, %t2
1343  ret i8 %t3
1344}
1345define i8 @negate_nabs(i8 %x, i8 %y) {
1346; CHECK-LABEL: @negate_nabs(
1347; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1348; CHECK-NEXT:    call void @use8(i8 [[T0]])
1349; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)
1350; CHECK-NEXT:    [[T3:%.*]] = add i8 [[Y:%.*]], [[TMP1]]
1351; CHECK-NEXT:    ret i8 [[T3]]
1352;
1353  %t0 = sub i8 0, %x
1354  call void @use8(i8 %t0)
1355  %t1 = icmp slt i8 %x, 0
1356  %t2 = select i1 %t1, i8 %x, i8 %t0, !prof !0
1357  %t3 = sub i8 %y, %t2
1358  ret i8 %t3
1359}
1360
1361; And in general, if hands of select are known to be negation of each other,
1362; we can negate the select
1363define i8 @negate_select_of_op_vs_negated_op(i8 %x, i8 %y, i1 %c) {
1364; CHECK-LABEL: @negate_select_of_op_vs_negated_op(
1365; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1366; CHECK-NEXT:    call void @use8(i8 [[T0]])
1367; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[T0]], !prof [[PROF0:![0-9]+]]
1368; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y:%.*]]
1369; CHECK-NEXT:    ret i8 [[T2]]
1370;
1371  %t0 = sub i8 0, %x
1372  call void @use8(i8 %t0)
1373  %t1 = select i1 %c, i8 %t0, i8 %x, !prof !0
1374  %t2 = sub i8 %y, %t1
1375  ret i8 %t2
1376}
1377
1378define i8 @negate_select_of_op_vs_negated_op_nsw(i8 %x, i8 %y, i1 %c) {
1379; CHECK-LABEL: @negate_select_of_op_vs_negated_op_nsw(
1380; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1381; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[T0]]
1382; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y:%.*]]
1383; CHECK-NEXT:    ret i8 [[T2]]
1384;
1385  %t0 = sub nsw i8 0, %x
1386  %t1 = select i1 %c, i8 %t0, i8 %x
1387  %t2 = sub i8 %y, %t1
1388  ret i8 %t2
1389}
1390
1391define i8 @negate_select_of_op_vs_negated_op_nsw_commuted(i8 %x, i8 %y, i1 %c) {
1392; CHECK-LABEL: @negate_select_of_op_vs_negated_op_nsw_commuted(
1393; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1394; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[T0]], i8 [[X]]
1395; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y:%.*]]
1396; CHECK-NEXT:    ret i8 [[T2]]
1397;
1398  %t0 = sub nsw i8 0, %x
1399  %t1 = select i1 %c, i8 %x, i8 %t0
1400  %t2 = sub i8 %y, %t1
1401  ret i8 %t2
1402}
1403
1404define i8 @negate_select_of_op_vs_negated_op_nsw_xyyx(i8 %x, i8 %y, i8 %z, i1 %c) {
1405; CHECK-LABEL: @negate_select_of_op_vs_negated_op_nsw_xyyx(
1406; CHECK-NEXT:    [[SUB1:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
1407; CHECK-NEXT:    [[SUB2:%.*]] = sub i8 [[Y]], [[X]]
1408; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[SUB2]], i8 [[SUB1]]
1409; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Z:%.*]]
1410; CHECK-NEXT:    ret i8 [[T2]]
1411;
1412  %sub1 = sub nsw i8 %x, %y
1413  %sub2 = sub nsw i8 %y, %x
1414  %t1 = select i1 %c, i8 %sub1, i8 %sub2
1415  %t2 = sub i8 %z, %t1
1416  ret i8 %t2
1417}
1418
1419define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) {
1420; CHECK-LABEL: @dont_negate_ordinary_select(
1421; CHECK-NEXT:    [[T0:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]
1422; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Z:%.*]], [[T0]]
1423; CHECK-NEXT:    ret i8 [[T1]]
1424;
1425  %t0 = select i1 %c, i8 %x, i8 %y
1426  %t1 = sub i8 %z, %t0
1427  ret i8 %t1
1428}
1429
1430define <2 x i32> @negate_select_of_negation_poison(<2 x i1> %c, <2 x i32> %x) {
1431; CHECK-LABEL: @negate_select_of_negation_poison(
1432; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i32> <i32 0, i32 poison>, [[X:%.*]]
1433; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i32> [[NEG]], <2 x i32> [[X]]
1434; CHECK-NEXT:    [[NEG2:%.*]] = sub <2 x i32> zeroinitializer, [[SEL]]
1435; CHECK-NEXT:    ret <2 x i32> [[NEG2]]
1436;
1437  %neg = sub <2 x i32> <i32 0, i32 poison>, %x
1438  %sel = select <2 x i1> %c, <2 x i32> %neg, <2 x i32> %x
1439  %neg2 = sub <2 x i32> zeroinitializer, %sel
1440  ret <2 x i32> %neg2
1441}
1442
1443; Freeze is transparent as far as negation is concerned
1444define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
1445; CHECK-LABEL: @negate_freeze(
1446; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i4 [[Y:%.*]], [[X:%.*]]
1447; CHECK-NEXT:    [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]]
1448; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]]
1449; CHECK-NEXT:    ret i4 [[T2]]
1450;
1451  %t0 = sub i4 %x, %y
1452  %t1 = freeze i4 %t0
1453  %t2 = sub i4 %z, %t1
1454  ret i4 %t2
1455}
1456define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) {
1457; CHECK-LABEL: @negate_freeze_extrause(
1458; CHECK-NEXT:    [[T0:%.*]] = sub i4 [[X:%.*]], [[Y:%.*]]
1459; CHECK-NEXT:    [[T1:%.*]] = freeze i4 [[T0]]
1460; CHECK-NEXT:    call void @use4(i4 [[T1]])
1461; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]]
1462; CHECK-NEXT:    ret i4 [[T2]]
1463;
1464  %t0 = sub i4 %x, %y
1465  %t1 = freeze i4 %t0
1466  call void @use4(i4 %t1)
1467  %t2 = sub i4 %z, %t1
1468  ret i4 %t2
1469}
1470
1471; Due to the InstCombine's worklist management, there are no guarantees that
1472; each instruction we'll encounter has been visited by InstCombine already.
1473; In particular, most importantly for us, that means we have to canonicalize
1474; constants to RHS ourselves, since that is helpful sometimes.
1475; This used to cause an endless combine loop.
1476define void @noncanonical_mul_with_constant_as_first_operand() {
1477; CHECK-LABEL: @noncanonical_mul_with_constant_as_first_operand(
1478; CHECK-NEXT:  entry:
1479; CHECK-NEXT:    br label [[IF_END:%.*]]
1480; CHECK:       if.end:
1481; CHECK-NEXT:    br label [[IF_END]]
1482;
1483entry:
1484  br label %if.end
1485
1486if.end:
1487  %e.0 = phi i32 [ undef, %entry ], [ %div, %if.end ]
1488  %conv = trunc i32 %e.0 to i16
1489  %mul.i = mul nsw i16 -1, %conv
1490  %conv1 = sext i16 %mul.i to i32
1491  %div = sub nsw i32 0, %conv1
1492  br label %if.end
1493}
1494
1495; This would infinite loop because we failed to match a
1496; vector constant with constant expression elements as
1497; a constant expression.
1498
1499@g = external hidden global [1 x [1 x double]]
1500
1501define <1 x i64> @PR56601(<1 x i64> %x, <1 x i64> %y) {
1502; CHECK-LABEL: @PR56601(
1503; CHECK-NEXT:    [[M1:%.*]] = mul nsw <1 x i64> [[X:%.*]], splat (i64 42)
1504; CHECK-NEXT:    [[M2:%.*]] = mul nsw <1 x i64> [[Y:%.*]], splat (i64 12)
1505; CHECK-NEXT:    [[A1:%.*]] = add <1 x i64> [[M1]], <i64 add (i64 ptrtoint (ptr @g to i64), i64 -4)>
1506; CHECK-NEXT:    [[A2:%.*]] = add <1 x i64> [[M2]], <i64 add (i64 ptrtoint (ptr @g to i64), i64 -3)>
1507; CHECK-NEXT:    [[R:%.*]] = sub <1 x i64> [[A1]], [[A2]]
1508; CHECK-NEXT:    ret <1 x i64> [[R]]
1509;
1510  %m1 = mul nsw <1 x i64> %x, <i64 42>
1511  %m2 = mul nsw <1 x i64> %y, <i64 12>
1512  %a1 = add <1 x i64> %m1, <i64 add (i64 ptrtoint (ptr @g to i64), i64 -4)>
1513  %a2 = add <1 x i64> %m2, <i64 add (i64 ptrtoint (ptr @g to i64), i64 -3)>
1514  %r = sub <1 x i64> %a1, %a2
1515  ret <1 x i64> %r
1516}
1517
1518; CHECK: !0 = !{!"branch_weights", i32 40, i32 1}
1519!0 = !{!"branch_weights", i32 40, i32 1}
1520