[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / sub-of-negatible.ll
blob63a13a0e9902e6b23b1a810efe5710e4f4e1120f
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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
98 define i8 @n4(i8 %x, i1 %y) {
99 ; CHECK-LABEL: @n4(
100 ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 44
101 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
102 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
103 ; CHECK-NEXT:    ret i8 [[T1]]
105   %t0 = select i1 %y, i8 -42, i8 44
106   call void @use8(i8 %t0)
107   %t1 = sub i8 %x, %t0
108   ret i8 %t1
110 define i8 @n5(i8 %x, i1 %y, i8 %z) {
111 ; CHECK-LABEL: @n5(
112 ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 [[Z:%.*]]
113 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
114 ; CHECK-NEXT:    ret i8 [[T1]]
116   %t0 = select i1 %y, i8 -42, i8 %z
117   %t1 = sub i8 %x, %t0
118   ret i8 %t1
120 define i8 @t6(i8 %x, i1 %y, i8 %z) {
121 ; CHECK-LABEL: @t6(
122 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
123 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
124 ; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 42, i8 [[Z]]
125 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
126 ; CHECK-NEXT:    ret i8 [[T2]]
128   %t0 = sub i8 0, %z
129   call void @use8(i8 %t0)
130   %t1 = select i1 %y, i8 -42, i8 %t0
131   %t2 = sub i8 %x, %t1
132   ret i8 %t2
134 define i8 @t7(i8 %x, i1 %y, i8 %z) {
135 ; CHECK-LABEL: @t7(
136 ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i8 -1, [[Z:%.*]]
137 ; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0_NEG]]
138 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
139 ; CHECK-NEXT:    ret i8 [[T2]]
141   %t0 = shl i8 1, %z
142   %t1 = select i1 %y, i8 0, i8 %t0
143   %t2 = sub i8 %x, %t1
144   ret i8 %t2
146 define i8 @n8(i8 %x, i1 %y, i8 %z) {
147 ; CHECK-LABEL: @n8(
148 ; CHECK-NEXT:    [[T0:%.*]] = shl i8 1, [[Z:%.*]]
149 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
150 ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]]
151 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
152 ; CHECK-NEXT:    ret i8 [[T2]]
154   %t0 = shl i8 1, %z
155   call void @use8(i8 %t0)
156   %t1 = select i1 %y, i8 0, i8 %t0
157   %t2 = sub i8 %x, %t1
158   ret i8 %t2
161 ; Subtraction can be negated by swapping its operands.
162 ; x - (y - z) -> x - y + z -> x + (z - y)
163 define i8 @t9(i8 %x, i8 %y) {
164 ; CHECK-LABEL: @t9(
165 ; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]]
166 ; CHECK-NEXT:    ret i8 [[T0_NEG]]
168   %t0 = sub i8 %y, %x
169   %t1 = sub i8 0, %t0
170   ret i8 %t1
173 define i8 @n10(i8 %x, i8 %y, i8 %z) {
174 ; CHECK-LABEL: @n10(
175 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]]
176 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
177 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[T0]]
178 ; CHECK-NEXT:    ret i8 [[T1]]
180   %t0 = sub i8 %y, %x
181   call void @use8(i8 %t0)
182   %t1 = sub i8 0, %t0
183   ret i8 %t1
186 define i8 @neg_of_sub_from_constant(i8 %x) {
187 ; CHECK-LABEL: @neg_of_sub_from_constant(
188 ; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42
189 ; CHECK-NEXT:    ret i8 [[S_NEG]]
191   %s = sub i8 42, %x
192   %r = sub i8 0, %s
193   ret i8 %r
196 define i8 @neg_of_sub_from_constant_multi_use(i8 %x) {
197 ; CHECK-LABEL: @neg_of_sub_from_constant_multi_use(
198 ; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42
199 ; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]]
200 ; CHECK-NEXT:    call void @use8(i8 [[S]])
201 ; CHECK-NEXT:    ret i8 [[S_NEG]]
203   %s = sub i8 42, %x
204   call void @use8(i8 %s)
205   %r = sub i8 0, %s
206   ret i8 %r
209 define i8 @sub_from_constant_of_sub_from_constant(i8 %x) {
210 ; CHECK-LABEL: @sub_from_constant_of_sub_from_constant(
211 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[X:%.*]], -31
212 ; CHECK-NEXT:    ret i8 [[R]]
214   %s = sub i8 42, %x
215   %r = sub i8 11, %s
216   ret i8 %r
219 define i8 @sub_from_constant_of_sub_from_constant_multi_use(i8 %x) {
220 ; CHECK-LABEL: @sub_from_constant_of_sub_from_constant_multi_use(
221 ; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X:%.*]]
222 ; CHECK-NEXT:    call void @use8(i8 [[S]])
223 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[X]], -31
224 ; CHECK-NEXT:    ret i8 [[R]]
226   %s = sub i8 42, %x
227   call void @use8(i8 %s)
228   %r = sub i8 11, %s
229   ret i8 %r
232 define i8 @sub_from_variable_of_sub_from_constant(i8 %x, i8 %y) {
233 ; CHECK-LABEL: @sub_from_variable_of_sub_from_constant(
234 ; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42
235 ; CHECK-NEXT:    [[R:%.*]] = add i8 [[S_NEG]], [[Y:%.*]]
236 ; CHECK-NEXT:    ret i8 [[R]]
238   %s = sub i8 42, %x
239   %r = sub i8 %y, %s
240   ret i8 %r
243 define i8 @sub_from_variable_of_sub_from_constant_multi_use(i8 %x, i8 %y) {
244 ; CHECK-LABEL: @sub_from_variable_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:%.*]] = sub i8 [[Y:%.*]], [[S]]
248 ; CHECK-NEXT:    ret i8 [[R]]
250   %s = sub i8 42, %x
251   call void @use8(i8 %s)
252   %r = sub i8 %y, %s
253   ret i8 %r
256 ; Addition can be negated if both operands can be negated
257 ; x - (y + z) -> x - y - z -> x + ((-y) + (-z)))
258 define i8 @t12(i8 %x, i8 %y, i8 %z) {
259 ; CHECK-LABEL: @t12(
260 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
261 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
262 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]]
263 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
264 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]
265 ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[X:%.*]]
266 ; CHECK-NEXT:    ret i8 [[T3]]
268   %t0 = sub i8 0, %y
269   call void @use8(i8 %t0)
270   %t1 = sub i8 0, %z
271   call void @use8(i8 %t1)
272   %t2 = add i8 %t0, %t1
273   %t3 = sub i8 %x, %t2
274   ret i8 %t3
276 define i8 @n13(i8 %x, i8 %y, i8 %z) {
277 ; CHECK-LABEL: @n13(
278 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
279 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
280 ; CHECK-NEXT:    [[T1_NEG:%.*]] = sub i8 [[Y]], [[Z:%.*]]
281 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
282 ; CHECK-NEXT:    ret i8 [[T2]]
284   %t0 = sub i8 0, %y
285   call void @use8(i8 %t0)
286   %t1 = add i8 %t0, %z
287   %t2 = sub i8 %x, %t1
288   ret i8 %t2
290 define i8 @n14(i8 %x, i8 %y, i8 %z) {
291 ; CHECK-LABEL: @n14(
292 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
293 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
294 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]]
295 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
296 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]
297 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 0, [[TMP1]]
298 ; CHECK-NEXT:    call void @use8(i8 [[T2]])
299 ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[X:%.*]]
300 ; CHECK-NEXT:    ret i8 [[T3]]
302   %t0 = sub i8 0, %y
303   call void @use8(i8 %t0)
304   %t1 = sub i8 0, %z
305   call void @use8(i8 %t1)
306   %t2 = add i8 %t0, %t1
307   call void @use8(i8 %t2)
308   %t3 = sub i8 %x, %t2
309   ret i8 %t3
312 define i8 @neg_of_add_with_constant(i8 %x) {
313 ; CHECK-LABEL: @neg_of_add_with_constant(
314 ; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X:%.*]]
315 ; CHECK-NEXT:    ret i8 [[R]]
317   %s = add i8 %x, 42
318   %r = sub i8 0, %s
319   ret i8 %r
322 define i8 @neg_of_add_with_constant_multi_use(i8 %x) {
323 ; CHECK-LABEL: @neg_of_add_with_constant_multi_use(
324 ; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42
325 ; CHECK-NEXT:    call void @use8(i8 [[S]])
326 ; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X]]
327 ; CHECK-NEXT:    ret i8 [[R]]
329   %s = add i8 %x, 42
330   call void @use8(i8 %s)
331   %r = sub i8 0, %s
332   ret i8 %r
335 define i8 @sub_from_constant_of_add_with_constant(i8 %x) {
336 ; CHECK-LABEL: @sub_from_constant_of_add_with_constant(
337 ; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X:%.*]]
338 ; CHECK-NEXT:    ret i8 [[R]]
340   %s = add i8 %x, 42
341   %r = sub i8 11, %s
342   ret i8 %r
345 define i8 @sub_from_constant_of_add_with_constant_multi_use(i8 %x) {
346 ; CHECK-LABEL: @sub_from_constant_of_add_with_constant_multi_use(
347 ; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42
348 ; CHECK-NEXT:    call void @use8(i8 [[S]])
349 ; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X]]
350 ; CHECK-NEXT:    ret i8 [[R]]
352   %s = add i8 %x, 42
353   call void @use8(i8 %s)
354   %r = sub i8 11, %s
355   ret i8 %r
358 define i8 @sub_from_variable_of_add_with_constant(i8 %x, i8 %y) {
359 ; CHECK-LABEL: @sub_from_variable_of_add_with_constant(
360 ; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42
361 ; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y:%.*]], [[S]]
362 ; CHECK-NEXT:    ret i8 [[R]]
364   %s = add i8 %x, 42
365   %r = sub i8 %y, %s
366   ret i8 %r
369 define i8 @sub_from_variable_of_add_with_constant_multi_use(i8 %x, i8 %y) {
370 ; CHECK-LABEL: @sub_from_variable_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 [[Y:%.*]], [[S]]
374 ; CHECK-NEXT:    ret i8 [[R]]
376   %s = add i8 %x, 42
377   call void @use8(i8 %s)
378   %r = sub i8 %y, %s
379   ret i8 %r
382 ; Multiplication can be negated if either one of operands can be negated
383 ; x - (y * z) -> x + ((-y) * z) or  x + ((-z) * y)
384 define i8 @t15(i8 %x, i8 %y, i8 %z) {
385 ; CHECK-LABEL: @t15(
386 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
387 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
388 ; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[Y]], [[Z:%.*]]
389 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
390 ; CHECK-NEXT:    ret i8 [[T2]]
392   %t0 = sub i8 0, %y
393   call void @use8(i8 %t0)
394   %t1 = mul i8 %t0, %z
395   %t2 = sub i8 %x, %t1
396   ret i8 %t2
398 define i8 @n16(i8 %x, i8 %y, i8 %z) {
399 ; CHECK-LABEL: @n16(
400 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
401 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
402 ; CHECK-NEXT:    [[T1:%.*]] = mul i8 [[T0]], [[Z:%.*]]
403 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
404 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
405 ; CHECK-NEXT:    ret i8 [[T2]]
407   %t0 = sub i8 0, %y
408   call void @use8(i8 %t0)
409   %t1 = mul i8 %t0, %z
410   call void @use8(i8 %t1)
411   %t2 = sub i8 %x, %t1
412   ret i8 %t2
415 ; Phi can be negated if all incoming values can be negated
416 define i8 @t16(i1 %c, i8 %x) {
417 ; CHECK-LABEL: @t16(
418 ; CHECK-NEXT:  begin:
419 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
420 ; CHECK:       then:
421 ; CHECK-NEXT:    br label [[END:%.*]]
422 ; CHECK:       else:
423 ; CHECK-NEXT:    br label [[END]]
424 ; CHECK:       end:
425 ; CHECK-NEXT:    [[Z_NEG:%.*]] = phi i8 [ [[X:%.*]], [[THEN]] ], [ 42, [[ELSE]] ]
426 ; CHECK-NEXT:    ret i8 [[Z_NEG]]
428 begin:
429   br i1 %c, label %then, label %else
430 then:
431   %y = sub i8 0, %x
432   br label %end
433 else:
434   br label %end
435 end:
436   %z = phi i8 [ %y, %then], [ -42, %else ]
437   %n = sub i8 0, %z
438   ret i8 %n
440 define i8 @n17(i1 %c, i8 %x) {
441 ; CHECK-LABEL: @n17(
442 ; CHECK-NEXT:  begin:
443 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
444 ; CHECK:       then:
445 ; CHECK-NEXT:    [[Y:%.*]] = sub i8 0, [[X:%.*]]
446 ; CHECK-NEXT:    br label [[END:%.*]]
447 ; CHECK:       else:
448 ; CHECK-NEXT:    br label [[END]]
449 ; CHECK:       end:
450 ; CHECK-NEXT:    [[Z:%.*]] = phi i8 [ [[Y]], [[THEN]] ], [ -42, [[ELSE]] ]
451 ; CHECK-NEXT:    call void @use8(i8 [[Z]])
452 ; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[Z]]
453 ; CHECK-NEXT:    ret i8 [[N]]
455 begin:
456   br i1 %c, label %then, label %else
457 then:
458   %y = sub i8 0, %x
459   br label %end
460 else:
461   br label %end
462 end:
463   %z = phi i8 [ %y, %then], [ -42, %else ]
464   call void @use8(i8 %z)
465   %n = sub i8 0, %z
466   ret i8 %n
468 define i8 @n19(i1 %c, i8 %x, i8 %y) {
469 ; CHECK-LABEL: @n19(
470 ; CHECK-NEXT:  begin:
471 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
472 ; CHECK:       then:
473 ; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[X:%.*]]
474 ; CHECK-NEXT:    br label [[END:%.*]]
475 ; CHECK:       else:
476 ; CHECK-NEXT:    br label [[END]]
477 ; CHECK:       end:
478 ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[Z]], [[THEN]] ], [ [[Y:%.*]], [[ELSE]] ]
479 ; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[R]]
480 ; CHECK-NEXT:    ret i8 [[N]]
482 begin:
483   br i1 %c, label %then, label %else
484 then:
485   %z = sub i8 0, %x
486   br label %end
487 else:
488   br label %end
489 end:
490   %r = phi i8 [ %z, %then], [ %y, %else ]
491   %n = sub i8 0, %r
492   ret i8 %n
494 define void @phi_with_duplicate_incoming_basic_blocks(i32 %x, i32 %y, i1 %should_lookup, i32 %z) {
495 ; CHECK-LABEL: @phi_with_duplicate_incoming_basic_blocks(
496 ; CHECK-NEXT:  entry:
497 ; CHECK-NEXT:    [[X_INC_NEG:%.*]] = xor i32 [[X:%.*]], -1
498 ; CHECK-NEXT:    br i1 [[SHOULD_LOOKUP:%.*]], label [[LOOKUP:%.*]], label [[LOOP:%.*]]
499 ; CHECK:       lookup:
500 ; CHECK-NEXT:    [[TO_LOOKUP:%.*]] = phi i32 [ [[Y:%.*]], [[ENTRY:%.*]] ], [ [[METAVAL_NEG:%.*]], [[LOOP]] ]
501 ; CHECK-NEXT:    switch i32 [[TO_LOOKUP]], label [[END:%.*]] [
502 ; CHECK-NEXT:    i32 0, label [[LOOP]]
503 ; CHECK-NEXT:    i32 42, label [[LOOP]]
504 ; CHECK-NEXT:    ]
505 ; CHECK:       loop:
506 ; CHECK-NEXT:    [[METAVAL_NEG]] = phi i32 [ [[X_INC_NEG]], [[LOOKUP]] ], [ [[X_INC_NEG]], [[LOOKUP]] ], [ -84, [[ENTRY]] ]
507 ; CHECK-NEXT:    [[REPEAT:%.*]] = call i1 @use32gen1(i32 [[METAVAL_NEG]])
508 ; CHECK-NEXT:    br i1 [[REPEAT]], label [[LOOKUP]], label [[END]]
509 ; CHECK:       end:
510 ; CHECK-NEXT:    ret void
512 entry:
513   %x_inc = add i32 %x, 1
514   br i1 %should_lookup, label %lookup, label %loop
516 lookup:
517   %to_lookup = phi i32 [ %y, %entry ], [ %negated_metaval, %loop ]
518   switch i32 %to_lookup, label %end [
519   i32 0, label %loop
520   i32 42, label %loop
521   ]
523 loop:
524   %metaval = phi i32 [ %x_inc, %lookup ], [ %x_inc, %lookup ], [ 84, %entry ]
525   %negated_metaval = sub i32 0, %metaval
526   %repeat = call i1 @use32gen1(i32 %negated_metaval)
527   br i1 %repeat, label %lookup, label %end
529 end:
530   ret void
533 ; truncation can be negated if it's operand can be negated
534 define i8 @t20(i8 %x, i16 %y) {
535 ; CHECK-LABEL: @t20(
536 ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i16 42, [[Y:%.*]]
537 ; CHECK-NEXT:    [[T1_NEG:%.*]] = trunc i16 [[T0_NEG]] to i8
538 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
539 ; CHECK-NEXT:    ret i8 [[T2]]
541   %t0 = shl i16 -42, %y
542   %t1 = trunc i16 %t0 to i8
543   %t2 = sub i8 %x, %t1
544   ret i8 %t2
546 define i8 @n21(i8 %x, i16 %y) {
547 ; CHECK-LABEL: @n21(
548 ; CHECK-NEXT:    [[T0:%.*]] = shl i16 -42, [[Y:%.*]]
549 ; CHECK-NEXT:    [[T1:%.*]] = trunc i16 [[T0]] to i8
550 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
551 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
552 ; CHECK-NEXT:    ret i8 [[T2]]
554   %t0 = shl i16 -42, %y
555   %t1 = trunc i16 %t0 to i8
556   call void @use8(i8 %t1)
557   %t2 = sub i8 %x, %t1
558   ret i8 %t2
561 define i4 @negate_xor(i4 %x) {
562 ; CHECK-LABEL: @negate_xor(
563 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], -6
564 ; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1
565 ; CHECK-NEXT:    ret i4 [[O_NEG]]
567   %o = xor i4 %x, 5
568   %r = sub i4 0, %o
569   ret i4 %r
572 define <2 x i4> @negate_xor_vec(<2 x i4> %x) {
573 ; CHECK-LABEL: @negate_xor_vec(
574 ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[X:%.*]], <i4 -6, i4 5>
575 ; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[TMP1]], <i4 1, i4 1>
576 ; CHECK-NEXT:    ret <2 x i4> [[O_NEG]]
578   %o = xor <2 x i4> %x, <i4 5, i4 10>
579   %r = sub <2 x i4> zeroinitializer, %o
580   ret <2 x i4> %r
583 define i8 @negate_xor_use(i8 %x) {
584 ; CHECK-LABEL: @negate_xor_use(
585 ; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X:%.*]], 5
586 ; CHECK-NEXT:    call void @use8(i8 [[O]])
587 ; CHECK-NEXT:    [[R:%.*]] = sub i8 0, [[O]]
588 ; CHECK-NEXT:    ret i8 [[R]]
590   %o = xor i8 %x, 5
591   call void @use8(i8 %o)
592   %r = sub i8 0, %o
593   ret i8 %r
596 define i4 @negate_shl_xor(i4 %x, i4 %y) {
597 ; CHECK-LABEL: @negate_shl_xor(
598 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], -6
599 ; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1
600 ; CHECK-NEXT:    [[S_NEG:%.*]] = shl i4 [[O_NEG]], [[Y:%.*]]
601 ; CHECK-NEXT:    ret i4 [[S_NEG]]
603   %o = xor i4 %x, 5
604   %s = shl i4 %o, %y
605   %r = sub i4 0, %s
606   ret i4 %r
609 define i8 @negate_shl_not_uses(i8 %x, i8 %y) {
610 ; CHECK-LABEL: @negate_shl_not_uses(
611 ; CHECK-NEXT:    [[O_NEG:%.*]] = add i8 [[X:%.*]], 1
612 ; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X]], -1
613 ; CHECK-NEXT:    call void @use8(i8 [[O]])
614 ; CHECK-NEXT:    [[S_NEG:%.*]] = shl i8 [[O_NEG]], [[Y:%.*]]
615 ; CHECK-NEXT:    ret i8 [[S_NEG]]
617   %o = xor i8 %x, -1
618   call void @use8(i8 %o)
619   %s = shl i8 %o, %y
620   %r = sub i8 0, %s
621   ret i8 %r
624 define <2 x i4> @negate_mul_not_uses_vec(<2 x i4> %x, <2 x i4> %y) {
625 ; CHECK-LABEL: @negate_mul_not_uses_vec(
626 ; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[X:%.*]], <i4 1, i4 1>
627 ; CHECK-NEXT:    [[O:%.*]] = xor <2 x i4> [[X]], <i4 -1, i4 -1>
628 ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[O]])
629 ; CHECK-NEXT:    [[S_NEG:%.*]] = mul <2 x i4> [[O_NEG]], [[Y:%.*]]
630 ; CHECK-NEXT:    ret <2 x i4> [[S_NEG]]
632   %o = xor <2 x i4> %x, <i4 -1, i4 -1>
633   call void @use_v2i4(<2 x i4> %o)
634   %s = mul <2 x i4> %o, %y
635   %r = sub <2 x i4> zeroinitializer, %s
636   ret <2 x i4> %r
639 ; signed division can be negated if divisor can be negated and is not 1/-1
640 define i8 @negate_sdiv(i8 %x, i8 %y) {
641 ; CHECK-LABEL: @negate_sdiv(
642 ; CHECK-NEXT:    [[T0_NEG:%.*]] = sdiv i8 [[Y:%.*]], -42
643 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
644 ; CHECK-NEXT:    ret i8 [[T1]]
646   %t0 = sdiv i8 %y, 42
647   %t1 = sub i8 %x, %t0
648   ret i8 %t1
650 define i8 @negate_sdiv_extrause(i8 %x, i8 %y) {
651 ; CHECK-LABEL: @negate_sdiv_extrause(
652 ; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y:%.*]], 42
653 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
654 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
655 ; CHECK-NEXT:    ret i8 [[T1]]
657   %t0 = sdiv i8 %y, 42
658   call void @use8(i8 %t0)
659   %t1 = sub i8 %x, %t0
660   ret i8 %t1
662 define i8 @negate_sdiv_extrause2(i8 %x, i8 %y) {
663 ; CHECK-LABEL: @negate_sdiv_extrause2(
664 ; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y:%.*]], 42
665 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
666 ; CHECK-NEXT:    [[T1:%.*]] = sub nsw i8 0, [[T0]]
667 ; CHECK-NEXT:    ret i8 [[T1]]
669   %t0 = sdiv i8 %y, 42
670   call void @use8(i8 %t0)
671   %t1 = sub i8 0, %t0
672   ret i8 %t1
675 ; Right-shift sign bit smear is negatible.
676 define i8 @negate_ashr(i8 %x, i8 %y) {
677 ; CHECK-LABEL: @negate_ashr(
678 ; CHECK-NEXT:    [[T0_NEG:%.*]] = lshr i8 [[Y:%.*]], 7
679 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
680 ; CHECK-NEXT:    ret i8 [[T1]]
682   %t0 = ashr i8 %y, 7
683   %t1 = sub i8 %x, %t0
684   ret i8 %t1
686 define i8 @negate_lshr(i8 %x, i8 %y) {
687 ; CHECK-LABEL: @negate_lshr(
688 ; CHECK-NEXT:    [[T0_NEG:%.*]] = ashr i8 [[Y:%.*]], 7
689 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
690 ; CHECK-NEXT:    ret i8 [[T1]]
692   %t0 = lshr i8 %y, 7
693   %t1 = sub i8 %x, %t0
694   ret i8 %t1
696 define i8 @negate_ashr_extrause(i8 %x, i8 %y) {
697 ; CHECK-LABEL: @negate_ashr_extrause(
698 ; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y:%.*]], 7
699 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
700 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
701 ; CHECK-NEXT:    ret i8 [[T1]]
703   %t0 = ashr i8 %y, 7
704   call void @use8(i8 %t0)
705   %t1 = sub i8 %x, %t0
706   ret i8 %t1
708 define i8 @negate_lshr_extrause(i8 %x, i8 %y) {
709 ; CHECK-LABEL: @negate_lshr_extrause(
710 ; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y:%.*]], 7
711 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
712 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
713 ; CHECK-NEXT:    ret i8 [[T1]]
715   %t0 = lshr i8 %y, 7
716   call void @use8(i8 %t0)
717   %t1 = sub i8 %x, %t0
718   ret i8 %t1
720 define i8 @negate_ashr_wrongshift(i8 %x, i8 %y) {
721 ; CHECK-LABEL: @negate_ashr_wrongshift(
722 ; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y:%.*]], 6
723 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
724 ; CHECK-NEXT:    ret i8 [[T1]]
726   %t0 = ashr i8 %y, 6
727   %t1 = sub i8 %x, %t0
728   ret i8 %t1
730 define i8 @negate_lshr_wrongshift(i8 %x, i8 %y) {
731 ; CHECK-LABEL: @negate_lshr_wrongshift(
732 ; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y:%.*]], 6
733 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
734 ; CHECK-NEXT:    ret i8 [[T1]]
736   %t0 = lshr i8 %y, 6
737   %t1 = sub i8 %x, %t0
738   ret i8 %t1
741 ; *ext of i1 is always negatible
742 define i8 @negate_sext(i8 %x, i1 %y) {
743 ; CHECK-LABEL: @negate_sext(
744 ; CHECK-NEXT:    [[T0_NEG:%.*]] = zext i1 [[Y:%.*]] to i8
745 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
746 ; CHECK-NEXT:    ret i8 [[T1]]
748   %t0 = sext i1 %y to i8
749   %t1 = sub i8 %x, %t0
750   ret i8 %t1
752 define i8 @negate_zext(i8 %x, i1 %y) {
753 ; CHECK-LABEL: @negate_zext(
754 ; CHECK-NEXT:    [[T0_NEG:%.*]] = sext i1 [[Y:%.*]] to i8
755 ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]]
756 ; CHECK-NEXT:    ret i8 [[T1]]
758   %t0 = zext i1 %y to i8
759   %t1 = sub i8 %x, %t0
760   ret i8 %t1
762 define i8 @negate_sext_extrause(i8 %x, i1 %y) {
763 ; CHECK-LABEL: @negate_sext_extrause(
764 ; CHECK-NEXT:    [[T0:%.*]] = sext i1 [[Y:%.*]] to i8
765 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
766 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
767 ; CHECK-NEXT:    ret i8 [[T1]]
769   %t0 = sext i1 %y to i8
770   call void @use8(i8 %t0)
771   %t1 = sub i8 %x, %t0
772   ret i8 %t1
774 define i8 @negate_zext_extrause(i8 %x, i1 %y) {
775 ; CHECK-LABEL: @negate_zext_extrause(
776 ; CHECK-NEXT:    [[T0:%.*]] = zext i1 [[Y:%.*]] to i8
777 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
778 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
779 ; CHECK-NEXT:    ret i8 [[T1]]
781   %t0 = zext i1 %y to i8
782   call void @use8(i8 %t0)
783   %t1 = sub i8 %x, %t0
784   ret i8 %t1
786 define i8 @negate_sext_wrongwidth(i8 %x, i2 %y) {
787 ; CHECK-LABEL: @negate_sext_wrongwidth(
788 ; CHECK-NEXT:    [[T0:%.*]] = sext i2 [[Y:%.*]] to i8
789 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
790 ; CHECK-NEXT:    ret i8 [[T1]]
792   %t0 = sext i2 %y to i8
793   %t1 = sub i8 %x, %t0
794   ret i8 %t1
796 define i8 @negate_zext_wrongwidth(i8 %x, i2 %y) {
797 ; CHECK-LABEL: @negate_zext_wrongwidth(
798 ; CHECK-NEXT:    [[T0:%.*]] = zext i2 [[Y:%.*]] to i8
799 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]]
800 ; CHECK-NEXT:    ret i8 [[T1]]
802   %t0 = zext i2 %y to i8
803   %t1 = sub i8 %x, %t0
804   ret i8 %t1
807 define <2 x i4> @negate_shufflevector_oneinput_reverse(<2 x i4> %x, <2 x i4> %y) {
808 ; CHECK-LABEL: @negate_shufflevector_oneinput_reverse(
809 ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
810 ; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> undef, <2 x i32> <i32 1, i32 0>
811 ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y:%.*]]
812 ; CHECK-NEXT:    ret <2 x i4> [[T2]]
814   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
815   %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 1, i32 0>
816   %t2 = sub <2 x i4> %y, %t1
817   ret <2 x i4> %t2
819 define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(<2 x i4> %x, <2 x i4> %y) {
820 ; CHECK-LABEL: @negate_shufflevector_oneinput_second_lane_is_undef(
821 ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
822 ; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> undef, <2 x i32> <i32 0, i32 undef>
823 ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y:%.*]]
824 ; CHECK-NEXT:    ret <2 x i4> [[T2]]
826   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
827   %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 0, i32 2>
828   %t2 = sub <2 x i4> %y, %t1
829   ret <2 x i4> %t2
831 define <2 x i4> @negate_shufflevector_twoinputs(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {
832 ; CHECK-LABEL: @negate_shufflevector_twoinputs(
833 ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]]
834 ; CHECK-NEXT:    [[T1_NEG:%.*]] = add <2 x i4> [[Y:%.*]], <i4 poison, i4 1>
835 ; CHECK-NEXT:    [[T2_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> [[T1_NEG]], <2 x i32> <i32 0, i32 3>
836 ; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[Z:%.*]]
837 ; CHECK-NEXT:    ret <2 x i4> [[T3]]
839   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
840   %t1 = xor <2 x i4> %y, <i4 -1, i4 -1>
841   %t2 = shufflevector <2 x i4> %t0, <2 x i4> %t1, <2 x i32> <i32 0, i32 3>
842   %t3 = sub <2 x i4> %z, %t2
843   ret <2 x i4> %t3
845 define <2 x i4> @negate_shufflevector_oneinput_extrause(<2 x i4> %x, <2 x i4> %y) {
846 ; CHECK-LABEL: @negate_shufflevector_oneinput_extrause(
847 ; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X:%.*]]
848 ; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> undef, <2 x i32> <i32 1, i32 0>
849 ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T1]])
850 ; CHECK-NEXT:    [[T2:%.*]] = sub <2 x i4> [[Y:%.*]], [[T1]]
851 ; CHECK-NEXT:    ret <2 x i4> [[T2]]
853   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x
854   %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 1, i32 0>
855   call void @use_v2i4(<2 x i4> %t1)
856   %t2 = sub <2 x i4> %y, %t1
857   ret <2 x i4> %t2
860 ; zext of non-negative can be negated
861 ; sext of non-positive can be negated
862 define i16 @negation_of_zeroext_of_nonnegative(i8 %x) {
863 ; CHECK-LABEL: @negation_of_zeroext_of_nonnegative(
864 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
865 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -1
866 ; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]]
867 ; CHECK:       nonneg_bb:
868 ; CHECK-NEXT:    [[T2:%.*]] = zext i8 [[T0]] to i16
869 ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
870 ; CHECK-NEXT:    ret i16 [[T3]]
871 ; CHECK:       neg_bb:
872 ; CHECK-NEXT:    ret i16 0
874   %t0 = sub i8 0, %x
875   %t1 = icmp sge i8 %t0, 0
876   br i1 %t1, label %nonneg_bb, label %neg_bb
878 nonneg_bb:
879   %t2 = zext i8 %t0 to i16
880   %t3 = sub i16 0, %t2
881   ret i16 %t3
883 neg_bb:
884   ret i16 0
886 define i16 @negation_of_zeroext_of_positive(i8 %x) {
887 ; CHECK-LABEL: @negation_of_zeroext_of_positive(
888 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
889 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], 0
890 ; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]]
891 ; CHECK:       nonneg_bb:
892 ; CHECK-NEXT:    [[T2:%.*]] = zext 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 sgt 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_signext_of_negative(i8 %x) {
911 ; CHECK-LABEL: @negation_of_signext_of_negative(
912 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
913 ; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 0
914 ; CHECK-NEXT:    br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]]
915 ; CHECK:       neg_bb:
916 ; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i16
917 ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
918 ; CHECK-NEXT:    ret i16 [[T3]]
919 ; CHECK:       nonneg_bb:
920 ; CHECK-NEXT:    ret i16 0
922   %t0 = sub i8 0, %x
923   %t1 = icmp slt i8 %t0, 0
924   br i1 %t1, label %neg_bb, label %nonneg_bb
926 neg_bb:
927   %t2 = sext i8 %t0 to i16
928   %t3 = sub i16 0, %t2
929   ret i16 %t3
931 nonneg_bb:
932   ret i16 0
934 define i16 @negation_of_signext_of_nonpositive(i8 %x) {
935 ; CHECK-LABEL: @negation_of_signext_of_nonpositive(
936 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
937 ; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 1
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 sle 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_nonnegative__wrong_cast(i8 %x) {
959 ; CHECK-LABEL: @negation_of_signext_of_nonnegative__wrong_cast(
960 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
961 ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -1
962 ; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]]
963 ; CHECK:       nonneg_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:       neg_bb:
968 ; CHECK-NEXT:    ret i16 0
970   %t0 = sub i8 0, %x
971   %t1 = icmp sge i8 %t0, 0
972   br i1 %t1, label %nonneg_bb, label %neg_bb
974 nonneg_bb:
975   %t2 = sext i8 %t0 to i16
976   %t3 = sub i16 0, %t2
977   ret i16 %t3
979 neg_bb:
980   ret i16 0
982 define i16 @negation_of_zeroext_of_negative_wrongcast(i8 %x) {
983 ; CHECK-LABEL: @negation_of_zeroext_of_negative_wrongcast(
984 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
985 ; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 0
986 ; CHECK-NEXT:    br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]]
987 ; CHECK:       neg_bb:
988 ; CHECK-NEXT:    [[T2:%.*]] = zext i8 [[T0]] to i16
989 ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]
990 ; CHECK-NEXT:    ret i16 [[T3]]
991 ; CHECK:       nonneg_bb:
992 ; CHECK-NEXT:    ret i16 0
994   %t0 = sub i8 0, %x
995   %t1 = icmp slt i8 %t0, 0
996   br i1 %t1, label %neg_bb, label %nonneg_bb
998 neg_bb:
999   %t2 = zext i8 %t0 to i16
1000   %t3 = sub i16 0, %t2
1001   ret i16 %t3
1003 nonneg_bb:
1004   ret i16 0
1007 ; 'or' of 1 and operand with no lowest bit set is 'inc'
1008 define i8 @negation_of_increment_via_or_with_no_common_bits_set(i8 %x, i8 %y) {
1009 ; CHECK-LABEL: @negation_of_increment_via_or_with_no_common_bits_set(
1010 ; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1
1011 ; CHECK-NEXT:    [[T1_NEG:%.*]] = xor i8 [[T0]], -1
1012 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
1013 ; CHECK-NEXT:    ret i8 [[T2]]
1015   %t0 = shl i8 %y, 1
1016   %t1 = or i8 %t0, 1
1017   %t2 = sub i8 %x, %t1
1018   ret i8 %t2
1020 define i8 @negation_of_increment_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) {
1021 ; CHECK-LABEL: @negation_of_increment_via_or_with_no_common_bits_set_extrause(
1022 ; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1
1023 ; CHECK-NEXT:    [[T1:%.*]] = or i8 [[T0]], 1
1024 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
1025 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1026 ; CHECK-NEXT:    ret i8 [[T2]]
1028   %t0 = shl i8 %y, 1
1029   %t1 = or i8 %t0, 1
1030   call void @use8(i8 %t1)
1031   %t2 = sub i8 %x, %t1
1032   ret i8 %t2
1034 define i8 @negation_of_increment_via_or_common_bits_set(i8 %x, i8 %y) {
1035 ; CHECK-LABEL: @negation_of_increment_via_or_common_bits_set(
1036 ; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1
1037 ; CHECK-NEXT:    [[T1:%.*]] = or i8 [[T0]], 3
1038 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1039 ; CHECK-NEXT:    ret i8 [[T2]]
1041   %t0 = shl i8 %y, 1
1042   %t1 = or i8 %t0, 3
1043   %t2 = sub i8 %x, %t1
1044   ret i8 %t2
1047 ; 'or' of operands with no common bits set is 'add'
1048 define i8 @add_via_or_with_no_common_bits_set(i8 %x, i8 %y) {
1049 ; CHECK-LABEL: @add_via_or_with_no_common_bits_set(
1050 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
1051 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1052 ; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Y]], 2
1053 ; CHECK-NEXT:    [[T2_NEG:%.*]] = add i8 [[T1_NEG]], -3
1054 ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[T2_NEG]], [[X:%.*]]
1055 ; CHECK-NEXT:    ret i8 [[T3]]
1057   %t0 = sub i8 0, %y
1058   call void @use8(i8 %t0)
1059   %t1 = shl i8 %t0, 2
1060   %t2 = or i8 %t1, 3
1061   %t3 = sub i8 %x, %t2
1062   ret i8 %t3
1064 define i8 @add_via_or_with_common_bit_maybe_set(i8 %x, i8 %y) {
1065 ; CHECK-LABEL: @add_via_or_with_common_bit_maybe_set(
1066 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
1067 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1068 ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 2
1069 ; CHECK-NEXT:    [[T2:%.*]] = or i8 [[T1]], 4
1070 ; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X:%.*]], [[T2]]
1071 ; CHECK-NEXT:    ret i8 [[T3]]
1073   %t0 = sub i8 0, %y
1074   call void @use8(i8 %t0)
1075   %t1 = shl i8 %t0, 2
1076   %t2 = or i8 %t1, 4
1077   %t3 = sub i8 %x, %t2
1078   ret i8 %t3
1080 define i8 @add_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) {
1081 ; CHECK-LABEL: @add_via_or_with_no_common_bits_set_extrause(
1082 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]]
1083 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1084 ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 2
1085 ; CHECK-NEXT:    [[T2:%.*]] = or i8 [[T1]], 3
1086 ; CHECK-NEXT:    call void @use8(i8 [[T2]])
1087 ; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X:%.*]], [[T2]]
1088 ; CHECK-NEXT:    ret i8 [[T3]]
1090   %t0 = sub i8 0, %y
1091   call void @use8(i8 %t0)
1092   %t1 = shl i8 %t0, 2
1093   %t2 = or i8 %t1, 3
1094   call void @use8(i8 %t2)
1095   %t3 = sub i8 %x, %t2
1096   ret i8 %t3
1099 ; `extractelement` is negatible if source operand is negatible.
1100 define i4 @negate_extractelement(<2 x i4> %x, i32 %y, i4 %z) {
1101 ; CHECK-LABEL: @negate_extractelement(
1102 ; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X:%.*]]
1103 ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]])
1104 ; CHECK-NEXT:    [[T1_NEG:%.*]] = extractelement <2 x i4> [[X]], i32 [[Y:%.*]]
1105 ; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]]
1106 ; CHECK-NEXT:    ret i4 [[T2]]
1108   %t0 = sub <2 x i4> zeroinitializer, %x
1109   call void @use_v2i4(<2 x i4> %t0)
1110   %t1 = extractelement <2 x i4> %t0, i32 %y
1111   %t2 = sub i4 %z, %t1
1112   ret i4 %t2
1114 define i4 @negate_extractelement_extrause(<2 x i4> %x, i32 %y, i4 %z) {
1115 ; CHECK-LABEL: @negate_extractelement_extrause(
1116 ; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X:%.*]]
1117 ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]])
1118 ; CHECK-NEXT:    [[T1:%.*]] = extractelement <2 x i4> [[T0]], i32 [[Y:%.*]]
1119 ; CHECK-NEXT:    call void @use4(i4 [[T1]])
1120 ; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]]
1121 ; CHECK-NEXT:    ret i4 [[T2]]
1123   %t0 = sub <2 x i4> zeroinitializer, %x
1124   call void @use_v2i4(<2 x i4> %t0)
1125   %t1 = extractelement <2 x i4> %t0, i32 %y
1126   call void @use4(i4 %t1)
1127   %t2 = sub i4 %z, %t1
1128   ret i4 %t2
1131 ; `insertelement` is negatible if both source vector and element-to-be-inserted are negatible.
1132 define <2 x i4> @negate_insertelement(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
1133 ; CHECK-LABEL: @negate_insertelement(
1134 ; CHECK-NEXT:    [[T2_NEG:%.*]] = insertelement <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]]
1135 ; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[B:%.*]]
1136 ; CHECK-NEXT:    ret <2 x i4> [[T3]]
1138   %t0 = sub <2 x i4> zeroinitializer, %src
1139   %t1 = sub i4 zeroinitializer, %a
1140   %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x
1141   %t3 = sub <2 x i4> %b, %t2
1142   ret <2 x i4> %t3
1144 define <2 x i4> @negate_insertelement_extrause(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
1145 ; CHECK-LABEL: @negate_insertelement_extrause(
1146 ; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC:%.*]]
1147 ; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A:%.*]]
1148 ; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[T1]], i32 [[X:%.*]]
1149 ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T2]])
1150 ; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]]
1151 ; CHECK-NEXT:    ret <2 x i4> [[T3]]
1153   %t0 = sub <2 x i4> zeroinitializer, %src
1154   %t1 = sub i4 zeroinitializer, %a
1155   %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x
1156   call void @use_v2i4(<2 x i4> %t2)
1157   %t3 = sub <2 x i4> %b, %t2
1158   ret <2 x i4> %t3
1160 define <2 x i4> @negate_insertelement_nonnegatible_base(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
1161 ; CHECK-LABEL: @negate_insertelement_nonnegatible_base(
1162 ; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A:%.*]]
1163 ; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[SRC:%.*]], i4 [[T1]], i32 [[X:%.*]]
1164 ; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]]
1165 ; CHECK-NEXT:    ret <2 x i4> [[T3]]
1167   %t1 = sub i4 zeroinitializer, %a
1168   %t2 = insertelement <2 x i4> %src, i4 %t1, i32 %x
1169   %t3 = sub <2 x i4> %b, %t2
1170   ret <2 x i4> %t3
1172 define <2 x i4> @negate_insertelement_nonnegatible_insert(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {
1173 ; CHECK-LABEL: @negate_insertelement_nonnegatible_insert(
1174 ; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC:%.*]]
1175 ; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[A:%.*]], i32 [[X:%.*]]
1176 ; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]]
1177 ; CHECK-NEXT:    ret <2 x i4> [[T3]]
1179   %t0 = sub <2 x i4> zeroinitializer, %src
1180   %t2 = insertelement <2 x i4> %t0, i4 %a, i32 %x
1181   %t3 = sub <2 x i4> %b, %t2
1182   ret <2 x i4> %t3
1185 ; left-shift by constant can always be negated
1186 define i8 @negate_left_shift_by_constant_prefer_keeping_shl(i8 %x, i8 %y, i8 %z) {
1187 ; CHECK-LABEL: @negate_left_shift_by_constant_prefer_keeping_shl(
1188 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
1189 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1190 ; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Z]], 4
1191 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
1192 ; CHECK-NEXT:    ret i8 [[T2]]
1194   %t0 = sub i8 0, %z
1195   call void @use8(i8 %t0)
1196   %t1 = shl i8 %t0, 4
1197   %t2 = sub i8 %x, %t1
1198   ret i8 %t2
1200 define i8 @negate_left_shift_by_constant_prefer_keeping_shl_extrause(i8 %x, i8 %y, i8 %z) {
1201 ; CHECK-LABEL: @negate_left_shift_by_constant_prefer_keeping_shl_extrause(
1202 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]]
1203 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1204 ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 4
1205 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
1206 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1207 ; CHECK-NEXT:    ret i8 [[T2]]
1209   %t0 = sub i8 0, %z
1210   call void @use8(i8 %t0)
1211   %t1 = shl i8 %t0, 4
1212   call void @use8(i8 %t1)
1213   %t2 = sub i8 %x, %t1
1214   ret i8 %t2
1216 define i8 @negate_left_shift_by_constant(i8 %x, i8 %y, i8 %z, i8 %k) {
1217 ; CHECK-LABEL: @negate_left_shift_by_constant(
1218 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]]
1219 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1220 ; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[T0]], -16
1221 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
1222 ; CHECK-NEXT:    ret i8 [[T2]]
1224   %t0 = sub i8 %k, %z
1225   call void @use8(i8 %t0)
1226   %t1 = shl i8 %t0, 4
1227   %t2 = sub i8 %x, %t1
1228   ret i8 %t2
1230 define i8 @negate_left_shift_by_constant_extrause(i8 %x, i8 %y, i8 %z, i8 %k) {
1231 ; CHECK-LABEL: @negate_left_shift_by_constant_extrause(
1232 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]]
1233 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1234 ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 4
1235 ; CHECK-NEXT:    call void @use8(i8 [[T1]])
1236 ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]]
1237 ; CHECK-NEXT:    ret i8 [[T2]]
1239   %t0 = sub i8 %k, %z
1240   call void @use8(i8 %t0)
1241   %t1 = shl i8 %t0, 4
1242   call void @use8(i8 %t1)
1243   %t2 = sub i8 %x, %t1
1244   ret i8 %t2
1247 ; `add` with single negatible operand is still negatible
1248 define i8 @negate_add_with_single_negatible_operand(i8 %x, i8 %y) {
1249 ; CHECK-LABEL: @negate_add_with_single_negatible_operand(
1250 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X:%.*]]
1251 ; CHECK-NEXT:    ret i8 [[T1]]
1253   %t0 = add i8 %x, 42
1254   %t1 = sub i8 0, %t0
1255   ret i8 %t1
1257 ; do so even if we are two levels deep
1258 define i8 @negate_add_with_single_negatible_operand_depth2(i8 %x, i8 %y) {
1259 ; CHECK-LABEL: @negate_add_with_single_negatible_operand_depth2(
1260 ; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 -21, [[X:%.*]]
1261 ; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[T0_NEG]], [[Y:%.*]]
1262 ; CHECK-NEXT:    ret i8 [[T1_NEG]]
1264   %t0 = add i8 %x, 21
1265   %t1 = mul i8 %t0, %y
1266   %t2 = sub i8 0, %t1
1267   ret i8 %t2
1270 define i8 @negate_add_with_single_negatible_operand_extrause(i8 %x, i8 %y) {
1271 ; CHECK-LABEL: @negate_add_with_single_negatible_operand_extrause(
1272 ; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42
1273 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1274 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X]]
1275 ; CHECK-NEXT:    ret i8 [[T1]]
1277   %t0 = add i8 %x, 42
1278   call void @use8(i8 %t0)
1279   %t1 = sub i8 0, %t0
1280   ret i8 %t1
1282 ; But don't do this if that means just sinking the negation.
1283 define i8 @negate_add_with_single_negatible_operand_non_negation(i8 %x, i8 %y) {
1284 ; CHECK-LABEL: @negate_add_with_single_negatible_operand_non_negation(
1285 ; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42
1286 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Y:%.*]], [[T0]]
1287 ; CHECK-NEXT:    ret i8 [[T1]]
1289   %t0 = add i8 %x, 42
1290   %t1 = sub i8 %y, %t0
1291   ret i8 %t1
1294 ; abs/nabs can be negated
1295 define i8 @negate_abs(i8 %x, i8 %y) {
1296 ; CHECK-LABEL: @negate_abs(
1297 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1298 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1299 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)
1300 ; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[Y:%.*]], [[TMP1]]
1301 ; CHECK-NEXT:    ret i8 [[T3]]
1303   %t0 = sub i8 0, %x
1304   call void @use8(i8 %t0)
1305   %t1 = icmp slt i8 %x, 0
1306   %t2 = select i1 %t1, i8 %t0, i8 %x, !prof !0
1307   %t3 = sub i8 %y, %t2
1308   ret i8 %t3
1310 define i8 @negate_nabs(i8 %x, i8 %y) {
1311 ; CHECK-LABEL: @negate_nabs(
1312 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1313 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1314 ; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)
1315 ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[Y:%.*]]
1316 ; CHECK-NEXT:    ret i8 [[T3]]
1318   %t0 = sub i8 0, %x
1319   call void @use8(i8 %t0)
1320   %t1 = icmp slt i8 %x, 0
1321   %t2 = select i1 %t1, i8 %x, i8 %t0, !prof !0
1322   %t3 = sub i8 %y, %t2
1323   ret i8 %t3
1326 ; And in general, if hands of select are known to be negation of each other,
1327 ; we can negate the select
1328 define i8 @negate_select_of_op_vs_negated_op(i8 %x, i8 %y, i1 %c) {
1329 ; CHECK-LABEL: @negate_select_of_op_vs_negated_op(
1330 ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]]
1331 ; CHECK-NEXT:    call void @use8(i8 [[T0]])
1332 ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[T0]], !prof !0
1333 ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y:%.*]]
1334 ; CHECK-NEXT:    ret i8 [[T2]]
1336   %t0 = sub i8 0, %x
1337   call void @use8(i8 %t0)
1338   %t1 = select i1 %c, i8 %t0, i8 %x, !prof !0
1339   %t2 = sub i8 %y, %t1
1340   ret i8 %t2
1342 define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) {
1343 ; CHECK-LABEL: @dont_negate_ordinary_select(
1344 ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]
1345 ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Z:%.*]], [[T0]]
1346 ; CHECK-NEXT:    ret i8 [[T1]]
1348   %t0 = select i1 %c, i8 %x, i8 %y
1349   %t1 = sub i8 %z, %t0
1350   ret i8 %t1
1353 ; Freeze is transparent as far as negation is concerned
1354 define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {
1355 ; CHECK-LABEL: @negate_freeze(
1356 ; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i4 [[Y:%.*]], [[X:%.*]]
1357 ; CHECK-NEXT:    [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]]
1358 ; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]]
1359 ; CHECK-NEXT:    ret i4 [[T2]]
1361   %t0 = sub i4 %x, %y
1362   %t1 = freeze i4 %t0
1363   %t2 = sub i4 %z, %t1
1364   ret i4 %t2
1366 define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) {
1367 ; CHECK-LABEL: @negate_freeze_extrause(
1368 ; CHECK-NEXT:    [[T0:%.*]] = sub i4 [[X:%.*]], [[Y:%.*]]
1369 ; CHECK-NEXT:    [[T1:%.*]] = freeze i4 [[T0]]
1370 ; CHECK-NEXT:    call void @use4(i4 [[T1]])
1371 ; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]]
1372 ; CHECK-NEXT:    ret i4 [[T2]]
1374   %t0 = sub i4 %x, %y
1375   %t1 = freeze i4 %t0
1376   call void @use4(i4 %t1)
1377   %t2 = sub i4 %z, %t1
1378   ret i4 %t2
1381 ; Due to the InstCombine's worklist management, there are no guarantees that
1382 ; each instruction we'll encounter has been visited by InstCombine already.
1383 ; In particular, most importantly for us, that means we have to canonicalize
1384 ; constants to RHS ourselves, since that is helpful sometimes.
1385 ; This used to cause an endless combine loop.
1386 define void @noncanonical_mul_with_constant_as_first_operand() {
1387 ; CHECK-LABEL: @noncanonical_mul_with_constant_as_first_operand(
1388 ; CHECK-NEXT:  entry:
1389 ; CHECK-NEXT:    br label [[IF_END:%.*]]
1390 ; CHECK:       if.end:
1391 ; CHECK-NEXT:    br label [[IF_END]]
1393 entry:
1394   br label %if.end
1396 if.end:
1397   %e.0 = phi i32 [ undef, %entry ], [ %div, %if.end ]
1398   %conv = trunc i32 %e.0 to i16
1399   %mul.i = mul nsw i16 -1, %conv
1400   %conv1 = sext i16 %mul.i to i32
1401   %div = sub nsw i32 0, %conv1
1402   br label %if.end
1405 ; CHECK: !0 = !{!"branch_weights", i32 40, i32 1}
1406 !0 = !{!"branch_weights", i32 40, i32 1}