992 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -disable-complex-addr-modes=false -addr-sink-new-phis=true -addr-sink-new-select=true -disable-cgp-delete-phis %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-YES3; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -disable-complex-addr-modes=false -addr-sink-new-phis=false -addr-sink-new-select=true -disable-cgp-delete-phis %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO4target datalayout =5"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"6target triple = "x86_64-unknown-linux-gnu"7 8; Can we sink for different base if there is no phi for base?9define i32 @test1(i1 %cond, ptr %b1, ptr %b2) {10; CHECK-YES-LABEL: define i32 @test1(11; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {12; CHECK-YES-NEXT: [[ENTRY:.*]]:13; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]14; CHECK-YES: [[IF_THEN]]:15; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]16; CHECK-YES: [[FALLTHROUGH]]:17; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ]18; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 4019; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 420; CHECK-YES-NEXT: ret i32 [[V]]21;22; CHECK-NO-LABEL: define i32 @test1(23; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {24; CHECK-NO-NEXT: [[ENTRY:.*]]:25; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 526; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]27; CHECK-NO: [[IF_THEN]]:28; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 529; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]30; CHECK-NO: [[FALLTHROUGH]]:31; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ]32; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[C]], align 433; CHECK-NO-NEXT: ret i32 [[V]]34;35entry:36 %a1 = getelementptr inbounds i64, ptr %b1, i64 537 br i1 %cond, label %if.then, label %fallthrough38 39if.then:40 %a2 = getelementptr inbounds i64, ptr %b2, i64 541 br label %fallthrough42 43fallthrough:44 %c = phi ptr [%a1, %entry], [%a2, %if.then]45 %v = load i32, ptr %c, align 446 ret i32 %v47}48 49; Can we sink for different base if there is phi for base?50define i32 @test2(i1 %cond, ptr %b1, ptr %b2) {51; CHECK-LABEL: define i32 @test2(52; CHECK-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {53; CHECK-NEXT: [[ENTRY:.*]]:54; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]55; CHECK: [[IF_THEN]]:56; CHECK-NEXT: br label %[[FALLTHROUGH]]57; CHECK: [[FALLTHROUGH]]:58; CHECK-NEXT: [[B:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[IF_THEN]] ]59; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 4060; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 461; CHECK-NEXT: ret i32 [[V]]62;63entry:64 %a1 = getelementptr inbounds i64, ptr %b1, i64 565 br i1 %cond, label %if.then, label %fallthrough66 67if.then:68 %a2 = getelementptr inbounds i64, ptr %b2, i64 569 br label %fallthrough70 71fallthrough:72 %b = phi ptr [%b1, %entry], [%b2, %if.then]73 %c = phi ptr [%a1, %entry], [%a2, %if.then]74 %v = load i32, ptr %c, align 475 ret i32 %v76}77 78; Can we sink for different base if there is phi for base but not valid one?79define i32 @test3(i1 %cond, ptr %b1, ptr %b2) {80; CHECK-YES-LABEL: define i32 @test3(81; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {82; CHECK-YES-NEXT: [[ENTRY:.*]]:83; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]84; CHECK-YES: [[IF_THEN]]:85; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]86; CHECK-YES: [[FALLTHROUGH]]:87; CHECK-YES-NEXT: [[B:%.*]] = phi ptr [ [[B2]], %[[ENTRY]] ], [ [[B1]], %[[IF_THEN]] ]88; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ]89; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 4090; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 491; CHECK-YES-NEXT: ret i32 [[V]]92;93; CHECK-NO-LABEL: define i32 @test3(94; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {95; CHECK-NO-NEXT: [[ENTRY:.*]]:96; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 597; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]98; CHECK-NO: [[IF_THEN]]:99; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5100; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]101; CHECK-NO: [[FALLTHROUGH]]:102; CHECK-NO-NEXT: [[B:%.*]] = phi ptr [ [[B2]], %[[ENTRY]] ], [ [[B1]], %[[IF_THEN]] ]103; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ]104; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[C]], align 4105; CHECK-NO-NEXT: ret i32 [[V]]106;107entry:108 %a1 = getelementptr inbounds i64, ptr %b1, i64 5109 br i1 %cond, label %if.then, label %fallthrough110 111if.then:112 %a2 = getelementptr inbounds i64, ptr %b2, i64 5113 br label %fallthrough114 115fallthrough:116 %b = phi ptr [%b2, %entry], [%b1, %if.then]117 %c = phi ptr [%a1, %entry], [%a2, %if.then]118 %v = load i32, ptr %c, align 4119 ret i32 %v120}121 122; Can we sink for different base if both addresses are in the same block?123define i32 @test4(i1 %cond, ptr %b1, ptr %b2) {124; CHECK-YES-LABEL: define i32 @test4(125; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {126; CHECK-YES-NEXT: [[ENTRY:.*]]:127; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]128; CHECK-YES: [[IF_THEN]]:129; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]130; CHECK-YES: [[FALLTHROUGH]]:131; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ]132; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40133; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4134; CHECK-YES-NEXT: ret i32 [[V]]135;136; CHECK-NO-LABEL: define i32 @test4(137; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {138; CHECK-NO-NEXT: [[ENTRY:.*]]:139; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5140; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5141; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]142; CHECK-NO: [[IF_THEN]]:143; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]144; CHECK-NO: [[FALLTHROUGH]]:145; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ]146; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[C]], align 4147; CHECK-NO-NEXT: ret i32 [[V]]148;149entry:150 %a1 = getelementptr inbounds i64, ptr %b1, i64 5151 %a2 = getelementptr inbounds i64, ptr %b2, i64 5152 br i1 %cond, label %if.then, label %fallthrough153 154if.then:155 br label %fallthrough156 157fallthrough:158 %c = phi ptr [%a1, %entry], [%a2, %if.then]159 %v = load i32, ptr %c, align 4160 ret i32 %v161}162 163; Can we sink for different base if there is phi for base?164; Both addresses are in the same block.165define i32 @test5(i1 %cond, ptr %b1, ptr %b2) {166; CHECK-LABEL: define i32 @test5(167; CHECK-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {168; CHECK-NEXT: [[ENTRY:.*]]:169; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]170; CHECK: [[IF_THEN]]:171; CHECK-NEXT: br label %[[FALLTHROUGH]]172; CHECK: [[FALLTHROUGH]]:173; CHECK-NEXT: [[B:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[IF_THEN]] ]174; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 40175; CHECK-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4176; CHECK-NEXT: ret i32 [[V]]177;178entry:179 %a1 = getelementptr inbounds i64, ptr %b1, i64 5180 %a2 = getelementptr inbounds i64, ptr %b2, i64 5181 br i1 %cond, label %if.then, label %fallthrough182 183if.then:184 br label %fallthrough185 186fallthrough:187 %b = phi ptr [%b1, %entry], [%b2, %if.then]188 %c = phi ptr [%a1, %entry], [%a2, %if.then]189 %v = load i32, ptr %c, align 4190 ret i32 %v191}192 193; Can we sink for different base if there is phi for base but not valid one?194; Both addresses are in the same block.195define i32 @test6(i1 %cond, ptr %b1, ptr %b2) {196; CHECK-YES-LABEL: define i32 @test6(197; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {198; CHECK-YES-NEXT: [[ENTRY:.*]]:199; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]200; CHECK-YES: [[IF_THEN]]:201; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]202; CHECK-YES: [[FALLTHROUGH]]:203; CHECK-YES-NEXT: [[B:%.*]] = phi ptr [ [[B2]], %[[ENTRY]] ], [ [[B1]], %[[IF_THEN]] ]204; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ]205; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40206; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR]], align 4207; CHECK-YES-NEXT: ret i32 [[V]]208;209; CHECK-NO-LABEL: define i32 @test6(210; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {211; CHECK-NO-NEXT: [[ENTRY:.*]]:212; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5213; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5214; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]215; CHECK-NO: [[IF_THEN]]:216; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]217; CHECK-NO: [[FALLTHROUGH]]:218; CHECK-NO-NEXT: [[B:%.*]] = phi ptr [ [[B2]], %[[ENTRY]] ], [ [[B1]], %[[IF_THEN]] ]219; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ]220; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[C]], align 4221; CHECK-NO-NEXT: ret i32 [[V]]222;223entry:224 %a1 = getelementptr inbounds i64, ptr %b1, i64 5225 %a2 = getelementptr inbounds i64, ptr %b2, i64 5226 br i1 %cond, label %if.then, label %fallthrough227 228if.then:229 br label %fallthrough230 231fallthrough:232 %b = phi ptr [%b2, %entry], [%b1, %if.then]233 %c = phi ptr [%a1, %entry], [%a2, %if.then]234 %v = load i32, ptr %c, align 4235 ret i32 %v236}237 238; case with a loop. No phi node.239define i32 @test7(i32 %N, i1 %cond, ptr %b1, ptr %b2) {240; CHECK-YES-LABEL: define i32 @test7(241; CHECK-YES-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {242; CHECK-YES-NEXT: [[ENTRY:.*]]:243; CHECK-YES-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5244; CHECK-YES-NEXT: br label %[[LOOP:.*]]245; CHECK-YES: [[LOOP]]:246; CHECK-YES-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ]247; CHECK-YES-NEXT: [[SUNK_PHI1:%.*]] = phi ptr [ [[SUNK_PHI:%.*]], %[[FALLTHROUGH]] ], [ [[B1]], %[[ENTRY]] ]248; CHECK-YES-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ]249; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]]250; CHECK-YES: [[IF_THEN]]:251; CHECK-YES-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5252; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]253; CHECK-YES: [[FALLTHROUGH]]:254; CHECK-YES-NEXT: [[SUNK_PHI]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[SUNK_PHI1]], %[[LOOP]] ]255; CHECK-YES-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ]256; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40257; CHECK-YES-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4258; CHECK-YES-NEXT: [[IV_INC]] = add i32 [[IV]], 1259; CHECK-YES-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]]260; CHECK-YES-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]261; CHECK-YES: [[EXIT]]:262; CHECK-YES-NEXT: ret i32 [[V]]263;264; CHECK-NO-LABEL: define i32 @test7(265; CHECK-NO-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {266; CHECK-NO-NEXT: [[ENTRY:.*]]:267; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5268; CHECK-NO-NEXT: br label %[[LOOP:.*]]269; CHECK-NO: [[LOOP]]:270; CHECK-NO-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ]271; CHECK-NO-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ]272; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]]273; CHECK-NO: [[IF_THEN]]:274; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5275; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]276; CHECK-NO: [[FALLTHROUGH]]:277; CHECK-NO-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ]278; CHECK-NO-NEXT: [[V:%.*]] = load volatile i32, ptr [[C]], align 4279; CHECK-NO-NEXT: [[IV_INC]] = add i32 [[IV]], 1280; CHECK-NO-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]]281; CHECK-NO-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]282; CHECK-NO: [[EXIT]]:283; CHECK-NO-NEXT: ret i32 [[V]]284;285entry:286 %a1 = getelementptr inbounds i64, ptr %b1, i64 5287 br label %loop288 289loop:290 %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]291 %c3 = phi ptr [%a1, %entry], [%c, %fallthrough]292 br i1 %cond, label %if.then, label %fallthrough293 294if.then:295 %a2 = getelementptr inbounds i64, ptr %b2, i64 5296 br label %fallthrough297 298fallthrough:299 %c = phi ptr [%c3, %loop], [%a2, %if.then]300 %v = load volatile i32, ptr %c, align 4301 %iv.inc = add i32 %iv, 1302 %cmp = icmp slt i32 %iv.inc, %N303 br i1 %cmp, label %loop, label %exit304 305exit:306 ret i32 %v307}308 309; case with a loop. There is phi node.310define i32 @test8(i32 %N, i1 %cond, ptr %b1, ptr %b2) {311; CHECK-LABEL: define i32 @test8(312; CHECK-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {313; CHECK-NEXT: [[ENTRY:.*]]:314; CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5315; CHECK-NEXT: br label %[[LOOP:.*]]316; CHECK: [[LOOP]]:317; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ]318; CHECK-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ]319; CHECK-NEXT: [[B3:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B:%.*]], %[[FALLTHROUGH]] ]320; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]]321; CHECK: [[IF_THEN]]:322; CHECK-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5323; CHECK-NEXT: br label %[[FALLTHROUGH]]324; CHECK: [[FALLTHROUGH]]:325; CHECK-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ]326; CHECK-NEXT: [[B]] = phi ptr [ [[B3]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ]327; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 40328; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4329; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1330; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]]331; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]332; CHECK: [[EXIT]]:333; CHECK-NEXT: ret i32 [[V]]334;335entry:336 %a1 = getelementptr inbounds i64, ptr %b1, i64 5337 br label %loop338 339loop:340 %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]341 %c3 = phi ptr [%a1, %entry], [%c, %fallthrough]342 %b3 = phi ptr [%b1, %entry], [%b, %fallthrough]343 br i1 %cond, label %if.then, label %fallthrough344 345if.then:346 %a2 = getelementptr inbounds i64, ptr %b2, i64 5347 br label %fallthrough348 349fallthrough:350 %c = phi ptr [%c3, %loop], [%a2, %if.then]351 %b = phi ptr [%b3, %loop], [%b2, %if.then]352 %v = load volatile i32, ptr %c, align 4353 %iv.inc = add i32 %iv, 1354 %cmp = icmp slt i32 %iv.inc, %N355 br i1 %cmp, label %loop, label %exit356 357exit:358 ret i32 %v359}360 361; case with a loop. There is phi node but it does not fit.362define i32 @test9(i32 %N, i1 %cond, ptr %b1, ptr %b2) {363; CHECK-YES-LABEL: define i32 @test9(364; CHECK-YES-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {365; CHECK-YES-NEXT: [[ENTRY:.*]]:366; CHECK-YES-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5367; CHECK-YES-NEXT: br label %[[LOOP:.*]]368; CHECK-YES: [[LOOP]]:369; CHECK-YES-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ]370; CHECK-YES-NEXT: [[SUNK_PHI1:%.*]] = phi ptr [ [[SUNK_PHI:%.*]], %[[FALLTHROUGH]] ], [ [[B1]], %[[ENTRY]] ]371; CHECK-YES-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ]372; CHECK-YES-NEXT: [[B3:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[FALLTHROUGH]] ]373; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]]374; CHECK-YES: [[IF_THEN]]:375; CHECK-YES-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5376; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]377; CHECK-YES: [[FALLTHROUGH]]:378; CHECK-YES-NEXT: [[SUNK_PHI]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[SUNK_PHI1]], %[[LOOP]] ]379; CHECK-YES-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ]380; CHECK-YES-NEXT: [[B:%.*]] = phi ptr [ [[B3]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ]381; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40382; CHECK-YES-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4383; CHECK-YES-NEXT: [[IV_INC]] = add i32 [[IV]], 1384; CHECK-YES-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]]385; CHECK-YES-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]386; CHECK-YES: [[EXIT]]:387; CHECK-YES-NEXT: ret i32 [[V]]388;389; CHECK-NO-LABEL: define i32 @test9(390; CHECK-NO-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {391; CHECK-NO-NEXT: [[ENTRY:.*]]:392; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5393; CHECK-NO-NEXT: br label %[[LOOP:.*]]394; CHECK-NO: [[LOOP]]:395; CHECK-NO-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[FALLTHROUGH:.*]] ]396; CHECK-NO-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[FALLTHROUGH]] ]397; CHECK-NO-NEXT: [[B3:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[FALLTHROUGH]] ]398; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH]]399; CHECK-NO: [[IF_THEN]]:400; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5401; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]402; CHECK-NO: [[FALLTHROUGH]]:403; CHECK-NO-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ]404; CHECK-NO-NEXT: [[B:%.*]] = phi ptr [ [[B3]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ]405; CHECK-NO-NEXT: [[V:%.*]] = load volatile i32, ptr [[C]], align 4406; CHECK-NO-NEXT: [[IV_INC]] = add i32 [[IV]], 1407; CHECK-NO-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]]408; CHECK-NO-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]409; CHECK-NO: [[EXIT]]:410; CHECK-NO-NEXT: ret i32 [[V]]411;412entry:413 %a1 = getelementptr inbounds i64, ptr %b1, i64 5414 br label %loop415 416loop:417 %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]418 %c3 = phi ptr [%a1, %entry], [%c, %fallthrough]419 %b3 = phi ptr [%b1, %entry], [%b2, %fallthrough]420 br i1 %cond, label %if.then, label %fallthrough421 422if.then:423 %a2 = getelementptr inbounds i64, ptr %b2, i64 5424 br label %fallthrough425 426fallthrough:427 %c = phi ptr [%c3, %loop], [%a2, %if.then]428 %b = phi ptr [%b3, %loop], [%b2, %if.then]429 %v = load volatile i32, ptr %c, align 4430 %iv.inc = add i32 %iv, 1431 %cmp = icmp slt i32 %iv.inc, %N432 br i1 %cmp, label %loop, label %exit433 434exit:435 ret i32 %v436}437 438; Case through a loop. No phi node.439define i32 @test10(i32 %N, i1 %cond, ptr %b1, ptr %b2) {440; CHECK-YES-LABEL: define i32 @test10(441; CHECK-YES-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {442; CHECK-YES-NEXT: [[ENTRY:.*]]:443; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]444; CHECK-YES: [[IF_THEN]]:445; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]446; CHECK-YES: [[FALLTHROUGH]]:447; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ]448; CHECK-YES-NEXT: br label %[[LOOP:.*]]449; CHECK-YES: [[LOOP]]:450; CHECK-YES-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[FALLTHROUGH]] ], [ [[IV_INC:%.*]], %[[LOOP]] ]451; CHECK-YES-NEXT: [[IV_INC]] = add i32 [[IV]], 1452; CHECK-YES-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]]453; CHECK-YES-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]454; CHECK-YES: [[EXIT]]:455; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40456; CHECK-YES-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4457; CHECK-YES-NEXT: ret i32 [[V]]458;459; CHECK-NO-LABEL: define i32 @test10(460; CHECK-NO-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {461; CHECK-NO-NEXT: [[ENTRY:.*]]:462; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5463; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]464; CHECK-NO: [[IF_THEN]]:465; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5466; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]467; CHECK-NO: [[FALLTHROUGH]]:468; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ]469; CHECK-NO-NEXT: br label %[[LOOP:.*]]470; CHECK-NO: [[LOOP]]:471; CHECK-NO-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[FALLTHROUGH]] ], [ [[IV_INC:%.*]], %[[LOOP]] ]472; CHECK-NO-NEXT: [[IV_INC]] = add i32 [[IV]], 1473; CHECK-NO-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]]474; CHECK-NO-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]475; CHECK-NO: [[EXIT]]:476; CHECK-NO-NEXT: [[V:%.*]] = load volatile i32, ptr [[C]], align 4477; CHECK-NO-NEXT: ret i32 [[V]]478;479entry:480 %a1 = getelementptr inbounds i64, ptr %b1, i64 5481 br i1 %cond, label %if.then, label %fallthrough482 483if.then:484 %a2 = getelementptr inbounds i64, ptr %b2, i64 5485 br label %fallthrough486 487fallthrough:488 %c = phi ptr [%a1, %entry], [%a2, %if.then]489 br label %loop490 491loop:492 %iv = phi i32 [0, %fallthrough], [%iv.inc, %loop]493 %iv.inc = add i32 %iv, 1494 %cmp = icmp slt i32 %iv.inc, %N495 br i1 %cmp, label %loop, label %exit496 497exit:498 %v = load volatile i32, ptr %c, align 4499 ret i32 %v500}501 502; Case through a loop. There is a phi.503define i32 @test11(i32 %N, i1 %cond, ptr %b1, ptr %b2) {504; CHECK-LABEL: define i32 @test11(505; CHECK-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {506; CHECK-NEXT: [[ENTRY:.*]]:507; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]508; CHECK: [[IF_THEN]]:509; CHECK-NEXT: br label %[[FALLTHROUGH]]510; CHECK: [[FALLTHROUGH]]:511; CHECK-NEXT: [[B:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[IF_THEN]] ]512; CHECK-NEXT: br label %[[LOOP:.*]]513; CHECK: [[LOOP]]:514; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[FALLTHROUGH]] ], [ [[IV_INC:%.*]], %[[LOOP]] ]515; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1516; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV_INC]], [[N]]517; CHECK-NEXT: br i1 [[CMP]], label %[[LOOP]], label %[[EXIT:.*]]518; CHECK: [[EXIT]]:519; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[B]], i64 40520; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4521; CHECK-NEXT: ret i32 [[V]]522;523entry:524 %a1 = getelementptr inbounds i64, ptr %b1, i64 5525 br i1 %cond, label %if.then, label %fallthrough526 527if.then:528 %a2 = getelementptr inbounds i64, ptr %b2, i64 5529 br label %fallthrough530 531fallthrough:532 %c = phi ptr [%a1, %entry], [%a2, %if.then]533 %b = phi ptr [%b1, %entry], [%b2, %if.then]534 br label %loop535 536loop:537 %iv = phi i32 [0, %fallthrough], [%iv.inc, %loop]538 %iv.inc = add i32 %iv, 1539 %cmp = icmp slt i32 %iv.inc, %N540 br i1 %cmp, label %loop, label %exit541 542exit:543 %v = load volatile i32, ptr %c, align 4544 ret i32 %v545}546 547; Complex case with address value from previous iteration.548define i32 @test12(i32 %N, i1 %cond, ptr %b1, ptr %b2, ptr %b3) {549; CHECK-YES-LABEL: define i32 @test12(550; CHECK-YES-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) {551; CHECK-YES-NEXT: [[ENTRY:.*]]:552; CHECK-YES-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5553; CHECK-YES-NEXT: br label %[[LOOP:.*]]554; CHECK-YES: [[LOOP]]:555; CHECK-YES-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[BACKEDGE:.*]] ]556; CHECK-YES-NEXT: [[SUNK_PHI1:%.*]] = phi ptr [ [[SUNK_PHI:%.*]], %[[BACKEDGE]] ], [ [[B1]], %[[ENTRY]] ]557; CHECK-YES-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[BACKEDGE]] ]558; CHECK-YES-NEXT: [[B4:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B5:%.*]], %[[BACKEDGE]] ]559; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]560; CHECK-YES: [[IF_THEN]]:561; CHECK-YES-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5562; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]563; CHECK-YES: [[FALLTHROUGH]]:564; CHECK-YES-NEXT: [[SUNK_PHI]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[SUNK_PHI1]], %[[LOOP]] ]565; CHECK-YES-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ]566; CHECK-YES-NEXT: [[B6:%.*]] = phi ptr [ [[B4]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ]567; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40568; CHECK-YES-NEXT: [[V:%.*]] = load volatile i32, ptr [[SUNKADDR]], align 4569; CHECK-YES-NEXT: [[A4:%.*]] = getelementptr inbounds i64, ptr [[B4]], i64 5570; CHECK-YES-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 20571; CHECK-YES-NEXT: br i1 [[CMP]], label %[[BACKEDGE]], label %[[IF_THEN_2:.*]]572; CHECK-YES: [[IF_THEN_2]]:573; CHECK-YES-NEXT: br label %[[BACKEDGE]]574; CHECK-YES: [[BACKEDGE]]:575; CHECK-YES-NEXT: [[B5]] = phi ptr [ [[B4]], %[[FALLTHROUGH]] ], [ [[B6]], %[[IF_THEN_2]] ]576; CHECK-YES-NEXT: [[IV_INC]] = add i32 [[IV]], 1577; CHECK-YES-NEXT: [[CMP2:%.*]] = icmp slt i32 [[IV_INC]], [[N]]578; CHECK-YES-NEXT: br i1 [[CMP2]], label %[[LOOP]], label %[[EXIT:.*]]579; CHECK-YES: [[EXIT]]:580; CHECK-YES-NEXT: ret i32 [[V]]581;582; CHECK-NO-LABEL: define i32 @test12(583; CHECK-NO-SAME: i32 [[N:%.*]], i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) {584; CHECK-NO-NEXT: [[ENTRY:.*]]:585; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5586; CHECK-NO-NEXT: br label %[[LOOP:.*]]587; CHECK-NO: [[LOOP]]:588; CHECK-NO-NEXT: [[IV:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[IV_INC:%.*]], %[[BACKEDGE:.*]] ]589; CHECK-NO-NEXT: [[C3:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[C:%.*]], %[[BACKEDGE]] ]590; CHECK-NO-NEXT: [[B4:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B5:%.*]], %[[BACKEDGE]] ]591; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]592; CHECK-NO: [[IF_THEN]]:593; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5594; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]595; CHECK-NO: [[FALLTHROUGH]]:596; CHECK-NO-NEXT: [[C]] = phi ptr [ [[C3]], %[[LOOP]] ], [ [[A2]], %[[IF_THEN]] ]597; CHECK-NO-NEXT: [[B6:%.*]] = phi ptr [ [[B4]], %[[LOOP]] ], [ [[B2]], %[[IF_THEN]] ]598; CHECK-NO-NEXT: [[V:%.*]] = load volatile i32, ptr [[C]], align 4599; CHECK-NO-NEXT: [[A4:%.*]] = getelementptr inbounds i64, ptr [[B4]], i64 5600; CHECK-NO-NEXT: [[CMP:%.*]] = icmp slt i32 [[IV]], 20601; CHECK-NO-NEXT: br i1 [[CMP]], label %[[BACKEDGE]], label %[[IF_THEN_2:.*]]602; CHECK-NO: [[IF_THEN_2]]:603; CHECK-NO-NEXT: br label %[[BACKEDGE]]604; CHECK-NO: [[BACKEDGE]]:605; CHECK-NO-NEXT: [[B5]] = phi ptr [ [[B4]], %[[FALLTHROUGH]] ], [ [[B6]], %[[IF_THEN_2]] ]606; CHECK-NO-NEXT: [[IV_INC]] = add i32 [[IV]], 1607; CHECK-NO-NEXT: [[CMP2:%.*]] = icmp slt i32 [[IV_INC]], [[N]]608; CHECK-NO-NEXT: br i1 [[CMP2]], label %[[LOOP]], label %[[EXIT:.*]]609; CHECK-NO: [[EXIT]]:610; CHECK-NO-NEXT: ret i32 [[V]]611;612entry:613 %a1 = getelementptr inbounds i64, ptr %b1, i64 5614 br label %loop615 616loop:617 %iv = phi i32 [0, %entry], [%iv.inc, %backedge]618 %c3 = phi ptr [%a1, %entry], [%c, %backedge]619 %b4 = phi ptr [%b1, %entry], [%b5, %backedge]620 br i1 %cond, label %if.then, label %fallthrough621 622if.then:623 %a2 = getelementptr inbounds i64, ptr %b2, i64 5624 br label %fallthrough625 626fallthrough:627 %c = phi ptr [%c3, %loop], [%a2, %if.then]628 %b6 = phi ptr [%b4, %loop], [%b2, %if.then]629 %v = load volatile i32, ptr %c, align 4630 %a4 = getelementptr inbounds i64, ptr %b4, i64 5631 %cmp = icmp slt i32 %iv, 20632 br i1 %cmp, label %backedge, label %if.then.2633 634if.then.2:635 br label %backedge636 637backedge:638 %b5 = phi ptr [%b4, %fallthrough], [%b6, %if.then.2]639 %iv.inc = add i32 %iv, 1640 %cmp2 = icmp slt i32 %iv.inc, %N641 br i1 %cmp2, label %loop, label %exit642 643exit:644 ret i32 %v645}646 647%struct.S = type {i32, i32}648; Case with index649define i32 @test13(i1 %cond, ptr %b1, ptr %b2, i64 %Index) {650; CHECK-YES-LABEL: define i32 @test13(651; CHECK-YES-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], i64 [[INDEX:%.*]]) {652; CHECK-YES-NEXT: [[ENTRY:.*]]:653; CHECK-YES-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]654; CHECK-YES: [[IF_THEN]]:655; CHECK-YES-NEXT: [[I2:%.*]] = mul i64 [[INDEX]], 2656; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]657; CHECK-YES: [[FALLTHROUGH]]:658; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ]659; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = mul i64 [[INDEX]], 8660; CHECK-YES-NEXT: [[SUNKADDR1:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 [[SUNKADDR]]661; CHECK-YES-NEXT: [[SUNKADDR2:%.*]] = getelementptr inbounds i8, ptr [[SUNKADDR1]], i64 4662; CHECK-YES-NEXT: [[V:%.*]] = load i32, ptr [[SUNKADDR2]], align 4663; CHECK-YES-NEXT: ret i32 [[V]]664;665; CHECK-NO-LABEL: define i32 @test13(666; CHECK-NO-SAME: i1 [[COND:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], i64 [[INDEX:%.*]]) {667; CHECK-NO-NEXT: [[ENTRY:.*]]:668; CHECK-NO-NEXT: [[A1:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[B1]], i64 [[INDEX]], i32 1669; CHECK-NO-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]670; CHECK-NO: [[IF_THEN]]:671; CHECK-NO-NEXT: [[I2:%.*]] = mul i64 [[INDEX]], 2672; CHECK-NO-NEXT: [[A2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[B2]], i64 [[INDEX]], i32 1673; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]674; CHECK-NO: [[FALLTHROUGH]]:675; CHECK-NO-NEXT: [[A:%.*]] = phi ptr [ [[A1]], %[[ENTRY]] ], [ [[A2]], %[[IF_THEN]] ]676; CHECK-NO-NEXT: [[V:%.*]] = load i32, ptr [[A]], align 4677; CHECK-NO-NEXT: ret i32 [[V]]678;679entry:680 %a1 = getelementptr inbounds %struct.S, ptr %b1, i64 %Index, i32 1681 br i1 %cond, label %if.then, label %fallthrough682 683if.then:684 %i2 = mul i64 %Index, 2685 %a2 = getelementptr inbounds %struct.S, ptr %b2, i64 %Index, i32 1686 br label %fallthrough687 688fallthrough:689 %a = phi ptr [%a1, %entry], [%a2, %if.then]690 %v = load i32, ptr %a, align 4691 ret i32 %v692}693 694; Select of Select case.695define i64 @test14(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) {696; CHECK-LABEL: define i64 @test14(697; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) {698; CHECK-NEXT: [[ENTRY:.*:]]699; CHECK-NEXT: [[S12:%.*]] = select i1 [[C1]], ptr [[B1]], ptr [[B2]]700; CHECK-NEXT: [[S21:%.*]] = select i1 [[C2]], ptr [[S12]], ptr [[B3]]701; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[S21]], i64 40702; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[SUNKADDR]], align 8703; CHECK-NEXT: ret i64 [[V]]704;705entry:706 %g1 = getelementptr inbounds i64, ptr %b1, i64 5707 %g2 = getelementptr inbounds i64, ptr %b2, i64 5708 %g3 = getelementptr inbounds i64, ptr %b3, i64 5709 %s1 = select i1 %c1, ptr %g1, ptr %g2710 %s2 = select i1 %c2, ptr %s1, ptr %g3711 %v = load i64 , ptr %s2, align 8712 ret i64 %v713}714 715; Select of Phi case.716define i64 @test15(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) {717; CHECK-YES-LABEL: define i64 @test15(718; CHECK-YES-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) {719; CHECK-YES-NEXT: [[ENTRY:.*]]:720; CHECK-YES-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]721; CHECK-YES: [[IF_THEN]]:722; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]723; CHECK-YES: [[FALLTHROUGH]]:724; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN]] ], [ [[B1]], %[[ENTRY]] ]725; CHECK-YES-NEXT: [[S11:%.*]] = select i1 [[C2]], ptr [[SUNK_PHI]], ptr [[B3]]726; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[S11]], i64 40727; CHECK-YES-NEXT: [[V:%.*]] = load i64, ptr [[SUNKADDR]], align 8728; CHECK-YES-NEXT: ret i64 [[V]]729;730; CHECK-NO-LABEL: define i64 @test15(731; CHECK-NO-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) {732; CHECK-NO-NEXT: [[ENTRY:.*]]:733; CHECK-NO-NEXT: [[G1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5734; CHECK-NO-NEXT: [[G2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5735; CHECK-NO-NEXT: [[G3:%.*]] = getelementptr inbounds i64, ptr [[B3]], i64 5736; CHECK-NO-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]737; CHECK-NO: [[IF_THEN]]:738; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]739; CHECK-NO: [[FALLTHROUGH]]:740; CHECK-NO-NEXT: [[P1:%.*]] = phi ptr [ [[G1]], %[[ENTRY]] ], [ [[G2]], %[[IF_THEN]] ]741; CHECK-NO-NEXT: [[S1:%.*]] = select i1 [[C2]], ptr [[P1]], ptr [[G3]]742; CHECK-NO-NEXT: [[V:%.*]] = load i64, ptr [[S1]], align 8743; CHECK-NO-NEXT: ret i64 [[V]]744;745entry:746 %g1 = getelementptr inbounds i64, ptr %b1, i64 5747 %g2 = getelementptr inbounds i64, ptr %b2, i64 5748 %g3 = getelementptr inbounds i64, ptr %b3, i64 5749 br i1 %c1, label %if.then, label %fallthrough750 751if.then:752 br label %fallthrough753 754fallthrough:755 %p1 = phi ptr [%g1, %entry], [%g2, %if.then]756 %s1 = select i1 %c2, ptr %p1, ptr %g3757 %v = load i64 , ptr %s1, align 8758 ret i64 %v759}760 761; Select of Phi case. Phi exists762define i64 @test16(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) {763; CHECK-LABEL: define i64 @test16(764; CHECK-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) {765; CHECK-NEXT: [[ENTRY:.*]]:766; CHECK-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]767; CHECK: [[IF_THEN]]:768; CHECK-NEXT: br label %[[FALLTHROUGH]]769; CHECK: [[FALLTHROUGH]]:770; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[B1]], %[[ENTRY]] ], [ [[B2]], %[[IF_THEN]] ]771; CHECK-NEXT: [[S11:%.*]] = select i1 [[C2]], ptr [[P]], ptr [[B3]]772; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[S11]], i64 40773; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[SUNKADDR]], align 8774; CHECK-NEXT: ret i64 [[V]]775;776entry:777 %g1 = getelementptr inbounds i64, ptr %b1, i64 5778 %g2 = getelementptr inbounds i64, ptr %b2, i64 5779 %g3 = getelementptr inbounds i64, ptr %b3, i64 5780 br i1 %c1, label %if.then, label %fallthrough781 782if.then:783 br label %fallthrough784 785fallthrough:786 %p = phi ptr [%b1, %entry], [%b2, %if.then]787 %p1 = phi ptr [%g1, %entry], [%g2, %if.then]788 %s1 = select i1 %c2, ptr %p1, ptr %g3789 %v = load i64 , ptr %s1, align 8790 ret i64 %v791}792 793; Phi of Select case.794define i64 @test17(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) {795; CHECK-YES-LABEL: define i64 @test17(796; CHECK-YES-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) {797; CHECK-YES-NEXT: [[ENTRY:.*]]:798; CHECK-YES-NEXT: [[S11:%.*]] = select i1 [[C2]], ptr [[B1]], ptr [[B2]]799; CHECK-YES-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]800; CHECK-YES: [[IF_THEN]]:801; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]802; CHECK-YES: [[FALLTHROUGH]]:803; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B3]], %[[IF_THEN]] ], [ [[S11]], %[[ENTRY]] ]804; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40805; CHECK-YES-NEXT: [[V:%.*]] = load i64, ptr [[SUNKADDR]], align 8806; CHECK-YES-NEXT: ret i64 [[V]]807;808; CHECK-NO-LABEL: define i64 @test17(809; CHECK-NO-SAME: i1 [[C1:%.*]], i1 [[C2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]], ptr [[B3:%.*]]) {810; CHECK-NO-NEXT: [[ENTRY:.*]]:811; CHECK-NO-NEXT: [[G1:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5812; CHECK-NO-NEXT: [[G2:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5813; CHECK-NO-NEXT: [[G3:%.*]] = getelementptr inbounds i64, ptr [[B3]], i64 5814; CHECK-NO-NEXT: [[S1:%.*]] = select i1 [[C2]], ptr [[G1]], ptr [[G2]]815; CHECK-NO-NEXT: br i1 [[C1]], label %[[IF_THEN:.*]], label %[[FALLTHROUGH:.*]]816; CHECK-NO: [[IF_THEN]]:817; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]818; CHECK-NO: [[FALLTHROUGH]]:819; CHECK-NO-NEXT: [[P1:%.*]] = phi ptr [ [[S1]], %[[ENTRY]] ], [ [[G3]], %[[IF_THEN]] ]820; CHECK-NO-NEXT: [[V:%.*]] = load i64, ptr [[P1]], align 8821; CHECK-NO-NEXT: ret i64 [[V]]822;823entry:824 %g1 = getelementptr inbounds i64, ptr %b1, i64 5825 %g2 = getelementptr inbounds i64, ptr %b2, i64 5826 %g3 = getelementptr inbounds i64, ptr %b3, i64 5827 %s1 = select i1 %c2, ptr %g1, ptr %g2828 br i1 %c1, label %if.then, label %fallthrough829 830if.then:831 br label %fallthrough832 833fallthrough:834 %p1 = phi ptr [%s1, %entry], [%g3, %if.then]835 %v = load i64 , ptr %p1, align 8836 ret i64 %v837}838 839; The same two addr modes by different paths840define i32 @test18(i1 %cond1, i1 %cond2, ptr %b1, ptr %b2) {841; CHECK-YES-LABEL: define i32 @test18(842; CHECK-YES-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {843; CHECK-YES-NEXT: [[ENTRY:.*:]]844; CHECK-YES-NEXT: br i1 [[COND1]], label %[[IF_THEN1:.*]], label %[[IF_THEN2:.*]]845; CHECK-YES: [[IF_THEN1]]:846; CHECK-YES-NEXT: br label %[[FALLTHROUGH:.*]]847; CHECK-YES: [[IF_THEN2]]:848; CHECK-YES-NEXT: br label %[[FALLTHROUGH]]849; CHECK-YES: [[FALLTHROUGH]]:850; CHECK-YES-NEXT: [[SUNK_PHI:%.*]] = phi ptr [ [[B2]], %[[IF_THEN2]] ], [ [[B1]], %[[IF_THEN1]] ]851; CHECK-YES-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[SUNK_PHI]], i64 40852; CHECK-YES-NEXT: [[V1:%.*]] = load i32, ptr [[SUNKADDR]], align 4853; CHECK-YES-NEXT: [[G1_1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5854; CHECK-YES-NEXT: [[V2:%.*]] = load i32, ptr [[G1_1]], align 4855; CHECK-YES-NEXT: [[V:%.*]] = add i32 [[V1]], [[V2]]856; CHECK-YES-NEXT: ret i32 [[V]]857;858; CHECK-NO-LABEL: define i32 @test18(859; CHECK-NO-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[B1:%.*]], ptr [[B2:%.*]]) {860; CHECK-NO-NEXT: [[ENTRY:.*:]]861; CHECK-NO-NEXT: [[G1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5862; CHECK-NO-NEXT: br i1 [[COND1]], label %[[IF_THEN1:.*]], label %[[IF_THEN2:.*]]863; CHECK-NO: [[IF_THEN1]]:864; CHECK-NO-NEXT: [[G2:%.*]] = getelementptr inbounds i64, ptr [[B1]], i64 5865; CHECK-NO-NEXT: br label %[[FALLTHROUGH:.*]]866; CHECK-NO: [[IF_THEN2]]:867; CHECK-NO-NEXT: br label %[[FALLTHROUGH]]868; CHECK-NO: [[FALLTHROUGH]]:869; CHECK-NO-NEXT: [[C:%.*]] = phi ptr [ [[G2]], %[[IF_THEN1]] ], [ [[G1]], %[[IF_THEN2]] ]870; CHECK-NO-NEXT: [[V1:%.*]] = load i32, ptr [[C]], align 4871; CHECK-NO-NEXT: [[G1_1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5872; CHECK-NO-NEXT: [[V2:%.*]] = load i32, ptr [[G1_1]], align 4873; CHECK-NO-NEXT: [[V:%.*]] = add i32 [[V1]], [[V2]]874; CHECK-NO-NEXT: ret i32 [[V]]875;876entry:877 %g1 = getelementptr inbounds i64, ptr %b2, i64 5878 br i1 %cond1, label %if.then1, label %if.then2879 880if.then1:881 %g2 = getelementptr inbounds i64, ptr %b1, i64 5882 br label %fallthrough883 884if.then2:885 br i1 %cond2, label %fallthrough, label %if.then3886 887if.then3:888 br label %fallthrough889 890fallthrough:891 %c = phi ptr [%g2, %if.then1], [%g1, %if.then2], [%g1, %if.then3]892 %v1 = load i32, ptr %c, align 4893 %g1_1 = getelementptr inbounds i64, ptr %b2, i64 5894 %v2 = load i32, ptr %g1_1, align 4895 %v = add i32 %v1, %v2896 ret i32 %v897}898 899; Different types but null is the first?900define i32 @test19(i1 %cond1, i1 %cond2, ptr %b2, ptr %b1) {901; CHECK-LABEL: define i32 @test19(902; CHECK-SAME: i1 [[COND1:%.*]], i1 [[COND2:%.*]], ptr [[B2:%.*]], ptr [[B1:%.*]]) {903; CHECK-NEXT: [[ENTRY:.*:]]904; CHECK-NEXT: [[G1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5905; CHECK-NEXT: br i1 [[COND1]], label %[[IF_THEN1:.*]], label %[[IF_THEN2:.*]]906; CHECK: [[IF_THEN1]]:907; CHECK-NEXT: [[G2:%.*]] = getelementptr inbounds i8, ptr [[B1]], i64 40908; CHECK-NEXT: [[BC2:%.*]] = bitcast ptr [[G2]] to ptr909; CHECK-NEXT: br label %[[FALLTHROUGH:.*]]910; CHECK: [[IF_THEN2]]:911; CHECK-NEXT: [[BC1_1:%.*]] = bitcast ptr [[G1]] to ptr912; CHECK-NEXT: br i1 [[COND2]], label %[[FALLTHROUGH]], label %[[IF_THEN3:.*]]913; CHECK: [[IF_THEN3]]:914; CHECK-NEXT: [[G3:%.*]] = getelementptr inbounds i64, ptr null, i64 5915; CHECK-NEXT: [[BC1_2:%.*]] = bitcast ptr [[G3]] to ptr916; CHECK-NEXT: br label %[[FALLTHROUGH]]917; CHECK: [[FALLTHROUGH]]:918; CHECK-NEXT: [[C:%.*]] = phi ptr [ [[BC2]], %[[IF_THEN1]] ], [ [[BC1_1]], %[[IF_THEN2]] ], [ [[BC1_2]], %[[IF_THEN3]] ]919; CHECK-NEXT: [[V1:%.*]] = load i32, ptr [[C]], align 4920; CHECK-NEXT: [[G1_1:%.*]] = getelementptr inbounds i64, ptr [[B2]], i64 5921; CHECK-NEXT: [[BC1_1_1:%.*]] = bitcast ptr [[G1_1]] to ptr922; CHECK-NEXT: [[V2:%.*]] = load i32, ptr [[BC1_1_1]], align 4923; CHECK-NEXT: [[V:%.*]] = add i32 [[V1]], [[V2]]924; CHECK-NEXT: ret i32 [[V]]925;926entry:927 %g1 = getelementptr inbounds i64, ptr %b2, i64 5928 %bc1 = bitcast ptr %g1 to ptr929 br i1 %cond1, label %if.then1, label %if.then2930 931if.then1:932 %g2 = getelementptr inbounds i8, ptr %b1, i64 40933 %bc2 = bitcast ptr %g2 to ptr934 br label %fallthrough935 936if.then2:937 %bc1_1 = bitcast ptr %g1 to ptr938 br i1 %cond2, label %fallthrough, label %if.then3939 940if.then3:941 %g3 = getelementptr inbounds i64, ptr null, i64 5942 %bc1_2 = bitcast ptr %g3 to ptr943 br label %fallthrough944 945fallthrough:946 %c = phi ptr [%bc2, %if.then1], [%bc1_1, %if.then2], [%bc1_2, %if.then3]947 %v1 = load i32, ptr %c, align 4948 %g1_1 = getelementptr inbounds i64, ptr %b2, i64 5949 %bc1_1_1 = bitcast ptr %g1_1 to ptr950 %v2 = load i32, ptr %bc1_1_1, align 4951 %v = add i32 %v1, %v2952 ret i32 %v953}954 955; Make sure we don't simplify an incomplete expression tree.956define i8 @pr163453(ptr %p, i1 %cond) {957; CHECK-LABEL: define i8 @pr163453(958; CHECK-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) {959; CHECK-NEXT: [[ENTRY:.*:]]960; CHECK-NEXT: [[P_ADDR_0:%.*]] = getelementptr i8, ptr [[P]], i64 1961; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[P]], align 1962; CHECK-NEXT: [[INCDEC_PTR11:%.*]] = getelementptr i8, ptr [[P]], i64 2963; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND]], ptr [[P_ADDR_0]], ptr [[INCDEC_PTR11]]964; CHECK-NEXT: [[LOAD:%.*]] = load i8, ptr [[SPEC_SELECT]], align 1965; CHECK-NEXT: ret i8 [[LOAD]]966;967entry:968 br label %for.cond969 970for.cond:971 %p.pn = phi ptr [ %p, %entry ], [ %p.addr.0, %for.inc ]972 %p.addr.0 = getelementptr i8, ptr %p.pn, i64 1973 br i1 false, label %exit, label %for.body974 975for.body:976 %1 = load i8, ptr %p.pn, align 1977 br i1 false, label %for.inc, label %if.else978 979if.else:980 %incdec.ptr11 = getelementptr i8, ptr %p.pn, i64 2981 %spec.select = select i1 %cond, ptr %p.addr.0, ptr %incdec.ptr11982 br label %exit983 984for.inc:985 br label %for.cond986 987exit:988 %p.addr.3 = phi ptr [ %spec.select, %if.else ], [ %p.addr.0, %for.cond ]989 %load = load i8, ptr %p.addr.3, align 1990 ret i8 %load991}992