brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.1 KiB · 45c3bbd Raw
768 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals2; RUN: opt -S -passes='sroa<preserve-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG3; RUN: opt -S -passes='sroa<modify-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG4 5%pair = type { i32, i32 }6 7;.8; CHECK: @g = global %pair zeroinitializer, align 49;.10define i32 @test_sroa_phi_gep(i1 %cond) {11; CHECK-LABEL: @test_sroa_phi_gep(12; CHECK-NEXT:  entry:13; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]14; CHECK:       if.then:15; CHECK-NEXT:    br label [[END]]16; CHECK:       end:17; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ]18; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]19;20entry:21  %a = alloca %pair, align 422  %b = alloca %pair, align 423  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 124  %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 125  store i32 1, ptr %gep_a, align 426  store i32 2, ptr %gep_b, align 427  br i1 %cond, label %if.then, label %end28 29if.then:30  br label %end31 32end:33  %phi = phi ptr [ %a, %entry], [ %b, %if.then ]34  %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 135  %load = load i32, ptr %gep, align 436  ret i32 %load37}38 39define i32 @test_sroa_phi_gep_non_inbound(i1 %cond) {40; CHECK-LABEL: @test_sroa_phi_gep_non_inbound(41; CHECK-NEXT:  entry:42; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]43; CHECK:       if.then:44; CHECK-NEXT:    br label [[END]]45; CHECK:       end:46; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ]47; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]48;49entry:50  %a = alloca %pair, align 451  %b = alloca %pair, align 452  %gep_a = getelementptr %pair, ptr %a, i32 0, i32 153  %gep_b = getelementptr %pair, ptr %b, i32 0, i32 154  store i32 1, ptr %gep_a, align 455  store i32 2, ptr %gep_b, align 456  br i1 %cond, label %if.then, label %end57 58if.then:59  br label %end60 61end:62  %phi = phi ptr [ %a, %entry], [ %b, %if.then ]63  %gep = getelementptr %pair, ptr %phi, i32 0, i32 164  %load = load i32, ptr %gep, align 465  ret i32 %load66}67 68define i32 @test_sroa_phi_gep_poison(i1 %cond) {69; CHECK-LABEL: @test_sroa_phi_gep_poison(70; CHECK-NEXT:  entry:71; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]72; CHECK:       if.then:73; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATE_LOAD_IF_THEN:%.*]] = load i32, ptr poison, align 474; CHECK-NEXT:    br label [[END]]75; CHECK:       end:76; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ undef, [[ENTRY:%.*]] ], [ [[PHI_SROA_PHI_SROA_SPECULATE_LOAD_IF_THEN]], [[IF_THEN]] ]77; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]78;79entry:80  %a = alloca %pair, align 481  br i1 %cond, label %if.then, label %end82 83if.then:84  br label %end85 86end:87  %phi = phi ptr [ %a, %entry], [ poison, %if.then ]88  %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 189  %load = load i32, ptr %gep, align 490  ret i32 %load91}92 93@g = global %pair zeroinitializer, align 494 95define i32 @test_sroa_phi_gep_global(i1 %cond) {96; CHECK-LABEL: @test_sroa_phi_gep_global(97; CHECK-NEXT:  entry:98; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]99; CHECK:       if.then:100; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATE_LOAD_IF_THEN:%.*]] = load i32, ptr getelementptr inbounds ([[PAIR:%.*]], ptr @g, i32 0, i32 1), align 4101; CHECK-NEXT:    br label [[END]]102; CHECK:       end:103; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ [[PHI_SROA_PHI_SROA_SPECULATE_LOAD_IF_THEN]], [[IF_THEN]] ]104; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]105;106entry:107  %a = alloca %pair, align 4108  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1109  store i32 1, ptr %gep_a, align 4110  br i1 %cond, label %if.then, label %end111 112if.then:113  br label %end114 115end:116  %phi = phi ptr [ %a, %entry], [ @g, %if.then ]117  %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1118  %load = load i32, ptr %gep, align 4119  ret i32 %load120}121 122define i32 @test_sroa_phi_gep_arg_phi_inspt(i1 %cond) {123; CHECK-LABEL: @test_sroa_phi_gep_arg_phi_inspt(124; CHECK-NEXT:  entry:125; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]126; CHECK:       for:127; CHECK-NEXT:    [[PHI_INSPT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ]128; CHECK-NEXT:    [[I]] = add i32 [[PHI_INSPT]], 1129; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10130; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[FOR]], label [[END]]131; CHECK:       end:132; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ 2, [[FOR]] ]133; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]134;135entry:136  %a = alloca %pair, align 4137  %b = alloca %pair, align 4138  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1139  %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1140  store i32 1, ptr %gep_a, align 4141  store i32 2, ptr %gep_b, align 4142  br i1 %cond, label %for, label %end143 144for:145  %phi_inspt = phi i32 [ 0, %entry ], [ %i, %for ]146  %i = add i32 %phi_inspt, 1147  %loop.cond = icmp ult i32 %i, 10148  br i1 %loop.cond, label %for, label %end149 150end:151  %phi = phi ptr [ %a, %entry], [ %b, %for ]152  %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1153  %load = load i32, ptr %gep, align 4154  ret i32 %load155}156 157define i32 @test_sroa_phi_gep_phi_inspt(i1 %cond) {158; CHECK-LABEL: @test_sroa_phi_gep_phi_inspt(159; CHECK-NEXT:  entry:160; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4161; CHECK-NEXT:    [[B:%.*]] = alloca [[PAIR]], align 4162; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], ptr [[A]], i32 0, i32 1163; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr inbounds [[PAIR]], ptr [[B]], i32 0, i32 1164; CHECK-NEXT:    store i32 1, ptr [[GEP_A]], align 4165; CHECK-NEXT:    store i32 2, ptr [[GEP_B]], align 4166; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]167; CHECK:       for:168; CHECK-NEXT:    [[PHI_IN:%.*]] = phi ptr [ null, [[ENTRY:%.*]] ], [ [[B]], [[FOR]] ]169; CHECK-NEXT:    [[PHI_INSPT:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[I:%.*]], [[FOR]] ]170; CHECK-NEXT:    [[I]] = add i32 [[PHI_INSPT]], 1171; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10172; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[FOR]], label [[END]]173; CHECK:       end:174; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A]], [[ENTRY]] ], [ [[PHI_IN]], [[FOR]] ]175; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i32 0, i32 1176; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4177; CHECK-NEXT:    ret i32 [[LOAD]]178;179entry:180  %a = alloca %pair, align 4181  %b = alloca %pair, align 4182  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1183  %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1184  store i32 1, ptr %gep_a, align 4185  store i32 2, ptr %gep_b, align 4186  br i1 %cond, label %for, label %end187 188for:189  %phi_in = phi ptr [ null, %entry ], [ %b, %for ]190  %phi_inspt = phi i32 [ 0, %entry ], [ %i, %for ]191  %i = add i32 %phi_inspt, 1192  %loop.cond = icmp ult i32 %i, 10193  br i1 %loop.cond, label %for, label %end194 195end:196  %phi = phi ptr [ %a, %entry], [ %phi_in, %for ]197  %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1198  %load = load i32, ptr %gep, align 4199  ret i32 %load200}201 202define i32 @test_sroa_gep_phi_gep(i1 %cond) {203; CHECK-LABEL: @test_sroa_gep_phi_gep(204; CHECK-NEXT:  entry:205; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4206; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]207; CHECK:       for:208; CHECK-NEXT:    [[PHI_I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ]209; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A_SROA_0]], [[ENTRY]] ], [ [[GEP_FOR:%.*]], [[FOR]] ]210; CHECK-NEXT:    [[I]] = add i32 [[PHI_I]], 1211; CHECK-NEXT:    [[GEP_FOR]] = getelementptr inbounds i32, ptr [[PHI]], i32 0212; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10213; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[FOR]], label [[END]]214; CHECK:       end:215; CHECK-NEXT:    [[PHI_END:%.*]] = phi ptr [ [[A_SROA_0]], [[ENTRY]] ], [ [[PHI]], [[FOR]] ]216; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[PHI_END]], align 4217; CHECK-NEXT:    ret i32 [[LOAD]]218;219entry:220  %a = alloca %pair, align 4221  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1222  br i1 %cond, label %for, label %end223 224for:225  %phi_i = phi i32 [ 0, %entry ], [ %i, %for ]226  %phi = phi ptr [ %gep_a, %entry], [ %gep_for, %for ]227  %i = add i32 %phi_i, 1228  %gep_for = getelementptr inbounds i32, ptr %phi, i32 0229  %loop.cond = icmp ult i32 %i, 10230  br i1 %loop.cond, label %for, label %end231 232end:233  %phi_end = phi ptr [ %gep_a, %entry], [ %phi, %for ]234  %load = load i32, ptr %phi_end, align 4235  ret i32 %load236}237 238define i32 @test_sroa_invoke_phi_gep(i1 %cond) personality ptr @__gxx_personality_v0 {239; CHECK-LABEL: @test_sroa_invoke_phi_gep(240; CHECK-NEXT:  entry:241; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4242; CHECK-NEXT:    br i1 [[COND:%.*]], label [[CALL:%.*]], label [[END:%.*]]243; CHECK:       call:244; CHECK-NEXT:    [[B:%.*]] = invoke ptr @foo()245; CHECK-NEXT:            to label [[END]] unwind label [[INVOKE_CATCH:%.*]]246; CHECK:       end:247; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[CALL]] ]248; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i32 0, i32 1249; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4250; CHECK-NEXT:    ret i32 [[LOAD]]251; CHECK:       invoke_catch:252; CHECK-NEXT:    [[RES:%.*]] = landingpad { ptr, i32 }253; CHECK-NEXT:            catch ptr null254; CHECK-NEXT:    ret i32 0255;256entry:257  %a = alloca %pair, align 4258  br i1 %cond, label %call, label %end259 260call:261  %b = invoke ptr @foo()262  to label %end unwind label %invoke_catch263 264end:265  %phi = phi ptr [ %a, %entry], [ %b, %call ]266  %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1267  %load = load i32, ptr %gep, align 4268  ret i32 %load269 270invoke_catch:271  %res = landingpad { ptr, i32 }272  catch ptr null273  ret i32 0274}275 276define i32 @test_sroa_phi_gep_nonconst_idx(i1 %cond, i32 %idx) {277; CHECK-LABEL: @test_sroa_phi_gep_nonconst_idx(278; CHECK-NEXT:  entry:279; CHECK-NEXT:    [[A:%.*]] = alloca [[PAIR:%.*]], align 4280; CHECK-NEXT:    [[B:%.*]] = alloca [[PAIR]], align 4281; CHECK-NEXT:    [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], ptr [[A]], i32 0, i32 1282; CHECK-NEXT:    [[GEP_B:%.*]] = getelementptr inbounds [[PAIR]], ptr [[B]], i32 0, i32 1283; CHECK-NEXT:    store i32 1, ptr [[GEP_A]], align 4284; CHECK-NEXT:    store i32 2, ptr [[GEP_B]], align 4285; CHECK-NEXT:    br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]]286; CHECK:       if.then:287; CHECK-NEXT:    br label [[END]]288; CHECK:       end:289; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ]290; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i32 [[IDX:%.*]], i32 1291; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4292; CHECK-NEXT:    ret i32 [[LOAD]]293;294entry:295  %a = alloca %pair, align 4296  %b = alloca %pair, align 4297  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1298  %gep_b = getelementptr inbounds %pair, ptr %b, i32 0, i32 1299  store i32 1, ptr %gep_a, align 4300  store i32 2, ptr %gep_b, align 4301  br i1 %cond, label %if.then, label %end302 303if.then:304  br label %end305 306end:307  %phi = phi ptr [ %a, %entry], [ %b, %if.then ]308  %gep = getelementptr inbounds %pair, ptr %phi, i32 %idx, i32 1309  %load = load i32, ptr %gep, align 4310  ret i32 %load311}312 313define void @test_sroa_gep_phi_select_other_block(i1 %c1, i1 %c2, ptr %ptr) {314; CHECK-LABEL: @test_sroa_gep_phi_select_other_block(315; CHECK-NEXT:  entry:316; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8317; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]318; CHECK:       while.body:319; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[ALLOCA]], [[ENTRY:%.*]] ], [ [[SELECT:%.*]], [[WHILE_BODY]] ]320; CHECK-NEXT:    [[SELECT]] = select i1 [[C1:%.*]], ptr [[PHI]], ptr [[PTR:%.*]]321; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[WHILE_BODY]]322; CHECK:       exit:323; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i64 1324; CHECK-NEXT:    unreachable325;326entry:327  %alloca = alloca %pair, align 8328  br label %while.body329 330while.body:331  %phi = phi ptr [ %alloca, %entry ], [ %select, %while.body ]332  %select = select i1 %c1, ptr %phi, ptr %ptr333  br i1 %c2, label %exit, label %while.body334 335exit:336  %gep = getelementptr inbounds %pair, ptr %phi, i64 1337  unreachable338}339 340define void @test_sroa_gep_phi_select_same_block(i1 %c1, i1 %c2, ptr %ptr) !prof !0 {341; CHECK-LABEL: @test_sroa_gep_phi_select_same_block(342; CHECK-NEXT:  entry:343; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8344; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]345; CHECK:       while.body:346; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[ALLOCA]], [[ENTRY:%.*]] ], [ [[SELECT:%.*]], [[WHILE_BODY]] ]347; CHECK-NEXT:    [[SELECT]] = select i1 [[C1:%.*]], ptr [[PHI]], ptr [[PTR:%.*]], !prof [[PROF1:![0-9]+]]348; CHECK-NEXT:    [[PHI_SROA_GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PHI]], i64 1349; CHECK-NEXT:    [[PTR_SROA_GEP:%.*]] = getelementptr inbounds [[PAIR]], ptr [[PTR]], i64 1350; CHECK-NEXT:    [[SELECT_SROA_SEL:%.*]] = select i1 [[C1]], ptr [[PHI_SROA_GEP]], ptr [[PTR_SROA_GEP]], !prof [[PROF1]]351; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[WHILE_BODY]], !prof [[PROF2:![0-9]+]]352; CHECK:       exit:353; CHECK-NEXT:    ret void354;355entry:356  %alloca = alloca %pair, align 8357  br label %while.body358 359while.body:360  %phi = phi ptr [ %alloca, %entry ], [ %select, %while.body ]361  %select = select i1 %c1, ptr %phi, ptr %ptr, !prof !1362  %gep = getelementptr inbounds %pair, ptr %select, i64 1363  br i1 %c2, label %exit, label %while.body, !prof !2364 365exit:366  ret void367}368 369define void @test_sroa_gep_phi_select_same_block_nuw(i1 %c1, i1 %c2, ptr %ptr) {370; CHECK-LABEL: @test_sroa_gep_phi_select_same_block_nuw(371; CHECK-NEXT:  entry:372; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8373; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]374; CHECK:       while.body:375; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[ALLOCA]], [[ENTRY:%.*]] ], [ [[SELECT:%.*]], [[WHILE_BODY]] ]376; CHECK-NEXT:    [[SELECT]] = select i1 [[C1:%.*]], ptr [[PHI]], ptr [[PTR:%.*]]377; CHECK-NEXT:    [[PHI_SROA_GEP:%.*]] = getelementptr nuw [[PAIR]], ptr [[PHI]], i64 1378; CHECK-NEXT:    [[PTR_SROA_GEP:%.*]] = getelementptr nuw [[PAIR]], ptr [[PTR]], i64 1379; CHECK-NEXT:    [[SELECT_SROA_SEL:%.*]] = select i1 [[C1]], ptr [[PHI_SROA_GEP]], ptr [[PTR_SROA_GEP]]380; CHECK-NEXT:    br i1 [[C2:%.*]], label [[EXIT:%.*]], label [[WHILE_BODY]]381; CHECK:       exit:382; CHECK-NEXT:    ret void383;384entry:385  %alloca = alloca %pair, align 8386  br label %while.body387 388while.body:389  %phi = phi ptr [ %alloca, %entry ], [ %select, %while.body ]390  %select = select i1 %c1, ptr %phi, ptr %ptr391  %gep = getelementptr nuw %pair, ptr %select, i64 1392  br i1 %c2, label %exit, label %while.body393 394exit:395  ret void396}397 398define i32 @test_sroa_gep_cast_phi_gep(i1 %cond) {399; CHECK-LABEL: @test_sroa_gep_cast_phi_gep(400; CHECK-NEXT:  entry:401; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4402; CHECK-NEXT:    store i32 1065353216, ptr [[A_SROA_0]], align 4403; CHECK-NEXT:    br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]]404; CHECK:       for:405; CHECK-NEXT:    [[PHI_I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ]406; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A_SROA_0]], [[ENTRY]] ], [ [[GEP_FOR:%.*]], [[FOR]] ]407; CHECK-NEXT:    [[I]] = add i32 [[PHI_I]], 1408; CHECK-NEXT:    [[GEP_FOR]] = getelementptr inbounds float, ptr [[PHI]], i32 0409; CHECK-NEXT:    [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10410; CHECK-NEXT:    br i1 [[LOOP_COND]], label [[FOR]], label [[END]]411; CHECK:       end:412; CHECK-NEXT:    [[PHI_END:%.*]] = phi ptr [ [[A_SROA_0]], [[ENTRY]] ], [ [[PHI]], [[FOR]] ]413; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[PHI_END]], align 4414; CHECK-NEXT:    ret i32 [[LOAD]]415;416entry:417  %a = alloca %pair, align 4418  %gep_a = getelementptr inbounds %pair, ptr %a, i32 0, i32 1419  store float 1.0, ptr %gep_a, align 4420  br i1 %cond, label %for, label %end421 422for:423  %phi_i = phi i32 [ 0, %entry ], [ %i, %for ]424  %phi = phi ptr [ %gep_a, %entry], [ %gep_for, %for ]425  %i = add i32 %phi_i, 1426  %gep_for = getelementptr inbounds float, ptr %phi, i32 0427  %loop.cond = icmp ult i32 %i, 10428  br i1 %loop.cond, label %for, label %end429 430end:431  %phi_end = phi ptr [ %gep_a, %entry], [ %phi, %for ]432  %load = load i32, ptr %phi_end, align 4433  ret i32 %load434}435 436define void @unreachable_term(i1 %c1) {437; CHECK-LABEL: @unreachable_term(438; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 4439; CHECK-NEXT:    unreachable440; CHECK:       bb1:441; CHECK-NEXT:    br label [[BB1_I:%.*]]442; CHECK:       bb1.i:443; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A_SROA_0]], [[BB1:%.*]] ], [ null, [[BB1_I]] ]444; CHECK-NEXT:    store i32 0, ptr [[PHI]], align 1445; CHECK-NEXT:    br i1 [[C1:%.*]], label [[BB1_I]], label [[EXIT:%.*]]446; CHECK:       exit:447; CHECK-NEXT:    br label [[BB2:%.*]]448; CHECK:       bb2:449; CHECK-NEXT:    ret void450;451  %a = alloca [3 x i32], align 1452  unreachable453 454bb1:455  br label %bb1.i456 457bb1.i:458  %phi = phi ptr [ %a, %bb1 ], [ null, %bb1.i ]459  store i32 0, ptr %phi, align 1460  br i1 %c1, label %bb1.i, label %exit461 462exit:463  br label %bb2464 465bb2:466  ret void467}468 469define void @constant_value_phi(i1 %c1) {470; CHECK-LABEL: @constant_value_phi(471; CHECK-NEXT:  entry:472; CHECK-NEXT:    br label [[LAND_LHS_TRUE_I:%.*]]473; CHECK:       land.lhs.true.i:474; CHECK-NEXT:    br i1 [[C1:%.*]], label [[COND_END_I:%.*]], label [[COND_END_I]]475; CHECK:       cond.end.i:476; CHECK-NEXT:    unreachable477;478entry:479  %s1 = alloca [3 x i16]480  %s = alloca [3 x i16]481  br label %land.lhs.true.i482 483land.lhs.true.i:                                  ; preds = %entry484  br i1 %c1, label %cond.end.i, label %cond.end.i485 486cond.end.i:                                       ; preds = %land.lhs.true.i, %land.lhs.true.i487  %.pre-phi1 = phi ptr [ %s1, %land.lhs.true.i ], [ %s1, %land.lhs.true.i ]488  call void @llvm.memcpy.p0.p0.i64(ptr %.pre-phi1, ptr %s, i64 3, i1 false)489  %load = load i16, ptr %s490  unreachable491}492 493define i32 @test_sroa_phi_gep_multiple_values_from_same_block(i32 %arg) {494; CHECK-LABEL: @test_sroa_phi_gep_multiple_values_from_same_block(495; CHECK-NEXT:  bb.1:496; CHECK-NEXT:    switch i32 [[ARG:%.*]], label [[BB_3:%.*]] [497; CHECK-NEXT:      i32 1, label [[BB_2:%.*]]498; CHECK-NEXT:      i32 2, label [[BB_2]]499; CHECK-NEXT:      i32 3, label [[BB_4:%.*]]500; CHECK-NEXT:      i32 4, label [[BB_4]]501; CHECK-NEXT:    ]502; CHECK:       bb.2:503; CHECK-NEXT:    br label [[BB_4]]504; CHECK:       bb.3:505; CHECK-NEXT:    br label [[BB_4]]506; CHECK:       bb.4:507; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ undef, [[BB_3]] ], [ undef, [[BB_2]] ], [ undef, [[BB_1:%.*]] ], [ undef, [[BB_1]] ]508; CHECK-NEXT:    ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]]509;510bb.1:511  %a = alloca %pair, align 4512  %b = alloca %pair, align 4513  switch i32 %arg, label %bb.3 [514  i32 1, label %bb.2515  i32 2, label %bb.2516  i32 3, label %bb.4517  i32 4, label %bb.4518  ]519 520bb.2:                                                ; preds = %bb.1, %bb.1521  br label %bb.4522 523bb.3:                                                ; preds = %bb.1524  br label %bb.4525 526bb.4:                                                ; preds = %bb.1, %bb.1, %bb.3, %bb.2527  %phi = phi ptr [ %a, %bb.3 ], [ %a, %bb.2 ], [ %b, %bb.1 ], [ %b, %bb.1 ]528  %gep = getelementptr inbounds %pair, ptr %phi, i32 0, i32 1529  %load = load i32, ptr %gep, align 4530  ret i32 %load531}532 533define i64 @test_phi_idx_mem2reg_const(i1 %arg) {534; CHECK-LABEL: @test_phi_idx_mem2reg_const(535; CHECK-NEXT:  bb:536; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]537; CHECK:       bb1:538; CHECK-NEXT:    br label [[END:%.*]]539; CHECK:       bb2:540; CHECK-NEXT:    br label [[END]]541; CHECK:       end:542; CHECK-NEXT:    [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i64 [ 2, [[BB1]] ], [ 3, [[BB2]] ]543; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ 0, [[BB1]] ], [ 1, [[BB2]] ]544; CHECK-NEXT:    ret i64 [[PHI_SROA_PHI_SROA_SPECULATED]]545;546bb:547  %alloca = alloca [2 x i64], align 8548  %gep1 = getelementptr inbounds i64, ptr %alloca, i64 1549  store i64 2, ptr %alloca550  store i64 3, ptr %gep1551  br i1 %arg, label %bb1, label %bb2552 553bb1:554  br label %end555 556bb2:557  br label %end558 559end:560  %phi = phi i64 [ 0, %bb1 ], [ 1, %bb2 ]561  %getelementptr = getelementptr inbounds i64, ptr %alloca, i64 %phi562  %load = load i64, ptr %getelementptr563  ret i64 %load564}565 566define i64 @test_phi_idx_mem2reg_not_const(i1 %arg, i64 %idx) {567; CHECK-LABEL: @test_phi_idx_mem2reg_not_const(568; CHECK-NEXT:  bb:569; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [2 x i64], align 8570; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 1571; CHECK-NEXT:    store i64 2, ptr [[ALLOCA]], align 4572; CHECK-NEXT:    store i64 3, ptr [[GEP1]], align 4573; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]574; CHECK:       bb1:575; CHECK-NEXT:    br label [[END:%.*]]576; CHECK:       bb2:577; CHECK-NEXT:    br label [[END]]578; CHECK:       end:579; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ 0, [[BB1]] ], [ [[IDX:%.*]], [[BB2]] ]580; CHECK-NEXT:    [[GETELEMENTPTR:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 [[PHI]]581; CHECK-NEXT:    [[LOAD:%.*]] = load i64, ptr [[GETELEMENTPTR]], align 4582; CHECK-NEXT:    ret i64 [[LOAD]]583;584bb:585  %alloca = alloca [2 x i64], align 8586  %gep1 = getelementptr inbounds i64, ptr %alloca, i64 1587  store i64 2, ptr %alloca588  store i64 3, ptr %gep1589  br i1 %arg, label %bb1, label %bb2590 591bb1:592  br label %end593 594bb2:595  br label %end596 597end:598  %phi = phi i64 [ 0, %bb1 ], [ %idx, %bb2 ]599  %getelementptr = getelementptr inbounds i64, ptr %alloca, i64 %phi600  %load = load i64, ptr %getelementptr601  ret i64 %load602}603 604define i64 @test_phi_mem2reg_pointer_op_is_non_const_gep(i1 %arg, i64 %idx) {605; CHECK-LABEL: @test_phi_mem2reg_pointer_op_is_non_const_gep(606; CHECK-NEXT:  bb:607; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca [2 x i64], align 8608; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 1609; CHECK-NEXT:    store i64 2, ptr [[ALLOCA]], align 4610; CHECK-NEXT:    store i64 3, ptr [[GEP1]], align 4611; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]612; CHECK:       bb1:613; CHECK-NEXT:    br label [[END:%.*]]614; CHECK:       bb2:615; CHECK-NEXT:    br label [[END]]616; CHECK:       end:617; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ 0, [[BB1]] ], [ 1, [[BB2]] ]618; CHECK-NEXT:    [[GETELEMENTPTR:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 [[IDX:%.*]]619; CHECK-NEXT:    [[GETELEMENTPTR2:%.*]] = getelementptr inbounds i64, ptr [[GETELEMENTPTR]], i64 [[PHI]]620; CHECK-NEXT:    [[LOAD:%.*]] = load i64, ptr [[GETELEMENTPTR]], align 4621; CHECK-NEXT:    ret i64 [[LOAD]]622;623bb:624  %alloca = alloca [2 x i64], align 8625  %gep1 = getelementptr inbounds i64, ptr %alloca, i64 1626  store i64 2, ptr %alloca627  store i64 3, ptr %gep1628  br i1 %arg, label %bb1, label %bb2629 630bb1:631  br label %end632 633bb2:634  br label %end635 636end:637  %phi = phi i64 [ 0, %bb1 ], [ 1, %bb2 ]638  %getelementptr = getelementptr inbounds i64, ptr %alloca, i64 %idx639  %getelementptr2 = getelementptr inbounds i64, ptr %getelementptr, i64 %phi640  %load = load i64, ptr %getelementptr641  ret i64 %load642}643 644define i1 @test_phi_mem2reg_entry_block_alloca_not_at_beginning(i1 %arg) {645; CHECK-LABEL: @test_phi_mem2reg_entry_block_alloca_not_at_beginning(646; CHECK-NEXT:  bb:647; CHECK-NEXT:    call void @f()648; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca i64, align 8649; CHECK-NEXT:    [[PHI_SROA_GEP:%.*]] = getelementptr i64, ptr [[ALLOCA]], i64 1650; CHECK-NEXT:    [[PHI_SROA_GEP1:%.*]] = getelementptr i64, ptr [[ALLOCA]], i64 2651; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[BB2:%.*]], label [[BB3:%.*]]652; CHECK:       bb2:653; CHECK-NEXT:    br label [[BB3]]654; CHECK:       bb3:655; CHECK-NEXT:    [[PHI_SROA_PHI:%.*]] = phi ptr [ [[PHI_SROA_GEP]], [[BB:%.*]] ], [ [[PHI_SROA_GEP1]], [[BB2]] ]656; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ 1, [[BB]] ], [ 2, [[BB2]] ]657; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq ptr [[PHI_SROA_PHI]], null658; CHECK-NEXT:    ret i1 [[ICMP]]659;660bb:661  call void @f()662  %alloca = alloca i64663  br i1 %arg, label %bb2, label %bb3664bb2:665  br label %bb3666bb3:667  %phi = phi i64 [ 1, %bb ], [ 2, %bb2 ]668  %gep = getelementptr i64, ptr %alloca, i64 %phi669  %icmp = icmp eq ptr %gep, null670  ret i1 %icmp671}672 673define i32 @test_phi_mem2reg_alloca_not_in_entry_block(i1 %arg) {674; CHECK-LABEL: @test_phi_mem2reg_alloca_not_in_entry_block(675; CHECK-NEXT:  bb:676; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca i64, align 8677; CHECK-NEXT:    store i64 123, ptr [[ALLOCA]], align 4678; CHECK-NEXT:    br label [[BB2:%.*]]679; CHECK:       bb2:680; CHECK-NEXT:    [[ALLOCA2:%.*]] = alloca i64, align 8681; CHECK-NEXT:    store i64 124, ptr [[ALLOCA]], align 4682; CHECK-NEXT:    br i1 [[ARG:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]683; CHECK:       bb3:684; CHECK-NEXT:    br label [[BB4]]685; CHECK:       bb4:686; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[ALLOCA]], [[BB2]] ], [ [[ALLOCA2]], [[BB3]] ]687; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i32, ptr [[PHI]], i64 1688; CHECK-NEXT:    [[LOAD:%.*]] = load i32, ptr [[GEP]], align 4689; CHECK-NEXT:    ret i32 [[LOAD]]690;691bb:692  %alloca = alloca i64693  store i64 123, ptr %alloca694  br label %bb2695bb2:696  %alloca2 = alloca i64697  store i64 124, ptr %alloca698  br i1 %arg, label %bb3, label %bb4699bb3:700  br label %bb4701bb4:702  %phi = phi ptr [ %alloca, %bb2 ], [ %alloca2, %bb3 ]703  %gep = getelementptr i32, ptr %phi, i64 1704  %load = load i32, ptr %gep705  ret i32 %load706}707 708define i64 @test_unfold_phi_duplicate_phi_entry(ptr %arg, i8 %arg1, i1 %arg2) {709; CHECK-LABEL: @test_unfold_phi_duplicate_phi_entry(710; CHECK-NEXT:  bb:711; CHECK-NEXT:    [[ALLOCA_SROA_0:%.*]] = alloca i64, align 8712; CHECK-NEXT:    [[PHI_SROA_GEP:%.*]] = getelementptr i64, ptr [[ARG:%.*]], i64 1713; CHECK-NEXT:    br i1 [[ARG2:%.*]], label [[BB5:%.*]], label [[BB3:%.*]]714; CHECK:       bb3:715; CHECK-NEXT:    switch i8 [[ARG1:%.*]], label [[BB4:%.*]] [716; CHECK-NEXT:      i8 0, label [[BB5]]717; CHECK-NEXT:      i8 1, label [[BB5]]718; CHECK-NEXT:    ]719; CHECK:       bb4:720; CHECK-NEXT:    ret i64 0721; CHECK:       bb5:722; CHECK-NEXT:    [[PHI_SROA_PHI:%.*]] = phi ptr [ [[PHI_SROA_GEP]], [[BB3]] ], [ [[PHI_SROA_GEP]], [[BB3]] ], [ [[ALLOCA_SROA_0]], [[BB:%.*]] ]723; CHECK-NEXT:    [[LOAD:%.*]] = load i64, ptr [[PHI_SROA_PHI]], align 4724; CHECK-NEXT:    ret i64 [[LOAD]]725;726bb:727  %alloca = alloca [2 x i64], align 8728  br i1 %arg2, label %bb5, label %bb3729 730bb3:                                              ; preds = %bb731  switch i8 %arg1, label %bb4 [732  i8 0, label %bb5733  i8 1, label %bb5734  ]735 736bb4:                                              ; preds = %bb5, %bb3737  ret i64 0738 739bb5:                                              ; preds = %bb3, %bb3, %bb740  %phi = phi ptr [ %arg, %bb3 ], [ %arg, %bb3 ], [ %alloca, %bb ]741  %getelementptr = getelementptr i64, ptr %phi, i64 1742  %load = load i64, ptr %getelementptr743  ret i64 %load744}745 746declare void @f()747 748declare ptr @foo()749 750declare i32 @__gxx_personality_v0(...)751 752declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg)753 754!0 = !{!"function_entry_count", i32 10}755!1 = !{!"branch_weights", i32 3, i32 5}756!2 = !{!"branch_weights", i32 7, i32 11}757 758;.759; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }760;.761; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}762; CHECK: [[PROF1]] = !{!"branch_weights", i32 3, i32 5}763; CHECK: [[PROF2]] = !{!"branch_weights", i32 7, i32 11}764;.765;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:766; CHECK-MODIFY-CFG: {{.*}}767; CHECK-PRESERVE-CFG: {{.*}}768