Revert "[InstCombine] Support gep nuw in icmp folds" (#118698)
[llvm-project.git] / llvm / test / Transforms / InstCombine / sub-of-negatible.ll
blob871cf37976d89d31bd38106e6a92223bdbd99d65
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use4(i4)
5 declare void @use8(i8)
6 declare void @use_v2i4(<2 x i4>)
7 declare i1 @use32gen1(i32)
9 ; Constant can be freely negated.
10 define i8 @t0(i8 %x) {
11 ; CHECK-LABEL: @t0(
12 ; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42
13 ; CHECK-NEXT:    ret i8 [[T0]]
15   %t0 = sub i8 %x, -42
16   ret i8 %t0
19 ; Negation can be negated for free
20 define 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]]
27   %t0 = sub i8 0, %y
28   call void @use8(i8 %t0)
29   %t1 = sub i8 %x, %t0
30   ret i8 %t1
33 ; Shift-left can be negated if all uses can be updated
34 define 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]]
40   %t0 = shl i8 -42, %y
41   %t1 = sub i8 %x, %t0
42   ret i8 %t1
44 define 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]]
51   %t0 = shl i8 -42, %y
52   call void @use8(i8 %t0)
53   %t1 = sub i8 %x, %t0
54   ret i8 %t1
56 define 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]]
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
70 define 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]]
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
87 ; Select can be negated if all it's operands can be negated and all the users of select can be updated
88 define 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]]
94   %t0 = select i1 %y, i8 -42, i8 44
95   %t1 = sub i8 %x, %t0
96   ret i8 %t1
99 define 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]]
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
112 define i32 @PR52261(i1 %b) {
113 ; CHECK-LABEL: @PR52261(
114 ; CHECK-NEXT:    ret i32 2
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
122 define 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]]
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
134 define 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]]
140   %t0 = select i1 %y, i8 -42, i8 %z
141   %t1 = sub i8 %x, %t0
142   ret i8 %t1
144 define 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]]
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
158 define 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]]
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
170 define 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]]
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
185 ; Subtraction can be negated by swapping its operands.
186 ; x - (y - z) -> x - y + z -> x + (z - y)
187 define 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]]
192   %t0 = sub i8 %y, %x
193   %t1 = sub i8 0, %t0
194   ret i8 %t1
197 define 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]]
204   %t0 = sub i8 %y, %x
205   call void @use8(i8 %t0)
206   %t1 = sub i8 0, %t0
207   ret i8 %t1
210 define 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]]
215   %s = sub i8 42, %x
216   %r = sub i8 0, %s
217   ret i8 %r
220 define 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]]
227   %s = sub i8 42, %x
228   call void @use8(i8 %s)
229   %r = sub i8 0, %s
230   ret i8 %r
233 define 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]]
238   %s = sub i8 42, %x
239   %r = sub i8 11, %s
240   ret i8 %r
243 define 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]]
250   %s = sub i8 42, %x
251   call void @use8(i8 %s)
252   %r = sub i8 11, %s
253   ret i8 %r
256 define 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]]
262   %s = sub i8 42, %x
263   %r = sub i8 %y, %s
264   ret i8 %r
267 define 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]]
274   %s = sub i8 42, %x
275   call void @use8(i8 %s)
276   %r = sub i8 %y, %s
277   ret i8 %r
280 ; Addition can be negated if both operands can be negated
281 ; x - (y + z) -> x - y - z -> x + ((-y) + (-z)))
282 define 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]]
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
300 define 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]]
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
314 define 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]]
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
336 define 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]]
341   %s = add i8 %x, 42
342   %r = sub i8 0, %s
343   ret i8 %r
346 define 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]]
353   %s = add i8 %x, 42
354   call void @use8(i8 %s)
355   %r = sub i8 0, %s
356   ret i8 %r
359 define 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]]
364   %s = add i8 %x, 42
365   %r = sub i8 11, %s
366   ret i8 %r
369 define 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]]
376   %s = add i8 %x, 42
377   call void @use8(i8 %s)
378   %r = sub i8 11, %s
379   ret i8 %r
382 define 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]]
388   %s = add i8 %x, 42
389   %r = sub i8 %y, %s
390   ret i8 %r
393 define 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]]
400   %s = add i8 %x, 42
401   call void @use8(i8 %s)
402   %r = sub i8 %y, %s
403   ret i8 %r
406 ; Multiplication can be negated if either one of operands can be negated
407 ; x - (y * z) -> x + ((-y) * z) or  x + ((-z) * y)
408 define 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]]
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
422 define 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]]
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
439 ; Phi can be negated if all incoming values can be negated
440 define 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]]
452 begin:
453   br i1 %c, label %then, label %else
454 then:
455   %y = sub i8 0, %x
456   br label %end
457 else:
458   br label %end
459 end:
460   %z = phi i8 [ %y, %then], [ -42, %else ]
461   %n = sub i8 0, %z
462   ret i8 %n
464 define 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]]
479 begin:
480   br i1 %c, label %then, label %else
481 then:
482   %y = sub i8 0, %x
483   br label %end
484 else:
485   br label %end
486 end:
487   %z = phi i8 [ %y, %then], [ -42, %else ]
488   call void @use8(i8 %z)
489   %n = sub i8 0, %z
490   ret i8 %n
492 define 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]]
506 begin:
507   br i1 %c, label %then, label %else
508 then:
509   %z = sub i8 0, %x
510   br label %end
511 else:
512   br label %end
513 end:
514   %r = phi i8 [ %z, %then], [ %y, %else ]
515   %n = sub i8 0, %r
516   ret i8 %n
518 define 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
536 entry:
537   %x_inc = add i32 %x, 1
538   br i1 %should_lookup, label %lookup, label %loop
540 lookup:
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   ]
547 loop:
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
553 end:
554   ret void
557 ; truncation can be negated if it's operand can be negated
558 define 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]]
565   %t0 = shl i16 -42, %y
566   %t1 = trunc i16 %t0 to i8
567   %t2 = sub i8 %x, %t1
568   ret i8 %t2
570 define 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]]
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
585 define 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]]
591   %o = xor i4 %x, 5
592   %r = sub i4 0, %o
593   ret i4 %r
596 define <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]]
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
607 define 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]]
614   %o = xor i8 %x, 5
615   call void @use8(i8 %o)
616   %r = sub i8 0, %o
617   ret i8 %r
620 define 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]]
627   %o = xor i4 %x, 5
628   %s = shl i4 %o, %y
629   %r = sub i4 0, %s
630   ret i4 %r
633 define 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]]
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
648 define <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]]
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
663 ; signed division can be negated if divisor can be negated and is not 1/-1
664 define 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]]
670   %t0 = sdiv i8 %y, 42
671   %t1 = sub i8 %x, %t0
672   ret i8 %t1
674 define 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]]
681   %t0 = sdiv i8 %y, 42
682   call void @use8(i8 %t0)
683   %t1 = sub i8 %x, %t0
684   ret i8 %t1
686 define 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]]
693   %t0 = sdiv i8 %y, 42
694   call void @use8(i8 %t0)
695   %t1 = sub i8 0, %t0
696   ret i8 %t1
699 ; Right-shift sign bit smear is negatible.
700 define 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]]
706   %t0 = ashr i8 %y, 7
707   %t1 = sub i8 %x, %t0
708   ret i8 %t1
710 define 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]]
716   %t0 = lshr i8 %y, 7
717   %t1 = sub i8 %x, %t0
718   ret i8 %t1
720 define 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]]
727   %t0 = ashr i8 %y, 7
728   call void @use8(i8 %t0)
729   %t1 = sub i8 %x, %t0
730   ret i8 %t1
732 define 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]]
739   %t0 = lshr i8 %y, 7
740   call void @use8(i8 %t0)
741   %t1 = sub i8 %x, %t0
742   ret i8 %t1
744 define 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]]
750   %t0 = ashr i8 %y, 6
751   %t1 = sub i8 %x, %t0
752   ret i8 %t1
754 define 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]]
760   %t0 = lshr i8 %y, 6
761   %t1 = sub i8 %x, %t0
762   ret i8 %t1
765 ; *ext of i1 is always negatible
766 define 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]]
772   %t0 = sext i1 %y to i8
773   %t1 = sub i8 %x, %t0
774   ret i8 %t1
776 define 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]]
782   %t0 = zext i1 %y to i8
783   %t1 = sub i8 %x, %t0
784   ret i8 %t1
786 define 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]]
793   %t0 = sext i1 %y to i8
794   call void @use8(i8 %t0)
795   %t1 = sub i8 %x, %t0
796   ret i8 %t1
798 define 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]]
805   %t0 = zext i1 %y to i8
806   call void @use8(i8 %t0)
807   %t1 = sub i8 %x, %t0
808   ret i8 %t1
810 define 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]]
816   %t0 = sext i2 %y to i8
817   %t1 = sub i8 %x, %t0
818   ret i8 %t1
820 define 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]]
826   %t0 = zext i2 %y to i8
827   %t1 = sub i8 %x, %t0
828   ret i8 %t1
831 define <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]]
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
843 define <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]]
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
855 define <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]]
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
869 define <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]]
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
884 ; zext of non-negative can be negated
885 ; sext of non-positive can be negated
886 define 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
898   %t0 = sub i8 0, %x
899   %t1 = icmp sge i8 %t0, 0
900   br i1 %t1, label %nonneg_bb, label %neg_bb
902 nonneg_bb:
903   %t2 = zext i8 %t0 to i16
904   %t3 = sub i16 0, %t2
905   ret i16 %t3
907 neg_bb:
908   ret i16 0
910 define 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
922   %t0 = sub i8 0, %x
923   %t1 = icmp sgt i8 %t0, 0
924   br i1 %t1, label %nonneg_bb, label %neg_bb
926 nonneg_bb:
927   %t2 = zext i8 %t0 to i16
928   %t3 = sub i16 0, %t2
929   ret i16 %t3
931 neg_bb:
932   ret i16 0
934 define 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
946   %t0 = sub i8 0, %x
947   %t1 = icmp slt i8 %t0, 0
948   br i1 %t1, label %neg_bb, label %nonneg_bb
950 neg_bb:
951   %t2 = sext i8 %t0 to i16
952   %t3 = sub i16 0, %t2
953   ret i16 %t3
955 nonneg_bb:
956   ret i16 0
958 define 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
970   %t0 = sub i8 0, %x
971   %t1 = icmp sle i8 %t0, 0
972   br i1 %t1, label %neg_bb, label %nonneg_bb
974 neg_bb:
975   %t2 = sext i8 %t0 to i16
976   %t3 = sub i16 0, %t2
977   ret i16 %t3
979 nonneg_bb:
980   ret i16 0
982 define 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
994   %t0 = sub i8 0, %x
995   %t1 = icmp sge i8 %t0, 0
996   br i1 %t1, label %nonneg_bb, label %neg_bb
998 nonneg_bb:
999   %t2 = sext i8 %t0 to i16
1000   %t3 = sub i16 0, %t2
1001   ret i16 %t3
1003 neg_bb:
1004   ret i16 0
1006 define 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
1018   %t0 = sub i8 0, %x
1019   %t1 = icmp slt i8 %t0, 0
1020   br i1 %t1, label %neg_bb, label %nonneg_bb
1022 neg_bb:
1023   %t2 = zext i8 %t0 to i16
1024   %t3 = sub i16 0, %t2
1025   ret i16 %t3
1027 nonneg_bb:
1028   ret i16 0
1031 ; 'or' of 1 and operand with no lowest bit set is 'inc'
1032 define 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]]
1039   %t0 = shl i8 %y, 1
1040   %t1 = or i8 %t0, 1
1041   %t2 = sub i8 %x, %t1
1042   ret i8 %t2
1044 define 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]]
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
1058 define 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]]
1065   %t0 = shl i8 %y, 1
1066   %t1 = or i8 %t0, 3
1067   %t2 = sub i8 %x, %t1
1068   ret i8 %t2
1071 define 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]]
1077   %t1 = or disjoint i8 %y, 1
1078   %t2 = sub i8 %x, %t1
1079   ret i8 %t2
1082 ; 'or' of operands with no common bits set is 'add'
1083 define 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]]
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
1099 define 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]]
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
1115 define 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]]
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
1134 ; `extractelement` is negatible if source operand is negatible.
1135 define 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]]
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
1149 define 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]]
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
1166 ; `insertelement` is negatible if both source vector and element-to-be-inserted are negatible.
1167 define <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]]
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
1179 define <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]]
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
1195 define <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]]
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
1207 define <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]]
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
1220 ; left-shift by constant can always be negated
1221 define 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]]
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
1235 define 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]]
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
1251 define 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]]
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
1265 define 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]]
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
1282 ; `add` with single negatible operand is still negatible
1283 define 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]]
1288   %t0 = add i8 %x, 42
1289   %t1 = sub i8 0, %t0
1290   ret i8 %t1
1292 ; do so even if we are two levels deep
1293 define 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]]
1299   %t0 = add i8 %x, 21
1300   %t1 = mul i8 %t0, %y
1301   %t2 = sub i8 0, %t1
1302   ret i8 %t2
1305 define 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]]
1312   %t0 = add i8 %x, 42
1313   call void @use8(i8 %t0)
1314   %t1 = sub i8 0, %t0
1315   ret i8 %t1
1317 ; But don't do this if that means just sinking the negation.
1318 define 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]]
1324   %t0 = add i8 %x, 42
1325   %t1 = sub i8 %y, %t0
1326   ret i8 %t1
1329 ; abs/nabs can be negated
1330 define 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]]
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
1345 define 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]]
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
1361 ; And in general, if hands of select are known to be negation of each other,
1362 ; we can negate the select
1363 define 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]]
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
1378 define 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]]
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
1391 define 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]]
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
1404 define 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]]
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
1419 define 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]]
1425   %t0 = select i1 %c, i8 %x, i8 %y
1426   %t1 = sub i8 %z, %t0
1427   ret i8 %t1
1430 define <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]]
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
1443 ; Freeze is transparent as far as negation is concerned
1444 define 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]]
1451   %t0 = sub i4 %x, %y
1452   %t1 = freeze i4 %t0
1453   %t2 = sub i4 %z, %t1
1454   ret i4 %t2
1456 define 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]]
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
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.
1476 define 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]]
1483 entry:
1484   br label %if.end
1486 if.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
1495 ; This would infinite loop because we failed to match a
1496 ; vector constant with constant expression elements as
1497 ; a constant expression.
1499 @g = external hidden global [1 x [1 x double]]
1501 define <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]]
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
1518 ; CHECK: !0 = !{!"branch_weights", i32 40, i32 1}
1519 !0 = !{!"branch_weights", i32 40, i32 1}