brintos

brintos / llvm-project-archived public Read only

0
0
Text · 46.8 KiB · b5eef4e Raw
1409 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 4; Reassociate add.5define i8 @add_reassoc(i32 %n) {6; CHECK-LABEL: define i8 @add_reassoc(7; CHECK-SAME: i32 [[N:%.*]]) {8; CHECK-NEXT:  [[ENTRY:.*]]:9; CHECK-NEXT:    br label %[[BODY:.*]]10; CHECK:       [[BODY]]:11; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]12; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]13; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 514; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 115; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]16; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]17; CHECK:       [[EXIT]]:18; CHECK-NEXT:    ret i8 [[RDX]]19;20entry:21  br label %body22 23body:24  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]25  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]26  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]27  %op1 = add i8 %pn, 228  %op2 = add i8 %pn2, 329  %i.next = add nuw nsw i32 %i, 130  %cmp = icmp eq i32 %i.next, %n31  br i1 %cmp, label %exit, label %body32 33exit:34  %rdx = add i8 %op2, %op135  ret i8 %rdx36}37 38; Reassociate add, and maintain nuw if all ops have it.39define i8 @add_nuw(i32 %n) {40; CHECK-LABEL: define i8 @add_nuw(41; CHECK-SAME: i32 [[N:%.*]]) {42; CHECK-NEXT:  [[ENTRY:.*]]:43; CHECK-NEXT:    br label %[[BODY:.*]]44; CHECK:       [[BODY]]:45; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]46; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]47; CHECK-NEXT:    [[RDX]] = add nuw i8 [[REDUCED_PHI]], 548; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 149; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]50; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]51; CHECK:       [[EXIT]]:52; CHECK-NEXT:    ret i8 [[RDX]]53;54entry:55  br label %body56 57body:58  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]59  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]60  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]61  %op1 = add nuw i8 %pn, 262  %op2 = add nuw i8 %pn2, 363  %i.next = add nuw nsw i32 %i, 164  %cmp = icmp eq i32 %i.next, %n65  br i1 %cmp, label %exit, label %body66 67exit:68  %rdx = add nuw i8 %op2, %op169  ret i8 %rdx70}71 72; Reassociate add, drop nuw if op1 doesn't have it.73define i8 @add_op1_no_nuw(i32 %n) {74; CHECK-LABEL: define i8 @add_op1_no_nuw(75; CHECK-SAME: i32 [[N:%.*]]) {76; CHECK-NEXT:  [[ENTRY:.*]]:77; CHECK-NEXT:    br label %[[BODY:.*]]78; CHECK:       [[BODY]]:79; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]80; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]81; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 582; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 183; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]84; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]85; CHECK:       [[EXIT]]:86; CHECK-NEXT:    ret i8 [[RDX]]87;88entry:89  br label %body90 91body:92  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]93  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]94  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]95  %op1 = add i8 %pn, 296  %op2 = add nuw i8 %pn2, 397  %i.next = add nuw nsw i32 %i, 198  %cmp = icmp eq i32 %i.next, %n99  br i1 %cmp, label %exit, label %body100 101exit:102  %rdx = add nuw i8 %op2, %op1103  ret i8 %rdx104}105 106; Reassociate add, drop nuw if op2 doesn't have it.107define i8 @add_op2_no_nuw(i32 %n) {108; CHECK-LABEL: define i8 @add_op2_no_nuw(109; CHECK-SAME: i32 [[N:%.*]]) {110; CHECK-NEXT:  [[ENTRY:.*]]:111; CHECK-NEXT:    br label %[[BODY:.*]]112; CHECK:       [[BODY]]:113; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]114; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]115; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 5116; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1117; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]118; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]119; CHECK:       [[EXIT]]:120; CHECK-NEXT:    ret i8 [[RDX]]121;122entry:123  br label %body124 125body:126  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]127  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]128  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]129  %op1 = add nuw i8 %pn, 2130  %op2 = add i8 %pn2, 3131  %i.next = add nuw nsw i32 %i, 1132  %cmp = icmp eq i32 %i.next, %n133  br i1 %cmp, label %exit, label %body134 135exit:136  %rdx = add nuw i8 %op2, %op1137  ret i8 %rdx138}139 140; Reassociate add, drop nuw if rdx doesn't have it.141define i8 @add_rdx_no_nuw(i32 %n) {142; CHECK-LABEL: define i8 @add_rdx_no_nuw(143; CHECK-SAME: i32 [[N:%.*]]) {144; CHECK-NEXT:  [[ENTRY:.*]]:145; CHECK-NEXT:    br label %[[BODY:.*]]146; CHECK:       [[BODY]]:147; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]148; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]149; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 5150; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1151; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]152; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]153; CHECK:       [[EXIT]]:154; CHECK-NEXT:    ret i8 [[RDX]]155;156entry:157  br label %body158 159body:160  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]161  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]162  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]163  %op1 = add nuw i8 %pn, 2164  %op2 = add nuw i8 %pn2, 3165  %i.next = add nuw nsw i32 %i, 1166  %cmp = icmp eq i32 %i.next, %n167  br i1 %cmp, label %exit, label %body168 169exit:170  %rdx = add i8 %op2, %op1171  ret i8 %rdx172}173 174; Reassociate add, drop nsw even if all ops have it.175define i8 @add_no_nsw(i32 %n) {176; CHECK-LABEL: define i8 @add_no_nsw(177; CHECK-SAME: i32 [[N:%.*]]) {178; CHECK-NEXT:  [[ENTRY:.*]]:179; CHECK-NEXT:    br label %[[BODY:.*]]180; CHECK:       [[BODY]]:181; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]182; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]183; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 5184; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1185; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]186; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]187; CHECK:       [[EXIT]]:188; CHECK-NEXT:    ret i8 [[RDX]]189;190entry:191  br label %body192 193body:194  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]195  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]196  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]197  %op1 = add nsw i8 %pn, 2198  %op2 = add nsw i8 %pn2, 3199  %i.next = add nuw nsw i32 %i, 1200  %cmp = icmp eq i32 %i.next, %n201  br i1 %cmp, label %exit, label %body202 203exit:204  %rdx = add nsw i8 %op2, %op1205  ret i8 %rdx206}207 208; Reassociate add, keep nuw/nsw if all ops have them.209define i8 @add_nuw_nsw(i32 %n) {210; CHECK-LABEL: define i8 @add_nuw_nsw(211; CHECK-SAME: i32 [[N:%.*]]) {212; CHECK-NEXT:  [[ENTRY:.*]]:213; CHECK-NEXT:    br label %[[BODY:.*]]214; CHECK:       [[BODY]]:215; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]216; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]217; CHECK-NEXT:    [[RDX]] = add nuw nsw i8 [[REDUCED_PHI]], 5218; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1219; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]220; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]221; CHECK:       [[EXIT]]:222; CHECK-NEXT:    ret i8 [[RDX]]223;224entry:225  br label %body226 227body:228  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]229  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]230  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]231  %op1 = add nuw nsw i8 %pn, 2232  %op2 = add nuw nsw i8 %pn2, 3233  %i.next = add nuw nsw i32 %i, 1234  %cmp = icmp eq i32 %i.next, %n235  br i1 %cmp, label %exit, label %body236 237exit:238  %rdx = add nuw nsw i8 %op2, %op1239  ret i8 %rdx240}241 242; Reassociate fixed-length vector operands.243define <16 x i8> @add_v16i8(i32 %n) {244; CHECK-LABEL: define <16 x i8> @add_v16i8(245; CHECK-SAME: i32 [[N:%.*]]) {246; CHECK-NEXT:  [[ENTRY:.*]]:247; CHECK-NEXT:    br label %[[BODY:.*]]248; CHECK:       [[BODY]]:249; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]250; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi <16 x i8> [ splat (i8 1), %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]251; CHECK-NEXT:    [[RDX]] = add <16 x i8> [[REDUCED_PHI]], splat (i8 5)252; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1253; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]254; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]255; CHECK:       [[EXIT]]:256; CHECK-NEXT:    ret <16 x i8> [[RDX]]257;258entry:259  br label %body260 261body:262  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]263  %pn = phi <16 x i8> [ splat (i8 0), %entry ], [ %op1, %body ]264  %pn2 = phi <16 x i8> [ splat (i8 1), %entry ], [ %op2, %body ]265  %op1 = add <16 x i8> %pn, splat (i8 2)266  %op2 = add <16 x i8> %pn2, splat (i8 3)267  %i.next = add nuw nsw i32 %i, 1268  %cmp = icmp eq i32 %i.next, %n269  br i1 %cmp, label %exit, label %body270 271exit:272  %rdx = add <16 x i8> %op2, %op1273  ret <16 x i8> %rdx274}275 276; Reassociate scalable vector operands.277define <vscale x 16 x i8> @add_nxv16i8(i32 %n) {278; CHECK-LABEL: define <vscale x 16 x i8> @add_nxv16i8(279; CHECK-SAME: i32 [[N:%.*]]) {280; CHECK-NEXT:  [[ENTRY:.*]]:281; CHECK-NEXT:    br label %[[BODY:.*]]282; CHECK:       [[BODY]]:283; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]284; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi <vscale x 16 x i8> [ splat (i8 1), %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]285; CHECK-NEXT:    [[RDX]] = add <vscale x 16 x i8> [[REDUCED_PHI]], splat (i8 5)286; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1287; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]288; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]289; CHECK:       [[EXIT]]:290; CHECK-NEXT:    ret <vscale x 16 x i8> [[RDX]]291;292entry:293  br label %body294 295body:296  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]297  %pn = phi <vscale x 16 x i8> [ splat (i8 0), %entry ], [ %op1, %body ]298  %pn2 = phi <vscale x 16 x i8> [ splat (i8 1), %entry ], [ %op2, %body ]299  %op1 = add <vscale x 16 x i8> %pn, splat (i8 2)300  %op2 = add <vscale x 16 x i8> %pn2, splat (i8 3)301  %i.next = add nuw nsw i32 %i, 1302  %cmp = icmp eq i32 %i.next, %n303  br i1 %cmp, label %exit, label %body304 305exit:306  %rdx = add <vscale x 16 x i8> %op2, %op1307  ret <vscale x 16 x i8> %rdx308}309 310; Check other opcodes.311 312; Reassociate mul.313define i8 @mul_reassoc(i32 %n) {314; CHECK-LABEL: define i8 @mul_reassoc(315; CHECK-SAME: i32 [[N:%.*]]) {316; CHECK-NEXT:  [[ENTRY:.*]]:317; CHECK-NEXT:    br label %[[BODY:.*]]318; CHECK:       [[BODY]]:319; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]320; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 2, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]321; CHECK-NEXT:    [[RDX]] = mul i8 [[REDUCED_PHI]], 15322; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1323; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]324; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]325; CHECK:       [[EXIT]]:326; CHECK-NEXT:    ret i8 [[RDX]]327;328entry:329  br label %body330 331body:332  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]333  %pn = phi i8 [ 1, %entry ], [ %op1, %body ]334  %pn2 = phi i8 [ 2, %entry ], [ %op2, %body ]335  %op1 = mul i8 %pn, 3336  %op2 = mul i8 %pn2, 5337  %i.next = add nuw nsw i32 %i, 1338  %cmp = icmp eq i32 %i.next, %n339  br i1 %cmp, label %exit, label %body340 341exit:342  %rdx = mul i8 %op2, %op1343  ret i8 %rdx344}345 346; Reassociate mul, don't expect any flags to be propagated.347define i8 @mul_reassoc_no_nuw_no_nsw(i32 %n) {348; CHECK-LABEL: define i8 @mul_reassoc_no_nuw_no_nsw(349; CHECK-SAME: i32 [[N:%.*]]) {350; CHECK-NEXT:  [[ENTRY:.*]]:351; CHECK-NEXT:    br label %[[BODY:.*]]352; CHECK:       [[BODY]]:353; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]354; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 2, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]355; CHECK-NEXT:    [[RDX]] = mul i8 [[REDUCED_PHI]], 15356; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1357; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]358; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]359; CHECK:       [[EXIT]]:360; CHECK-NEXT:    ret i8 [[RDX]]361;362entry:363  br label %body364 365body:366  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]367  %pn = phi i8 [ 1, %entry ], [ %op1, %body ]368  %pn2 = phi i8 [ 2, %entry ], [ %op2, %body ]369  %op1 = mul nuw nsw i8 %pn, 3370  %op2 = mul nuw nsw i8 %pn2, 5371  %i.next = add nuw nsw i32 %i, 1372  %cmp = icmp eq i32 %i.next, %n373  br i1 %cmp, label %exit, label %body374 375exit:376  %rdx = mul nuw nsw i8 %op2, %op1377  ret i8 %rdx378}379 380; Reassociate and, although it should already be optimized separately.381define i8 @and_reassoc(i32 %n) {382; CHECK-LABEL: define i8 @and_reassoc(383; CHECK-SAME: i32 [[N:%.*]]) {384; CHECK-NEXT:  [[ENTRY:.*]]:385; CHECK-NEXT:    br label %[[BODY:.*]]386; CHECK:       [[BODY]]:387; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]388; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1389; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]390; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]391; CHECK:       [[EXIT]]:392; CHECK-NEXT:    ret i8 3393;394entry:395  br label %body396 397body:398  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]399  %pn = phi i8 [ 31, %entry ], [ %op1, %body ]400  %pn2 = phi i8 [ 63, %entry ], [ %op2, %body ]401  %op1 = and i8 %pn, 3402  %op2 = and i8 %pn2, 7403  %i.next = add nuw nsw i32 %i, 1404  %cmp = icmp eq i32 %i.next, %n405  br i1 %cmp, label %exit, label %body406 407exit:408  %rdx = and i8 %op2, %op1409  ret i8 %rdx410}411 412; Reassociate or, although it should already be optimized separately.413define i8 @or_reassoc(i32 %n) {414; CHECK-LABEL: define i8 @or_reassoc(415; CHECK-SAME: i32 [[N:%.*]]) {416; CHECK-NEXT:  [[ENTRY:.*]]:417; CHECK-NEXT:    br label %[[BODY:.*]]418; CHECK:       [[BODY]]:419; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]420; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1421; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]422; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]423; CHECK:       [[EXIT]]:424; CHECK-NEXT:    ret i8 7425;426entry:427  br label %body428 429body:430  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]431  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]432  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]433  %op1 = or i8 %pn, 3434  %op2 = or i8 %pn2, 7435  %i.next = add nuw nsw i32 %i, 1436  %cmp = icmp eq i32 %i.next, %n437  br i1 %cmp, label %exit, label %body438 439exit:440  %rdx = or i8 %op2, %op1441  ret i8 %rdx442}443 444; Reassociate or and propagate disjoint if all ops have it.445; Note: This can't currently be seen as the results get optimized away.446define i8 @or_disjoint(i32 %n) {447; CHECK-LABEL: define i8 @or_disjoint(448; CHECK-SAME: i32 [[N:%.*]]) {449; CHECK-NEXT:  [[ENTRY:.*]]:450; CHECK-NEXT:    br label %[[BODY:.*]]451; CHECK:       [[BODY]]:452; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]453; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1454; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]455; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]456; CHECK:       [[EXIT]]:457; CHECK-NEXT:    ret i8 7458;459entry:460  br label %body461 462body:463  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]464  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]465  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]466  %op1 = or disjoint i8 %pn, 3467  %op2 = or disjoint i8 %pn2, 7468  %i.next = add nuw nsw i32 %i, 1469  %cmp = icmp eq i32 %i.next, %n470  br i1 %cmp, label %exit, label %body471 472exit:473  %rdx = or disjoint i8 %op2, %op1474  ret i8 %rdx475}476 477; Reassociate xor.478define i8 @xor_reassoc(i32 %n) {479; CHECK-LABEL: define i8 @xor_reassoc(480; CHECK-SAME: i32 [[N:%.*]]) {481; CHECK-NEXT:  [[ENTRY:.*]]:482; CHECK-NEXT:    br label %[[BODY:.*]]483; CHECK:       [[BODY]]:484; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]485; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]486; CHECK-NEXT:    [[RDX]] = xor i8 [[REDUCED_PHI]], 4487; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1488; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]489; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]490; CHECK:       [[EXIT]]:491; CHECK-NEXT:    ret i8 [[RDX]]492;493entry:494  br label %body495 496body:497  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]498  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]499  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]500  %op1 = xor i8 %pn, 3501  %op2 = xor i8 %pn2, 7502  %i.next = add nuw nsw i32 %i, 1503  %cmp = icmp eq i32 %i.next, %n504  br i1 %cmp, label %exit, label %body505 506exit:507  %rdx = xor i8 %op2, %op1508  ret i8 %rdx509}510 511; Reassociate fadd if reassoc and nsz are present on all instructions.512define float @fadd_reassoc_nsz(i32 %n) {513; CHECK-LABEL: define float @fadd_reassoc_nsz(514; CHECK-SAME: i32 [[N:%.*]]) {515; CHECK-NEXT:  [[ENTRY:.*]]:516; CHECK-NEXT:    br label %[[BODY:.*]]517; CHECK:       [[BODY]]:518; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]519; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi float [ 1.000000e+00, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]520; CHECK-NEXT:    [[RDX]] = fadd reassoc nsz float [[REDUCED_PHI]], 5.000000e+00521; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1522; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]523; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]524; CHECK:       [[EXIT]]:525; CHECK-NEXT:    ret float [[RDX]]526;527entry:528  br label %body529 530body:531  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]532  %pn = phi float [ 0.0, %entry ], [ %op1, %body ]533  %pn2 = phi float [ 1.0, %entry ], [ %op2, %body ]534  %op1 = fadd reassoc nsz float %pn, 2.0535  %op2 = fadd reassoc nsz float %pn2, 3.0536  %i.next = add nuw nsw i32 %i, 1537  %cmp = icmp eq i32 %i.next, %n538  br i1 %cmp, label %exit, label %body539 540exit:541  %rdx = fadd reassoc nsz float %op2, %op1542  ret float %rdx543}544 545; Reassociate fmul if reassoc and nsz are present on all instructions.546define float @fmul_reassoc_nsz(i32 %n) {547; CHECK-LABEL: define float @fmul_reassoc_nsz(548; CHECK-SAME: i32 [[N:%.*]]) {549; CHECK-NEXT:  [[ENTRY:.*]]:550; CHECK-NEXT:    br label %[[BODY:.*]]551; CHECK:       [[BODY]]:552; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]553; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi float [ 2.000000e+00, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]554; CHECK-NEXT:    [[RDX]] = fmul reassoc nsz float [[REDUCED_PHI]], 1.200000e+01555; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1556; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]557; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]558; CHECK:       [[EXIT]]:559; CHECK-NEXT:    ret float [[RDX]]560;561entry:562  br label %body563 564body:565  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]566  %pn = phi float [ 1.0, %entry ], [ %op1, %body ]567  %pn2 = phi float [ 2.0, %entry ], [ %op2, %body ]568  %op1 = fmul reassoc nsz float %pn, 3.0569  %op2 = fmul reassoc nsz float %pn2, 4.0570  %i.next = add nuw nsw i32 %i, 1571  %cmp = icmp eq i32 %i.next, %n572  br i1 %cmp, label %exit, label %body573 574exit:575  %rdx = fmul reassoc nsz float %op2, %op1576  ret float %rdx577}578 579; Don't reassociate without `reassoc'.580define float @fadd_no_reassoc(i32 %n) {581; CHECK-LABEL: define float @fadd_no_reassoc(582; CHECK-SAME: i32 [[N:%.*]]) {583; CHECK-NEXT:  [[ENTRY:.*]]:584; CHECK-NEXT:    br label %[[BODY:.*]]585; CHECK:       [[BODY]]:586; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]587; CHECK-NEXT:    [[PN:%.*]] = phi float [ 0.000000e+00, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]588; CHECK-NEXT:    [[PN2:%.*]] = phi float [ 1.000000e+00, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]589; CHECK-NEXT:    [[OP1]] = fadd nsz float [[PN]], 2.000000e+00590; CHECK-NEXT:    [[OP2]] = fadd nsz float [[PN2]], 3.000000e+00591; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1592; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]593; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]594; CHECK:       [[EXIT]]:595; CHECK-NEXT:    [[RDX:%.*]] = fadd nsz float [[OP2]], [[OP1]]596; CHECK-NEXT:    ret float [[RDX]]597;598entry:599  br label %body600 601body:602  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]603  %pn = phi float [ 0.0, %entry ], [ %op1, %body ]604  %pn2 = phi float [ 1.0, %entry ], [ %op2, %body ]605  %op1 = fadd nsz float %pn, 2.0606  %op2 = fadd nsz float %pn2, 3.0607  %i.next = add nuw nsw i32 %i, 1608  %cmp = icmp eq i32 %i.next, %n609  br i1 %cmp, label %exit, label %body610 611exit:612  %rdx = fadd nsz float %op2, %op1613  ret float %rdx614}615 616; Don't reassociate without `nsz'.617define float @fadd_no_nsz(i32 %n) {618; CHECK-LABEL: define float @fadd_no_nsz(619; CHECK-SAME: i32 [[N:%.*]]) {620; CHECK-NEXT:  [[ENTRY:.*]]:621; CHECK-NEXT:    br label %[[BODY:.*]]622; CHECK:       [[BODY]]:623; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]624; CHECK-NEXT:    [[PN:%.*]] = phi float [ 0.000000e+00, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]625; CHECK-NEXT:    [[PN2:%.*]] = phi float [ 1.000000e+00, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]626; CHECK-NEXT:    [[OP1]] = fadd reassoc float [[PN]], 2.000000e+00627; CHECK-NEXT:    [[OP2]] = fadd reassoc float [[PN2]], 3.000000e+00628; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1629; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]630; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]631; CHECK:       [[EXIT]]:632; CHECK-NEXT:    [[RDX:%.*]] = fadd reassoc float [[OP2]], [[OP1]]633; CHECK-NEXT:    ret float [[RDX]]634;635entry:636  br label %body637 638body:639  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]640  %pn = phi float [ 0.0, %entry ], [ %op1, %body ]641  %pn2 = phi float [ 1.0, %entry ], [ %op2, %body ]642  %op1 = fadd reassoc float %pn, 2.0643  %op2 = fadd reassoc float %pn2, 3.0644  %i.next = add nuw nsw i32 %i, 1645  %cmp = icmp eq i32 %i.next, %n646  br i1 %cmp, label %exit, label %body647 648exit:649  %rdx = fadd reassoc float %op2, %op1650  ret float %rdx651}652 653; Check commuted operands.654 655; Reassociate, even if op1 has commuted operands.656define i8 @add_op1_commuted(i32 %n) {657; CHECK-LABEL: define i8 @add_op1_commuted(658; CHECK-SAME: i32 [[N:%.*]]) {659; CHECK-NEXT:  [[ENTRY:.*]]:660; CHECK-NEXT:    br label %[[BODY:.*]]661; CHECK:       [[BODY]]:662; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]663; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]664; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 5665; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1666; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]667; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]668; CHECK:       [[EXIT]]:669; CHECK-NEXT:    ret i8 [[RDX]]670;671entry:672  br label %body673 674body:675  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]676  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]677  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]678  %op1 = add i8 2, %pn679  %op2 = add i8 %pn2, 3680  %i.next = add nuw nsw i32 %i, 1681  %cmp = icmp eq i32 %i.next, %n682  br i1 %cmp, label %exit, label %body683 684exit:685  %rdx = add i8 %op2, %op1686  ret i8 %rdx687}688 689; Reassociate, even if op2 has commuted operands.690define i8 @add_op2_commuted(i32 %n) {691; CHECK-LABEL: define i8 @add_op2_commuted(692; CHECK-SAME: i32 [[N:%.*]]) {693; CHECK-NEXT:  [[ENTRY:.*]]:694; CHECK-NEXT:    br label %[[BODY:.*]]695; CHECK:       [[BODY]]:696; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]697; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]698; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 5699; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1700; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]701; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]702; CHECK:       [[EXIT]]:703; CHECK-NEXT:    ret i8 [[RDX]]704;705entry:706  br label %body707 708body:709  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]710  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]711  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]712  %op1 = add i8 %pn, 2713  %op2 = add i8 3, %pn2714  %i.next = add nuw nsw i32 %i, 1715  %cmp = icmp eq i32 %i.next, %n716  br i1 %cmp, label %exit, label %body717 718exit:719  %rdx = add i8 %op2, %op1720  ret i8 %rdx721}722 723; Reassociate, even if rdx has commuted operands.724define i8 @add_rdx_commuted(i32 %n) {725; CHECK-LABEL: define i8 @add_rdx_commuted(726; CHECK-SAME: i32 [[N:%.*]]) {727; CHECK-NEXT:  [[ENTRY:.*]]:728; CHECK-NEXT:    br label %[[BODY:.*]]729; CHECK:       [[BODY]]:730; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]731; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]732; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 5733; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1734; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]735; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]736; CHECK:       [[EXIT]]:737; CHECK-NEXT:    ret i8 [[RDX]]738;739entry:740  br label %body741 742body:743  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]744  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]745  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]746  %op1 = add i8 %pn, 2747  %op2 = add i8 %pn2, 3748  %i.next = add nuw nsw i32 %i, 1749  %cmp = icmp eq i32 %i.next, %n750  br i1 %cmp, label %exit, label %body751 752exit:753  %rdx = add i8 %op1, %op2754  ret i8 %rdx755}756 757; Reassociate, even if pn has commuted incoming values.758define i8 @add_pn_commuted(i32 %n) {759; CHECK-LABEL: define i8 @add_pn_commuted(760; CHECK-SAME: i32 [[N:%.*]]) {761; CHECK-NEXT:  [[ENTRY:.*]]:762; CHECK-NEXT:    br label %[[BODY:.*]]763; CHECK:       [[BODY]]:764; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]765; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]766; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 5767; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1768; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]769; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]770; CHECK:       [[EXIT]]:771; CHECK-NEXT:    ret i8 [[RDX]]772;773entry:774  br label %body775 776body:777  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]778  %pn = phi i8 [ %op1, %body ], [ 0, %entry ]779  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]780  %op1 = add i8 %pn, 2781  %op2 = add i8 %pn2, 3782  %i.next = add nuw nsw i32 %i, 1783  %cmp = icmp eq i32 %i.next, %n784  br i1 %cmp, label %exit, label %body785 786exit:787  %rdx = add i8 %op2, %op1788  ret i8 %rdx789}790 791; Reassociate, even if pn2 has commuted incoming values.792define i8 @add_pn2_commuted(i32 %n) {793; CHECK-LABEL: define i8 @add_pn2_commuted(794; CHECK-SAME: i32 [[N:%.*]]) {795; CHECK-NEXT:  [[ENTRY:.*]]:796; CHECK-NEXT:    br label %[[BODY:.*]]797; CHECK:       [[BODY]]:798; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]799; CHECK-NEXT:    [[REDUCED_PHI:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[RDX:%.*]], %[[BODY]] ]800; CHECK-NEXT:    [[RDX]] = add i8 [[REDUCED_PHI]], 5801; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1802; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]803; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]804; CHECK:       [[EXIT]]:805; CHECK-NEXT:    ret i8 [[RDX]]806;807entry:808  br label %body809 810body:811  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]812  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]813  %pn2 = phi i8 [ %op2, %body ], [ 1, %entry ]814  %op1 = add i8 %pn, 2815  %op2 = add i8 %pn2, 3816  %i.next = add nuw nsw i32 %i, 1817  %cmp = icmp eq i32 %i.next, %n818  br i1 %cmp, label %exit, label %body819 820exit:821  %rdx = add i8 %op1, %op2822  ret i8 %rdx823}824 825; Check the instructions have the same opcodes.826 827; Don't reassociate if the first op doesn't match the rest.828define i8 @no_mul_add_add(i32 %n) {829; CHECK-LABEL: define i8 @no_mul_add_add(830; CHECK-SAME: i32 [[N:%.*]]) {831; CHECK-NEXT:  [[ENTRY:.*]]:832; CHECK-NEXT:    br label %[[BODY:.*]]833; CHECK:       [[BODY]]:834; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]835; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]836; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]837; CHECK-NEXT:    [[OP1]] = shl i8 [[PN]], 1838; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 3839; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1840; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]841; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]842; CHECK:       [[EXIT]]:843; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]844; CHECK-NEXT:    ret i8 [[RDX]]845;846entry:847  br label %body848 849body:850  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]851  %pn = phi i8 [ 1, %entry ], [ %op1, %body ]852  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]853  %op1 = mul i8 %pn, 2854  %op2 = add i8 %pn2, 3855  %i.next = add nuw nsw i32 %i, 1856  %cmp = icmp eq i32 %i.next, %n857  br i1 %cmp, label %exit, label %body858 859exit:860  %rdx = add i8 %op2, %op1861  ret i8 %rdx862}863 864; Don't reassociate if the second op doesn't match the rest.865define i8 @no_add_mul_add(i32 %n) {866; CHECK-LABEL: define i8 @no_add_mul_add(867; CHECK-SAME: i32 [[N:%.*]]) {868; CHECK-NEXT:  [[ENTRY:.*]]:869; CHECK-NEXT:    br label %[[BODY:.*]]870; CHECK:       [[BODY]]:871; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]872; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]873; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]874; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 2875; CHECK-NEXT:    [[OP2]] = mul i8 [[PN2]], 3876; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1877; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]878; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]879; CHECK:       [[EXIT]]:880; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]881; CHECK-NEXT:    ret i8 [[RDX]]882;883entry:884  br label %body885 886body:887  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]888  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]889  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]890  %op1 = add i8 %pn, 2891  %op2 = mul i8 %pn2, 3892  %i.next = add nuw nsw i32 %i, 1893  %cmp = icmp eq i32 %i.next, %n894  br i1 %cmp, label %exit, label %body895 896exit:897  %rdx = add i8 %op2, %op1898  ret i8 %rdx899}900 901; Don't reassociate if the third op doesn't match the rest.902define i8 @no_add_add_mul(i32 %n) {903; CHECK-LABEL: define i8 @no_add_add_mul(904; CHECK-SAME: i32 [[N:%.*]]) {905; CHECK-NEXT:  [[ENTRY:.*]]:906; CHECK-NEXT:    br label %[[BODY:.*]]907; CHECK:       [[BODY]]:908; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]909; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]910; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]911; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 2912; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 3913; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1914; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]915; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]916; CHECK:       [[EXIT]]:917; CHECK-NEXT:    [[RDX:%.*]] = mul i8 [[OP2]], [[OP1]]918; CHECK-NEXT:    ret i8 [[RDX]]919;920entry:921  br label %body922 923body:924  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]925  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]926  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]927  %op1 = add i8 %pn, 2928  %op2 = add i8 %pn2, 3929  %i.next = add nuw nsw i32 %i, 1930  %cmp = icmp eq i32 %i.next, %n931  br i1 %cmp, label %exit, label %body932 933exit:934  %rdx = mul i8 %op2, %op1935  ret i8 %rdx936}937 938; Check the number of uses of pn, pn2, op1 and op2.939 940; Don't reassociate if pn has more uses.941define i8 @no_add_pn_use(i32 %n) {942; CHECK-LABEL: define i8 @no_add_pn_use(943; CHECK-SAME: i32 [[N:%.*]]) {944; CHECK-NEXT:  [[ENTRY:.*]]:945; CHECK-NEXT:    br label %[[BODY:.*]]946; CHECK:       [[BODY]]:947; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]948; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]949; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]950; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 2951; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 3952; CHECK-NEXT:    tail call void @use(i8 [[PN]])953; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1954; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]955; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]956; CHECK:       [[EXIT]]:957; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]958; CHECK-NEXT:    ret i8 [[RDX]]959;960entry:961  br label %body962 963body:964  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]965  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]966  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]967  %op1 = add i8 %pn, 2968  %op2 = add i8 %pn2, 3969  tail call void @use(i8 %pn)970  %i.next = add nuw nsw i32 %i, 1971  %cmp = icmp eq i32 %i.next, %n972  br i1 %cmp, label %exit, label %body973 974exit:975  %rdx = add i8 %op2, %op1976  ret i8 %rdx977}978 979; Don't reassociate if pn2 has more uses.980define i8 @no_add_pn2_use(i32 %n) {981; CHECK-LABEL: define i8 @no_add_pn2_use(982; CHECK-SAME: i32 [[N:%.*]]) {983; CHECK-NEXT:  [[ENTRY:.*]]:984; CHECK-NEXT:    br label %[[BODY:.*]]985; CHECK:       [[BODY]]:986; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]987; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]988; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]989; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 2990; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 3991; CHECK-NEXT:    tail call void @use(i8 [[PN2]])992; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 1993; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]994; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]995; CHECK:       [[EXIT]]:996; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]997; CHECK-NEXT:    ret i8 [[RDX]]998;999entry:1000  br label %body1001 1002body:1003  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1004  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]1005  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]1006  %op1 = add i8 %pn, 21007  %op2 = add i8 %pn2, 31008  tail call void @use(i8 %pn2)1009  %i.next = add nuw nsw i32 %i, 11010  %cmp = icmp eq i32 %i.next, %n1011  br i1 %cmp, label %exit, label %body1012 1013exit:1014  %rdx = add i8 %op2, %op11015  ret i8 %rdx1016}1017 1018; Don't reassociate if op1 has more uses.1019define i8 @no_add_op1_use(i32 %n) {1020; CHECK-LABEL: define i8 @no_add_op1_use(1021; CHECK-SAME: i32 [[N:%.*]]) {1022; CHECK-NEXT:  [[ENTRY:.*]]:1023; CHECK-NEXT:    br label %[[BODY:.*]]1024; CHECK:       [[BODY]]:1025; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1026; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]1027; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]1028; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 21029; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 31030; CHECK-NEXT:    tail call void @use(i8 [[OP1]])1031; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11032; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1033; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1034; CHECK:       [[EXIT]]:1035; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1036; CHECK-NEXT:    ret i8 [[RDX]]1037;1038entry:1039  br label %body1040 1041body:1042  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1043  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]1044  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]1045  %op1 = add i8 %pn, 21046  %op2 = add i8 %pn2, 31047  tail call void @use(i8 %op1)1048  %i.next = add nuw nsw i32 %i, 11049  %cmp = icmp eq i32 %i.next, %n1050  br i1 %cmp, label %exit, label %body1051 1052exit:1053  %rdx = add i8 %op2, %op11054  ret i8 %rdx1055}1056 1057; Don't reassociate if op2 has more uses.1058define i8 @no_add_op2_use(i32 %n) {1059; CHECK-LABEL: define i8 @no_add_op2_use(1060; CHECK-SAME: i32 [[N:%.*]]) {1061; CHECK-NEXT:  [[ENTRY:.*]]:1062; CHECK-NEXT:    br label %[[BODY:.*]]1063; CHECK:       [[BODY]]:1064; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1065; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]1066; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]1067; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 21068; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 31069; CHECK-NEXT:    tail call void @use(i8 [[OP2]])1070; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11071; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1072; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1073; CHECK:       [[EXIT]]:1074; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1075; CHECK-NEXT:    ret i8 [[RDX]]1076;1077entry:1078  br label %body1079 1080body:1081  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1082  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]1083  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]1084  %op1 = add i8 %pn, 21085  %op2 = add i8 %pn2, 31086  tail call void @use(i8 %op2)1087  %i.next = add nuw nsw i32 %i, 11088  %cmp = icmp eq i32 %i.next, %n1089  br i1 %cmp, label %exit, label %body1090 1091exit:1092  %rdx = add i8 %op2, %op11093  ret i8 %rdx1094}1095 1096; Check that init1, init2, c1 and c2 are constants.1097; Note: It should be possible to support non-constant operands, we just don't1098; do so yet.1099 1100; Don't reassociate if the initial value of pn isn't constant.1101define i8 @no_add_init1(i8 %init1, i32 %n) {1102; CHECK-LABEL: define i8 @no_add_init1(1103; CHECK-SAME: i8 [[INIT1:%.*]], i32 [[N:%.*]]) {1104; CHECK-NEXT:  [[ENTRY:.*]]:1105; CHECK-NEXT:    br label %[[BODY:.*]]1106; CHECK:       [[BODY]]:1107; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1108; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ [[INIT1]], %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]1109; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]1110; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 21111; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 31112; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11113; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1114; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1115; CHECK:       [[EXIT]]:1116; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1117; CHECK-NEXT:    ret i8 [[RDX]]1118;1119entry:1120  br label %body1121 1122body:1123  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1124  %pn = phi i8 [ %init1, %entry ], [ %op1, %body ]1125  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]1126  %op1 = add i8 %pn, 21127  %op2 = add i8 %pn2, 31128  %i.next = add nuw nsw i32 %i, 11129  %cmp = icmp eq i32 %i.next, %n1130  br i1 %cmp, label %exit, label %body1131 1132exit:1133  %rdx = add i8 %op2, %op11134  ret i8 %rdx1135}1136 1137; Don't reassociate if the initial value of pn2 isn't constant.1138define i8 @no_add_init2(i8 %init2, i32 %n) {1139; CHECK-LABEL: define i8 @no_add_init2(1140; CHECK-SAME: i8 [[INIT2:%.*]], i32 [[N:%.*]]) {1141; CHECK-NEXT:  [[ENTRY:.*]]:1142; CHECK-NEXT:    br label %[[BODY:.*]]1143; CHECK:       [[BODY]]:1144; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1145; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]1146; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ [[INIT2]], %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]1147; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 21148; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 31149; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11150; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1151; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1152; CHECK:       [[EXIT]]:1153; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1154; CHECK-NEXT:    ret i8 [[RDX]]1155;1156entry:1157  br label %body1158 1159body:1160  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1161  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]1162  %pn2 = phi i8 [ %init2, %entry ], [ %op2, %body ]1163  %op1 = add i8 %pn, 21164  %op2 = add i8 %pn2, 31165  %i.next = add nuw nsw i32 %i, 11166  %cmp = icmp eq i32 %i.next, %n1167  br i1 %cmp, label %exit, label %body1168 1169exit:1170  %rdx = add i8 %op2, %op11171  ret i8 %rdx1172}1173 1174; Don't reassociate if the recurrence operand of op1 isn't constant.1175define i8 @no_add_c1(i8 %c1, i32 %n) {1176; CHECK-LABEL: define i8 @no_add_c1(1177; CHECK-SAME: i8 [[C1:%.*]], i32 [[N:%.*]]) {1178; CHECK-NEXT:  [[ENTRY:.*]]:1179; CHECK-NEXT:    br label %[[BODY:.*]]1180; CHECK:       [[BODY]]:1181; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1182; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]1183; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]1184; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], [[C1]]1185; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 31186; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11187; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1188; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1189; CHECK:       [[EXIT]]:1190; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1191; CHECK-NEXT:    ret i8 [[RDX]]1192;1193entry:1194  br label %body1195 1196body:1197  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1198  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]1199  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]1200  %op1 = add i8 %pn, %c11201  %op2 = add i8 %pn2, 31202  %i.next = add nuw nsw i32 %i, 11203  %cmp = icmp eq i32 %i.next, %n1204  br i1 %cmp, label %exit, label %body1205 1206exit:1207  %rdx = add i8 %op2, %op11208  ret i8 %rdx1209}1210 1211; Don't reassociate if the recurrence operand of op2 isn't constant.1212define i8 @no_add_c2(i8 %c2, i32 %n) {1213; CHECK-LABEL: define i8 @no_add_c2(1214; CHECK-SAME: i8 [[C2:%.*]], i32 [[N:%.*]]) {1215; CHECK-NEXT:  [[ENTRY:.*]]:1216; CHECK-NEXT:    br label %[[BODY:.*]]1217; CHECK:       [[BODY]]:1218; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1219; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]1220; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]1221; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 21222; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], [[C2]]1223; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11224; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1225; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1226; CHECK:       [[EXIT]]:1227; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1228; CHECK-NEXT:    ret i8 [[RDX]]1229;1230entry:1231  br label %body1232 1233body:1234  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1235  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]1236  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]1237  %op1 = add i8 %pn, 21238  %op2 = add i8 %pn2, %c21239  %i.next = add nuw nsw i32 %i, 11240  %cmp = icmp eq i32 %i.next, %n1241  br i1 %cmp, label %exit, label %body1242 1243exit:1244  %rdx = add i8 %op2, %op11245  ret i8 %rdx1246}1247 1248; Check the incoming values of pn and pn2.1249 1250; Don't reassociate if op1 doesn't recurse to pn.1251define i8 @no_add_op1_to_pn(i1 %c, i32 %n) {1252; CHECK-LABEL: define i8 @no_add_op1_to_pn(1253; CHECK-SAME: i1 [[C:%.*]], i32 [[N:%.*]]) {1254; CHECK-NEXT:  [[ENTRY:.*]]:1255; CHECK-NEXT:    br label %[[BODY:.*]]1256; CHECK:       [[BODY]]:1257; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1258; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP2:%.*]], %[[BODY]] ]1259; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2]], %[[BODY]] ]1260; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 31261; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11262; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1263; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1264; CHECK:       [[EXIT]]:1265; CHECK-NEXT:    [[OP1:%.*]] = add i8 [[PN]], 21266; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1267; CHECK-NEXT:    ret i8 [[RDX]]1268;1269entry:1270  br label %body1271 1272body:1273  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1274  %pn = phi i8 [ 0, %entry ], [ %op2, %body ]1275  %pn2 = phi i8 [ 1, %entry ], [ %op2, %body ]1276  %op1 = add i8 %pn, 21277  %op2 = add i8 %pn2, 31278  %i.next = add nuw nsw i32 %i, 11279  %cmp = icmp eq i32 %i.next, %n1280  br i1 %cmp, label %exit, label %body1281 1282exit:1283  %rdx = add i8 %op2, %op11284  ret i8 %rdx1285}1286 1287; Don't reassociate if op2 doesn't recurse to pn2.1288define i8 @no_add_op2_to_pn2(i1 %c, i32 %n) {1289; CHECK-LABEL: define i8 @no_add_op2_to_pn2(1290; CHECK-SAME: i1 [[C:%.*]], i32 [[N:%.*]]) {1291; CHECK-NEXT:  [[ENTRY:.*]]:1292; CHECK-NEXT:    br label %[[BODY:.*]]1293; CHECK:       [[BODY]]:1294; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1295; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[BODY]] ]1296; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP1]], %[[BODY]] ]1297; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 21298; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11299; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1300; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1301; CHECK:       [[EXIT]]:1302; CHECK-NEXT:    [[OP2:%.*]] = add i8 [[PN2]], 31303; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1304; CHECK-NEXT:    ret i8 [[RDX]]1305;1306entry:1307  br label %body1308 1309body:1310  %i = phi i32 [ 0, %entry ], [ %i.next, %body ]1311  %pn = phi i8 [ 0, %entry ], [ %op1, %body ]1312  %pn2 = phi i8 [ 1, %entry ], [ %op1, %body ]1313  %op1 = add i8 %pn, 21314  %op2 = add i8 %pn2, 31315  %i.next = add nuw nsw i32 %i, 11316  %cmp = icmp eq i32 %i.next, %n1317  br i1 %cmp, label %exit, label %body1318 1319exit:1320  %rdx = add i8 %op2, %op11321  ret i8 %rdx1322}1323 1324; Don't reassociate if the phis have more than two incoming values.1325define i8 @no_add_phis_more_incoming_values(i1 %c, i32 %n) {1326; CHECK-LABEL: define i8 @no_add_phis_more_incoming_values(1327; CHECK-SAME: i1 [[C:%.*]], i32 [[N:%.*]]) {1328; CHECK-NEXT:  [[ENTRY:.*]]:1329; CHECK-NEXT:    br i1 [[C]], label %[[BODY:.*]], label %[[OTHER:.*]]1330; CHECK:       [[OTHER]]:1331; CHECK-NEXT:    br label %[[BODY]]1332; CHECK:       [[BODY]]:1333; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ 1, %[[OTHER]] ], [ [[I_NEXT:%.*]], %[[BODY]] ]1334; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ 0, %[[OTHER]] ], [ [[OP1:%.*]], %[[BODY]] ]1335; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ 1, %[[OTHER]] ], [ [[OP2:%.*]], %[[BODY]] ]1336; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 21337; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 31338; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11339; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1340; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1341; CHECK:       [[EXIT]]:1342; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1343; CHECK-NEXT:    ret i8 [[RDX]]1344;1345entry:1346  br i1 %c, label %body, label %other1347 1348other:1349  br label %body1350 1351body:1352  %i = phi i32 [ 0, %entry ], [ 1, %other ], [ %i.next, %body ]1353  %pn = phi i8 [ 0, %entry ], [ 0, %other ], [ %op1, %body ]1354  %pn2 = phi i8 [ 1, %entry ], [ 1, %other ], [ %op2, %body ]1355  %op1 = add i8 %pn, 21356  %op2 = add i8 %pn2, 31357  %i.next = add nuw nsw i32 %i, 11358  %cmp = icmp eq i32 %i.next, %n1359  br i1 %cmp, label %exit, label %body1360 1361exit:1362  %rdx = add i8 %op2, %op11363  ret i8 %rdx1364}1365 1366; Don't reassociate if the ops span different blocks.1367define i8 @no_add_op_multi_block(i32 %n) {1368; CHECK-LABEL: define i8 @no_add_op_multi_block(1369; CHECK-SAME: i32 [[N:%.*]]) {1370; CHECK-NEXT:  [[ENTRY:.*]]:1371; CHECK-NEXT:    br label %[[BODY:.*]]1372; CHECK:       [[BODY]]:1373; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[I_NEXT:%.*]], %[[OTHER:.*]] ]1374; CHECK-NEXT:    [[PN:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ [[OP1:%.*]], %[[OTHER]] ]1375; CHECK-NEXT:    [[PN2:%.*]] = phi i8 [ 1, %[[ENTRY]] ], [ [[OP2:%.*]], %[[OTHER]] ]1376; CHECK-NEXT:    [[OP1]] = add i8 [[PN]], 21377; CHECK-NEXT:    br label %[[OTHER]]1378; CHECK:       [[OTHER]]:1379; CHECK-NEXT:    [[OP2]] = add i8 [[PN2]], 31380; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i32 [[I]], 11381; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[N]]1382; CHECK-NEXT:    br i1 [[CMP]], label %[[EXIT:.*]], label %[[BODY]]1383; CHECK:       [[EXIT]]:1384; CHECK-NEXT:    [[RDX:%.*]] = add i8 [[OP2]], [[OP1]]1385; CHECK-NEXT:    ret i8 [[RDX]]1386;1387entry:1388  br label %body1389 1390body:1391  %i = phi i32 [ 0, %entry ], [ %i.next, %other ]1392  %pn = phi i8 [ 0, %entry ], [ %op1, %other ]1393  %pn2 = phi i8 [ 1, %entry ], [ %op2, %other ]1394  %op1 = add i8 %pn, 21395  br label %other1396 1397other:1398  %op2 = add i8 %pn2, 31399  %i.next = add nuw nsw i32 %i, 11400  %cmp = icmp eq i32 %i.next, %n1401  br i1 %cmp, label %exit, label %body1402 1403exit:1404  %rdx = add i8 %op2, %op11405  ret i8 %rdx1406}1407 1408declare void @use(i8)1409