brintos

brintos / llvm-project-archived public Read only

0
0
Text · 48.4 KiB · 109669e Raw
1505 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use4(i4)5declare void @use8(i8)6declare void @use_v2i4(<2 x i4>)7declare i1 @use32gen1(i32)8 9; Constant can be freely negated.10define i8 @t0(i8 %x) {11; CHECK-LABEL: define i8 @t0(12; CHECK-SAME: i8 [[X:%.*]]) {13; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X]], 4214; CHECK-NEXT:    ret i8 [[T0]]15;16  %t0 = sub i8 %x, -4217  ret i8 %t018}19 20; Negation can be negated for free21define i8 @t1(i8 %x, i8 %y) {22; CHECK-LABEL: define i8 @t1(23; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {24; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]25; CHECK-NEXT:    call void @use8(i8 [[T0]])26; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X]], [[Y]]27; CHECK-NEXT:    ret i8 [[T1]]28;29  %t0 = sub i8 0, %y30  call void @use8(i8 %t0)31  %t1 = sub i8 %x, %t032  ret i8 %t133}34 35; Shift-left can be negated if all uses can be updated36define i8 @t2(i8 %x, i8 %y) {37; CHECK-LABEL: define i8 @t2(38; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {39; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i8 42, [[Y]]40; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X]]41; CHECK-NEXT:    ret i8 [[T1]]42;43  %t0 = shl i8 -42, %y44  %t1 = sub i8 %x, %t045  ret i8 %t146}47define i8 @n2(i8 %x, i8 %y) {48; CHECK-LABEL: define i8 @n2(49; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {50; CHECK-NEXT:    [[T0:%.*]] = shl i8 -42, [[Y]]51; CHECK-NEXT:    call void @use8(i8 [[T0]])52; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]53; CHECK-NEXT:    ret i8 [[T1]]54;55  %t0 = shl i8 -42, %y56  call void @use8(i8 %t0)57  %t1 = sub i8 %x, %t058  ret i8 %t159}60define i8 @t3(i8 %x, i8 %y, i8 %z) {61; CHECK-LABEL: define i8 @t3(62; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {63; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z]]64; CHECK-NEXT:    call void @use8(i8 [[T0]])65; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Z]], [[Y]]66; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]67; CHECK-NEXT:    ret i8 [[T2]]68;69  %t0 = sub i8 0, %z70  call void @use8(i8 %t0)71  %t1 = shl i8 %t0, %y72  %t2 = sub i8 %x, %t173  ret i8 %t274}75define i8 @n3(i8 %x, i8 %y, i8 %z) {76; CHECK-LABEL: define i8 @n3(77; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {78; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z]]79; CHECK-NEXT:    call void @use8(i8 [[T0]])80; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], [[Y]]81; CHECK-NEXT:    call void @use8(i8 [[T1]])82; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]83; CHECK-NEXT:    ret i8 [[T2]]84;85  %t0 = sub i8 0, %z86  call void @use8(i8 %t0)87  %t1 = shl i8 %t0, %y88  call void @use8(i8 %t1)89  %t2 = sub i8 %x, %t190  ret i8 %t291}92 93; Select can be negated if all it's operands can be negated and all the users of select can be updated94define i8 @t4(i8 %x, i1 %y) {95; CHECK-LABEL: define i8 @t4(96; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {97; CHECK-NEXT:    [[T0_NEG:%.*]] = select i1 [[Y]], i8 42, i8 -4498; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X]]99; CHECK-NEXT:    ret i8 [[T1]]100;101  %t0 = select i1 %y, i8 -42, i8 44102  %t1 = sub i8 %x, %t0103  ret i8 %t1104}105define i8 @n4(i8 %x, i1 %y) {106; CHECK-LABEL: define i8 @n4(107; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {108; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y]], i8 -42, i8 44109; CHECK-NEXT:    call void @use8(i8 [[T0]])110; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]111; CHECK-NEXT:    ret i8 [[T1]]112;113  %t0 = select i1 %y, i8 -42, i8 44114  call void @use8(i8 %t0)115  %t1 = sub i8 %x, %t0116  ret i8 %t1117}118define i8 @n5(i8 %x, i1 %y, i8 %z) {119; CHECK-LABEL: define i8 @n5(120; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]], i8 [[Z:%.*]]) {121; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y]], i8 -42, i8 [[Z]]122; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]123; CHECK-NEXT:    ret i8 [[T1]]124;125  %t0 = select i1 %y, i8 -42, i8 %z126  %t1 = sub i8 %x, %t0127  ret i8 %t1128}129define i8 @t6(i8 %x, i1 %y, i8 %z) {130; CHECK-LABEL: define i8 @t6(131; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]], i8 [[Z:%.*]]) {132; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z]]133; CHECK-NEXT:    call void @use8(i8 [[T0]])134; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y]], i8 42, i8 [[Z]]135; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]136; CHECK-NEXT:    ret i8 [[T2]]137;138  %t0 = sub i8 0, %z139  call void @use8(i8 %t0)140  %t1 = select i1 %y, i8 -42, i8 %t0141  %t2 = sub i8 %x, %t1142  ret i8 %t2143}144define i8 @t7(i8 %x, i1 %y, i8 %z) {145; CHECK-LABEL: define i8 @t7(146; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]], i8 [[Z:%.*]]) {147; CHECK-NEXT:    [[T0_NEG:%.*]] = shl nsw i8 -1, [[Z]]148; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y]], i8 0, i8 [[T0_NEG]]149; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]150; CHECK-NEXT:    ret i8 [[T2]]151;152  %t0 = shl i8 1, %z153  %t1 = select i1 %y, i8 0, i8 %t0154  %t2 = sub i8 %x, %t1155  ret i8 %t2156}157define i8 @n8(i8 %x, i1 %y, i8 %z) {158; CHECK-LABEL: define i8 @n8(159; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]], i8 [[Z:%.*]]) {160; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[Z]]161; CHECK-NEXT:    call void @use8(i8 [[T0]])162; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y]], i8 0, i8 [[T0]]163; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]164; CHECK-NEXT:    ret i8 [[T2]]165;166  %t0 = shl i8 1, %z167  call void @use8(i8 %t0)168  %t1 = select i1 %y, i8 0, i8 %t0169  %t2 = sub i8 %x, %t1170  ret i8 %t2171}172 173; Subtraction can be negated by swapping its operands.174; x - (y - z) -> x - y + z -> x + (z - y)175define i8 @t9(i8 %x, i8 %y) {176; CHECK-LABEL: define i8 @t9(177; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {178; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 [[X]], [[Y]]179; CHECK-NEXT:    ret i8 [[T0_NEG]]180;181  %t0 = sub i8 %y, %x182  %t1 = sub i8 0, %t0183  ret i8 %t1184}185 186define i8 @n10(i8 %x, i8 %y, i8 %z) {187; CHECK-LABEL: define i8 @n10(188; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {189; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[Y]], [[X]]190; CHECK-NEXT:    call void @use8(i8 [[T0]])191; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[T0]]192; CHECK-NEXT:    ret i8 [[T1]]193;194  %t0 = sub i8 %y, %x195  call void @use8(i8 %t0)196  %t1 = sub i8 0, %t0197  ret i8 %t1198}199 200define i8 @neg_of_sub_from_constant(i8 %x) {201; CHECK-LABEL: define i8 @neg_of_sub_from_constant(202; CHECK-SAME: i8 [[X:%.*]]) {203; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X]], -42204; CHECK-NEXT:    ret i8 [[S_NEG]]205;206  %s = sub i8 42, %x207  %r = sub i8 0, %s208  ret i8 %r209}210 211define i8 @neg_of_sub_from_constant_multi_use(i8 %x) {212; CHECK-LABEL: define i8 @neg_of_sub_from_constant_multi_use(213; CHECK-SAME: i8 [[X:%.*]]) {214; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X]], -42215; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]]216; CHECK-NEXT:    call void @use8(i8 [[S]])217; CHECK-NEXT:    ret i8 [[S_NEG]]218;219  %s = sub i8 42, %x220  call void @use8(i8 %s)221  %r = sub i8 0, %s222  ret i8 %r223}224 225define i8 @sub_from_constant_of_sub_from_constant(i8 %x) {226; CHECK-LABEL: define i8 @sub_from_constant_of_sub_from_constant(227; CHECK-SAME: i8 [[X:%.*]]) {228; CHECK-NEXT:    [[R:%.*]] = add i8 [[X]], -31229; CHECK-NEXT:    ret i8 [[R]]230;231  %s = sub i8 42, %x232  %r = sub i8 11, %s233  ret i8 %r234}235 236define i8 @sub_from_constant_of_sub_from_constant_multi_use(i8 %x) {237; CHECK-LABEL: define i8 @sub_from_constant_of_sub_from_constant_multi_use(238; CHECK-SAME: i8 [[X:%.*]]) {239; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]]240; CHECK-NEXT:    call void @use8(i8 [[S]])241; CHECK-NEXT:    [[R:%.*]] = add i8 [[X]], -31242; CHECK-NEXT:    ret i8 [[R]]243;244  %s = sub i8 42, %x245  call void @use8(i8 %s)246  %r = sub i8 11, %s247  ret i8 %r248}249 250define i8 @sub_from_variable_of_sub_from_constant(i8 %x, i8 %y) {251; CHECK-LABEL: define i8 @sub_from_variable_of_sub_from_constant(252; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {253; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X]], -42254; CHECK-NEXT:    [[R:%.*]] = add i8 [[S_NEG]], [[Y]]255; CHECK-NEXT:    ret i8 [[R]]256;257  %s = sub i8 42, %x258  %r = sub i8 %y, %s259  ret i8 %r260}261 262define i8 @sub_from_variable_of_sub_from_constant_multi_use(i8 %x, i8 %y) {263; CHECK-LABEL: define i8 @sub_from_variable_of_sub_from_constant_multi_use(264; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {265; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]]266; CHECK-NEXT:    call void @use8(i8 [[S]])267; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y]], [[S]]268; CHECK-NEXT:    ret i8 [[R]]269;270  %s = sub i8 42, %x271  call void @use8(i8 %s)272  %r = sub i8 %y, %s273  ret i8 %r274}275 276; Addition can be negated if both operands can be negated277; x - (y + z) -> x - y - z -> x + ((-y) + (-z)))278define i8 @t12(i8 %x, i8 %y, i8 %z) {279; CHECK-LABEL: define i8 @t12(280; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {281; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]282; CHECK-NEXT:    call void @use8(i8 [[T0]])283; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z]]284; CHECK-NEXT:    call void @use8(i8 [[T1]])285; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]286; CHECK-NEXT:    [[T3:%.*]] = add i8 [[X]], [[TMP1]]287; CHECK-NEXT:    ret i8 [[T3]]288;289  %t0 = sub i8 0, %y290  call void @use8(i8 %t0)291  %t1 = sub i8 0, %z292  call void @use8(i8 %t1)293  %t2 = add i8 %t0, %t1294  %t3 = sub i8 %x, %t2295  ret i8 %t3296}297define i8 @n13(i8 %x, i8 %y, i8 %z) {298; CHECK-LABEL: define i8 @n13(299; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {300; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]301; CHECK-NEXT:    call void @use8(i8 [[T0]])302; CHECK-NEXT:    [[T1_NEG:%.*]] = sub i8 [[Y]], [[Z]]303; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]304; CHECK-NEXT:    ret i8 [[T2]]305;306  %t0 = sub i8 0, %y307  call void @use8(i8 %t0)308  %t1 = add i8 %t0, %z309  %t2 = sub i8 %x, %t1310  ret i8 %t2311}312define i8 @n14(i8 %x, i8 %y, i8 %z) {313; CHECK-LABEL: define i8 @n14(314; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {315; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]316; CHECK-NEXT:    call void @use8(i8 [[T0]])317; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z]]318; CHECK-NEXT:    call void @use8(i8 [[T1]])319; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]320; CHECK-NEXT:    [[T2:%.*]] = sub i8 0, [[TMP1]]321; CHECK-NEXT:    call void @use8(i8 [[T2]])322; CHECK-NEXT:    [[T3:%.*]] = add i8 [[X]], [[TMP1]]323; CHECK-NEXT:    ret i8 [[T3]]324;325  %t0 = sub i8 0, %y326  call void @use8(i8 %t0)327  %t1 = sub i8 0, %z328  call void @use8(i8 %t1)329  %t2 = add i8 %t0, %t1330  call void @use8(i8 %t2)331  %t3 = sub i8 %x, %t2332  ret i8 %t3333}334 335define i8 @neg_of_add_with_constant(i8 %x) {336; CHECK-LABEL: define i8 @neg_of_add_with_constant(337; CHECK-SAME: i8 [[X:%.*]]) {338; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X]]339; CHECK-NEXT:    ret i8 [[R]]340;341  %s = add i8 %x, 42342  %r = sub i8 0, %s343  ret i8 %r344}345 346define i8 @neg_of_add_with_constant_multi_use(i8 %x) {347; CHECK-LABEL: define i8 @neg_of_add_with_constant_multi_use(348; CHECK-SAME: i8 [[X:%.*]]) {349; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], 42350; CHECK-NEXT:    call void @use8(i8 [[S]])351; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X]]352; CHECK-NEXT:    ret i8 [[R]]353;354  %s = add i8 %x, 42355  call void @use8(i8 %s)356  %r = sub i8 0, %s357  ret i8 %r358}359 360define i8 @sub_from_constant_of_add_with_constant(i8 %x) {361; CHECK-LABEL: define i8 @sub_from_constant_of_add_with_constant(362; CHECK-SAME: i8 [[X:%.*]]) {363; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X]]364; CHECK-NEXT:    ret i8 [[R]]365;366  %s = add i8 %x, 42367  %r = sub i8 11, %s368  ret i8 %r369}370 371define i8 @sub_from_constant_of_add_with_constant_multi_use(i8 %x) {372; CHECK-LABEL: define i8 @sub_from_constant_of_add_with_constant_multi_use(373; CHECK-SAME: i8 [[X:%.*]]) {374; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], 42375; CHECK-NEXT:    call void @use8(i8 [[S]])376; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X]]377; CHECK-NEXT:    ret i8 [[R]]378;379  %s = add i8 %x, 42380  call void @use8(i8 %s)381  %r = sub i8 11, %s382  ret i8 %r383}384 385define i8 @sub_from_variable_of_add_with_constant(i8 %x, i8 %y) {386; CHECK-LABEL: define i8 @sub_from_variable_of_add_with_constant(387; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {388; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], 42389; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y]], [[S]]390; CHECK-NEXT:    ret i8 [[R]]391;392  %s = add i8 %x, 42393  %r = sub i8 %y, %s394  ret i8 %r395}396 397define i8 @sub_from_variable_of_add_with_constant_multi_use(i8 %x, i8 %y) {398; CHECK-LABEL: define i8 @sub_from_variable_of_add_with_constant_multi_use(399; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {400; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], 42401; CHECK-NEXT:    call void @use8(i8 [[S]])402; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y]], [[S]]403; CHECK-NEXT:    ret i8 [[R]]404;405  %s = add i8 %x, 42406  call void @use8(i8 %s)407  %r = sub i8 %y, %s408  ret i8 %r409}410 411; Multiplication can be negated if either one of operands can be negated412; x - (y * z) -> x + ((-y) * z) or  x + ((-z) * y)413define i8 @t15(i8 %x, i8 %y, i8 %z) {414; CHECK-LABEL: define i8 @t15(415; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {416; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]417; CHECK-NEXT:    call void @use8(i8 [[T0]])418; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[Y]], [[Z]]419; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]420; CHECK-NEXT:    ret i8 [[T2]]421;422  %t0 = sub i8 0, %y423  call void @use8(i8 %t0)424  %t1 = mul i8 %t0, %z425  %t2 = sub i8 %x, %t1426  ret i8 %t2427}428define i8 @n16(i8 %x, i8 %y, i8 %z) {429; CHECK-LABEL: define i8 @n16(430; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {431; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]432; CHECK-NEXT:    call void @use8(i8 [[T0]])433; CHECK-NEXT:    [[T1:%.*]] = mul i8 [[Z]], [[T0]]434; CHECK-NEXT:    call void @use8(i8 [[T1]])435; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]436; CHECK-NEXT:    ret i8 [[T2]]437;438  %t0 = sub i8 0, %y439  call void @use8(i8 %t0)440  %t1 = mul i8 %t0, %z441  call void @use8(i8 %t1)442  %t2 = sub i8 %x, %t1443  ret i8 %t2444}445 446; Phi can be negated if all incoming values can be negated447define i8 @t16(i1 %c, i8 %x) {448; CHECK-LABEL: define i8 @t16(449; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]]) {450; CHECK-NEXT:  [[BEGIN:.*:]]451; CHECK-NEXT:    br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]452; CHECK:       [[THEN]]:453; CHECK-NEXT:    br label %[[END:.*]]454; CHECK:       [[ELSE]]:455; CHECK-NEXT:    br label %[[END]]456; CHECK:       [[END]]:457; CHECK-NEXT:    [[Z_NEG:%.*]] = phi i8 [ [[X]], %[[THEN]] ], [ 42, %[[ELSE]] ]458; CHECK-NEXT:    ret i8 [[Z_NEG]]459;460begin:461  br i1 %c, label %then, label %else462then:463  %y = sub i8 0, %x464  br label %end465else:466  br label %end467end:468  %z = phi i8 [ %y, %then], [ -42, %else ]469  %n = sub i8 0, %z470  ret i8 %n471}472define i8 @n17(i1 %c, i8 %x) {473; CHECK-LABEL: define i8 @n17(474; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]]) {475; CHECK-NEXT:  [[BEGIN:.*:]]476; CHECK-NEXT:    br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]477; CHECK:       [[THEN]]:478; CHECK-NEXT:    [[Y:%.*]] = sub i8 0, [[X]]479; CHECK-NEXT:    br label %[[END:.*]]480; CHECK:       [[ELSE]]:481; CHECK-NEXT:    br label %[[END]]482; CHECK:       [[END]]:483; CHECK-NEXT:    [[Z:%.*]] = phi i8 [ [[Y]], %[[THEN]] ], [ -42, %[[ELSE]] ]484; CHECK-NEXT:    call void @use8(i8 [[Z]])485; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[Z]]486; CHECK-NEXT:    ret i8 [[N]]487;488begin:489  br i1 %c, label %then, label %else490then:491  %y = sub i8 0, %x492  br label %end493else:494  br label %end495end:496  %z = phi i8 [ %y, %then], [ -42, %else ]497  call void @use8(i8 %z)498  %n = sub i8 0, %z499  ret i8 %n500}501define i8 @n19(i1 %c, i8 %x, i8 %y) {502; CHECK-LABEL: define i8 @n19(503; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {504; CHECK-NEXT:  [[BEGIN:.*:]]505; CHECK-NEXT:    br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]506; CHECK:       [[THEN]]:507; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[X]]508; CHECK-NEXT:    br label %[[END:.*]]509; CHECK:       [[ELSE]]:510; CHECK-NEXT:    br label %[[END]]511; CHECK:       [[END]]:512; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[Z]], %[[THEN]] ], [ [[Y]], %[[ELSE]] ]513; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[R]]514; CHECK-NEXT:    ret i8 [[N]]515;516begin:517  br i1 %c, label %then, label %else518then:519  %z = sub i8 0, %x520  br label %end521else:522  br label %end523end:524  %r = phi i8 [ %z, %then], [ %y, %else ]525  %n = sub i8 0, %r526  ret i8 %n527}528define void @phi_with_duplicate_incoming_basic_blocks(i32 %x, i32 %y, i1 %should_lookup, i32 %z) {529; CHECK-LABEL: define void @phi_with_duplicate_incoming_basic_blocks(530; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[SHOULD_LOOKUP:%.*]], i32 [[Z:%.*]]) {531; CHECK-NEXT:  [[ENTRY:.*]]:532; CHECK-NEXT:    [[X_INC_NEG:%.*]] = xor i32 [[X]], -1533; CHECK-NEXT:    br i1 [[SHOULD_LOOKUP]], label %[[LOOKUP:.*]], label %[[LOOP:.*]]534; CHECK:       [[LOOKUP]]:535; CHECK-NEXT:    [[TO_LOOKUP:%.*]] = phi i32 [ [[Y]], %[[ENTRY]] ], [ [[METAVAL_NEG:%.*]], %[[LOOP]] ]536; CHECK-NEXT:    switch i32 [[TO_LOOKUP]], label %[[END:.*]] [537; CHECK-NEXT:      i32 0, label %[[LOOP]]538; CHECK-NEXT:      i32 42, label %[[LOOP]]539; CHECK-NEXT:    ]540; CHECK:       [[LOOP]]:541; CHECK-NEXT:    [[METAVAL_NEG]] = phi i32 [ [[X_INC_NEG]], %[[LOOKUP]] ], [ [[X_INC_NEG]], %[[LOOKUP]] ], [ -84, %[[ENTRY]] ]542; CHECK-NEXT:    [[REPEAT:%.*]] = call i1 @use32gen1(i32 [[METAVAL_NEG]])543; CHECK-NEXT:    br i1 [[REPEAT]], label %[[LOOKUP]], label %[[END]]544; CHECK:       [[END]]:545; CHECK-NEXT:    ret void546;547entry:548  %x_inc = add i32 %x, 1549  br i1 %should_lookup, label %lookup, label %loop550 551lookup:552  %to_lookup = phi i32 [ %y, %entry ], [ %negated_metaval, %loop ]553  switch i32 %to_lookup, label %end [554  i32 0, label %loop555  i32 42, label %loop556  ]557 558loop:559  %metaval = phi i32 [ %x_inc, %lookup ], [ %x_inc, %lookup ], [ 84, %entry ]560  %negated_metaval = sub i32 0, %metaval561  %repeat = call i1 @use32gen1(i32 %negated_metaval)562  br i1 %repeat, label %lookup, label %end563 564end:565  ret void566}567 568; truncation can be negated if it's operand can be negated569define i8 @t20(i8 %x, i16 %y) {570; CHECK-LABEL: define i8 @t20(571; CHECK-SAME: i8 [[X:%.*]], i16 [[Y:%.*]]) {572; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i16 42, [[Y]]573; CHECK-NEXT:    [[T1_NEG:%.*]] = trunc i16 [[T0_NEG]] to i8574; CHECK-NEXT:    [[T2:%.*]] = add i8 [[X]], [[T1_NEG]]575; CHECK-NEXT:    ret i8 [[T2]]576;577  %t0 = shl i16 -42, %y578  %t1 = trunc i16 %t0 to i8579  %t2 = sub i8 %x, %t1580  ret i8 %t2581}582define i8 @n21(i8 %x, i16 %y) {583; CHECK-LABEL: define i8 @n21(584; CHECK-SAME: i8 [[X:%.*]], i16 [[Y:%.*]]) {585; CHECK-NEXT:    [[T0:%.*]] = shl i16 -42, [[Y]]586; CHECK-NEXT:    [[T1:%.*]] = trunc i16 [[T0]] to i8587; CHECK-NEXT:    call void @use8(i8 [[T1]])588; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]589; CHECK-NEXT:    ret i8 [[T2]]590;591  %t0 = shl i16 -42, %y592  %t1 = trunc i16 %t0 to i8593  call void @use8(i8 %t1)594  %t2 = sub i8 %x, %t1595  ret i8 %t2596}597 598define i4 @negate_xor(i4 %x) {599; CHECK-LABEL: define i4 @negate_xor(600; CHECK-SAME: i4 [[X:%.*]]) {601; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X]], -6602; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1603; CHECK-NEXT:    ret i4 [[O_NEG]]604;605  %o = xor i4 %x, 5606  %r = sub i4 0, %o607  ret i4 %r608}609 610define <2 x i4> @negate_xor_vec(<2 x i4> %x) {611; CHECK-LABEL: define <2 x i4> @negate_xor_vec(612; CHECK-SAME: <2 x i4> [[X:%.*]]) {613; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[X]], <i4 -6, i4 5>614; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[TMP1]], splat (i4 1)615; CHECK-NEXT:    ret <2 x i4> [[O_NEG]]616;617  %o = xor <2 x i4> %x, <i4 5, i4 10>618  %r = sub <2 x i4> zeroinitializer, %o619  ret <2 x i4> %r620}621 622define i8 @negate_xor_use(i8 %x) {623; CHECK-LABEL: define i8 @negate_xor_use(624; CHECK-SAME: i8 [[X:%.*]]) {625; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X]], 5626; CHECK-NEXT:    call void @use8(i8 [[O]])627; CHECK-NEXT:    [[R:%.*]] = sub i8 0, [[O]]628; CHECK-NEXT:    ret i8 [[R]]629;630  %o = xor i8 %x, 5631  call void @use8(i8 %o)632  %r = sub i8 0, %o633  ret i8 %r634}635 636define i4 @negate_shl_xor(i4 %x, i4 %y) {637; CHECK-LABEL: define i4 @negate_shl_xor(638; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]]) {639; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X]], -6640; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1641; CHECK-NEXT:    [[S_NEG:%.*]] = shl i4 [[O_NEG]], [[Y]]642; CHECK-NEXT:    ret i4 [[S_NEG]]643;644  %o = xor i4 %x, 5645  %s = shl i4 %o, %y646  %r = sub i4 0, %s647  ret i4 %r648}649 650define i8 @negate_shl_not_uses(i8 %x, i8 %y) {651; CHECK-LABEL: define i8 @negate_shl_not_uses(652; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {653; CHECK-NEXT:    [[O_NEG:%.*]] = add i8 [[X]], 1654; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X]], -1655; CHECK-NEXT:    call void @use8(i8 [[O]])656; CHECK-NEXT:    [[S_NEG:%.*]] = shl i8 [[O_NEG]], [[Y]]657; CHECK-NEXT:    ret i8 [[S_NEG]]658;659  %o = xor i8 %x, -1660  call void @use8(i8 %o)661  %s = shl i8 %o, %y662  %r = sub i8 0, %s663  ret i8 %r664}665 666define <2 x i4> @negate_mul_not_uses_vec(<2 x i4> %x, <2 x i4> %y) {667; CHECK-LABEL: define <2 x i4> @negate_mul_not_uses_vec(668; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]]) {669; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[X]], splat (i4 1)670; CHECK-NEXT:    [[O:%.*]] = xor <2 x i4> [[X]], splat (i4 -1)671; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[O]])672; CHECK-NEXT:    [[S_NEG:%.*]] = mul <2 x i4> [[O_NEG]], [[Y]]673; CHECK-NEXT:    ret <2 x i4> [[S_NEG]]674;675  %o = xor <2 x i4> %x, <i4 -1, i4 -1>676  call void @use_v2i4(<2 x i4> %o)677  %s = mul <2 x i4> %o, %y678  %r = sub <2 x i4> zeroinitializer, %s679  ret <2 x i4> %r680}681 682; signed division can be negated if divisor can be negated and is not 1/-1683define i8 @negate_sdiv(i8 %x, i8 %y) {684; CHECK-LABEL: define i8 @negate_sdiv(685; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {686; CHECK-NEXT:    [[T0_NEG:%.*]] = sdiv i8 [[Y]], -42687; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X]]688; CHECK-NEXT:    ret i8 [[T1]]689;690  %t0 = sdiv i8 %y, 42691  %t1 = sub i8 %x, %t0692  ret i8 %t1693}694define i8 @negate_sdiv_extrause(i8 %x, i8 %y) {695; CHECK-LABEL: define i8 @negate_sdiv_extrause(696; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {697; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y]], 42698; CHECK-NEXT:    call void @use8(i8 [[T0]])699; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]700; CHECK-NEXT:    ret i8 [[T1]]701;702  %t0 = sdiv i8 %y, 42703  call void @use8(i8 %t0)704  %t1 = sub i8 %x, %t0705  ret i8 %t1706}707define i8 @negate_sdiv_extrause2(i8 %x, i8 %y) {708; CHECK-LABEL: define i8 @negate_sdiv_extrause2(709; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {710; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y]], 42711; CHECK-NEXT:    call void @use8(i8 [[T0]])712; CHECK-NEXT:    [[T1:%.*]] = sub nsw i8 0, [[T0]]713; CHECK-NEXT:    ret i8 [[T1]]714;715  %t0 = sdiv i8 %y, 42716  call void @use8(i8 %t0)717  %t1 = sub i8 0, %t0718  ret i8 %t1719}720 721; Right-shift sign bit smear is negatible.722define i8 @negate_ashr(i8 %x, i8 %y) {723; CHECK-LABEL: define i8 @negate_ashr(724; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {725; CHECK-NEXT:    [[T0_NEG:%.*]] = lshr i8 [[Y]], 7726; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X]]727; CHECK-NEXT:    ret i8 [[T1]]728;729  %t0 = ashr i8 %y, 7730  %t1 = sub i8 %x, %t0731  ret i8 %t1732}733define i8 @negate_lshr(i8 %x, i8 %y) {734; CHECK-LABEL: define i8 @negate_lshr(735; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {736; CHECK-NEXT:    [[T0_NEG:%.*]] = ashr i8 [[Y]], 7737; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X]]738; CHECK-NEXT:    ret i8 [[T1]]739;740  %t0 = lshr i8 %y, 7741  %t1 = sub i8 %x, %t0742  ret i8 %t1743}744define i8 @negate_ashr_extrause(i8 %x, i8 %y) {745; CHECK-LABEL: define i8 @negate_ashr_extrause(746; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {747; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y]], 7748; CHECK-NEXT:    call void @use8(i8 [[T0]])749; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]750; CHECK-NEXT:    ret i8 [[T1]]751;752  %t0 = ashr i8 %y, 7753  call void @use8(i8 %t0)754  %t1 = sub i8 %x, %t0755  ret i8 %t1756}757define i8 @negate_lshr_extrause(i8 %x, i8 %y) {758; CHECK-LABEL: define i8 @negate_lshr_extrause(759; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {760; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y]], 7761; CHECK-NEXT:    call void @use8(i8 [[T0]])762; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]763; CHECK-NEXT:    ret i8 [[T1]]764;765  %t0 = lshr i8 %y, 7766  call void @use8(i8 %t0)767  %t1 = sub i8 %x, %t0768  ret i8 %t1769}770define i8 @negate_ashr_wrongshift(i8 %x, i8 %y) {771; CHECK-LABEL: define i8 @negate_ashr_wrongshift(772; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {773; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y]], 6774; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]775; CHECK-NEXT:    ret i8 [[T1]]776;777  %t0 = ashr i8 %y, 6778  %t1 = sub i8 %x, %t0779  ret i8 %t1780}781define i8 @negate_lshr_wrongshift(i8 %x, i8 %y) {782; CHECK-LABEL: define i8 @negate_lshr_wrongshift(783; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {784; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y]], 6785; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]786; CHECK-NEXT:    ret i8 [[T1]]787;788  %t0 = lshr i8 %y, 6789  %t1 = sub i8 %x, %t0790  ret i8 %t1791}792 793; *ext of i1 is always negatible794define i8 @negate_sext(i8 %x, i1 %y) {795; CHECK-LABEL: define i8 @negate_sext(796; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {797; CHECK-NEXT:    [[T0_NEG:%.*]] = zext i1 [[Y]] to i8798; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X]], [[T0_NEG]]799; CHECK-NEXT:    ret i8 [[T1]]800;801  %t0 = sext i1 %y to i8802  %t1 = sub i8 %x, %t0803  ret i8 %t1804}805define i8 @negate_zext(i8 %x, i1 %y) {806; CHECK-LABEL: define i8 @negate_zext(807; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {808; CHECK-NEXT:    [[T0_NEG:%.*]] = sext i1 [[Y]] to i8809; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X]], [[T0_NEG]]810; CHECK-NEXT:    ret i8 [[T1]]811;812  %t0 = zext i1 %y to i8813  %t1 = sub i8 %x, %t0814  ret i8 %t1815}816define i8 @negate_sext_extrause(i8 %x, i1 %y) {817; CHECK-LABEL: define i8 @negate_sext_extrause(818; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {819; CHECK-NEXT:    [[T0:%.*]] = sext i1 [[Y]] to i8820; CHECK-NEXT:    call void @use8(i8 [[T0]])821; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]822; CHECK-NEXT:    ret i8 [[T1]]823;824  %t0 = sext i1 %y to i8825  call void @use8(i8 %t0)826  %t1 = sub i8 %x, %t0827  ret i8 %t1828}829define i8 @negate_zext_extrause(i8 %x, i1 %y) {830; CHECK-LABEL: define i8 @negate_zext_extrause(831; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {832; CHECK-NEXT:    [[T0:%.*]] = zext i1 [[Y]] to i8833; CHECK-NEXT:    call void @use8(i8 [[T0]])834; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]835; CHECK-NEXT:    ret i8 [[T1]]836;837  %t0 = zext i1 %y to i8838  call void @use8(i8 %t0)839  %t1 = sub i8 %x, %t0840  ret i8 %t1841}842define i8 @negate_sext_wrongwidth(i8 %x, i2 %y) {843; CHECK-LABEL: define i8 @negate_sext_wrongwidth(844; CHECK-SAME: i8 [[X:%.*]], i2 [[Y:%.*]]) {845; CHECK-NEXT:    [[T0:%.*]] = sext i2 [[Y]] to i8846; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]847; CHECK-NEXT:    ret i8 [[T1]]848;849  %t0 = sext i2 %y to i8850  %t1 = sub i8 %x, %t0851  ret i8 %t1852}853define i8 @negate_zext_wrongwidth(i8 %x, i2 %y) {854; CHECK-LABEL: define i8 @negate_zext_wrongwidth(855; CHECK-SAME: i8 [[X:%.*]], i2 [[Y:%.*]]) {856; CHECK-NEXT:    [[T0:%.*]] = zext i2 [[Y]] to i8857; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]858; CHECK-NEXT:    ret i8 [[T1]]859;860  %t0 = zext i2 %y to i8861  %t1 = sub i8 %x, %t0862  ret i8 %t1863}864 865define <2 x i4> @negate_shufflevector_oneinput_reverse(<2 x i4> %x, <2 x i4> %y) {866; CHECK-LABEL: define <2 x i4> @negate_shufflevector_oneinput_reverse(867; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]]) {868; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X]]869; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> poison, <2 x i32> <i32 1, i32 0>870; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y]]871; CHECK-NEXT:    ret <2 x i4> [[T2]]872;873  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x874  %t1 = shufflevector <2 x i4> %t0, <2 x i4> poison, <2 x i32> <i32 1, i32 0>875  %t2 = sub <2 x i4> %y, %t1876  ret <2 x i4> %t2877}878define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(<2 x i4> %x, <2 x i4> %y) {879; CHECK-LABEL: define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(880; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]]) {881; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X]]882; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> poison, <2 x i32> <i32 0, i32 poison>883; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y]]884; CHECK-NEXT:    ret <2 x i4> [[T2]]885;886  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x887  %t1 = shufflevector <2 x i4> %t0, <2 x i4> poison, <2 x i32> <i32 0, i32 2>888  %t2 = sub <2 x i4> %y, %t1889  ret <2 x i4> %t2890}891define <2 x i4> @negate_shufflevector_twoinputs(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {892; CHECK-LABEL: define <2 x i4> @negate_shufflevector_twoinputs(893; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]], <2 x i4> [[Z:%.*]]) {894; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X]]895; CHECK-NEXT:    [[T1_NEG:%.*]] = add <2 x i4> [[Y]], <i4 poison, i4 1>896; CHECK-NEXT:    [[T2_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> [[T1_NEG]], <2 x i32> <i32 0, i32 3>897; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[Z]]898; CHECK-NEXT:    ret <2 x i4> [[T3]]899;900  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x901  %t1 = xor <2 x i4> %y, <i4 -1, i4 -1>902  %t2 = shufflevector <2 x i4> %t0, <2 x i4> %t1, <2 x i32> <i32 0, i32 3>903  %t3 = sub <2 x i4> %z, %t2904  ret <2 x i4> %t3905}906define <2 x i4> @negate_shufflevector_oneinput_extrause(<2 x i4> %x, <2 x i4> %y) {907; CHECK-LABEL: define <2 x i4> @negate_shufflevector_oneinput_extrause(908; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]]) {909; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X]]910; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> poison, <2 x i32> <i32 1, i32 0>911; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T1]])912; CHECK-NEXT:    [[T2:%.*]] = sub <2 x i4> [[Y]], [[T1]]913; CHECK-NEXT:    ret <2 x i4> [[T2]]914;915  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x916  %t1 = shufflevector <2 x i4> %t0, <2 x i4> poison, <2 x i32> <i32 1, i32 0>917  call void @use_v2i4(<2 x i4> %t1)918  %t2 = sub <2 x i4> %y, %t1919  ret <2 x i4> %t2920}921 922; zext of non-negative can be negated923; sext of non-positive can be negated924define i16 @negation_of_zeroext_of_nonnegative(i8 %x) {925; CHECK-LABEL: define i16 @negation_of_zeroext_of_nonnegative(926; CHECK-SAME: i8 [[X:%.*]]) {927; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]928; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -1929; CHECK-NEXT:    br i1 [[T1]], label %[[NONNEG_BB:.*]], label %[[NEG_BB:.*]]930; CHECK:       [[NONNEG_BB]]:931; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i16932; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]933; CHECK-NEXT:    ret i16 [[T3]]934; CHECK:       [[NEG_BB]]:935; CHECK-NEXT:    ret i16 0936;937  %t0 = sub i8 0, %x938  %t1 = icmp sge i8 %t0, 0939  br i1 %t1, label %nonneg_bb, label %neg_bb940 941nonneg_bb:942  %t2 = zext i8 %t0 to i16943  %t3 = sub i16 0, %t2944  ret i16 %t3945 946neg_bb:947  ret i16 0948}949define i16 @negation_of_zeroext_of_positive(i8 %x) {950; CHECK-LABEL: define i16 @negation_of_zeroext_of_positive(951; CHECK-SAME: i8 [[X:%.*]]) {952; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]953; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], 0954; CHECK-NEXT:    br i1 [[T1]], label %[[NONNEG_BB:.*]], label %[[NEG_BB:.*]]955; CHECK:       [[NONNEG_BB]]:956; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i16957; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]958; CHECK-NEXT:    ret i16 [[T3]]959; CHECK:       [[NEG_BB]]:960; CHECK-NEXT:    ret i16 0961;962  %t0 = sub i8 0, %x963  %t1 = icmp sgt i8 %t0, 0964  br i1 %t1, label %nonneg_bb, label %neg_bb965 966nonneg_bb:967  %t2 = zext i8 %t0 to i16968  %t3 = sub i16 0, %t2969  ret i16 %t3970 971neg_bb:972  ret i16 0973}974define i16 @negation_of_signext_of_negative(i8 %x) {975; CHECK-LABEL: define i16 @negation_of_signext_of_negative(976; CHECK-SAME: i8 [[X:%.*]]) {977; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]978; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 0979; CHECK-NEXT:    br i1 [[T1]], label %[[NEG_BB:.*]], label %[[NONNEG_BB:.*]]980; CHECK:       [[NEG_BB]]:981; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i16982; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]983; CHECK-NEXT:    ret i16 [[T3]]984; CHECK:       [[NONNEG_BB]]:985; CHECK-NEXT:    ret i16 0986;987  %t0 = sub i8 0, %x988  %t1 = icmp slt i8 %t0, 0989  br i1 %t1, label %neg_bb, label %nonneg_bb990 991neg_bb:992  %t2 = sext i8 %t0 to i16993  %t3 = sub i16 0, %t2994  ret i16 %t3995 996nonneg_bb:997  ret i16 0998}999define i16 @negation_of_signext_of_nonpositive(i8 %x) {1000; CHECK-LABEL: define i16 @negation_of_signext_of_nonpositive(1001; CHECK-SAME: i8 [[X:%.*]]) {1002; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1003; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 11004; CHECK-NEXT:    br i1 [[T1]], label %[[NEG_BB:.*]], label %[[NONNEG_BB:.*]]1005; CHECK:       [[NEG_BB]]:1006; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i161007; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]1008; CHECK-NEXT:    ret i16 [[T3]]1009; CHECK:       [[NONNEG_BB]]:1010; CHECK-NEXT:    ret i16 01011;1012  %t0 = sub i8 0, %x1013  %t1 = icmp sle i8 %t0, 01014  br i1 %t1, label %neg_bb, label %nonneg_bb1015 1016neg_bb:1017  %t2 = sext i8 %t0 to i161018  %t3 = sub i16 0, %t21019  ret i16 %t31020 1021nonneg_bb:1022  ret i16 01023}1024define i16 @negation_of_signext_of_nonnegative__wrong_cast(i8 %x) {1025; CHECK-LABEL: define i16 @negation_of_signext_of_nonnegative__wrong_cast(1026; CHECK-SAME: i8 [[X:%.*]]) {1027; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1028; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -11029; CHECK-NEXT:    br i1 [[T1]], label %[[NONNEG_BB:.*]], label %[[NEG_BB:.*]]1030; CHECK:       [[NONNEG_BB]]:1031; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i161032; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]1033; CHECK-NEXT:    ret i16 [[T3]]1034; CHECK:       [[NEG_BB]]:1035; CHECK-NEXT:    ret i16 01036;1037  %t0 = sub i8 0, %x1038  %t1 = icmp sge i8 %t0, 01039  br i1 %t1, label %nonneg_bb, label %neg_bb1040 1041nonneg_bb:1042  %t2 = sext i8 %t0 to i161043  %t3 = sub i16 0, %t21044  ret i16 %t31045 1046neg_bb:1047  ret i16 01048}1049define i16 @negation_of_zeroext_of_negative_wrongcast(i8 %x) {1050; CHECK-LABEL: define i16 @negation_of_zeroext_of_negative_wrongcast(1051; CHECK-SAME: i8 [[X:%.*]]) {1052; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1053; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 01054; CHECK-NEXT:    br i1 [[T1]], label %[[NEG_BB:.*]], label %[[NONNEG_BB:.*]]1055; CHECK:       [[NEG_BB]]:1056; CHECK-NEXT:    [[T2:%.*]] = zext i8 [[T0]] to i161057; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]1058; CHECK-NEXT:    ret i16 [[T3]]1059; CHECK:       [[NONNEG_BB]]:1060; CHECK-NEXT:    ret i16 01061;1062  %t0 = sub i8 0, %x1063  %t1 = icmp slt i8 %t0, 01064  br i1 %t1, label %neg_bb, label %nonneg_bb1065 1066neg_bb:1067  %t2 = zext i8 %t0 to i161068  %t3 = sub i16 0, %t21069  ret i16 %t31070 1071nonneg_bb:1072  ret i16 01073}1074 1075; 'or' of 1 and operand with no lowest bit set is 'inc'1076define i8 @negation_of_increment_via_or_with_no_common_bits_set(i8 %x, i8 %y) {1077; CHECK-LABEL: define i8 @negation_of_increment_via_or_with_no_common_bits_set(1078; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1079; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y]], 11080; CHECK-NEXT:    [[T1_NEG:%.*]] = xor i8 [[T0]], -11081; CHECK-NEXT:    [[T2:%.*]] = add i8 [[X]], [[T1_NEG]]1082; CHECK-NEXT:    ret i8 [[T2]]1083;1084  %t0 = shl i8 %y, 11085  %t1 = or i8 %t0, 11086  %t2 = sub i8 %x, %t11087  ret i8 %t21088}1089define i8 @negation_of_increment_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) {1090; CHECK-LABEL: define i8 @negation_of_increment_via_or_with_no_common_bits_set_extrause(1091; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1092; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y]], 11093; CHECK-NEXT:    [[T1:%.*]] = or disjoint i8 [[T0]], 11094; CHECK-NEXT:    call void @use8(i8 [[T1]])1095; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1096; CHECK-NEXT:    ret i8 [[T2]]1097;1098  %t0 = shl i8 %y, 11099  %t1 = or i8 %t0, 11100  call void @use8(i8 %t1)1101  %t2 = sub i8 %x, %t11102  ret i8 %t21103}1104define i8 @negation_of_increment_via_or_common_bits_set(i8 %x, i8 %y) {1105; CHECK-LABEL: define i8 @negation_of_increment_via_or_common_bits_set(1106; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1107; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y]], 11108; CHECK-NEXT:    [[T1:%.*]] = or i8 [[T0]], 31109; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1110; CHECK-NEXT:    ret i8 [[T2]]1111;1112  %t0 = shl i8 %y, 11113  %t1 = or i8 %t0, 31114  %t2 = sub i8 %x, %t11115  ret i8 %t21116}1117 1118; 'or' of operands with no common bits set is 'add'1119define i8 @add_via_or_with_no_common_bits_set(i8 %x, i8 %y) {1120; CHECK-LABEL: define i8 @add_via_or_with_no_common_bits_set(1121; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1122; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]1123; CHECK-NEXT:    call void @use8(i8 [[T0]])1124; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Y]], 21125; CHECK-NEXT:    [[T2_NEG:%.*]] = add i8 [[T1_NEG]], -31126; CHECK-NEXT:    [[T3:%.*]] = add i8 [[T2_NEG]], [[X]]1127; CHECK-NEXT:    ret i8 [[T3]]1128;1129  %t0 = sub i8 0, %y1130  call void @use8(i8 %t0)1131  %t1 = shl i8 %t0, 21132  %t2 = or i8 %t1, 31133  %t3 = sub i8 %x, %t21134  ret i8 %t31135}1136define i8 @add_via_or_with_common_bit_maybe_set(i8 %x, i8 %y) {1137; CHECK-LABEL: define i8 @add_via_or_with_common_bit_maybe_set(1138; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1139; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]1140; CHECK-NEXT:    call void @use8(i8 [[T0]])1141; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 21142; CHECK-NEXT:    [[T2:%.*]] = or i8 [[T1]], 41143; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X]], [[T2]]1144; CHECK-NEXT:    ret i8 [[T3]]1145;1146  %t0 = sub i8 0, %y1147  call void @use8(i8 %t0)1148  %t1 = shl i8 %t0, 21149  %t2 = or i8 %t1, 41150  %t3 = sub i8 %x, %t21151  ret i8 %t31152}1153define i8 @add_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) {1154; CHECK-LABEL: define i8 @add_via_or_with_no_common_bits_set_extrause(1155; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1156; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]1157; CHECK-NEXT:    call void @use8(i8 [[T0]])1158; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 21159; CHECK-NEXT:    [[T2:%.*]] = or disjoint i8 [[T1]], 31160; CHECK-NEXT:    call void @use8(i8 [[T2]])1161; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X]], [[T2]]1162; CHECK-NEXT:    ret i8 [[T3]]1163;1164  %t0 = sub i8 0, %y1165  call void @use8(i8 %t0)1166  %t1 = shl i8 %t0, 21167  %t2 = or i8 %t1, 31168  call void @use8(i8 %t2)1169  %t3 = sub i8 %x, %t21170  ret i8 %t31171}1172 1173; `extractelement` is negatible if source operand is negatible.1174define i4 @negate_extractelement(<2 x i4> %x, i32 %y, i4 %z) {1175; CHECK-LABEL: define i4 @negate_extractelement(1176; CHECK-SAME: <2 x i4> [[X:%.*]], i32 [[Y:%.*]], i4 [[Z:%.*]]) {1177; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X]]1178; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]])1179; CHECK-NEXT:    [[T1_NEG:%.*]] = extractelement <2 x i4> [[X]], i32 [[Y]]1180; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z]]1181; CHECK-NEXT:    ret i4 [[T2]]1182;1183  %t0 = sub <2 x i4> zeroinitializer, %x1184  call void @use_v2i4(<2 x i4> %t0)1185  %t1 = extractelement <2 x i4> %t0, i32 %y1186  %t2 = sub i4 %z, %t11187  ret i4 %t21188}1189define i4 @negate_extractelement_extrause(<2 x i4> %x, i32 %y, i4 %z) {1190; CHECK-LABEL: define i4 @negate_extractelement_extrause(1191; CHECK-SAME: <2 x i4> [[X:%.*]], i32 [[Y:%.*]], i4 [[Z:%.*]]) {1192; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X]]1193; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]])1194; CHECK-NEXT:    [[T1:%.*]] = extractelement <2 x i4> [[T0]], i32 [[Y]]1195; CHECK-NEXT:    call void @use4(i4 [[T1]])1196; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z]], [[T1]]1197; CHECK-NEXT:    ret i4 [[T2]]1198;1199  %t0 = sub <2 x i4> zeroinitializer, %x1200  call void @use_v2i4(<2 x i4> %t0)1201  %t1 = extractelement <2 x i4> %t0, i32 %y1202  call void @use4(i4 %t1)1203  %t2 = sub i4 %z, %t11204  ret i4 %t21205}1206 1207; `insertelement` is negatible if both source vector and element-to-be-inserted are negatible.1208define <2 x i4> @negate_insertelement(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {1209; CHECK-LABEL: define <2 x i4> @negate_insertelement(1210; CHECK-SAME: <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]], <2 x i4> [[B:%.*]]) {1211; CHECK-NEXT:    [[T2_NEG:%.*]] = insertelement <2 x i4> [[SRC]], i4 [[A]], i32 [[X]]1212; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[B]]1213; CHECK-NEXT:    ret <2 x i4> [[T3]]1214;1215  %t0 = sub <2 x i4> zeroinitializer, %src1216  %t1 = sub i4 zeroinitializer, %a1217  %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x1218  %t3 = sub <2 x i4> %b, %t21219  ret <2 x i4> %t31220}1221define <2 x i4> @negate_insertelement_extrause(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {1222; CHECK-LABEL: define <2 x i4> @negate_insertelement_extrause(1223; CHECK-SAME: <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]], <2 x i4> [[B:%.*]]) {1224; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC]]1225; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A]]1226; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[T1]], i32 [[X]]1227; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T2]])1228; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B]], [[T2]]1229; CHECK-NEXT:    ret <2 x i4> [[T3]]1230;1231  %t0 = sub <2 x i4> zeroinitializer, %src1232  %t1 = sub i4 zeroinitializer, %a1233  %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x1234  call void @use_v2i4(<2 x i4> %t2)1235  %t3 = sub <2 x i4> %b, %t21236  ret <2 x i4> %t31237}1238define <2 x i4> @negate_insertelement_nonnegatible_base(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {1239; CHECK-LABEL: define <2 x i4> @negate_insertelement_nonnegatible_base(1240; CHECK-SAME: <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]], <2 x i4> [[B:%.*]]) {1241; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A]]1242; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[SRC]], i4 [[T1]], i32 [[X]]1243; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B]], [[T2]]1244; CHECK-NEXT:    ret <2 x i4> [[T3]]1245;1246  %t1 = sub i4 zeroinitializer, %a1247  %t2 = insertelement <2 x i4> %src, i4 %t1, i32 %x1248  %t3 = sub <2 x i4> %b, %t21249  ret <2 x i4> %t31250}1251define <2 x i4> @negate_insertelement_nonnegatible_insert(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {1252; CHECK-LABEL: define <2 x i4> @negate_insertelement_nonnegatible_insert(1253; CHECK-SAME: <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]], <2 x i4> [[B:%.*]]) {1254; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC]]1255; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[A]], i32 [[X]]1256; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B]], [[T2]]1257; CHECK-NEXT:    ret <2 x i4> [[T3]]1258;1259  %t0 = sub <2 x i4> zeroinitializer, %src1260  %t2 = insertelement <2 x i4> %t0, i4 %a, i32 %x1261  %t3 = sub <2 x i4> %b, %t21262  ret <2 x i4> %t31263}1264 1265; left-shift by constant can always be negated1266define i8 @negate_left_shift_by_constant_prefer_keeping_shl(i8 %x, i8 %y, i8 %z) {1267; CHECK-LABEL: define i8 @negate_left_shift_by_constant_prefer_keeping_shl(1268; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {1269; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z]]1270; CHECK-NEXT:    call void @use8(i8 [[T0]])1271; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Z]], 41272; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]1273; CHECK-NEXT:    ret i8 [[T2]]1274;1275  %t0 = sub i8 0, %z1276  call void @use8(i8 %t0)1277  %t1 = shl i8 %t0, 41278  %t2 = sub i8 %x, %t11279  ret i8 %t21280}1281define i8 @negate_left_shift_by_constant_prefer_keeping_shl_extrause(i8 %x, i8 %y, i8 %z) {1282; CHECK-LABEL: define i8 @negate_left_shift_by_constant_prefer_keeping_shl_extrause(1283; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {1284; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z]]1285; CHECK-NEXT:    call void @use8(i8 [[T0]])1286; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 41287; CHECK-NEXT:    call void @use8(i8 [[T1]])1288; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1289; CHECK-NEXT:    ret i8 [[T2]]1290;1291  %t0 = sub i8 0, %z1292  call void @use8(i8 %t0)1293  %t1 = shl i8 %t0, 41294  call void @use8(i8 %t1)1295  %t2 = sub i8 %x, %t11296  ret i8 %t21297}1298define i8 @negate_left_shift_by_constant(i8 %x, i8 %y, i8 %z, i8 %k) {1299; CHECK-LABEL: define i8 @negate_left_shift_by_constant(1300; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[K:%.*]]) {1301; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K]], [[Z]]1302; CHECK-NEXT:    call void @use8(i8 [[T0]])1303; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 41304; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1305; CHECK-NEXT:    ret i8 [[T2]]1306;1307  %t0 = sub i8 %k, %z1308  call void @use8(i8 %t0)1309  %t1 = shl i8 %t0, 41310  %t2 = sub i8 %x, %t11311  ret i8 %t21312}1313define i8 @negate_left_shift_by_constant_extrause(i8 %x, i8 %y, i8 %z, i8 %k) {1314; CHECK-LABEL: define i8 @negate_left_shift_by_constant_extrause(1315; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[K:%.*]]) {1316; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K]], [[Z]]1317; CHECK-NEXT:    call void @use8(i8 [[T0]])1318; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 41319; CHECK-NEXT:    call void @use8(i8 [[T1]])1320; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1321; CHECK-NEXT:    ret i8 [[T2]]1322;1323  %t0 = sub i8 %k, %z1324  call void @use8(i8 %t0)1325  %t1 = shl i8 %t0, 41326  call void @use8(i8 %t1)1327  %t2 = sub i8 %x, %t11328  ret i8 %t21329}1330 1331; `add` with single negatible operand is still negatible1332define i8 @negate_add_with_single_negatible_operand(i8 %x, i8 %y) {1333; CHECK-LABEL: define i8 @negate_add_with_single_negatible_operand(1334; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1335; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X]]1336; CHECK-NEXT:    ret i8 [[T1]]1337;1338  %t0 = add i8 %x, 421339  %t1 = sub i8 0, %t01340  ret i8 %t11341}1342; do so even if we are two levels deep1343define i8 @negate_add_with_single_negatible_operand_depth2(i8 %x, i8 %y) {1344; CHECK-LABEL: define i8 @negate_add_with_single_negatible_operand_depth2(1345; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1346; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 -21, [[X]]1347; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[T0_NEG]], [[Y]]1348; CHECK-NEXT:    ret i8 [[T1_NEG]]1349;1350  %t0 = add i8 %x, 211351  %t1 = mul i8 %t0, %y1352  %t2 = sub i8 0, %t11353  ret i8 %t21354}1355 1356define i8 @negate_add_with_single_negatible_operand_extrause(i8 %x, i8 %y) {1357; CHECK-LABEL: define i8 @negate_add_with_single_negatible_operand_extrause(1358; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1359; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X]], 421360; CHECK-NEXT:    call void @use8(i8 [[T0]])1361; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X]]1362; CHECK-NEXT:    ret i8 [[T1]]1363;1364  %t0 = add i8 %x, 421365  call void @use8(i8 %t0)1366  %t1 = sub i8 0, %t01367  ret i8 %t11368}1369; But don't do this if that means just sinking the negation.1370define i8 @negate_add_with_single_negatible_operand_non_negation(i8 %x, i8 %y) {1371; CHECK-LABEL: define i8 @negate_add_with_single_negatible_operand_non_negation(1372; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1373; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X]], 421374; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Y]], [[T0]]1375; CHECK-NEXT:    ret i8 [[T1]]1376;1377  %t0 = add i8 %x, 421378  %t1 = sub i8 %y, %t01379  ret i8 %t11380}1381 1382; abs/nabs can be negated1383define i8 @negate_abs(i8 %x, i8 %y) {1384; CHECK-LABEL: define i8 @negate_abs(1385; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1386; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1387; CHECK-NEXT:    call void @use8(i8 [[T0]])1388; CHECK-NEXT:    [[T2:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)1389; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[Y]], [[T2]]1390; CHECK-NEXT:    ret i8 [[T3]]1391;1392  %t0 = sub i8 0, %x1393  call void @use8(i8 %t0)1394  %t1 = icmp slt i8 %x, 01395  %t2 = select i1 %t1, i8 %t0, i8 %x, !prof !01396  %t3 = sub i8 %y, %t21397  ret i8 %t31398}1399define i8 @negate_nabs(i8 %x, i8 %y) {1400; CHECK-LABEL: define i8 @negate_nabs(1401; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1402; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1403; CHECK-NEXT:    call void @use8(i8 [[T0]])1404; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)1405; CHECK-NEXT:    [[T3:%.*]] = add i8 [[Y]], [[TMP1]]1406; CHECK-NEXT:    ret i8 [[T3]]1407;1408  %t0 = sub i8 0, %x1409  call void @use8(i8 %t0)1410  %t1 = icmp slt i8 %x, 01411  %t2 = select i1 %t1, i8 %x, i8 %t0, !prof !01412  %t3 = sub i8 %y, %t21413  ret i8 %t31414}1415 1416; And in general, if hands of select are known to be negation of each other,1417; we can negate the select1418define i8 @negate_select_of_op_vs_negated_op(i8 %x, i8 %y, i1 %c) {1419; CHECK-LABEL: define i8 @negate_select_of_op_vs_negated_op(1420; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i1 [[C:%.*]]) {1421; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1422; CHECK-NEXT:    call void @use8(i8 [[T0]])1423; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C]], i8 [[X]], i8 [[T0]], !prof [[PROF0:![0-9]+]]1424; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y]]1425; CHECK-NEXT:    ret i8 [[T2]]1426;1427  %t0 = sub i8 0, %x1428  call void @use8(i8 %t0)1429  %t1 = select i1 %c, i8 %t0, i8 %x, !prof !01430  %t2 = sub i8 %y, %t11431  ret i8 %t21432}1433define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) {1434; CHECK-LABEL: define i8 @dont_negate_ordinary_select(1435; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i1 [[C:%.*]]) {1436; CHECK-NEXT:    [[T0:%.*]] = select i1 [[C]], i8 [[X]], i8 [[Y]]1437; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Z]], [[T0]]1438; CHECK-NEXT:    ret i8 [[T1]]1439;1440  %t0 = select i1 %c, i8 %x, i8 %y1441  %t1 = sub i8 %z, %t01442  ret i8 %t11443}1444 1445; Freeze is transparent as far as negation is concerned1446define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {1447; CHECK-LABEL: define i4 @negate_freeze(1448; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) {1449; CHECK-NEXT:    [[X_FR:%.*]] = freeze i4 [[X]]1450; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i4 [[Y]]1451; CHECK-NEXT:    [[T1_NEG:%.*]] = sub i4 [[Y_FR]], [[X_FR]]1452; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z]]1453; CHECK-NEXT:    ret i4 [[T2]]1454;1455  %t0 = sub i4 %x, %y1456  %t1 = freeze i4 %t01457  %t2 = sub i4 %z, %t11458  ret i4 %t21459}1460define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) {1461; CHECK-LABEL: define i4 @negate_freeze_extrause(1462; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) {1463; CHECK-NEXT:    [[X_FR:%.*]] = freeze i4 [[X]]1464; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i4 [[Y]]1465; CHECK-NEXT:    [[T1:%.*]] = sub i4 [[X_FR]], [[Y_FR]]1466; CHECK-NEXT:    call void @use4(i4 [[T1]])1467; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z]], [[T1]]1468; CHECK-NEXT:    ret i4 [[T2]]1469;1470  %t0 = sub i4 %x, %y1471  %t1 = freeze i4 %t01472  call void @use4(i4 %t1)1473  %t2 = sub i4 %z, %t11474  ret i4 %t21475}1476 1477; Due to the InstCombine's worklist management, there are no guarantees that1478; each instruction we'll encounter has been visited by InstCombine already.1479; In particular, most importantly for us, that means we have to canonicalize1480; constants to RHS ourselves, since that is helpful sometimes.1481; This used to cause an endless combine loop.1482define void @noncanonical_mul_with_constant_as_first_operand() {1483; CHECK-LABEL: define void @noncanonical_mul_with_constant_as_first_operand() {1484; CHECK-NEXT:  [[ENTRY:.*:]]1485; CHECK-NEXT:    br label %[[IF_END:.*]]1486; CHECK:       [[IF_END]]:1487; CHECK-NEXT:    br label %[[IF_END]]1488;1489entry:1490  br label %if.end1491 1492if.end:1493  %e.0 = phi i32 [ undef, %entry ], [ %div, %if.end ]1494  %conv = trunc i32 %e.0 to i161495  %mul.i = mul nsw i16 -1, %conv1496  %conv1 = sext i16 %mul.i to i321497  %div = sub nsw i32 0, %conv11498  br label %if.end1499}1500 1501!0 = !{!"branch_weights", i32 40, i32 1}1502;.1503; CHECK: [[PROF0]] = !{!"branch_weights", i32 40, i32 1}1504;.1505