| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | 
 | ; RUN: opt < %s -passes=instcombine -S | FileCheck %s | 
 |  | 
 | declare void @use4(i4) | 
 | declare void @use8(i8) | 
 | declare void @use_v2i4(<2 x i4>) | 
 | declare i1 @use32gen1(i32) | 
 |  | 
 | ; Constant can be freely negated. | 
 | define i8 @t0(i8 %x) { | 
 | ; CHECK-LABEL: @t0( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42 | 
 | ; CHECK-NEXT:    ret i8 [[T0]] | 
 | ; | 
 |   %t0 = sub i8 %x, -42 | 
 |   ret i8 %t0 | 
 | } | 
 |  | 
 | ; Negation can be negated for free | 
 | define i8 @t1(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @t1( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X:%.*]], [[Y]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 |  | 
 | ; Shift-left can be negated if all uses can be updated | 
 | define i8 @t2(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @t2( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i8 42, [[Y:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = shl i8 -42, %y | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @n2(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @n2( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = shl i8 -42, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = shl i8 -42, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @t3(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @t3( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Z]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %z | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, %y | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @n3(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @n3( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %z | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, %y | 
 |   call void @use8(i8 %t1) | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 |  | 
 | ; Select can be negated if all it's operands can be negated and all the users of select can be updated | 
 | define i8 @t4(i8 %x, i1 %y) { | 
 | ; CHECK-LABEL: @t4( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = select i1 [[Y:%.*]], i8 42, i8 -44 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = select i1 %y, i8 -42, i8 44 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @n4(i8 %x, i1 %y) { | 
 | ; CHECK-LABEL: @n4( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 44 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = select i1 %y, i8 -42, i8 44 | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @n5(i8 %x, i1 %y, i8 %z) { | 
 | ; CHECK-LABEL: @n5( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y:%.*]], i8 -42, i8 [[Z:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = select i1 %y, i8 -42, i8 %z | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @t6(i8 %x, i1 %y, i8 %z) { | 
 | ; CHECK-LABEL: @t6( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 42, i8 [[Z]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %z | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = select i1 %y, i8 -42, i8 %t0 | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @t7(i8 %x, i1 %y, i8 %z) { | 
 | ; CHECK-LABEL: @t7( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl nsw i8 -1, [[Z:%.*]] | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0_NEG]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = shl i8 1, %z | 
 |   %t1 = select i1 %y, i8 0, i8 %t0 | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @n8(i8 %x, i1 %y, i8 %z) { | 
 | ; CHECK-LABEL: @n8( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y:%.*]], i8 0, i8 [[T0]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = shl i8 1, %z | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = select i1 %y, i8 0, i8 %t0 | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 |  | 
 | ; Subtraction can be negated by swapping its operands. | 
 | ; x - (y - z) -> x - y + z -> x + (z - y) | 
 | define i8 @t9(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @t9( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T0_NEG]] | 
 | ; | 
 |   %t0 = sub i8 %y, %x | 
 |   %t1 = sub i8 0, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 |  | 
 | define i8 @n10(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @n10( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[Y:%.*]], [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = sub i8 %y, %x | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 0, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 |  | 
 | define i8 @neg_of_sub_from_constant(i8 %x) { | 
 | ; CHECK-LABEL: @neg_of_sub_from_constant( | 
 | ; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42 | 
 | ; CHECK-NEXT:    ret i8 [[S_NEG]] | 
 | ; | 
 |   %s = sub i8 42, %x | 
 |   %r = sub i8 0, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @neg_of_sub_from_constant_multi_use(i8 %x) { | 
 | ; CHECK-LABEL: @neg_of_sub_from_constant_multi_use( | 
 | ; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42 | 
 | ; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[S]]) | 
 | ; CHECK-NEXT:    ret i8 [[S_NEG]] | 
 | ; | 
 |   %s = sub i8 42, %x | 
 |   call void @use8(i8 %s) | 
 |   %r = sub i8 0, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @sub_from_constant_of_sub_from_constant(i8 %x) { | 
 | ; CHECK-LABEL: @sub_from_constant_of_sub_from_constant( | 
 | ; CHECK-NEXT:    [[R:%.*]] = add i8 [[X:%.*]], -31 | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = sub i8 42, %x | 
 |   %r = sub i8 11, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @sub_from_constant_of_sub_from_constant_multi_use(i8 %x) { | 
 | ; CHECK-LABEL: @sub_from_constant_of_sub_from_constant_multi_use( | 
 | ; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[S]]) | 
 | ; CHECK-NEXT:    [[R:%.*]] = add i8 [[X]], -31 | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = sub i8 42, %x | 
 |   call void @use8(i8 %s) | 
 |   %r = sub i8 11, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @sub_from_variable_of_sub_from_constant(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @sub_from_variable_of_sub_from_constant( | 
 | ; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X:%.*]], -42 | 
 | ; CHECK-NEXT:    [[R:%.*]] = add i8 [[S_NEG]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = sub i8 42, %x | 
 |   %r = sub i8 %y, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @sub_from_variable_of_sub_from_constant_multi_use(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @sub_from_variable_of_sub_from_constant_multi_use( | 
 | ; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[S]]) | 
 | ; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y:%.*]], [[S]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = sub i8 42, %x | 
 |   call void @use8(i8 %s) | 
 |   %r = sub i8 %y, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | ; Addition can be negated if both operands can be negated | 
 | ; x - (y + z) -> x - y - z -> x + ((-y) + (-z))) | 
 | define i8 @t12(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @t12( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T1]]) | 
 | ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]] | 
 | ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T3]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 0, %z | 
 |   call void @use8(i8 %t1) | 
 |   %t2 = add i8 %t0, %t1 | 
 |   %t3 = sub i8 %x, %t2 | 
 |   ret i8 %t3 | 
 | } | 
 | define i8 @n13(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @n13( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = sub i8 [[Y]], [[Z:%.*]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = add i8 %t0, %z | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @n14(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @n14( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T1]]) | 
 | ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 0, [[TMP1]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T2]]) | 
 | ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T3]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 0, %z | 
 |   call void @use8(i8 %t1) | 
 |   %t2 = add i8 %t0, %t1 | 
 |   call void @use8(i8 %t2) | 
 |   %t3 = sub i8 %x, %t2 | 
 |   ret i8 %t3 | 
 | } | 
 |  | 
 | define i8 @neg_of_add_with_constant(i8 %x) { | 
 | ; CHECK-LABEL: @neg_of_add_with_constant( | 
 | ; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = add i8 %x, 42 | 
 |   %r = sub i8 0, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @neg_of_add_with_constant_multi_use(i8 %x) { | 
 | ; CHECK-LABEL: @neg_of_add_with_constant_multi_use( | 
 | ; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[S]]) | 
 | ; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = add i8 %x, 42 | 
 |   call void @use8(i8 %s) | 
 |   %r = sub i8 0, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @sub_from_constant_of_add_with_constant(i8 %x) { | 
 | ; CHECK-LABEL: @sub_from_constant_of_add_with_constant( | 
 | ; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = add i8 %x, 42 | 
 |   %r = sub i8 11, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @sub_from_constant_of_add_with_constant_multi_use(i8 %x) { | 
 | ; CHECK-LABEL: @sub_from_constant_of_add_with_constant_multi_use( | 
 | ; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[S]]) | 
 | ; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = add i8 %x, 42 | 
 |   call void @use8(i8 %s) | 
 |   %r = sub i8 11, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @sub_from_variable_of_add_with_constant(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @sub_from_variable_of_add_with_constant( | 
 | ; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42 | 
 | ; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y:%.*]], [[S]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = add i8 %x, 42 | 
 |   %r = sub i8 %y, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i8 @sub_from_variable_of_add_with_constant_multi_use(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @sub_from_variable_of_add_with_constant_multi_use( | 
 | ; CHECK-NEXT:    [[S:%.*]] = add i8 [[X:%.*]], 42 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[S]]) | 
 | ; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y:%.*]], [[S]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %s = add i8 %x, 42 | 
 |   call void @use8(i8 %s) | 
 |   %r = sub i8 %y, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | ; Multiplication can be negated if either one of operands can be negated | 
 | ; x - (y * z) -> x + ((-y) * z) or  x + ((-z) * y) | 
 | define i8 @t15(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @t15( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[Y]], [[Z:%.*]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = mul i8 %t0, %z | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @n16(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @n16( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = mul i8 [[T0]], [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = mul i8 %t0, %z | 
 |   call void @use8(i8 %t1) | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 |  | 
 | ; Phi can be negated if all incoming values can be negated | 
 | define i8 @t16(i1 %c, i8 %x) { | 
 | ; CHECK-LABEL: @t16( | 
 | ; CHECK-NEXT:  begin: | 
 | ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] | 
 | ; CHECK:       then: | 
 | ; CHECK-NEXT:    br label [[END:%.*]] | 
 | ; CHECK:       else: | 
 | ; CHECK-NEXT:    br label [[END]] | 
 | ; CHECK:       end: | 
 | ; CHECK-NEXT:    [[Z_NEG:%.*]] = phi i8 [ [[X:%.*]], [[THEN]] ], [ 42, [[ELSE]] ] | 
 | ; CHECK-NEXT:    ret i8 [[Z_NEG]] | 
 | ; | 
 | begin: | 
 |   br i1 %c, label %then, label %else | 
 | then: | 
 |   %y = sub i8 0, %x | 
 |   br label %end | 
 | else: | 
 |   br label %end | 
 | end: | 
 |   %z = phi i8 [ %y, %then], [ -42, %else ] | 
 |   %n = sub i8 0, %z | 
 |   ret i8 %n | 
 | } | 
 | define i8 @n17(i1 %c, i8 %x) { | 
 | ; CHECK-LABEL: @n17( | 
 | ; CHECK-NEXT:  begin: | 
 | ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] | 
 | ; CHECK:       then: | 
 | ; CHECK-NEXT:    [[Y:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    br label [[END:%.*]] | 
 | ; CHECK:       else: | 
 | ; CHECK-NEXT:    br label [[END]] | 
 | ; CHECK:       end: | 
 | ; CHECK-NEXT:    [[Z:%.*]] = phi i8 [ [[Y]], [[THEN]] ], [ -42, [[ELSE]] ] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[Z]]) | 
 | ; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[Z]] | 
 | ; CHECK-NEXT:    ret i8 [[N]] | 
 | ; | 
 | begin: | 
 |   br i1 %c, label %then, label %else | 
 | then: | 
 |   %y = sub i8 0, %x | 
 |   br label %end | 
 | else: | 
 |   br label %end | 
 | end: | 
 |   %z = phi i8 [ %y, %then], [ -42, %else ] | 
 |   call void @use8(i8 %z) | 
 |   %n = sub i8 0, %z | 
 |   ret i8 %n | 
 | } | 
 | define i8 @n19(i1 %c, i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @n19( | 
 | ; CHECK-NEXT:  begin: | 
 | ; CHECK-NEXT:    br i1 [[C:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]] | 
 | ; CHECK:       then: | 
 | ; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    br label [[END:%.*]] | 
 | ; CHECK:       else: | 
 | ; CHECK-NEXT:    br label [[END]] | 
 | ; CHECK:       end: | 
 | ; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[Z]], [[THEN]] ], [ [[Y:%.*]], [[ELSE]] ] | 
 | ; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[R]] | 
 | ; CHECK-NEXT:    ret i8 [[N]] | 
 | ; | 
 | begin: | 
 |   br i1 %c, label %then, label %else | 
 | then: | 
 |   %z = sub i8 0, %x | 
 |   br label %end | 
 | else: | 
 |   br label %end | 
 | end: | 
 |   %r = phi i8 [ %z, %then], [ %y, %else ] | 
 |   %n = sub i8 0, %r | 
 |   ret i8 %n | 
 | } | 
 | define void @phi_with_duplicate_incoming_basic_blocks(i32 %x, i32 %y, i1 %should_lookup, i32 %z) { | 
 | ; CHECK-LABEL: @phi_with_duplicate_incoming_basic_blocks( | 
 | ; CHECK-NEXT:  entry: | 
 | ; CHECK-NEXT:    [[X_INC_NEG:%.*]] = xor i32 [[X:%.*]], -1 | 
 | ; CHECK-NEXT:    br i1 [[SHOULD_LOOKUP:%.*]], label [[LOOKUP:%.*]], label [[LOOP:%.*]] | 
 | ; CHECK:       lookup: | 
 | ; CHECK-NEXT:    [[TO_LOOKUP:%.*]] = phi i32 [ [[Y:%.*]], [[ENTRY:%.*]] ], [ [[METAVAL_NEG:%.*]], [[LOOP]] ] | 
 | ; CHECK-NEXT:    switch i32 [[TO_LOOKUP]], label [[END:%.*]] [ | 
 | ; CHECK-NEXT:      i32 0, label [[LOOP]] | 
 | ; CHECK-NEXT:      i32 42, label [[LOOP]] | 
 | ; CHECK-NEXT:    ] | 
 | ; CHECK:       loop: | 
 | ; CHECK-NEXT:    [[METAVAL_NEG]] = phi i32 [ [[X_INC_NEG]], [[LOOKUP]] ], [ [[X_INC_NEG]], [[LOOKUP]] ], [ -84, [[ENTRY]] ] | 
 | ; CHECK-NEXT:    [[REPEAT:%.*]] = call i1 @use32gen1(i32 [[METAVAL_NEG]]) | 
 | ; CHECK-NEXT:    br i1 [[REPEAT]], label [[LOOKUP]], label [[END]] | 
 | ; CHECK:       end: | 
 | ; CHECK-NEXT:    ret void | 
 | ; | 
 | entry: | 
 |   %x_inc = add i32 %x, 1 | 
 |   br i1 %should_lookup, label %lookup, label %loop | 
 |  | 
 | lookup: | 
 |   %to_lookup = phi i32 [ %y, %entry ], [ %negated_metaval, %loop ] | 
 |   switch i32 %to_lookup, label %end [ | 
 |   i32 0, label %loop | 
 |   i32 42, label %loop | 
 |   ] | 
 |  | 
 | loop: | 
 |   %metaval = phi i32 [ %x_inc, %lookup ], [ %x_inc, %lookup ], [ 84, %entry ] | 
 |   %negated_metaval = sub i32 0, %metaval | 
 |   %repeat = call i1 @use32gen1(i32 %negated_metaval) | 
 |   br i1 %repeat, label %lookup, label %end | 
 |  | 
 | end: | 
 |   ret void | 
 | } | 
 |  | 
 | ; truncation can be negated if it's operand can be negated | 
 | define i8 @t20(i8 %x, i16 %y) { | 
 | ; CHECK-LABEL: @t20( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i16 42, [[Y:%.*]] | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = trunc i16 [[T0_NEG]] to i8 | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = shl i16 -42, %y | 
 |   %t1 = trunc i16 %t0 to i8 | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @n21(i8 %x, i16 %y) { | 
 | ; CHECK-LABEL: @n21( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = shl i16 -42, [[Y:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = trunc i16 [[T0]] to i8 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = shl i16 -42, %y | 
 |   %t1 = trunc i16 %t0 to i8 | 
 |   call void @use8(i8 %t1) | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 |  | 
 | define i4 @negate_xor(i4 %x) { | 
 | ; CHECK-LABEL: @negate_xor( | 
 | ; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], -6 | 
 | ; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1 | 
 | ; CHECK-NEXT:    ret i4 [[O_NEG]] | 
 | ; | 
 |   %o = xor i4 %x, 5 | 
 |   %r = sub i4 0, %o | 
 |   ret i4 %r | 
 | } | 
 |  | 
 | define <2 x i4> @negate_xor_vec(<2 x i4> %x) { | 
 | ; CHECK-LABEL: @negate_xor_vec( | 
 | ; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[X:%.*]], <i4 -6, i4 5> | 
 | ; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[TMP1]], <i4 1, i4 1> | 
 | ; CHECK-NEXT:    ret <2 x i4> [[O_NEG]] | 
 | ; | 
 |   %o = xor <2 x i4> %x, <i4 5, i4 10> | 
 |   %r = sub <2 x i4> zeroinitializer, %o | 
 |   ret <2 x i4> %r | 
 | } | 
 |  | 
 | define i8 @negate_xor_use(i8 %x) { | 
 | ; CHECK-LABEL: @negate_xor_use( | 
 | ; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X:%.*]], 5 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[O]]) | 
 | ; CHECK-NEXT:    [[R:%.*]] = sub i8 0, [[O]] | 
 | ; CHECK-NEXT:    ret i8 [[R]] | 
 | ; | 
 |   %o = xor i8 %x, 5 | 
 |   call void @use8(i8 %o) | 
 |   %r = sub i8 0, %o | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define i4 @negate_shl_xor(i4 %x, i4 %y) { | 
 | ; CHECK-LABEL: @negate_shl_xor( | 
 | ; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X:%.*]], -6 | 
 | ; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1 | 
 | ; CHECK-NEXT:    [[S_NEG:%.*]] = shl i4 [[O_NEG]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret i4 [[S_NEG]] | 
 | ; | 
 |   %o = xor i4 %x, 5 | 
 |   %s = shl i4 %o, %y | 
 |   %r = sub i4 0, %s | 
 |   ret i4 %r | 
 | } | 
 |  | 
 | define i8 @negate_shl_not_uses(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_shl_not_uses( | 
 | ; CHECK-NEXT:    [[O_NEG:%.*]] = add i8 [[X:%.*]], 1 | 
 | ; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X]], -1 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[O]]) | 
 | ; CHECK-NEXT:    [[S_NEG:%.*]] = shl i8 [[O_NEG]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[S_NEG]] | 
 | ; | 
 |   %o = xor i8 %x, -1 | 
 |   call void @use8(i8 %o) | 
 |   %s = shl i8 %o, %y | 
 |   %r = sub i8 0, %s | 
 |   ret i8 %r | 
 | } | 
 |  | 
 | define <2 x i4> @negate_mul_not_uses_vec(<2 x i4> %x, <2 x i4> %y) { | 
 | ; CHECK-LABEL: @negate_mul_not_uses_vec( | 
 | ; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[X:%.*]], <i4 1, i4 1> | 
 | ; CHECK-NEXT:    [[O:%.*]] = xor <2 x i4> [[X]], <i4 -1, i4 -1> | 
 | ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[O]]) | 
 | ; CHECK-NEXT:    [[S_NEG:%.*]] = mul <2 x i4> [[O_NEG]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[S_NEG]] | 
 | ; | 
 |   %o = xor <2 x i4> %x, <i4 -1, i4 -1> | 
 |   call void @use_v2i4(<2 x i4> %o) | 
 |   %s = mul <2 x i4> %o, %y | 
 |   %r = sub <2 x i4> zeroinitializer, %s | 
 |   ret <2 x i4> %r | 
 | } | 
 |  | 
 | ; signed division can be negated if divisor can be negated and is not 1/-1 | 
 | define i8 @negate_sdiv(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_sdiv( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = sdiv i8 [[Y:%.*]], -42 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = sdiv i8 %y, 42 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_sdiv_extrause(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_sdiv_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y:%.*]], 42 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = sdiv i8 %y, 42 | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_sdiv_extrause2(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_sdiv_extrause2( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y:%.*]], 42 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub nsw i8 0, [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = sdiv i8 %y, 42 | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 0, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 |  | 
 | ; Right-shift sign bit smear is negatible. | 
 | define i8 @negate_ashr(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_ashr( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = lshr i8 [[Y:%.*]], 7 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = ashr i8 %y, 7 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_lshr(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_lshr( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = ashr i8 [[Y:%.*]], 7 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = lshr i8 %y, 7 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_ashr_extrause(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_ashr_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y:%.*]], 7 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = ashr i8 %y, 7 | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_lshr_extrause(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_lshr_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y:%.*]], 7 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = lshr i8 %y, 7 | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_ashr_wrongshift(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_ashr_wrongshift( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y:%.*]], 6 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = ashr i8 %y, 6 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_lshr_wrongshift(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_lshr_wrongshift( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y:%.*]], 6 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = lshr i8 %y, 6 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 |  | 
 | ; *ext of i1 is always negatible | 
 | define i8 @negate_sext(i8 %x, i1 %y) { | 
 | ; CHECK-LABEL: @negate_sext( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = zext i1 [[Y:%.*]] to i8 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = sext i1 %y to i8 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_zext(i8 %x, i1 %y) { | 
 | ; CHECK-LABEL: @negate_zext( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = sext i1 [[Y:%.*]] to i8 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = zext i1 %y to i8 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_sext_extrause(i8 %x, i1 %y) { | 
 | ; CHECK-LABEL: @negate_sext_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sext i1 [[Y:%.*]] to i8 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = sext i1 %y to i8 | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_zext_extrause(i8 %x, i1 %y) { | 
 | ; CHECK-LABEL: @negate_zext_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = zext i1 [[Y:%.*]] to i8 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = zext i1 %y to i8 | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_sext_wrongwidth(i8 %x, i2 %y) { | 
 | ; CHECK-LABEL: @negate_sext_wrongwidth( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sext i2 [[Y:%.*]] to i8 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = sext i2 %y to i8 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | define i8 @negate_zext_wrongwidth(i8 %x, i2 %y) { | 
 | ; CHECK-LABEL: @negate_zext_wrongwidth( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = zext i2 [[Y:%.*]] to i8 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = zext i2 %y to i8 | 
 |   %t1 = sub i8 %x, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 |  | 
 | define <2 x i4> @negate_shufflevector_oneinput_reverse(<2 x i4> %x, <2 x i4> %y) { | 
 | ; CHECK-LABEL: @negate_shufflevector_oneinput_reverse( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> poison, <2 x i32> <i32 1, i32 0> | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[T2]] | 
 | ; | 
 |   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x | 
 |   %t1 = shufflevector <2 x i4> %t0, <2 x i4> poison, <2 x i32> <i32 1, i32 0> | 
 |   %t2 = sub <2 x i4> %y, %t1 | 
 |   ret <2 x i4> %t2 | 
 | } | 
 | define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(<2 x i4> %x, <2 x i4> %y) { | 
 | ; CHECK-LABEL: @negate_shufflevector_oneinput_second_lane_is_undef( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> poison, <2 x i32> <i32 0, i32 poison> | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[T2]] | 
 | ; | 
 |   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x | 
 |   %t1 = shufflevector <2 x i4> %t0, <2 x i4> poison, <2 x i32> <i32 0, i32 2> | 
 |   %t2 = sub <2 x i4> %y, %t1 | 
 |   ret <2 x i4> %t2 | 
 | } | 
 | define <2 x i4> @negate_shufflevector_twoinputs(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) { | 
 | ; CHECK-LABEL: @negate_shufflevector_twoinputs( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = add <2 x i4> [[Y:%.*]], <i4 poison, i4 1> | 
 | ; CHECK-NEXT:    [[T2_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> [[T1_NEG]], <2 x i32> <i32 0, i32 3> | 
 | ; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[Z:%.*]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[T3]] | 
 | ; | 
 |   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x | 
 |   %t1 = xor <2 x i4> %y, <i4 -1, i4 -1> | 
 |   %t2 = shufflevector <2 x i4> %t0, <2 x i4> %t1, <2 x i32> <i32 0, i32 3> | 
 |   %t3 = sub <2 x i4> %z, %t2 | 
 |   ret <2 x i4> %t3 | 
 | } | 
 | define <2 x i4> @negate_shufflevector_oneinput_extrause(<2 x i4> %x, <2 x i4> %y) { | 
 | ; CHECK-LABEL: @negate_shufflevector_oneinput_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> poison, <2 x i32> <i32 1, i32 0> | 
 | ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub <2 x i4> [[Y:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[T2]] | 
 | ; | 
 |   %t0 = shl <2 x i4> <i4 -6, i4 5>, %x | 
 |   %t1 = shufflevector <2 x i4> %t0, <2 x i4> poison, <2 x i32> <i32 1, i32 0> | 
 |   call void @use_v2i4(<2 x i4> %t1) | 
 |   %t2 = sub <2 x i4> %y, %t1 | 
 |   ret <2 x i4> %t2 | 
 | } | 
 |  | 
 | ; zext of non-negative can be negated | 
 | ; sext of non-positive can be negated | 
 | define i16 @negation_of_zeroext_of_nonnegative(i8 %x) { | 
 | ; CHECK-LABEL: @negation_of_zeroext_of_nonnegative( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -1 | 
 | ; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]] | 
 | ; CHECK:       nonneg_bb: | 
 | ; CHECK-NEXT:    [[T2:%.*]] = zext i8 [[T0]] to i16 | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]] | 
 | ; CHECK-NEXT:    ret i16 [[T3]] | 
 | ; CHECK:       neg_bb: | 
 | ; CHECK-NEXT:    ret i16 0 | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   %t1 = icmp sge i8 %t0, 0 | 
 |   br i1 %t1, label %nonneg_bb, label %neg_bb | 
 |  | 
 | nonneg_bb: | 
 |   %t2 = zext i8 %t0 to i16 | 
 |   %t3 = sub i16 0, %t2 | 
 |   ret i16 %t3 | 
 |  | 
 | neg_bb: | 
 |   ret i16 0 | 
 | } | 
 | define i16 @negation_of_zeroext_of_positive(i8 %x) { | 
 | ; CHECK-LABEL: @negation_of_zeroext_of_positive( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], 0 | 
 | ; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]] | 
 | ; CHECK:       nonneg_bb: | 
 | ; CHECK-NEXT:    [[T2:%.*]] = zext i8 [[T0]] to i16 | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]] | 
 | ; CHECK-NEXT:    ret i16 [[T3]] | 
 | ; CHECK:       neg_bb: | 
 | ; CHECK-NEXT:    ret i16 0 | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   %t1 = icmp sgt i8 %t0, 0 | 
 |   br i1 %t1, label %nonneg_bb, label %neg_bb | 
 |  | 
 | nonneg_bb: | 
 |   %t2 = zext i8 %t0 to i16 | 
 |   %t3 = sub i16 0, %t2 | 
 |   ret i16 %t3 | 
 |  | 
 | neg_bb: | 
 |   ret i16 0 | 
 | } | 
 | define i16 @negation_of_signext_of_negative(i8 %x) { | 
 | ; CHECK-LABEL: @negation_of_signext_of_negative( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 0 | 
 | ; CHECK-NEXT:    br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]] | 
 | ; CHECK:       neg_bb: | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i16 | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]] | 
 | ; CHECK-NEXT:    ret i16 [[T3]] | 
 | ; CHECK:       nonneg_bb: | 
 | ; CHECK-NEXT:    ret i16 0 | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   %t1 = icmp slt i8 %t0, 0 | 
 |   br i1 %t1, label %neg_bb, label %nonneg_bb | 
 |  | 
 | neg_bb: | 
 |   %t2 = sext i8 %t0 to i16 | 
 |   %t3 = sub i16 0, %t2 | 
 |   ret i16 %t3 | 
 |  | 
 | nonneg_bb: | 
 |   ret i16 0 | 
 | } | 
 | define i16 @negation_of_signext_of_nonpositive(i8 %x) { | 
 | ; CHECK-LABEL: @negation_of_signext_of_nonpositive( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 1 | 
 | ; CHECK-NEXT:    br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]] | 
 | ; CHECK:       neg_bb: | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i16 | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]] | 
 | ; CHECK-NEXT:    ret i16 [[T3]] | 
 | ; CHECK:       nonneg_bb: | 
 | ; CHECK-NEXT:    ret i16 0 | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   %t1 = icmp sle i8 %t0, 0 | 
 |   br i1 %t1, label %neg_bb, label %nonneg_bb | 
 |  | 
 | neg_bb: | 
 |   %t2 = sext i8 %t0 to i16 | 
 |   %t3 = sub i16 0, %t2 | 
 |   ret i16 %t3 | 
 |  | 
 | nonneg_bb: | 
 |   ret i16 0 | 
 | } | 
 | define i16 @negation_of_signext_of_nonnegative__wrong_cast(i8 %x) { | 
 | ; CHECK-LABEL: @negation_of_signext_of_nonnegative__wrong_cast( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -1 | 
 | ; CHECK-NEXT:    br i1 [[T1]], label [[NONNEG_BB:%.*]], label [[NEG_BB:%.*]] | 
 | ; CHECK:       nonneg_bb: | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i16 | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]] | 
 | ; CHECK-NEXT:    ret i16 [[T3]] | 
 | ; CHECK:       neg_bb: | 
 | ; CHECK-NEXT:    ret i16 0 | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   %t1 = icmp sge i8 %t0, 0 | 
 |   br i1 %t1, label %nonneg_bb, label %neg_bb | 
 |  | 
 | nonneg_bb: | 
 |   %t2 = sext i8 %t0 to i16 | 
 |   %t3 = sub i16 0, %t2 | 
 |   ret i16 %t3 | 
 |  | 
 | neg_bb: | 
 |   ret i16 0 | 
 | } | 
 | define i16 @negation_of_zeroext_of_negative_wrongcast(i8 %x) { | 
 | ; CHECK-LABEL: @negation_of_zeroext_of_negative_wrongcast( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 0 | 
 | ; CHECK-NEXT:    br i1 [[T1]], label [[NEG_BB:%.*]], label [[NONNEG_BB:%.*]] | 
 | ; CHECK:       neg_bb: | 
 | ; CHECK-NEXT:    [[T2:%.*]] = zext i8 [[T0]] to i16 | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]] | 
 | ; CHECK-NEXT:    ret i16 [[T3]] | 
 | ; CHECK:       nonneg_bb: | 
 | ; CHECK-NEXT:    ret i16 0 | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   %t1 = icmp slt i8 %t0, 0 | 
 |   br i1 %t1, label %neg_bb, label %nonneg_bb | 
 |  | 
 | neg_bb: | 
 |   %t2 = zext i8 %t0 to i16 | 
 |   %t3 = sub i16 0, %t2 | 
 |   ret i16 %t3 | 
 |  | 
 | nonneg_bb: | 
 |   ret i16 0 | 
 | } | 
 |  | 
 | ; 'or' of 1 and operand with no lowest bit set is 'inc' | 
 | define i8 @negation_of_increment_via_or_with_no_common_bits_set(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negation_of_increment_via_or_with_no_common_bits_set( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1 | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = xor i8 [[T0]], -1 | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = shl i8 %y, 1 | 
 |   %t1 = or i8 %t0, 1 | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @negation_of_increment_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negation_of_increment_via_or_with_no_common_bits_set_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = or i8 [[T0]], 1 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = shl i8 %y, 1 | 
 |   %t1 = or i8 %t0, 1 | 
 |   call void @use8(i8 %t1) | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @negation_of_increment_via_or_common_bits_set(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negation_of_increment_via_or_common_bits_set( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y:%.*]], 1 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = or i8 [[T0]], 3 | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = shl i8 %y, 1 | 
 |   %t1 = or i8 %t0, 3 | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 |  | 
 | ; 'or' of operands with no common bits set is 'add' | 
 | define i8 @add_via_or_with_no_common_bits_set(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @add_via_or_with_no_common_bits_set( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Y]], 2 | 
 | ; CHECK-NEXT:    [[T2_NEG:%.*]] = add i8 [[T1_NEG]], -3 | 
 | ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[T2_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T3]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, 2 | 
 |   %t2 = or i8 %t1, 3 | 
 |   %t3 = sub i8 %x, %t2 | 
 |   ret i8 %t3 | 
 | } | 
 | define i8 @add_via_or_with_common_bit_maybe_set(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @add_via_or_with_common_bit_maybe_set( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 2 | 
 | ; CHECK-NEXT:    [[T2:%.*]] = or i8 [[T1]], 4 | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X:%.*]], [[T2]] | 
 | ; CHECK-NEXT:    ret i8 [[T3]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, 2 | 
 |   %t2 = or i8 %t1, 4 | 
 |   %t3 = sub i8 %x, %t2 | 
 |   ret i8 %t3 | 
 | } | 
 | define i8 @add_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @add_via_or_with_no_common_bits_set_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 2 | 
 | ; CHECK-NEXT:    [[T2:%.*]] = or i8 [[T1]], 3 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T2]]) | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X:%.*]], [[T2]] | 
 | ; CHECK-NEXT:    ret i8 [[T3]] | 
 | ; | 
 |   %t0 = sub i8 0, %y | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, 2 | 
 |   %t2 = or i8 %t1, 3 | 
 |   call void @use8(i8 %t2) | 
 |   %t3 = sub i8 %x, %t2 | 
 |   ret i8 %t3 | 
 | } | 
 |  | 
 | ; `extractelement` is negatible if source operand is negatible. | 
 | define i4 @negate_extractelement(<2 x i4> %x, i32 %y, i4 %z) { | 
 | ; CHECK-LABEL: @negate_extractelement( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]]) | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = extractelement <2 x i4> [[X]], i32 [[Y:%.*]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]] | 
 | ; CHECK-NEXT:    ret i4 [[T2]] | 
 | ; | 
 |   %t0 = sub <2 x i4> zeroinitializer, %x | 
 |   call void @use_v2i4(<2 x i4> %t0) | 
 |   %t1 = extractelement <2 x i4> %t0, i32 %y | 
 |   %t2 = sub i4 %z, %t1 | 
 |   ret i4 %t2 | 
 | } | 
 | define i4 @negate_extractelement_extrause(<2 x i4> %x, i32 %y, i4 %z) { | 
 | ; CHECK-LABEL: @negate_extractelement_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = extractelement <2 x i4> [[T0]], i32 [[Y:%.*]] | 
 | ; CHECK-NEXT:    call void @use4(i4 [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i4 [[T2]] | 
 | ; | 
 |   %t0 = sub <2 x i4> zeroinitializer, %x | 
 |   call void @use_v2i4(<2 x i4> %t0) | 
 |   %t1 = extractelement <2 x i4> %t0, i32 %y | 
 |   call void @use4(i4 %t1) | 
 |   %t2 = sub i4 %z, %t1 | 
 |   ret i4 %t2 | 
 | } | 
 |  | 
 | ; `insertelement` is negatible if both source vector and element-to-be-inserted are negatible. | 
 | define <2 x i4> @negate_insertelement(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) { | 
 | ; CHECK-LABEL: @negate_insertelement( | 
 | ; CHECK-NEXT:    [[T2_NEG:%.*]] = insertelement <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[B:%.*]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[T3]] | 
 | ; | 
 |   %t0 = sub <2 x i4> zeroinitializer, %src | 
 |   %t1 = sub i4 zeroinitializer, %a | 
 |   %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x | 
 |   %t3 = sub <2 x i4> %b, %t2 | 
 |   ret <2 x i4> %t3 | 
 | } | 
 | define <2 x i4> @negate_insertelement_extrause(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) { | 
 | ; CHECK-LABEL: @negate_insertelement_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A:%.*]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[T1]], i32 [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T2]]) | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[T3]] | 
 | ; | 
 |   %t0 = sub <2 x i4> zeroinitializer, %src | 
 |   %t1 = sub i4 zeroinitializer, %a | 
 |   %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x | 
 |   call void @use_v2i4(<2 x i4> %t2) | 
 |   %t3 = sub <2 x i4> %b, %t2 | 
 |   ret <2 x i4> %t3 | 
 | } | 
 | define <2 x i4> @negate_insertelement_nonnegatible_base(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) { | 
 | ; CHECK-LABEL: @negate_insertelement_nonnegatible_base( | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A:%.*]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[SRC:%.*]], i4 [[T1]], i32 [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[T3]] | 
 | ; | 
 |   %t1 = sub i4 zeroinitializer, %a | 
 |   %t2 = insertelement <2 x i4> %src, i4 %t1, i32 %x | 
 |   %t3 = sub <2 x i4> %b, %t2 | 
 |   ret <2 x i4> %t3 | 
 | } | 
 | define <2 x i4> @negate_insertelement_nonnegatible_insert(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) { | 
 | ; CHECK-LABEL: @negate_insertelement_nonnegatible_insert( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC:%.*]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[A:%.*]], i32 [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B:%.*]], [[T2]] | 
 | ; CHECK-NEXT:    ret <2 x i4> [[T3]] | 
 | ; | 
 |   %t0 = sub <2 x i4> zeroinitializer, %src | 
 |   %t2 = insertelement <2 x i4> %t0, i4 %a, i32 %x | 
 |   %t3 = sub <2 x i4> %b, %t2 | 
 |   ret <2 x i4> %t3 | 
 | } | 
 |  | 
 | ; left-shift by constant can always be negated | 
 | define i8 @negate_left_shift_by_constant_prefer_keeping_shl(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @negate_left_shift_by_constant_prefer_keeping_shl( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Z]], 4 | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %z | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, 4 | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @negate_left_shift_by_constant_prefer_keeping_shl_extrause(i8 %x, i8 %y, i8 %z) { | 
 | ; CHECK-LABEL: @negate_left_shift_by_constant_prefer_keeping_shl_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 4 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %z | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, 4 | 
 |   call void @use8(i8 %t1) | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @negate_left_shift_by_constant(i8 %x, i8 %y, i8 %z, i8 %k) { | 
 | ; CHECK-LABEL: @negate_left_shift_by_constant( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 4 | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 %k, %z | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, 4 | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @negate_left_shift_by_constant_extrause(i8 %x, i8 %y, i8 %z, i8 %k) { | 
 | ; CHECK-LABEL: @negate_left_shift_by_constant_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K:%.*]], [[Z:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 4 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 %k, %z | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = shl i8 %t0, 4 | 
 |   call void @use8(i8 %t1) | 
 |   %t2 = sub i8 %x, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 |  | 
 | ; `add` with single negatible operand is still negatible | 
 | define i8 @negate_add_with_single_negatible_operand(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_add_with_single_negatible_operand( | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = add i8 %x, 42 | 
 |   %t1 = sub i8 0, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | ; do so even if we are two levels deep | 
 | define i8 @negate_add_with_single_negatible_operand_depth2(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_add_with_single_negatible_operand_depth2( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 -21, [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[T0_NEG]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T1_NEG]] | 
 | ; | 
 |   %t0 = add i8 %x, 21 | 
 |   %t1 = mul i8 %t0, %y | 
 |   %t2 = sub i8 0, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 |  | 
 | define i8 @negate_add_with_single_negatible_operand_extrause(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_add_with_single_negatible_operand_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42 | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = add i8 %x, 42 | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = sub i8 0, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 | ; But don't do this if that means just sinking the negation. | 
 | define i8 @negate_add_with_single_negatible_operand_non_negation(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_add_with_single_negatible_operand_non_negation( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X:%.*]], 42 | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Y:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = add i8 %x, 42 | 
 |   %t1 = sub i8 %y, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 |  | 
 | ; abs/nabs can be negated | 
 | define i8 @negate_abs(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_abs( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false) | 
 | ; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[Y:%.*]], [[T2]] | 
 | ; CHECK-NEXT:    ret i8 [[T3]] | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = icmp slt i8 %x, 0 | 
 |   %t2 = select i1 %t1, i8 %t0, i8 %x, !prof !0 | 
 |   %t3 = sub i8 %y, %t2 | 
 |   ret i8 %t3 | 
 | } | 
 | define i8 @negate_nabs(i8 %x, i8 %y) { | 
 | ; CHECK-LABEL: @negate_nabs( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false) | 
 | ; CHECK-NEXT:    [[T3:%.*]] = add i8 [[TMP1]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T3]] | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = icmp slt i8 %x, 0 | 
 |   %t2 = select i1 %t1, i8 %x, i8 %t0, !prof !0 | 
 |   %t3 = sub i8 %y, %t2 | 
 |   ret i8 %t3 | 
 | } | 
 |  | 
 | ; And in general, if hands of select are known to be negation of each other, | 
 | ; we can negate the select | 
 | define i8 @negate_select_of_op_vs_negated_op(i8 %x, i8 %y, i1 %c) { | 
 | ; CHECK-LABEL: @negate_select_of_op_vs_negated_op( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X:%.*]] | 
 | ; CHECK-NEXT:    call void @use8(i8 [[T0]]) | 
 | ; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C:%.*]], i8 [[X]], i8 [[T0]], !prof [[PROF0:![0-9]+]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    ret i8 [[T2]] | 
 | ; | 
 |   %t0 = sub i8 0, %x | 
 |   call void @use8(i8 %t0) | 
 |   %t1 = select i1 %c, i8 %t0, i8 %x, !prof !0 | 
 |   %t2 = sub i8 %y, %t1 | 
 |   ret i8 %t2 | 
 | } | 
 | define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) { | 
 | ; CHECK-LABEL: @dont_negate_ordinary_select( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Z:%.*]], [[T0]] | 
 | ; CHECK-NEXT:    ret i8 [[T1]] | 
 | ; | 
 |   %t0 = select i1 %c, i8 %x, i8 %y | 
 |   %t1 = sub i8 %z, %t0 | 
 |   ret i8 %t1 | 
 | } | 
 |  | 
 | ; Freeze is transparent as far as negation is concerned | 
 | define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) { | 
 | ; CHECK-LABEL: @negate_freeze( | 
 | ; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i4 [[Y:%.*]], [[X:%.*]] | 
 | ; CHECK-NEXT:    [[T1_NEG:%.*]] = freeze i4 [[T0_NEG]] | 
 | ; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z:%.*]] | 
 | ; CHECK-NEXT:    ret i4 [[T2]] | 
 | ; | 
 |   %t0 = sub i4 %x, %y | 
 |   %t1 = freeze i4 %t0 | 
 |   %t2 = sub i4 %z, %t1 | 
 |   ret i4 %t2 | 
 | } | 
 | define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) { | 
 | ; CHECK-LABEL: @negate_freeze_extrause( | 
 | ; CHECK-NEXT:    [[T0:%.*]] = sub i4 [[X:%.*]], [[Y:%.*]] | 
 | ; CHECK-NEXT:    [[T1:%.*]] = freeze i4 [[T0]] | 
 | ; CHECK-NEXT:    call void @use4(i4 [[T1]]) | 
 | ; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z:%.*]], [[T1]] | 
 | ; CHECK-NEXT:    ret i4 [[T2]] | 
 | ; | 
 |   %t0 = sub i4 %x, %y | 
 |   %t1 = freeze i4 %t0 | 
 |   call void @use4(i4 %t1) | 
 |   %t2 = sub i4 %z, %t1 | 
 |   ret i4 %t2 | 
 | } | 
 |  | 
 | ; Due to the InstCombine's worklist management, there are no guarantees that | 
 | ; each instruction we'll encounter has been visited by InstCombine already. | 
 | ; In particular, most importantly for us, that means we have to canonicalize | 
 | ; constants to RHS ourselves, since that is helpful sometimes. | 
 | ; This used to cause an endless combine loop. | 
 | define void @noncanonical_mul_with_constant_as_first_operand() { | 
 | ; CHECK-LABEL: @noncanonical_mul_with_constant_as_first_operand( | 
 | ; CHECK-NEXT:  entry: | 
 | ; CHECK-NEXT:    br label [[IF_END:%.*]] | 
 | ; CHECK:       if.end: | 
 | ; CHECK-NEXT:    br label [[IF_END]] | 
 | ; | 
 | entry: | 
 |   br label %if.end | 
 |  | 
 | if.end: | 
 |   %e.0 = phi i32 [ undef, %entry ], [ %div, %if.end ] | 
 |   %conv = trunc i32 %e.0 to i16 | 
 |   %mul.i = mul nsw i16 -1, %conv | 
 |   %conv1 = sext i16 %mul.i to i32 | 
 |   %div = sub nsw i32 0, %conv1 | 
 |   br label %if.end | 
 | } | 
 |  | 
 | ; CHECK: !0 = !{!"branch_weights", i32 40, i32 1} | 
 | !0 = !{!"branch_weights", i32 40, i32 1} |