brintos

brintos / llvm-project-archived public Read only

0
0
Text · 52.6 KiB · aad006d Raw
1626 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}105 106define i8 @select_of_constants_multi_use(i1 %b) {107; CHECK-LABEL: define i8 @select_of_constants_multi_use(108; CHECK-SAME: i1 [[B:%.*]]) {109; CHECK-NEXT:    [[S_NEG:%.*]] = select i1 [[B]], i8 -42, i8 2110; CHECK-NEXT:    [[S:%.*]] = select i1 [[B]], i8 42, i8 -2111; CHECK-NEXT:    call void @use8(i8 [[S]])112; CHECK-NEXT:    ret i8 [[S_NEG]]113;114  %s = select i1 %b, i8 42, i8 -2115  call void @use8(i8 %s)116  %n = sub i8 0, %s117  ret i8 %n118}119 120define i32 @PR52261(i1 %b) {121; CHECK-LABEL: define i32 @PR52261(122; CHECK-SAME: i1 [[B:%.*]]) {123; CHECK-NEXT:    ret i32 2124;125  %s = select i1 %b, i32 2, i32 -2126  %n = sub nsw i32 0, %s127  %a = and i32 %s, %n128  ret i32 %a129}130 131define i8 @n4(i8 %x, i1 %y) {132; CHECK-LABEL: define i8 @n4(133; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {134; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y]], i8 -42, i8 44135; CHECK-NEXT:    call void @use8(i8 [[T0]])136; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]137; CHECK-NEXT:    ret i8 [[T1]]138;139  %t0 = select i1 %y, i8 -42, i8 44140  call void @use8(i8 %t0)141  %t1 = sub i8 %x, %t0142  ret i8 %t1143}144define i8 @n5(i8 %x, i1 %y, i8 %z) {145; CHECK-LABEL: define i8 @n5(146; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]], i8 [[Z:%.*]]) {147; CHECK-NEXT:    [[T0:%.*]] = select i1 [[Y]], i8 -42, i8 [[Z]]148; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]149; CHECK-NEXT:    ret i8 [[T1]]150;151  %t0 = select i1 %y, i8 -42, i8 %z152  %t1 = sub i8 %x, %t0153  ret i8 %t1154}155define i8 @t6(i8 %x, i1 %y, i8 %z) {156; CHECK-LABEL: define i8 @t6(157; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]], i8 [[Z:%.*]]) {158; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z]]159; CHECK-NEXT:    call void @use8(i8 [[T0]])160; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y]], i8 42, i8 [[Z]]161; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]162; CHECK-NEXT:    ret i8 [[T2]]163;164  %t0 = sub i8 0, %z165  call void @use8(i8 %t0)166  %t1 = select i1 %y, i8 -42, i8 %t0167  %t2 = sub i8 %x, %t1168  ret i8 %t2169}170define i8 @t7(i8 %x, i1 %y, i8 %z) {171; CHECK-LABEL: define i8 @t7(172; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]], i8 [[Z:%.*]]) {173; CHECK-NEXT:    [[T0_NEG:%.*]] = shl nsw i8 -1, [[Z]]174; CHECK-NEXT:    [[T1_NEG:%.*]] = select i1 [[Y]], i8 0, i8 [[T0_NEG]]175; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]176; CHECK-NEXT:    ret i8 [[T2]]177;178  %t0 = shl i8 1, %z179  %t1 = select i1 %y, i8 0, i8 %t0180  %t2 = sub i8 %x, %t1181  ret i8 %t2182}183define i8 @n8(i8 %x, i1 %y, i8 %z) {184; CHECK-LABEL: define i8 @n8(185; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]], i8 [[Z:%.*]]) {186; CHECK-NEXT:    [[T0:%.*]] = shl nuw i8 1, [[Z]]187; CHECK-NEXT:    call void @use8(i8 [[T0]])188; CHECK-NEXT:    [[T1:%.*]] = select i1 [[Y]], i8 0, i8 [[T0]]189; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]190; CHECK-NEXT:    ret i8 [[T2]]191;192  %t0 = shl i8 1, %z193  call void @use8(i8 %t0)194  %t1 = select i1 %y, i8 0, i8 %t0195  %t2 = sub i8 %x, %t1196  ret i8 %t2197}198 199; Subtraction can be negated by swapping its operands.200; x - (y - z) -> x - y + z -> x + (z - y)201define i8 @t9(i8 %x, i8 %y) {202; CHECK-LABEL: define i8 @t9(203; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {204; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 [[X]], [[Y]]205; CHECK-NEXT:    ret i8 [[T0_NEG]]206;207  %t0 = sub i8 %y, %x208  %t1 = sub i8 0, %t0209  ret i8 %t1210}211 212define i8 @n10(i8 %x, i8 %y, i8 %z) {213; CHECK-LABEL: define i8 @n10(214; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {215; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[Y]], [[X]]216; CHECK-NEXT:    call void @use8(i8 [[T0]])217; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[T0]]218; CHECK-NEXT:    ret i8 [[T1]]219;220  %t0 = sub i8 %y, %x221  call void @use8(i8 %t0)222  %t1 = sub i8 0, %t0223  ret i8 %t1224}225 226define i8 @neg_of_sub_from_constant(i8 %x) {227; CHECK-LABEL: define i8 @neg_of_sub_from_constant(228; CHECK-SAME: i8 [[X:%.*]]) {229; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X]], -42230; CHECK-NEXT:    ret i8 [[S_NEG]]231;232  %s = sub i8 42, %x233  %r = sub i8 0, %s234  ret i8 %r235}236 237define i8 @neg_of_sub_from_constant_multi_use(i8 %x) {238; CHECK-LABEL: define i8 @neg_of_sub_from_constant_multi_use(239; CHECK-SAME: i8 [[X:%.*]]) {240; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X]], -42241; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]]242; CHECK-NEXT:    call void @use8(i8 [[S]])243; CHECK-NEXT:    ret i8 [[S_NEG]]244;245  %s = sub i8 42, %x246  call void @use8(i8 %s)247  %r = sub i8 0, %s248  ret i8 %r249}250 251define i8 @sub_from_constant_of_sub_from_constant(i8 %x) {252; CHECK-LABEL: define i8 @sub_from_constant_of_sub_from_constant(253; CHECK-SAME: i8 [[X:%.*]]) {254; CHECK-NEXT:    [[R:%.*]] = add i8 [[X]], -31255; CHECK-NEXT:    ret i8 [[R]]256;257  %s = sub i8 42, %x258  %r = sub i8 11, %s259  ret i8 %r260}261 262define i8 @sub_from_constant_of_sub_from_constant_multi_use(i8 %x) {263; CHECK-LABEL: define i8 @sub_from_constant_of_sub_from_constant_multi_use(264; CHECK-SAME: i8 [[X:%.*]]) {265; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]]266; CHECK-NEXT:    call void @use8(i8 [[S]])267; CHECK-NEXT:    [[R:%.*]] = add i8 [[X]], -31268; CHECK-NEXT:    ret i8 [[R]]269;270  %s = sub i8 42, %x271  call void @use8(i8 %s)272  %r = sub i8 11, %s273  ret i8 %r274}275 276define i8 @sub_from_variable_of_sub_from_constant(i8 %x, i8 %y) {277; CHECK-LABEL: define i8 @sub_from_variable_of_sub_from_constant(278; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {279; CHECK-NEXT:    [[S_NEG:%.*]] = add i8 [[X]], -42280; CHECK-NEXT:    [[R:%.*]] = add i8 [[S_NEG]], [[Y]]281; CHECK-NEXT:    ret i8 [[R]]282;283  %s = sub i8 42, %x284  %r = sub i8 %y, %s285  ret i8 %r286}287 288define i8 @sub_from_variable_of_sub_from_constant_multi_use(i8 %x, i8 %y) {289; CHECK-LABEL: define i8 @sub_from_variable_of_sub_from_constant_multi_use(290; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {291; CHECK-NEXT:    [[S:%.*]] = sub i8 42, [[X]]292; CHECK-NEXT:    call void @use8(i8 [[S]])293; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y]], [[S]]294; CHECK-NEXT:    ret i8 [[R]]295;296  %s = sub i8 42, %x297  call void @use8(i8 %s)298  %r = sub i8 %y, %s299  ret i8 %r300}301 302; Addition can be negated if both operands can be negated303; x - (y + z) -> x - y - z -> x + ((-y) + (-z)))304define i8 @t12(i8 %x, i8 %y, i8 %z) {305; CHECK-LABEL: define i8 @t12(306; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {307; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]308; CHECK-NEXT:    call void @use8(i8 [[T0]])309; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z]]310; CHECK-NEXT:    call void @use8(i8 [[T1]])311; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]312; CHECK-NEXT:    [[T3:%.*]] = add i8 [[X]], [[TMP1]]313; CHECK-NEXT:    ret i8 [[T3]]314;315  %t0 = sub i8 0, %y316  call void @use8(i8 %t0)317  %t1 = sub i8 0, %z318  call void @use8(i8 %t1)319  %t2 = add i8 %t0, %t1320  %t3 = sub i8 %x, %t2321  ret i8 %t3322}323define i8 @n13(i8 %x, i8 %y, i8 %z) {324; CHECK-LABEL: define i8 @n13(325; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {326; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]327; CHECK-NEXT:    call void @use8(i8 [[T0]])328; CHECK-NEXT:    [[T1_NEG:%.*]] = sub i8 [[Y]], [[Z]]329; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]330; CHECK-NEXT:    ret i8 [[T2]]331;332  %t0 = sub i8 0, %y333  call void @use8(i8 %t0)334  %t1 = add i8 %t0, %z335  %t2 = sub i8 %x, %t1336  ret i8 %t2337}338define i8 @n14(i8 %x, i8 %y, i8 %z) {339; CHECK-LABEL: define i8 @n14(340; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {341; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]342; CHECK-NEXT:    call void @use8(i8 [[T0]])343; CHECK-NEXT:    [[T1:%.*]] = sub i8 0, [[Z]]344; CHECK-NEXT:    call void @use8(i8 [[T1]])345; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[Y]], [[Z]]346; CHECK-NEXT:    [[T2:%.*]] = sub i8 0, [[TMP1]]347; CHECK-NEXT:    call void @use8(i8 [[T2]])348; CHECK-NEXT:    [[T3:%.*]] = add i8 [[X]], [[TMP1]]349; CHECK-NEXT:    ret i8 [[T3]]350;351  %t0 = sub i8 0, %y352  call void @use8(i8 %t0)353  %t1 = sub i8 0, %z354  call void @use8(i8 %t1)355  %t2 = add i8 %t0, %t1356  call void @use8(i8 %t2)357  %t3 = sub i8 %x, %t2358  ret i8 %t3359}360 361define i8 @neg_of_add_with_constant(i8 %x) {362; CHECK-LABEL: define i8 @neg_of_add_with_constant(363; CHECK-SAME: i8 [[X:%.*]]) {364; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X]]365; CHECK-NEXT:    ret i8 [[R]]366;367  %s = add i8 %x, 42368  %r = sub i8 0, %s369  ret i8 %r370}371 372define i8 @neg_of_add_with_constant_multi_use(i8 %x) {373; CHECK-LABEL: define i8 @neg_of_add_with_constant_multi_use(374; CHECK-SAME: i8 [[X:%.*]]) {375; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], 42376; CHECK-NEXT:    call void @use8(i8 [[S]])377; CHECK-NEXT:    [[R:%.*]] = sub i8 -42, [[X]]378; CHECK-NEXT:    ret i8 [[R]]379;380  %s = add i8 %x, 42381  call void @use8(i8 %s)382  %r = sub i8 0, %s383  ret i8 %r384}385 386define i8 @sub_from_constant_of_add_with_constant(i8 %x) {387; CHECK-LABEL: define i8 @sub_from_constant_of_add_with_constant(388; CHECK-SAME: i8 [[X:%.*]]) {389; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X]]390; CHECK-NEXT:    ret i8 [[R]]391;392  %s = add i8 %x, 42393  %r = sub i8 11, %s394  ret i8 %r395}396 397define i8 @sub_from_constant_of_add_with_constant_multi_use(i8 %x) {398; CHECK-LABEL: define i8 @sub_from_constant_of_add_with_constant_multi_use(399; CHECK-SAME: i8 [[X:%.*]]) {400; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], 42401; CHECK-NEXT:    call void @use8(i8 [[S]])402; CHECK-NEXT:    [[R:%.*]] = sub i8 -31, [[X]]403; CHECK-NEXT:    ret i8 [[R]]404;405  %s = add i8 %x, 42406  call void @use8(i8 %s)407  %r = sub i8 11, %s408  ret i8 %r409}410 411define i8 @sub_from_variable_of_add_with_constant(i8 %x, i8 %y) {412; CHECK-LABEL: define i8 @sub_from_variable_of_add_with_constant(413; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {414; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], 42415; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y]], [[S]]416; CHECK-NEXT:    ret i8 [[R]]417;418  %s = add i8 %x, 42419  %r = sub i8 %y, %s420  ret i8 %r421}422 423define i8 @sub_from_variable_of_add_with_constant_multi_use(i8 %x, i8 %y) {424; CHECK-LABEL: define i8 @sub_from_variable_of_add_with_constant_multi_use(425; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {426; CHECK-NEXT:    [[S:%.*]] = add i8 [[X]], 42427; CHECK-NEXT:    call void @use8(i8 [[S]])428; CHECK-NEXT:    [[R:%.*]] = sub i8 [[Y]], [[S]]429; CHECK-NEXT:    ret i8 [[R]]430;431  %s = add i8 %x, 42432  call void @use8(i8 %s)433  %r = sub i8 %y, %s434  ret i8 %r435}436 437; Multiplication can be negated if either one of operands can be negated438; x - (y * z) -> x + ((-y) * z) or  x + ((-z) * y)439define i8 @t15(i8 %x, i8 %y, i8 %z) {440; CHECK-LABEL: define i8 @t15(441; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {442; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]443; CHECK-NEXT:    call void @use8(i8 [[T0]])444; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[Y]], [[Z]]445; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]446; CHECK-NEXT:    ret i8 [[T2]]447;448  %t0 = sub i8 0, %y449  call void @use8(i8 %t0)450  %t1 = mul i8 %t0, %z451  %t2 = sub i8 %x, %t1452  ret i8 %t2453}454define i8 @n16(i8 %x, i8 %y, i8 %z) {455; CHECK-LABEL: define i8 @n16(456; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {457; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]458; CHECK-NEXT:    call void @use8(i8 [[T0]])459; CHECK-NEXT:    [[T1:%.*]] = mul i8 [[Z]], [[T0]]460; CHECK-NEXT:    call void @use8(i8 [[T1]])461; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]462; CHECK-NEXT:    ret i8 [[T2]]463;464  %t0 = sub i8 0, %y465  call void @use8(i8 %t0)466  %t1 = mul i8 %t0, %z467  call void @use8(i8 %t1)468  %t2 = sub i8 %x, %t1469  ret i8 %t2470}471 472; Phi can be negated if all incoming values can be negated473define i8 @t16(i1 %c, i8 %x) {474; CHECK-LABEL: define i8 @t16(475; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]]) {476; CHECK-NEXT:  [[BEGIN:.*:]]477; CHECK-NEXT:    br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]478; CHECK:       [[THEN]]:479; CHECK-NEXT:    br label %[[END:.*]]480; CHECK:       [[ELSE]]:481; CHECK-NEXT:    br label %[[END]]482; CHECK:       [[END]]:483; CHECK-NEXT:    [[Z_NEG:%.*]] = phi i8 [ [[X]], %[[THEN]] ], [ 42, %[[ELSE]] ]484; CHECK-NEXT:    ret i8 [[Z_NEG]]485;486begin:487  br i1 %c, label %then, label %else488then:489  %y = sub i8 0, %x490  br label %end491else:492  br label %end493end:494  %z = phi i8 [ %y, %then], [ -42, %else ]495  %n = sub i8 0, %z496  ret i8 %n497}498define i8 @n17(i1 %c, i8 %x) {499; CHECK-LABEL: define i8 @n17(500; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]]) {501; CHECK-NEXT:  [[BEGIN:.*:]]502; CHECK-NEXT:    br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]503; CHECK:       [[THEN]]:504; CHECK-NEXT:    [[Y:%.*]] = sub i8 0, [[X]]505; CHECK-NEXT:    br label %[[END:.*]]506; CHECK:       [[ELSE]]:507; CHECK-NEXT:    br label %[[END]]508; CHECK:       [[END]]:509; CHECK-NEXT:    [[Z:%.*]] = phi i8 [ [[Y]], %[[THEN]] ], [ -42, %[[ELSE]] ]510; CHECK-NEXT:    call void @use8(i8 [[Z]])511; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[Z]]512; CHECK-NEXT:    ret i8 [[N]]513;514begin:515  br i1 %c, label %then, label %else516then:517  %y = sub i8 0, %x518  br label %end519else:520  br label %end521end:522  %z = phi i8 [ %y, %then], [ -42, %else ]523  call void @use8(i8 %z)524  %n = sub i8 0, %z525  ret i8 %n526}527define i8 @n19(i1 %c, i8 %x, i8 %y) {528; CHECK-LABEL: define i8 @n19(529; CHECK-SAME: i1 [[C:%.*]], i8 [[X:%.*]], i8 [[Y:%.*]]) {530; CHECK-NEXT:  [[BEGIN:.*:]]531; CHECK-NEXT:    br i1 [[C]], label %[[THEN:.*]], label %[[ELSE:.*]]532; CHECK:       [[THEN]]:533; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[X]]534; CHECK-NEXT:    br label %[[END:.*]]535; CHECK:       [[ELSE]]:536; CHECK-NEXT:    br label %[[END]]537; CHECK:       [[END]]:538; CHECK-NEXT:    [[R:%.*]] = phi i8 [ [[Z]], %[[THEN]] ], [ [[Y]], %[[ELSE]] ]539; CHECK-NEXT:    [[N:%.*]] = sub i8 0, [[R]]540; CHECK-NEXT:    ret i8 [[N]]541;542begin:543  br i1 %c, label %then, label %else544then:545  %z = sub i8 0, %x546  br label %end547else:548  br label %end549end:550  %r = phi i8 [ %z, %then], [ %y, %else ]551  %n = sub i8 0, %r552  ret i8 %n553}554define void @phi_with_duplicate_incoming_basic_blocks(i32 %x, i32 %y, i1 %should_lookup, i32 %z) {555; CHECK-LABEL: define void @phi_with_duplicate_incoming_basic_blocks(556; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i1 [[SHOULD_LOOKUP:%.*]], i32 [[Z:%.*]]) {557; CHECK-NEXT:  [[ENTRY:.*]]:558; CHECK-NEXT:    [[X_INC_NEG:%.*]] = xor i32 [[X]], -1559; CHECK-NEXT:    br i1 [[SHOULD_LOOKUP]], label %[[LOOKUP:.*]], label %[[LOOP:.*]]560; CHECK:       [[LOOKUP]]:561; CHECK-NEXT:    [[TO_LOOKUP:%.*]] = phi i32 [ [[Y]], %[[ENTRY]] ], [ [[METAVAL_NEG:%.*]], %[[LOOP]] ]562; CHECK-NEXT:    switch i32 [[TO_LOOKUP]], label %[[END:.*]] [563; CHECK-NEXT:      i32 0, label %[[LOOP]]564; CHECK-NEXT:      i32 42, label %[[LOOP]]565; CHECK-NEXT:    ]566; CHECK:       [[LOOP]]:567; CHECK-NEXT:    [[METAVAL_NEG]] = phi i32 [ [[X_INC_NEG]], %[[LOOKUP]] ], [ [[X_INC_NEG]], %[[LOOKUP]] ], [ -84, %[[ENTRY]] ]568; CHECK-NEXT:    [[REPEAT:%.*]] = call i1 @use32gen1(i32 [[METAVAL_NEG]])569; CHECK-NEXT:    br i1 [[REPEAT]], label %[[LOOKUP]], label %[[END]]570; CHECK:       [[END]]:571; CHECK-NEXT:    ret void572;573entry:574  %x_inc = add i32 %x, 1575  br i1 %should_lookup, label %lookup, label %loop576 577lookup:578  %to_lookup = phi i32 [ %y, %entry ], [ %negated_metaval, %loop ]579  switch i32 %to_lookup, label %end [580  i32 0, label %loop581  i32 42, label %loop582  ]583 584loop:585  %metaval = phi i32 [ %x_inc, %lookup ], [ %x_inc, %lookup ], [ 84, %entry ]586  %negated_metaval = sub i32 0, %metaval587  %repeat = call i1 @use32gen1(i32 %negated_metaval)588  br i1 %repeat, label %lookup, label %end589 590end:591  ret void592}593 594; truncation can be negated if it's operand can be negated595define i8 @t20(i8 %x, i16 %y) {596; CHECK-LABEL: define i8 @t20(597; CHECK-SAME: i8 [[X:%.*]], i16 [[Y:%.*]]) {598; CHECK-NEXT:    [[T0_NEG:%.*]] = shl i16 42, [[Y]]599; CHECK-NEXT:    [[T1_NEG:%.*]] = trunc i16 [[T0_NEG]] to i8600; CHECK-NEXT:    [[T2:%.*]] = add i8 [[X]], [[T1_NEG]]601; CHECK-NEXT:    ret i8 [[T2]]602;603  %t0 = shl i16 -42, %y604  %t1 = trunc i16 %t0 to i8605  %t2 = sub i8 %x, %t1606  ret i8 %t2607}608define i8 @n21(i8 %x, i16 %y) {609; CHECK-LABEL: define i8 @n21(610; CHECK-SAME: i8 [[X:%.*]], i16 [[Y:%.*]]) {611; CHECK-NEXT:    [[T0:%.*]] = shl i16 -42, [[Y]]612; CHECK-NEXT:    [[T1:%.*]] = trunc i16 [[T0]] to i8613; CHECK-NEXT:    call void @use8(i8 [[T1]])614; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]615; CHECK-NEXT:    ret i8 [[T2]]616;617  %t0 = shl i16 -42, %y618  %t1 = trunc i16 %t0 to i8619  call void @use8(i8 %t1)620  %t2 = sub i8 %x, %t1621  ret i8 %t2622}623 624define i4 @negate_xor(i4 %x) {625; CHECK-LABEL: define i4 @negate_xor(626; CHECK-SAME: i4 [[X:%.*]]) {627; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X]], -6628; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1629; CHECK-NEXT:    ret i4 [[O_NEG]]630;631  %o = xor i4 %x, 5632  %r = sub i4 0, %o633  ret i4 %r634}635 636define <2 x i4> @negate_xor_vec(<2 x i4> %x) {637; CHECK-LABEL: define <2 x i4> @negate_xor_vec(638; CHECK-SAME: <2 x i4> [[X:%.*]]) {639; CHECK-NEXT:    [[TMP1:%.*]] = xor <2 x i4> [[X]], <i4 -6, i4 5>640; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[TMP1]], splat (i4 1)641; CHECK-NEXT:    ret <2 x i4> [[O_NEG]]642;643  %o = xor <2 x i4> %x, <i4 5, i4 10>644  %r = sub <2 x i4> zeroinitializer, %o645  ret <2 x i4> %r646}647 648define i8 @negate_xor_use(i8 %x) {649; CHECK-LABEL: define i8 @negate_xor_use(650; CHECK-SAME: i8 [[X:%.*]]) {651; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X]], 5652; CHECK-NEXT:    call void @use8(i8 [[O]])653; CHECK-NEXT:    [[R:%.*]] = sub i8 0, [[O]]654; CHECK-NEXT:    ret i8 [[R]]655;656  %o = xor i8 %x, 5657  call void @use8(i8 %o)658  %r = sub i8 0, %o659  ret i8 %r660}661 662define i4 @negate_shl_xor(i4 %x, i4 %y) {663; CHECK-LABEL: define i4 @negate_shl_xor(664; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]]) {665; CHECK-NEXT:    [[TMP1:%.*]] = xor i4 [[X]], -6666; CHECK-NEXT:    [[O_NEG:%.*]] = add i4 [[TMP1]], 1667; CHECK-NEXT:    [[S_NEG:%.*]] = shl i4 [[O_NEG]], [[Y]]668; CHECK-NEXT:    ret i4 [[S_NEG]]669;670  %o = xor i4 %x, 5671  %s = shl i4 %o, %y672  %r = sub i4 0, %s673  ret i4 %r674}675 676define i8 @negate_shl_not_uses(i8 %x, i8 %y) {677; CHECK-LABEL: define i8 @negate_shl_not_uses(678; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {679; CHECK-NEXT:    [[O_NEG:%.*]] = add i8 [[X]], 1680; CHECK-NEXT:    [[O:%.*]] = xor i8 [[X]], -1681; CHECK-NEXT:    call void @use8(i8 [[O]])682; CHECK-NEXT:    [[S_NEG:%.*]] = shl i8 [[O_NEG]], [[Y]]683; CHECK-NEXT:    ret i8 [[S_NEG]]684;685  %o = xor i8 %x, -1686  call void @use8(i8 %o)687  %s = shl i8 %o, %y688  %r = sub i8 0, %s689  ret i8 %r690}691 692define <2 x i4> @negate_mul_not_uses_vec(<2 x i4> %x, <2 x i4> %y) {693; CHECK-LABEL: define <2 x i4> @negate_mul_not_uses_vec(694; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]]) {695; CHECK-NEXT:    [[O_NEG:%.*]] = add <2 x i4> [[X]], splat (i4 1)696; CHECK-NEXT:    [[O:%.*]] = xor <2 x i4> [[X]], splat (i4 -1)697; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[O]])698; CHECK-NEXT:    [[S_NEG:%.*]] = mul <2 x i4> [[O_NEG]], [[Y]]699; CHECK-NEXT:    ret <2 x i4> [[S_NEG]]700;701  %o = xor <2 x i4> %x, <i4 -1, i4 -1>702  call void @use_v2i4(<2 x i4> %o)703  %s = mul <2 x i4> %o, %y704  %r = sub <2 x i4> zeroinitializer, %s705  ret <2 x i4> %r706}707 708; signed division can be negated if divisor can be negated and is not 1/-1709define i8 @negate_sdiv(i8 %x, i8 %y) {710; CHECK-LABEL: define i8 @negate_sdiv(711; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {712; CHECK-NEXT:    [[T0_NEG:%.*]] = sdiv i8 [[Y]], -42713; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X]]714; CHECK-NEXT:    ret i8 [[T1]]715;716  %t0 = sdiv i8 %y, 42717  %t1 = sub i8 %x, %t0718  ret i8 %t1719}720define i8 @negate_sdiv_extrause(i8 %x, i8 %y) {721; CHECK-LABEL: define i8 @negate_sdiv_extrause(722; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {723; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y]], 42724; CHECK-NEXT:    call void @use8(i8 [[T0]])725; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]726; CHECK-NEXT:    ret i8 [[T1]]727;728  %t0 = sdiv i8 %y, 42729  call void @use8(i8 %t0)730  %t1 = sub i8 %x, %t0731  ret i8 %t1732}733define i8 @negate_sdiv_extrause2(i8 %x, i8 %y) {734; CHECK-LABEL: define i8 @negate_sdiv_extrause2(735; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {736; CHECK-NEXT:    [[T0:%.*]] = sdiv i8 [[Y]], 42737; CHECK-NEXT:    call void @use8(i8 [[T0]])738; CHECK-NEXT:    [[T1:%.*]] = sub nsw i8 0, [[T0]]739; CHECK-NEXT:    ret i8 [[T1]]740;741  %t0 = sdiv i8 %y, 42742  call void @use8(i8 %t0)743  %t1 = sub i8 0, %t0744  ret i8 %t1745}746 747; Right-shift sign bit smear is negatible.748define i8 @negate_ashr(i8 %x, i8 %y) {749; CHECK-LABEL: define i8 @negate_ashr(750; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {751; CHECK-NEXT:    [[T0_NEG:%.*]] = lshr i8 [[Y]], 7752; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X]]753; CHECK-NEXT:    ret i8 [[T1]]754;755  %t0 = ashr i8 %y, 7756  %t1 = sub i8 %x, %t0757  ret i8 %t1758}759define i8 @negate_lshr(i8 %x, i8 %y) {760; CHECK-LABEL: define i8 @negate_lshr(761; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {762; CHECK-NEXT:    [[T0_NEG:%.*]] = ashr i8 [[Y]], 7763; CHECK-NEXT:    [[T1:%.*]] = add i8 [[T0_NEG]], [[X]]764; CHECK-NEXT:    ret i8 [[T1]]765;766  %t0 = lshr i8 %y, 7767  %t1 = sub i8 %x, %t0768  ret i8 %t1769}770define i8 @negate_ashr_extrause(i8 %x, i8 %y) {771; CHECK-LABEL: define i8 @negate_ashr_extrause(772; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {773; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y]], 7774; CHECK-NEXT:    call void @use8(i8 [[T0]])775; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]776; CHECK-NEXT:    ret i8 [[T1]]777;778  %t0 = ashr i8 %y, 7779  call void @use8(i8 %t0)780  %t1 = sub i8 %x, %t0781  ret i8 %t1782}783define i8 @negate_lshr_extrause(i8 %x, i8 %y) {784; CHECK-LABEL: define i8 @negate_lshr_extrause(785; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {786; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y]], 7787; CHECK-NEXT:    call void @use8(i8 [[T0]])788; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]789; CHECK-NEXT:    ret i8 [[T1]]790;791  %t0 = lshr i8 %y, 7792  call void @use8(i8 %t0)793  %t1 = sub i8 %x, %t0794  ret i8 %t1795}796define i8 @negate_ashr_wrongshift(i8 %x, i8 %y) {797; CHECK-LABEL: define i8 @negate_ashr_wrongshift(798; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {799; CHECK-NEXT:    [[T0:%.*]] = ashr i8 [[Y]], 6800; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]801; CHECK-NEXT:    ret i8 [[T1]]802;803  %t0 = ashr i8 %y, 6804  %t1 = sub i8 %x, %t0805  ret i8 %t1806}807define i8 @negate_lshr_wrongshift(i8 %x, i8 %y) {808; CHECK-LABEL: define i8 @negate_lshr_wrongshift(809; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {810; CHECK-NEXT:    [[T0:%.*]] = lshr i8 [[Y]], 6811; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]812; CHECK-NEXT:    ret i8 [[T1]]813;814  %t0 = lshr i8 %y, 6815  %t1 = sub i8 %x, %t0816  ret i8 %t1817}818 819; *ext of i1 is always negatible820define i8 @negate_sext(i8 %x, i1 %y) {821; CHECK-LABEL: define i8 @negate_sext(822; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {823; CHECK-NEXT:    [[T0_NEG:%.*]] = zext i1 [[Y]] to i8824; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X]], [[T0_NEG]]825; CHECK-NEXT:    ret i8 [[T1]]826;827  %t0 = sext i1 %y to i8828  %t1 = sub i8 %x, %t0829  ret i8 %t1830}831define i8 @negate_zext(i8 %x, i1 %y) {832; CHECK-LABEL: define i8 @negate_zext(833; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {834; CHECK-NEXT:    [[T0_NEG:%.*]] = sext i1 [[Y]] to i8835; CHECK-NEXT:    [[T1:%.*]] = add i8 [[X]], [[T0_NEG]]836; CHECK-NEXT:    ret i8 [[T1]]837;838  %t0 = zext i1 %y to i8839  %t1 = sub i8 %x, %t0840  ret i8 %t1841}842define i8 @negate_sext_extrause(i8 %x, i1 %y) {843; CHECK-LABEL: define i8 @negate_sext_extrause(844; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {845; CHECK-NEXT:    [[T0:%.*]] = sext i1 [[Y]] to i8846; CHECK-NEXT:    call void @use8(i8 [[T0]])847; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]848; CHECK-NEXT:    ret i8 [[T1]]849;850  %t0 = sext i1 %y to i8851  call void @use8(i8 %t0)852  %t1 = sub i8 %x, %t0853  ret i8 %t1854}855define i8 @negate_zext_extrause(i8 %x, i1 %y) {856; CHECK-LABEL: define i8 @negate_zext_extrause(857; CHECK-SAME: i8 [[X:%.*]], i1 [[Y:%.*]]) {858; CHECK-NEXT:    [[T0:%.*]] = zext i1 [[Y]] to i8859; CHECK-NEXT:    call void @use8(i8 [[T0]])860; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]861; CHECK-NEXT:    ret i8 [[T1]]862;863  %t0 = zext i1 %y to i8864  call void @use8(i8 %t0)865  %t1 = sub i8 %x, %t0866  ret i8 %t1867}868define i8 @negate_sext_wrongwidth(i8 %x, i2 %y) {869; CHECK-LABEL: define i8 @negate_sext_wrongwidth(870; CHECK-SAME: i8 [[X:%.*]], i2 [[Y:%.*]]) {871; CHECK-NEXT:    [[T0:%.*]] = sext i2 [[Y]] to i8872; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]873; CHECK-NEXT:    ret i8 [[T1]]874;875  %t0 = sext i2 %y to i8876  %t1 = sub i8 %x, %t0877  ret i8 %t1878}879define i8 @negate_zext_wrongwidth(i8 %x, i2 %y) {880; CHECK-LABEL: define i8 @negate_zext_wrongwidth(881; CHECK-SAME: i8 [[X:%.*]], i2 [[Y:%.*]]) {882; CHECK-NEXT:    [[T0:%.*]] = zext i2 [[Y]] to i8883; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[X]], [[T0]]884; CHECK-NEXT:    ret i8 [[T1]]885;886  %t0 = zext i2 %y to i8887  %t1 = sub i8 %x, %t0888  ret i8 %t1889}890 891define <2 x i4> @negate_shufflevector_oneinput_reverse(<2 x i4> %x, <2 x i4> %y) {892; CHECK-LABEL: define <2 x i4> @negate_shufflevector_oneinput_reverse(893; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]]) {894; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X]]895; CHECK-NEXT:    [[T1_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> poison, <2 x i32> <i32 1, i32 0>896; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T1_NEG]], [[Y]]897; CHECK-NEXT:    ret <2 x i4> [[T2]]898;899  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x900  %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 1, i32 0>901  %t2 = sub <2 x i4> %y, %t1902  ret <2 x i4> %t2903}904define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(<2 x i4> %x, <2 x i4> %y) {905; CHECK-LABEL: define <2 x i4> @negate_shufflevector_oneinput_second_lane_is_undef(906; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]]) {907; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X]]908; CHECK-NEXT:    [[T11_NEG:%.*]] = insertelement <2 x i4> [[T0_NEG]], i4 undef, i64 1909; CHECK-NEXT:    [[T2:%.*]] = add <2 x i4> [[T11_NEG]], [[Y]]910; CHECK-NEXT:    ret <2 x i4> [[T2]]911;912  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x913  %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 0, i32 2>914  %t2 = sub <2 x i4> %y, %t1915  ret <2 x i4> %t2916}917define <2 x i4> @negate_shufflevector_twoinputs(<2 x i4> %x, <2 x i4> %y, <2 x i4> %z) {918; CHECK-LABEL: define <2 x i4> @negate_shufflevector_twoinputs(919; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]], <2 x i4> [[Z:%.*]]) {920; CHECK-NEXT:    [[T0_NEG:%.*]] = shl <2 x i4> <i4 6, i4 -5>, [[X]]921; CHECK-NEXT:    [[T1_NEG:%.*]] = add <2 x i4> [[Y]], <i4 poison, i4 1>922; CHECK-NEXT:    [[T2_NEG:%.*]] = shufflevector <2 x i4> [[T0_NEG]], <2 x i4> [[T1_NEG]], <2 x i32> <i32 0, i32 3>923; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[Z]]924; CHECK-NEXT:    ret <2 x i4> [[T3]]925;926  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x927  %t1 = xor <2 x i4> %y, <i4 -1, i4 -1>928  %t2 = shufflevector <2 x i4> %t0, <2 x i4> %t1, <2 x i32> <i32 0, i32 3>929  %t3 = sub <2 x i4> %z, %t2930  ret <2 x i4> %t3931}932define <2 x i4> @negate_shufflevector_oneinput_extrause(<2 x i4> %x, <2 x i4> %y) {933; CHECK-LABEL: define <2 x i4> @negate_shufflevector_oneinput_extrause(934; CHECK-SAME: <2 x i4> [[X:%.*]], <2 x i4> [[Y:%.*]]) {935; CHECK-NEXT:    [[T0:%.*]] = shl <2 x i4> <i4 -6, i4 5>, [[X]]936; CHECK-NEXT:    [[T1:%.*]] = shufflevector <2 x i4> [[T0]], <2 x i4> poison, <2 x i32> <i32 1, i32 0>937; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T1]])938; CHECK-NEXT:    [[T2:%.*]] = sub <2 x i4> [[Y]], [[T1]]939; CHECK-NEXT:    ret <2 x i4> [[T2]]940;941  %t0 = shl <2 x i4> <i4 -6, i4 5>, %x942  %t1 = shufflevector <2 x i4> %t0, <2 x i4> undef, <2 x i32> <i32 1, i32 0>943  call void @use_v2i4(<2 x i4> %t1)944  %t2 = sub <2 x i4> %y, %t1945  ret <2 x i4> %t2946}947 948; zext of non-negative can be negated949; sext of non-positive can be negated950define i16 @negation_of_zeroext_of_nonnegative(i8 %x) {951; CHECK-LABEL: define i16 @negation_of_zeroext_of_nonnegative(952; CHECK-SAME: i8 [[X:%.*]]) {953; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]954; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -1955; CHECK-NEXT:    br i1 [[T1]], label %[[NONNEG_BB:.*]], label %[[NEG_BB:.*]]956; CHECK:       [[NONNEG_BB]]:957; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i16958; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]959; CHECK-NEXT:    ret i16 [[T3]]960; CHECK:       [[NEG_BB]]:961; CHECK-NEXT:    ret i16 0962;963  %t0 = sub i8 0, %x964  %t1 = icmp sge i8 %t0, 0965  br i1 %t1, label %nonneg_bb, label %neg_bb966 967nonneg_bb:968  %t2 = zext i8 %t0 to i16969  %t3 = sub i16 0, %t2970  ret i16 %t3971 972neg_bb:973  ret i16 0974}975define i16 @negation_of_zeroext_of_positive(i8 %x) {976; CHECK-LABEL: define i16 @negation_of_zeroext_of_positive(977; CHECK-SAME: i8 [[X:%.*]]) {978; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]979; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], 0980; CHECK-NEXT:    br i1 [[T1]], label %[[NONNEG_BB:.*]], label %[[NEG_BB:.*]]981; CHECK:       [[NONNEG_BB]]:982; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i16983; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]984; CHECK-NEXT:    ret i16 [[T3]]985; CHECK:       [[NEG_BB]]:986; CHECK-NEXT:    ret i16 0987;988  %t0 = sub i8 0, %x989  %t1 = icmp sgt i8 %t0, 0990  br i1 %t1, label %nonneg_bb, label %neg_bb991 992nonneg_bb:993  %t2 = zext i8 %t0 to i16994  %t3 = sub i16 0, %t2995  ret i16 %t3996 997neg_bb:998  ret i16 0999}1000define i16 @negation_of_signext_of_negative(i8 %x) {1001; CHECK-LABEL: define i16 @negation_of_signext_of_negative(1002; CHECK-SAME: i8 [[X:%.*]]) {1003; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1004; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 01005; CHECK-NEXT:    br i1 [[T1]], label %[[NEG_BB:.*]], label %[[NONNEG_BB:.*]]1006; CHECK:       [[NEG_BB]]:1007; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i161008; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]1009; CHECK-NEXT:    ret i16 [[T3]]1010; CHECK:       [[NONNEG_BB]]:1011; CHECK-NEXT:    ret i16 01012;1013  %t0 = sub i8 0, %x1014  %t1 = icmp slt i8 %t0, 01015  br i1 %t1, label %neg_bb, label %nonneg_bb1016 1017neg_bb:1018  %t2 = sext i8 %t0 to i161019  %t3 = sub i16 0, %t21020  ret i16 %t31021 1022nonneg_bb:1023  ret i16 01024}1025define i16 @negation_of_signext_of_nonpositive(i8 %x) {1026; CHECK-LABEL: define i16 @negation_of_signext_of_nonpositive(1027; CHECK-SAME: i8 [[X:%.*]]) {1028; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1029; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 11030; CHECK-NEXT:    br i1 [[T1]], label %[[NEG_BB:.*]], label %[[NONNEG_BB:.*]]1031; CHECK:       [[NEG_BB]]:1032; CHECK-NEXT:    [[T2:%.*]] = sext i8 [[T0]] to i161033; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]1034; CHECK-NEXT:    ret i16 [[T3]]1035; CHECK:       [[NONNEG_BB]]:1036; CHECK-NEXT:    ret i16 01037;1038  %t0 = sub i8 0, %x1039  %t1 = icmp sle i8 %t0, 01040  br i1 %t1, label %neg_bb, label %nonneg_bb1041 1042neg_bb:1043  %t2 = sext i8 %t0 to i161044  %t3 = sub i16 0, %t21045  ret i16 %t31046 1047nonneg_bb:1048  ret i16 01049}1050define i16 @negation_of_signext_of_nonnegative__wrong_cast(i8 %x) {1051; CHECK-LABEL: define i16 @negation_of_signext_of_nonnegative__wrong_cast(1052; CHECK-SAME: i8 [[X:%.*]]) {1053; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1054; CHECK-NEXT:    [[T1:%.*]] = icmp sgt i8 [[T0]], -11055; CHECK-NEXT:    br i1 [[T1]], label %[[NONNEG_BB:.*]], label %[[NEG_BB:.*]]1056; CHECK:       [[NONNEG_BB]]:1057; CHECK-NEXT:    [[T2:%.*]] = zext nneg i8 [[T0]] to i161058; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]1059; CHECK-NEXT:    ret i16 [[T3]]1060; CHECK:       [[NEG_BB]]:1061; CHECK-NEXT:    ret i16 01062;1063  %t0 = sub i8 0, %x1064  %t1 = icmp sge i8 %t0, 01065  br i1 %t1, label %nonneg_bb, label %neg_bb1066 1067nonneg_bb:1068  %t2 = sext i8 %t0 to i161069  %t3 = sub i16 0, %t21070  ret i16 %t31071 1072neg_bb:1073  ret i16 01074}1075define i16 @negation_of_zeroext_of_negative_wrongcast(i8 %x) {1076; CHECK-LABEL: define i16 @negation_of_zeroext_of_negative_wrongcast(1077; CHECK-SAME: i8 [[X:%.*]]) {1078; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1079; CHECK-NEXT:    [[T1:%.*]] = icmp slt i8 [[T0]], 01080; CHECK-NEXT:    br i1 [[T1]], label %[[NEG_BB:.*]], label %[[NONNEG_BB:.*]]1081; CHECK:       [[NEG_BB]]:1082; CHECK-NEXT:    [[T2:%.*]] = zext i8 [[T0]] to i161083; CHECK-NEXT:    [[T3:%.*]] = sub nsw i16 0, [[T2]]1084; CHECK-NEXT:    ret i16 [[T3]]1085; CHECK:       [[NONNEG_BB]]:1086; CHECK-NEXT:    ret i16 01087;1088  %t0 = sub i8 0, %x1089  %t1 = icmp slt i8 %t0, 01090  br i1 %t1, label %neg_bb, label %nonneg_bb1091 1092neg_bb:1093  %t2 = zext i8 %t0 to i161094  %t3 = sub i16 0, %t21095  ret i16 %t31096 1097nonneg_bb:1098  ret i16 01099}1100 1101; 'or' of 1 and operand with no lowest bit set is 'inc'1102define i8 @negation_of_increment_via_or_with_no_common_bits_set(i8 %x, i8 %y) {1103; CHECK-LABEL: define i8 @negation_of_increment_via_or_with_no_common_bits_set(1104; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1105; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y]], 11106; CHECK-NEXT:    [[T1_NEG:%.*]] = xor i8 [[T0]], -11107; CHECK-NEXT:    [[T2:%.*]] = add i8 [[X]], [[T1_NEG]]1108; CHECK-NEXT:    ret i8 [[T2]]1109;1110  %t0 = shl i8 %y, 11111  %t1 = or i8 %t0, 11112  %t2 = sub i8 %x, %t11113  ret i8 %t21114}1115define i8 @negation_of_increment_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) {1116; CHECK-LABEL: define i8 @negation_of_increment_via_or_with_no_common_bits_set_extrause(1117; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1118; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y]], 11119; CHECK-NEXT:    [[T1:%.*]] = or disjoint i8 [[T0]], 11120; CHECK-NEXT:    call void @use8(i8 [[T1]])1121; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1122; CHECK-NEXT:    ret i8 [[T2]]1123;1124  %t0 = shl i8 %y, 11125  %t1 = or i8 %t0, 11126  call void @use8(i8 %t1)1127  %t2 = sub i8 %x, %t11128  ret i8 %t21129}1130define i8 @negation_of_increment_via_or_common_bits_set(i8 %x, i8 %y) {1131; CHECK-LABEL: define i8 @negation_of_increment_via_or_common_bits_set(1132; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1133; CHECK-NEXT:    [[T0:%.*]] = shl i8 [[Y]], 11134; CHECK-NEXT:    [[T1:%.*]] = or i8 [[T0]], 31135; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1136; CHECK-NEXT:    ret i8 [[T2]]1137;1138  %t0 = shl i8 %y, 11139  %t1 = or i8 %t0, 31140  %t2 = sub i8 %x, %t11141  ret i8 %t21142}1143 1144define i8 @negation_of_increment_via_or_disjoint(i8 %x, i8 %y) {1145; CHECK-LABEL: define i8 @negation_of_increment_via_or_disjoint(1146; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1147; CHECK-NEXT:    [[T1_NEG:%.*]] = xor i8 [[Y]], -11148; CHECK-NEXT:    [[T2:%.*]] = add i8 [[X]], [[T1_NEG]]1149; CHECK-NEXT:    ret i8 [[T2]]1150;1151  %t1 = or disjoint i8 %y, 11152  %t2 = sub i8 %x, %t11153  ret i8 %t21154}1155 1156; 'or' of operands with no common bits set is 'add'1157define i8 @add_via_or_with_no_common_bits_set(i8 %x, i8 %y) {1158; CHECK-LABEL: define i8 @add_via_or_with_no_common_bits_set(1159; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1160; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]1161; CHECK-NEXT:    call void @use8(i8 [[T0]])1162; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Y]], 21163; CHECK-NEXT:    [[T2_NEG:%.*]] = add i8 [[T1_NEG]], -31164; CHECK-NEXT:    [[T3:%.*]] = add i8 [[T2_NEG]], [[X]]1165; CHECK-NEXT:    ret i8 [[T3]]1166;1167  %t0 = sub i8 0, %y1168  call void @use8(i8 %t0)1169  %t1 = shl i8 %t0, 21170  %t2 = or i8 %t1, 31171  %t3 = sub i8 %x, %t21172  ret i8 %t31173}1174define i8 @add_via_or_with_common_bit_maybe_set(i8 %x, i8 %y) {1175; CHECK-LABEL: define i8 @add_via_or_with_common_bit_maybe_set(1176; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1177; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]1178; CHECK-NEXT:    call void @use8(i8 [[T0]])1179; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 21180; CHECK-NEXT:    [[T2:%.*]] = or i8 [[T1]], 41181; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X]], [[T2]]1182; CHECK-NEXT:    ret i8 [[T3]]1183;1184  %t0 = sub i8 0, %y1185  call void @use8(i8 %t0)1186  %t1 = shl i8 %t0, 21187  %t2 = or i8 %t1, 41188  %t3 = sub i8 %x, %t21189  ret i8 %t31190}1191define i8 @add_via_or_with_no_common_bits_set_extrause(i8 %x, i8 %y) {1192; CHECK-LABEL: define i8 @add_via_or_with_no_common_bits_set_extrause(1193; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1194; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Y]]1195; CHECK-NEXT:    call void @use8(i8 [[T0]])1196; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 21197; CHECK-NEXT:    [[T2:%.*]] = or disjoint i8 [[T1]], 31198; CHECK-NEXT:    call void @use8(i8 [[T2]])1199; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[X]], [[T2]]1200; CHECK-NEXT:    ret i8 [[T3]]1201;1202  %t0 = sub i8 0, %y1203  call void @use8(i8 %t0)1204  %t1 = shl i8 %t0, 21205  %t2 = or i8 %t1, 31206  call void @use8(i8 %t2)1207  %t3 = sub i8 %x, %t21208  ret i8 %t31209}1210 1211; `extractelement` is negatible if source operand is negatible.1212define i4 @negate_extractelement(<2 x i4> %x, i32 %y, i4 %z) {1213; CHECK-LABEL: define i4 @negate_extractelement(1214; CHECK-SAME: <2 x i4> [[X:%.*]], i32 [[Y:%.*]], i4 [[Z:%.*]]) {1215; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X]]1216; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]])1217; CHECK-NEXT:    [[T1_NEG:%.*]] = extractelement <2 x i4> [[X]], i32 [[Y]]1218; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z]]1219; CHECK-NEXT:    ret i4 [[T2]]1220;1221  %t0 = sub <2 x i4> zeroinitializer, %x1222  call void @use_v2i4(<2 x i4> %t0)1223  %t1 = extractelement <2 x i4> %t0, i32 %y1224  %t2 = sub i4 %z, %t11225  ret i4 %t21226}1227define i4 @negate_extractelement_extrause(<2 x i4> %x, i32 %y, i4 %z) {1228; CHECK-LABEL: define i4 @negate_extractelement_extrause(1229; CHECK-SAME: <2 x i4> [[X:%.*]], i32 [[Y:%.*]], i4 [[Z:%.*]]) {1230; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[X]]1231; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T0]])1232; CHECK-NEXT:    [[T1:%.*]] = extractelement <2 x i4> [[T0]], i32 [[Y]]1233; CHECK-NEXT:    call void @use4(i4 [[T1]])1234; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z]], [[T1]]1235; CHECK-NEXT:    ret i4 [[T2]]1236;1237  %t0 = sub <2 x i4> zeroinitializer, %x1238  call void @use_v2i4(<2 x i4> %t0)1239  %t1 = extractelement <2 x i4> %t0, i32 %y1240  call void @use4(i4 %t1)1241  %t2 = sub i4 %z, %t11242  ret i4 %t21243}1244 1245; `insertelement` is negatible if both source vector and element-to-be-inserted are negatible.1246define <2 x i4> @negate_insertelement(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {1247; CHECK-LABEL: define <2 x i4> @negate_insertelement(1248; CHECK-SAME: <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]], <2 x i4> [[B:%.*]]) {1249; CHECK-NEXT:    [[T2_NEG:%.*]] = insertelement <2 x i4> [[SRC]], i4 [[A]], i32 [[X]]1250; CHECK-NEXT:    [[T3:%.*]] = add <2 x i4> [[T2_NEG]], [[B]]1251; CHECK-NEXT:    ret <2 x i4> [[T3]]1252;1253  %t0 = sub <2 x i4> zeroinitializer, %src1254  %t1 = sub i4 zeroinitializer, %a1255  %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x1256  %t3 = sub <2 x i4> %b, %t21257  ret <2 x i4> %t31258}1259define <2 x i4> @negate_insertelement_extrause(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {1260; CHECK-LABEL: define <2 x i4> @negate_insertelement_extrause(1261; CHECK-SAME: <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]], <2 x i4> [[B:%.*]]) {1262; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC]]1263; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A]]1264; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[T1]], i32 [[X]]1265; CHECK-NEXT:    call void @use_v2i4(<2 x i4> [[T2]])1266; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B]], [[T2]]1267; CHECK-NEXT:    ret <2 x i4> [[T3]]1268;1269  %t0 = sub <2 x i4> zeroinitializer, %src1270  %t1 = sub i4 zeroinitializer, %a1271  %t2 = insertelement <2 x i4> %t0, i4 %t1, i32 %x1272  call void @use_v2i4(<2 x i4> %t2)1273  %t3 = sub <2 x i4> %b, %t21274  ret <2 x i4> %t31275}1276define <2 x i4> @negate_insertelement_nonnegatible_base(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {1277; CHECK-LABEL: define <2 x i4> @negate_insertelement_nonnegatible_base(1278; CHECK-SAME: <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]], <2 x i4> [[B:%.*]]) {1279; CHECK-NEXT:    [[T1:%.*]] = sub i4 0, [[A]]1280; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[SRC]], i4 [[T1]], i32 [[X]]1281; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B]], [[T2]]1282; CHECK-NEXT:    ret <2 x i4> [[T3]]1283;1284  %t1 = sub i4 zeroinitializer, %a1285  %t2 = insertelement <2 x i4> %src, i4 %t1, i32 %x1286  %t3 = sub <2 x i4> %b, %t21287  ret <2 x i4> %t31288}1289define <2 x i4> @negate_insertelement_nonnegatible_insert(<2 x i4> %src, i4 %a, i32 %x, <2 x i4> %b) {1290; CHECK-LABEL: define <2 x i4> @negate_insertelement_nonnegatible_insert(1291; CHECK-SAME: <2 x i4> [[SRC:%.*]], i4 [[A:%.*]], i32 [[X:%.*]], <2 x i4> [[B:%.*]]) {1292; CHECK-NEXT:    [[T0:%.*]] = sub <2 x i4> zeroinitializer, [[SRC]]1293; CHECK-NEXT:    [[T2:%.*]] = insertelement <2 x i4> [[T0]], i4 [[A]], i32 [[X]]1294; CHECK-NEXT:    [[T3:%.*]] = sub <2 x i4> [[B]], [[T2]]1295; CHECK-NEXT:    ret <2 x i4> [[T3]]1296;1297  %t0 = sub <2 x i4> zeroinitializer, %src1298  %t2 = insertelement <2 x i4> %t0, i4 %a, i32 %x1299  %t3 = sub <2 x i4> %b, %t21300  ret <2 x i4> %t31301}1302 1303; left-shift by constant can always be negated1304define i8 @negate_left_shift_by_constant_prefer_keeping_shl(i8 %x, i8 %y, i8 %z) {1305; CHECK-LABEL: define i8 @negate_left_shift_by_constant_prefer_keeping_shl(1306; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {1307; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z]]1308; CHECK-NEXT:    call void @use8(i8 [[T0]])1309; CHECK-NEXT:    [[T1_NEG:%.*]] = shl i8 [[Z]], 41310; CHECK-NEXT:    [[T2:%.*]] = add i8 [[T1_NEG]], [[X]]1311; CHECK-NEXT:    ret i8 [[T2]]1312;1313  %t0 = sub i8 0, %z1314  call void @use8(i8 %t0)1315  %t1 = shl i8 %t0, 41316  %t2 = sub i8 %x, %t11317  ret i8 %t21318}1319define i8 @negate_left_shift_by_constant_prefer_keeping_shl_extrause(i8 %x, i8 %y, i8 %z) {1320; CHECK-LABEL: define i8 @negate_left_shift_by_constant_prefer_keeping_shl_extrause(1321; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]]) {1322; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[Z]]1323; CHECK-NEXT:    call void @use8(i8 [[T0]])1324; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 41325; CHECK-NEXT:    call void @use8(i8 [[T1]])1326; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1327; CHECK-NEXT:    ret i8 [[T2]]1328;1329  %t0 = sub i8 0, %z1330  call void @use8(i8 %t0)1331  %t1 = shl i8 %t0, 41332  call void @use8(i8 %t1)1333  %t2 = sub i8 %x, %t11334  ret i8 %t21335}1336define i8 @negate_left_shift_by_constant(i8 %x, i8 %y, i8 %z, i8 %k) {1337; CHECK-LABEL: define i8 @negate_left_shift_by_constant(1338; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[K:%.*]]) {1339; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K]], [[Z]]1340; CHECK-NEXT:    call void @use8(i8 [[T0]])1341; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 41342; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1343; CHECK-NEXT:    ret i8 [[T2]]1344;1345  %t0 = sub i8 %k, %z1346  call void @use8(i8 %t0)1347  %t1 = shl i8 %t0, 41348  %t2 = sub i8 %x, %t11349  ret i8 %t21350}1351define i8 @negate_left_shift_by_constant_extrause(i8 %x, i8 %y, i8 %z, i8 %k) {1352; CHECK-LABEL: define i8 @negate_left_shift_by_constant_extrause(1353; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i8 [[K:%.*]]) {1354; CHECK-NEXT:    [[T0:%.*]] = sub i8 [[K]], [[Z]]1355; CHECK-NEXT:    call void @use8(i8 [[T0]])1356; CHECK-NEXT:    [[T1:%.*]] = shl i8 [[T0]], 41357; CHECK-NEXT:    call void @use8(i8 [[T1]])1358; CHECK-NEXT:    [[T2:%.*]] = sub i8 [[X]], [[T1]]1359; CHECK-NEXT:    ret i8 [[T2]]1360;1361  %t0 = sub i8 %k, %z1362  call void @use8(i8 %t0)1363  %t1 = shl i8 %t0, 41364  call void @use8(i8 %t1)1365  %t2 = sub i8 %x, %t11366  ret i8 %t21367}1368 1369; `add` with single negatible operand is still negatible1370define i8 @negate_add_with_single_negatible_operand(i8 %x, i8 %y) {1371; CHECK-LABEL: define i8 @negate_add_with_single_negatible_operand(1372; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1373; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X]]1374; CHECK-NEXT:    ret i8 [[T1]]1375;1376  %t0 = add i8 %x, 421377  %t1 = sub i8 0, %t01378  ret i8 %t11379}1380; do so even if we are two levels deep1381define i8 @negate_add_with_single_negatible_operand_depth2(i8 %x, i8 %y) {1382; CHECK-LABEL: define i8 @negate_add_with_single_negatible_operand_depth2(1383; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1384; CHECK-NEXT:    [[T0_NEG:%.*]] = sub i8 -21, [[X]]1385; CHECK-NEXT:    [[T1_NEG:%.*]] = mul i8 [[T0_NEG]], [[Y]]1386; CHECK-NEXT:    ret i8 [[T1_NEG]]1387;1388  %t0 = add i8 %x, 211389  %t1 = mul i8 %t0, %y1390  %t2 = sub i8 0, %t11391  ret i8 %t21392}1393 1394define i8 @negate_add_with_single_negatible_operand_extrause(i8 %x, i8 %y) {1395; CHECK-LABEL: define i8 @negate_add_with_single_negatible_operand_extrause(1396; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1397; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X]], 421398; CHECK-NEXT:    call void @use8(i8 [[T0]])1399; CHECK-NEXT:    [[T1:%.*]] = sub i8 -42, [[X]]1400; CHECK-NEXT:    ret i8 [[T1]]1401;1402  %t0 = add i8 %x, 421403  call void @use8(i8 %t0)1404  %t1 = sub i8 0, %t01405  ret i8 %t11406}1407; But don't do this if that means just sinking the negation.1408define i8 @negate_add_with_single_negatible_operand_non_negation(i8 %x, i8 %y) {1409; CHECK-LABEL: define i8 @negate_add_with_single_negatible_operand_non_negation(1410; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1411; CHECK-NEXT:    [[T0:%.*]] = add i8 [[X]], 421412; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Y]], [[T0]]1413; CHECK-NEXT:    ret i8 [[T1]]1414;1415  %t0 = add i8 %x, 421416  %t1 = sub i8 %y, %t01417  ret i8 %t11418}1419 1420; abs/nabs can be negated1421define i8 @negate_abs(i8 %x, i8 %y) {1422; CHECK-LABEL: define i8 @negate_abs(1423; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1424; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1425; CHECK-NEXT:    call void @use8(i8 [[T0]])1426; CHECK-NEXT:    [[T2:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)1427; CHECK-NEXT:    [[T3:%.*]] = sub i8 [[Y]], [[T2]]1428; CHECK-NEXT:    ret i8 [[T3]]1429;1430  %t0 = sub i8 0, %x1431  call void @use8(i8 %t0)1432  %t1 = icmp slt i8 %x, 01433  %t2 = select i1 %t1, i8 %t0, i8 %x, !prof !01434  %t3 = sub i8 %y, %t21435  ret i8 %t31436}1437define i8 @negate_nabs(i8 %x, i8 %y) {1438; CHECK-LABEL: define i8 @negate_nabs(1439; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]]) {1440; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1441; CHECK-NEXT:    call void @use8(i8 [[T0]])1442; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)1443; CHECK-NEXT:    [[T3:%.*]] = add i8 [[Y]], [[TMP1]]1444; CHECK-NEXT:    ret i8 [[T3]]1445;1446  %t0 = sub i8 0, %x1447  call void @use8(i8 %t0)1448  %t1 = icmp slt i8 %x, 01449  %t2 = select i1 %t1, i8 %x, i8 %t0, !prof !01450  %t3 = sub i8 %y, %t21451  ret i8 %t31452}1453 1454; And in general, if hands of select are known to be negation of each other,1455; we can negate the select1456define i8 @negate_select_of_op_vs_negated_op(i8 %x, i8 %y, i1 %c) {1457; CHECK-LABEL: define i8 @negate_select_of_op_vs_negated_op(1458; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i1 [[C:%.*]]) {1459; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1460; CHECK-NEXT:    call void @use8(i8 [[T0]])1461; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C]], i8 [[X]], i8 [[T0]], !prof [[PROF0:![0-9]+]]1462; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y]]1463; CHECK-NEXT:    ret i8 [[T2]]1464;1465  %t0 = sub i8 0, %x1466  call void @use8(i8 %t0)1467  %t1 = select i1 %c, i8 %t0, i8 %x, !prof !01468  %t2 = sub i8 %y, %t11469  ret i8 %t21470}1471 1472define i8 @negate_select_of_op_vs_negated_op_nsw(i8 %x, i8 %y, i1 %c) {1473; CHECK-LABEL: define i8 @negate_select_of_op_vs_negated_op_nsw(1474; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i1 [[C:%.*]]) {1475; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1476; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C]], i8 [[X]], i8 [[T0]]1477; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y]]1478; CHECK-NEXT:    ret i8 [[T2]]1479;1480  %t0 = sub nsw i8 0, %x1481  %t1 = select i1 %c, i8 %t0, i8 %x1482  %t2 = sub i8 %y, %t11483  ret i8 %t21484}1485 1486define i8 @negate_select_of_op_vs_negated_op_nsw_commuted(i8 %x, i8 %y, i1 %c) {1487; CHECK-LABEL: define i8 @negate_select_of_op_vs_negated_op_nsw_commuted(1488; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i1 [[C:%.*]]) {1489; CHECK-NEXT:    [[T0:%.*]] = sub i8 0, [[X]]1490; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C]], i8 [[T0]], i8 [[X]]1491; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Y]]1492; CHECK-NEXT:    ret i8 [[T2]]1493;1494  %t0 = sub nsw i8 0, %x1495  %t1 = select i1 %c, i8 %x, i8 %t01496  %t2 = sub i8 %y, %t11497  ret i8 %t21498}1499 1500define i8 @negate_select_of_op_vs_negated_op_nsw_xyyx(i8 %x, i8 %y, i8 %z, i1 %c) {1501; CHECK-LABEL: define i8 @negate_select_of_op_vs_negated_op_nsw_xyyx(1502; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i1 [[C:%.*]]) {1503; CHECK-NEXT:    [[SUB1:%.*]] = sub i8 [[X]], [[Y]]1504; CHECK-NEXT:    [[SUB2:%.*]] = sub i8 [[Y]], [[X]]1505; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[C]], i8 [[SUB2]], i8 [[SUB1]]1506; CHECK-NEXT:    [[T2:%.*]] = add i8 [[TMP1]], [[Z]]1507; CHECK-NEXT:    ret i8 [[T2]]1508;1509  %sub1 = sub nsw i8 %x, %y1510  %sub2 = sub nsw i8 %y, %x1511  %t1 = select i1 %c, i8 %sub1, i8 %sub21512  %t2 = sub i8 %z, %t11513  ret i8 %t21514}1515 1516define i8 @dont_negate_ordinary_select(i8 %x, i8 %y, i8 %z, i1 %c) {1517; CHECK-LABEL: define i8 @dont_negate_ordinary_select(1518; CHECK-SAME: i8 [[X:%.*]], i8 [[Y:%.*]], i8 [[Z:%.*]], i1 [[C:%.*]]) {1519; CHECK-NEXT:    [[T0:%.*]] = select i1 [[C]], i8 [[X]], i8 [[Y]]1520; CHECK-NEXT:    [[T1:%.*]] = sub i8 [[Z]], [[T0]]1521; CHECK-NEXT:    ret i8 [[T1]]1522;1523  %t0 = select i1 %c, i8 %x, i8 %y1524  %t1 = sub i8 %z, %t01525  ret i8 %t11526}1527 1528define <2 x i32> @negate_select_of_negation_poison(<2 x i1> %c, <2 x i32> %x) {1529; CHECK-LABEL: define <2 x i32> @negate_select_of_negation_poison(1530; CHECK-SAME: <2 x i1> [[C:%.*]], <2 x i32> [[X:%.*]]) {1531; CHECK-NEXT:    [[NEG:%.*]] = sub <2 x i32> <i32 0, i32 poison>, [[X]]1532; CHECK-NEXT:    [[SEL:%.*]] = select <2 x i1> [[C]], <2 x i32> [[NEG]], <2 x i32> [[X]]1533; CHECK-NEXT:    [[NEG2:%.*]] = sub <2 x i32> zeroinitializer, [[SEL]]1534; CHECK-NEXT:    ret <2 x i32> [[NEG2]]1535;1536  %neg = sub <2 x i32> <i32 0, i32 poison>, %x1537  %sel = select <2 x i1> %c, <2 x i32> %neg, <2 x i32> %x1538  %neg2 = sub <2 x i32> zeroinitializer, %sel1539  ret <2 x i32> %neg21540}1541 1542; Freeze is transparent as far as negation is concerned1543define i4 @negate_freeze(i4 %x, i4 %y, i4 %z) {1544; CHECK-LABEL: define i4 @negate_freeze(1545; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) {1546; CHECK-NEXT:    [[X_FR:%.*]] = freeze i4 [[X]]1547; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i4 [[Y]]1548; CHECK-NEXT:    [[T1_NEG:%.*]] = sub i4 [[Y_FR]], [[X_FR]]1549; CHECK-NEXT:    [[T2:%.*]] = add i4 [[T1_NEG]], [[Z]]1550; CHECK-NEXT:    ret i4 [[T2]]1551;1552  %t0 = sub i4 %x, %y1553  %t1 = freeze i4 %t01554  %t2 = sub i4 %z, %t11555  ret i4 %t21556}1557define i4 @negate_freeze_extrause(i4 %x, i4 %y, i4 %z) {1558; CHECK-LABEL: define i4 @negate_freeze_extrause(1559; CHECK-SAME: i4 [[X:%.*]], i4 [[Y:%.*]], i4 [[Z:%.*]]) {1560; CHECK-NEXT:    [[X_FR:%.*]] = freeze i4 [[X]]1561; CHECK-NEXT:    [[Y_FR:%.*]] = freeze i4 [[Y]]1562; CHECK-NEXT:    [[T1:%.*]] = sub i4 [[X_FR]], [[Y_FR]]1563; CHECK-NEXT:    call void @use4(i4 [[T1]])1564; CHECK-NEXT:    [[T2:%.*]] = sub i4 [[Z]], [[T1]]1565; CHECK-NEXT:    ret i4 [[T2]]1566;1567  %t0 = sub i4 %x, %y1568  %t1 = freeze i4 %t01569  call void @use4(i4 %t1)1570  %t2 = sub i4 %z, %t11571  ret i4 %t21572}1573 1574; Due to the InstCombine's worklist management, there are no guarantees that1575; each instruction we'll encounter has been visited by InstCombine already.1576; In particular, most importantly for us, that means we have to canonicalize1577; constants to RHS ourselves, since that is helpful sometimes.1578; This used to cause an endless combine loop.1579define void @noncanonical_mul_with_constant_as_first_operand() {1580; CHECK-LABEL: define void @noncanonical_mul_with_constant_as_first_operand() {1581; CHECK-NEXT:  [[ENTRY:.*:]]1582; CHECK-NEXT:    br label %[[IF_END:.*]]1583; CHECK:       [[IF_END]]:1584; CHECK-NEXT:    br label %[[IF_END]]1585;1586entry:1587  br label %if.end1588 1589if.end:1590  %e.0 = phi i32 [ undef, %entry ], [ %div, %if.end ]1591  %conv = trunc i32 %e.0 to i161592  %mul.i = mul nsw i16 -1, %conv1593  %conv1 = sext i16 %mul.i to i321594  %div = sub nsw i32 0, %conv11595  br label %if.end1596}1597 1598; This would infinite loop because we failed to match a1599; vector constant with constant expression elements as1600; a constant expression.1601 1602@g = external hidden global [1 x [1 x double]]1603 1604define <1 x i64> @PR56601(<1 x i64> %x, <1 x i64> %y) {1605; CHECK-LABEL: define <1 x i64> @PR56601(1606; CHECK-SAME: <1 x i64> [[X:%.*]], <1 x i64> [[Y:%.*]]) {1607; CHECK-NEXT:    [[M1:%.*]] = mul nsw <1 x i64> [[X]], splat (i64 42)1608; CHECK-NEXT:    [[M2:%.*]] = mul nsw <1 x i64> [[Y]], splat (i64 12)1609; CHECK-NEXT:    [[A1:%.*]] = add <1 x i64> [[M1]], <i64 add (i64 ptrtoint (ptr @g to i64), i64 -4)>1610; CHECK-NEXT:    [[A2:%.*]] = add <1 x i64> [[M2]], <i64 add (i64 ptrtoint (ptr @g to i64), i64 -3)>1611; CHECK-NEXT:    [[R:%.*]] = sub <1 x i64> [[A1]], [[A2]]1612; CHECK-NEXT:    ret <1 x i64> [[R]]1613;1614  %m1 = mul nsw <1 x i64> %x, <i64 42>1615  %m2 = mul nsw <1 x i64> %y, <i64 12>1616  %a1 = add <1 x i64> %m1, <i64 add (i64 ptrtoint (ptr @g to i64), i64 -4)>1617  %a2 = add <1 x i64> %m2, <i64 add (i64 ptrtoint (ptr @g to i64), i64 -3)>1618  %r = sub <1 x i64> %a1, %a21619  ret <1 x i64> %r1620}1621 1622!0 = !{!"branch_weights", i32 40, i32 1}1623;.1624; CHECK: [[PROF0]] = !{!"branch_weights", i32 40, i32 1}1625;.1626