brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.5 KiB · 5d5a610 Raw
887 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-CFG4target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"5 6define i32 @test1() {7; CHECK-LABEL: @test1(8; CHECK-NEXT:  entry:9; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 0, 110; CHECK-NEXT:    br i1 [[COND]], label [[THEN:%.*]], label [[EXIT:%.*]]11; CHECK:       then:12; CHECK-NEXT:    br label [[EXIT]]13; CHECK:       exit:14; CHECK-NEXT:    [[PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[THEN]] ], [ 0, [[ENTRY:%.*]] ]15; CHECK-NEXT:    ret i32 [[PHI_SROA_SPECULATED]]16;17entry:18  %a = alloca [2 x i32]19 20  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 121  store i32 0, ptr %a22  store i32 1, ptr %a123  %v0 = load i32, ptr %a24  %v1 = load i32, ptr %a125 26  %cond = icmp sle i32 %v0, %v127  br i1 %cond, label %then, label %exit28 29then:30  br label %exit31 32exit:33  %phi = phi ptr [ %a1, %then ], [ %a, %entry ]34 35  %result = load i32, ptr %phi36  ret i32 %result37}38 39define i32 @test2() !prof !0 {40; CHECK-LABEL: @test2(41; CHECK-NEXT:  entry:42; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 0, 143; CHECK-NEXT:    [[RESULT_SROA_SPECULATED:%.*]] = select i1 [[COND]], i32 1, i32 0, !prof [[PROF1:![0-9]+]]44; CHECK-NEXT:    ret i32 [[RESULT_SROA_SPECULATED]]45;46entry:47  %a = alloca [2 x i32]48 49  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 150  store i32 0, ptr %a51  store i32 1, ptr %a152  %v0 = load i32, ptr %a53  %v1 = load i32, ptr %a154 55  %cond = icmp sle i32 %v0, %v156  %select = select i1 %cond, ptr %a1, ptr %a, !prof !157 58  %result = load i32, ptr %select59  ret i32 %result60}61 62define float @test2_bitcast() {63; CHECK-LABEL: @test2_bitcast(64; CHECK-NEXT:  entry:65; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 0, 166; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32 1 to float67; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32 0 to float68; CHECK-NEXT:    [[RESULT_SROA_SPECULATED:%.*]] = select i1 [[COND]], float [[TMP0]], float [[TMP1]]69; CHECK-NEXT:    ret float [[RESULT_SROA_SPECULATED]]70;71entry:72  %a = alloca [2 x i32]73  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 174  store i32 0, ptr %a75  store i32 1, ptr %a176  %v0 = load i32, ptr %a77  %v1 = load i32, ptr %a178  %cond = icmp sle i32 %v0, %v179  %select = select i1 %cond, ptr %a1, ptr %a80  %result = load float, ptr %select81  ret float %result82}83 84define i32 @test2_addrspacecast() {85; CHECK-LABEL: @test2_addrspacecast(86; CHECK-NEXT:  entry:87; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca i32, align 488; CHECK-NEXT:    [[A_SROA_3:%.*]] = alloca i32, align 489; CHECK-NEXT:    store i32 0, ptr [[A_SROA_0]], align 490; CHECK-NEXT:    store i32 1, ptr [[A_SROA_3]], align 491; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_0_V0:%.*]] = load i32, ptr [[A_SROA_0]], align 492; CHECK-NEXT:    [[A_SROA_3_0_A_SROA_3_4_V1:%.*]] = load i32, ptr [[A_SROA_3]], align 493; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 [[A_SROA_0_0_A_SROA_0_0_V0]], [[A_SROA_3_0_A_SROA_3_4_V1]]94; CHECK-NEXT:    [[SELECT:%.*]] = select i1 [[COND]], ptr [[A_SROA_3]], ptr [[A_SROA_0]]95; CHECK-NEXT:    [[SELECT_ASC:%.*]] = addrspacecast ptr [[SELECT]] to ptr addrspace(1)96; CHECK-NEXT:    [[RESULT:%.*]] = load i32, ptr addrspace(1) [[SELECT_ASC]], align 497; CHECK-NEXT:    ret i32 [[RESULT]]98;99entry:100  %a = alloca [2 x i32]101  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1102  store i32 0, ptr %a103  store i32 1, ptr %a1104  %v0 = load i32, ptr %a105  %v1 = load i32, ptr %a1106  %cond = icmp sle i32 %v0, %v1107  %select = select i1 %cond, ptr %a1, ptr %a108  %select.asc = addrspacecast ptr %select to ptr addrspace(1)109  %result = load i32, ptr addrspace(1) %select.asc110  ret i32 %result111}112 113define i32 @test3(i32 %x) {114; CHECK-LABEL: @test3(115; CHECK-NEXT:  entry:116; CHECK-NEXT:    switch i32 [[X:%.*]], label [[BB0:%.*]] [117; CHECK-NEXT:      i32 1, label [[BB1:%.*]]118; CHECK-NEXT:      i32 2, label [[BB2:%.*]]119; CHECK-NEXT:      i32 3, label [[BB3:%.*]]120; CHECK-NEXT:      i32 4, label [[BB4:%.*]]121; CHECK-NEXT:      i32 5, label [[BB5:%.*]]122; CHECK-NEXT:      i32 6, label [[BB6:%.*]]123; CHECK-NEXT:      i32 7, label [[BB7:%.*]]124; CHECK-NEXT:    ]125; CHECK:       bb0:126; CHECK-NEXT:    br label [[EXIT:%.*]]127; CHECK:       bb1:128; CHECK-NEXT:    br label [[EXIT]]129; CHECK:       bb2:130; CHECK-NEXT:    br label [[EXIT]]131; CHECK:       bb3:132; CHECK-NEXT:    br label [[EXIT]]133; CHECK:       bb4:134; CHECK-NEXT:    br label [[EXIT]]135; CHECK:       bb5:136; CHECK-NEXT:    br label [[EXIT]]137; CHECK:       bb6:138; CHECK-NEXT:    br label [[EXIT]]139; CHECK:       bb7:140; CHECK-NEXT:    br label [[EXIT]]141; CHECK:       exit:142; CHECK-NEXT:    [[PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[BB0]] ], [ 0, [[BB1]] ], [ 0, [[BB2]] ], [ 1, [[BB3]] ], [ 1, [[BB4]] ], [ 0, [[BB5]] ], [ 0, [[BB6]] ], [ 1, [[BB7]] ]143; CHECK-NEXT:    ret i32 [[PHI_SROA_SPECULATED]]144;145entry:146  %a = alloca [2 x i32]147 148  ; Note that we build redundant GEPs here to ensure that having different GEPs149  ; into the same alloca partation continues to work with PHI speculation. This150  ; was the underlying cause of PR13926.151  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1152  %a1b = getelementptr [2 x i32], ptr %a, i64 0, i32 1153  store i32 0, ptr %a154  store i32 1, ptr %a1155 156  switch i32 %x, label %bb0 [ i32 1, label %bb1157  i32 2, label %bb2158  i32 3, label %bb3159  i32 4, label %bb4160  i32 5, label %bb5161  i32 6, label %bb6162  i32 7, label %bb7 ]163 164bb0:165  br label %exit166bb1:167  br label %exit168bb2:169  br label %exit170bb3:171  br label %exit172bb4:173  br label %exit174bb5:175  br label %exit176bb6:177  br label %exit178bb7:179  br label %exit180 181exit:182  %phi = phi ptr [ %a1, %bb0 ], [ %a, %bb1 ], [ %a, %bb2 ], [ %a1, %bb3 ],183  [ %a1b, %bb4 ], [ %a, %bb5 ], [ %a, %bb6 ], [ %a1b, %bb7 ]184 185  %result = load i32, ptr %phi186  ret i32 %result187}188 189define i32 @test4() {190; CHECK-LABEL: @test4(191; CHECK-NEXT:  entry:192; CHECK-NEXT:    ret i32 0193;194entry:195  %a = alloca [2 x i32]196 197  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1198  store i32 0, ptr %a199  store i32 1, ptr %a1200  %v0 = load i32, ptr %a201  %v1 = load i32, ptr %a1202 203  %cond = icmp sle i32 %v0, %v1204  %select = select i1 %cond, ptr %a, ptr %a205 206  %result = load i32, ptr %select207  ret i32 %result208}209 210define i32 @test5(ptr %b) {211; CHECK-LABEL: @test5(212; CHECK-NEXT:  entry:213; CHECK-NEXT:    ret i32 1214;215entry:216  %a = alloca [2 x i32]217 218  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1219  store i32 1, ptr %a1220 221  %select = select i1 true, ptr %a1, ptr %b222 223  %result = load i32, ptr %select224 225  ret i32 %result226}227 228declare void @f(ptr, ptr)229 230define i32 @test6(ptr %b) {231; CHECK-LABEL: @test6(232; CHECK-NEXT:  entry:233; CHECK-NEXT:    [[SELECT2:%.*]] = select i1 false, ptr poison, ptr [[B:%.*]]234; CHECK-NEXT:    [[SELECT3:%.*]] = select i1 false, ptr poison, ptr [[B]]235; CHECK-NEXT:    call void @f(ptr [[SELECT2]], ptr [[SELECT3]])236; CHECK-NEXT:    ret i32 1237;238entry:239  %a = alloca [2 x i32]240  %c = alloca i32241 242  %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1243  store i32 1, ptr %a1244 245  %select = select i1 true, ptr %a1, ptr %b246  %select2 = select i1 false, ptr %a1, ptr %b247  %select3 = select i1 false, ptr %c, ptr %b248 249  ; Note, this would potentially escape the alloca pointer except for the250  ; constant folding of the select.251  call void @f(ptr %select2, ptr %select3)252 253 254  %result = load i32, ptr %select255 256  %dead = load i32, ptr %c257 258  ret i32 %result259}260 261define i32 @test7(i1 %c1) {262; CHECK-LABEL: @test7(263; CHECK-NEXT:  entry:264; CHECK-NEXT:    br i1 [[C1:%.*]], label [[GOOD:%.*]], label [[BAD:%.*]]265; CHECK:       good:266; CHECK-NEXT:    br label [[EXIT:%.*]]267; CHECK:       bad:268; CHECK-NEXT:    [[P_SROA_SPECULATE_LOAD_BAD:%.*]] = load i32, ptr poison, align 4269; CHECK-NEXT:    br label [[EXIT]]270; CHECK:       exit:271; CHECK-NEXT:    [[P_SROA_SPECULATED:%.*]] = phi i32 [ 0, [[GOOD]] ], [ [[P_SROA_SPECULATE_LOAD_BAD]], [[BAD]] ]272; CHECK-NEXT:    ret i32 [[P_SROA_SPECULATED]]273;274entry:275  %X = alloca i32276  br i1 %c1, label %good, label %bad277 278good:279  store i32 0, ptr %X280  br label %exit281 282bad:283  %Y2 = getelementptr i32, ptr %X, i64 1284  store i32 0, ptr %Y2285  br label %exit286 287exit:288  %P = phi ptr [ %X, %good ], [ %Y2, %bad ]289  %Z2 = load i32, ptr %P290  ret i32 %Z2291}292 293define i32 @test8(i32 %b, ptr %ptr) {294; Ensure that we rewrite allocas to the used type when that use is hidden by295; a PHI that can be speculated.296;297; CHECK-LABEL: @test8(298; CHECK-NEXT:  entry:299; CHECK-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0300; CHECK-NEXT:    br i1 [[TEST]], label [[THEN:%.*]], label [[ELSE:%.*]]301; CHECK:       then:302; CHECK-NEXT:    [[PHI_SROA_SPECULATE_LOAD_THEN:%.*]] = load i32, ptr [[PTR:%.*]], align 4303; CHECK-NEXT:    br label [[EXIT:%.*]]304; CHECK:       else:305; CHECK-NEXT:    br label [[EXIT]]306; CHECK:       exit:307; CHECK-NEXT:    [[PHI_SROA_SPECULATED:%.*]] = phi i32 [ undef, [[ELSE]] ], [ [[PHI_SROA_SPECULATE_LOAD_THEN]], [[THEN]] ]308; CHECK-NEXT:    ret i32 [[PHI_SROA_SPECULATED]]309;310entry:311  %f = alloca float312  %test = icmp ne i32 %b, 0313  br i1 %test, label %then, label %else314 315then:316  br label %exit317 318else:319  br label %exit320 321exit:322  %phi = phi ptr [ %f, %else ], [ %ptr, %then ]323  %loaded = load i32, ptr %phi, align 4324  ret i32 %loaded325}326 327define i32 @test9(i32 %b, ptr %ptr) {328; Same as @test8 but for a select rather than a PHI node.329;330; CHECK-LABEL: @test9(331; CHECK-NEXT:  entry:332; CHECK-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4333; CHECK-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0334; CHECK-NEXT:    [[LOADED_SROA_SPECULATE_LOAD_FALSE:%.*]] = load i32, ptr [[PTR]], align 4335; CHECK-NEXT:    [[LOADED_SROA_SPECULATED:%.*]] = select i1 [[TEST]], i32 undef, i32 [[LOADED_SROA_SPECULATE_LOAD_FALSE]]336; CHECK-NEXT:    ret i32 [[LOADED_SROA_SPECULATED]]337;338entry:339  %f = alloca float340  store i32 0, ptr %ptr341  %test = icmp ne i32 %b, 0342  %select = select i1 %test, ptr %f, ptr %ptr343  %loaded = load i32, ptr %select, align 4344  ret i32 %loaded345}346 347; We should not unconditionally load with sanitizers.348define i32 @test9_asan(i32 %b, ptr %ptr) sanitize_address {349; Same as @test8 but for a select rather than a PHI node.350;351; CHECK-PRESERVE-CFG-LABEL: @test9_asan(352; CHECK-PRESERVE-CFG-NEXT:  entry:353; CHECK-PRESERVE-CFG-NEXT:    [[F:%.*]] = alloca float, align 4354; CHECK-PRESERVE-CFG-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4355; CHECK-PRESERVE-CFG-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0356; CHECK-PRESERVE-CFG-NEXT:    [[SELECT:%.*]] = select i1 [[TEST]], ptr [[F]], ptr [[PTR]]357; CHECK-PRESERVE-CFG-NEXT:    [[LOADED:%.*]] = load i32, ptr [[SELECT]], align 4358; CHECK-PRESERVE-CFG-NEXT:    ret i32 [[LOADED]]359;360; CHECK-MODIFY-CFG-LABEL: @test9_asan(361; CHECK-MODIFY-CFG-NEXT:  entry:362; CHECK-MODIFY-CFG-NEXT:    store i32 0, ptr [[PTR:%.*]], align 4363; CHECK-MODIFY-CFG-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0364; CHECK-MODIFY-CFG-NEXT:    [[LOADED_ELSE_VAL:%.*]] = load i32, ptr [[PTR]], align 4365; CHECK-MODIFY-CFG-NEXT:    br i1 [[TEST]], label [[ENTRY_THEN:%.*]], label [[ENTRY_CONT:%.*]]366; CHECK-MODIFY-CFG:       entry.then:367; CHECK-MODIFY-CFG-NEXT:    br label [[ENTRY_CONT]]368; CHECK-MODIFY-CFG:       entry.cont:369; CHECK-MODIFY-CFG-NEXT:    [[LOADED:%.*]] = phi i32 [ undef, [[ENTRY_THEN]] ], [ [[LOADED_ELSE_VAL]], [[ENTRY:%.*]] ]370; CHECK-MODIFY-CFG-NEXT:    ret i32 [[LOADED]]371;372entry:373  %f = alloca float374  store i32 0, ptr %ptr375  %test = icmp ne i32 %b, 0376  %select = select i1 %test, ptr %f, ptr %ptr377  %loaded = load i32, ptr %select, align 4378  ret i32 %loaded379}380 381define float @test10(i32 %b, ptr %ptr) {382; Don't try to promote allocas which are not elligible for it even after383; rewriting due to the necessity of inserting bitcasts when speculating a PHI384; node.385;386; CHECK-LABEL: @test10(387; CHECK-NEXT:  entry:388; CHECK-NEXT:    [[F:%.*]] = alloca double, align 8389; CHECK-NEXT:    store double 0.000000e+00, ptr [[F]], align 8390; CHECK-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0391; CHECK-NEXT:    br i1 [[TEST]], label [[THEN:%.*]], label [[ELSE:%.*]]392; CHECK:       then:393; CHECK-NEXT:    [[PHI_SROA_SPECULATE_LOAD_THEN:%.*]] = load float, ptr [[PTR:%.*]], align 4394; CHECK-NEXT:    br label [[EXIT:%.*]]395; CHECK:       else:396; CHECK-NEXT:    [[F_0_PHI_SROA_SPECULATE_LOAD_ELSE:%.*]] = load float, ptr [[F]], align 8397; CHECK-NEXT:    br label [[EXIT]]398; CHECK:       exit:399; CHECK-NEXT:    [[PHI_SROA_SPECULATED:%.*]] = phi float [ [[F_0_PHI_SROA_SPECULATE_LOAD_ELSE]], [[ELSE]] ], [ [[PHI_SROA_SPECULATE_LOAD_THEN]], [[THEN]] ]400; CHECK-NEXT:    ret float [[PHI_SROA_SPECULATED]]401;402entry:403  %f = alloca double404  store double 0.0, ptr %f405  %test = icmp ne i32 %b, 0406  br i1 %test, label %then, label %else407 408then:409  br label %exit410 411else:412  br label %exit413 414exit:415  %phi = phi ptr [ %f, %else ], [ %ptr, %then ]416  %loaded = load float, ptr %phi, align 4417  ret float %loaded418}419 420define float @test11(i32 %b, ptr %ptr) {421; Same as @test10 but for a select rather than a PHI node.422;423; CHECK-LABEL: @test11(424; CHECK-NEXT:  entry:425; CHECK-NEXT:    [[F:%.*]] = alloca double, align 8426; CHECK-NEXT:    store double 0.000000e+00, ptr [[F]], align 8427; CHECK-NEXT:    store float 0.000000e+00, ptr [[PTR:%.*]], align 4428; CHECK-NEXT:    [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0429; CHECK-NEXT:    [[F_0_LOADED_SROA_SPECULATE_LOAD_TRUE:%.*]] = load float, ptr [[F]], align 8430; CHECK-NEXT:    [[LOADED_SROA_SPECULATE_LOAD_FALSE:%.*]] = load float, ptr [[PTR]], align 4431; CHECK-NEXT:    [[LOADED_SROA_SPECULATED:%.*]] = select i1 [[TEST]], float [[F_0_LOADED_SROA_SPECULATE_LOAD_TRUE]], float [[LOADED_SROA_SPECULATE_LOAD_FALSE]]432; CHECK-NEXT:    ret float [[LOADED_SROA_SPECULATED]]433;434entry:435  %f = alloca double436  store double 0.0, ptr %f437  store float 0.0, ptr %ptr438  %test = icmp ne i32 %b, 0439  %select = select i1 %test, ptr %f, ptr %ptr440  %loaded = load float, ptr %select, align 4441  ret float %loaded442}443 444define i32 @test12(i32 %x, ptr %p, i1 %c1) {445; Ensure we don't crash or fail to nuke dead selects of allocas if no load is446; never found.447;448; CHECK-LABEL: @test12(449; CHECK-NEXT:  entry:450; CHECK-NEXT:    ret i32 [[X:%.*]]451;452entry:453  %a = alloca i32454  store i32 %x, ptr %a455  %dead = select i1 %c1, ptr %a, ptr %p456  %load = load i32, ptr %a457  ret i32 %load458}459 460define i32 @test13(i32 %x, ptr %p, i1 %c1) {461; Ensure we don't crash or fail to nuke dead phis of allocas if no load is ever462; found.463;464; CHECK-LABEL: @test13(465; CHECK-NEXT:  entry:466; CHECK-NEXT:    br label [[LOOP:%.*]]467; CHECK:       loop:468; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOOP]], label [[EXIT:%.*]]469; CHECK:       exit:470; CHECK-NEXT:    ret i32 [[X:%.*]]471;472entry:473  %a = alloca i32474  store i32 %x, ptr %a475  br label %loop476 477loop:478  %phi = phi ptr [ %p, %entry ], [ %a, %loop ]479  br i1 %c1, label %loop, label %exit480 481exit:482  %load = load i32, ptr %a483  ret i32 %load484}485 486define i32 @test14(i1 %b1, i1 %b2, ptr %ptr) {487; Check for problems when there are both selects and phis and one is488; speculatable toward promotion but the other is not. That should block all of489; the speculation.490;491; CHECK-LABEL: @test14(492; CHECK-NEXT:  entry:493; CHECK-NEXT:    [[F:%.*]] = alloca i32, align 4494; CHECK-NEXT:    [[G:%.*]] = alloca i32, align 4495; CHECK-NEXT:    store i32 0, ptr [[F]], align 4496; CHECK-NEXT:    store i32 0, ptr [[G]], align 4497; CHECK-NEXT:    [[F_SELECT:%.*]] = select i1 [[B1:%.*]], ptr [[F]], ptr [[PTR:%.*]]498; CHECK-NEXT:    br i1 [[B2:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]499; CHECK:       then:500; CHECK-NEXT:    br label [[EXIT:%.*]]501; CHECK:       else:502; CHECK-NEXT:    br label [[EXIT]]503; CHECK:       exit:504; CHECK-NEXT:    [[F_PHI:%.*]] = phi ptr [ [[F]], [[THEN]] ], [ [[F_SELECT]], [[ELSE]] ]505; CHECK-NEXT:    [[G_PHI:%.*]] = phi ptr [ [[G]], [[THEN]] ], [ [[PTR]], [[ELSE]] ]506; CHECK-NEXT:    [[F_LOADED:%.*]] = load i32, ptr [[F_PHI]], align 4507; CHECK-NEXT:    [[G_SELECT:%.*]] = select i1 [[B1]], ptr [[G]], ptr [[G_PHI]]508; CHECK-NEXT:    [[G_LOADED:%.*]] = load i32, ptr [[G_SELECT]], align 4509; CHECK-NEXT:    [[RESULT:%.*]] = add i32 [[F_LOADED]], [[G_LOADED]]510; CHECK-NEXT:    ret i32 [[RESULT]]511;512entry:513  %f = alloca i32514  %g = alloca i32515  store i32 0, ptr %f516  store i32 0, ptr %g517  %f.select = select i1 %b1, ptr %f, ptr %ptr518  br i1 %b2, label %then, label %else519 520then:521  br label %exit522 523else:524  br label %exit525 526exit:527  %f.phi = phi ptr [ %f, %then ], [ %f.select, %else ]528  %g.phi = phi ptr [ %g, %then ], [ %ptr, %else ]529  %f.loaded = load i32, ptr %f.phi530  %g.select = select i1 %b1, ptr %g, ptr %g.phi531  %g.loaded = load i32, ptr %g.select532  %result = add i32 %f.loaded, %g.loaded533  ret i32 %result534}535 536define void @PR13905(i1 %c1, i1 %c2, i1 %c3) {537; Check a pattern where we have a chain of dead phi nodes to ensure they are538; deleted and promotion can proceed.539;540; CHECK-LABEL: @PR13905(541; CHECK-NEXT:  entry:542; CHECK-NEXT:    br i1 [[C1:%.*]], label [[LOOP1:%.*]], label [[EXIT:%.*]]543; CHECK:       loop1:544; CHECK-NEXT:    br i1 [[C2:%.*]], label [[LOOP1]], label [[LOOP2:%.*]]545; CHECK:       loop2:546; CHECK-NEXT:    br i1 [[C3:%.*]], label [[LOOP1]], label [[EXIT]]547; CHECK:       exit:548; CHECK-NEXT:    [[PHI2:%.*]] = phi ptr [ poison, [[LOOP2]] ], [ null, [[ENTRY:%.*]] ]549; CHECK-NEXT:    ret void550;551entry:552  %h = alloca i32553  store i32 0, ptr %h554  br i1 %c1, label %loop1, label %exit555 556loop1:557  %phi1 = phi ptr [ null, %entry ], [ %h, %loop1 ], [ %h, %loop2 ]558  br i1 %c2, label %loop1, label %loop2559 560loop2:561  br i1 %c3, label %loop1, label %exit562 563exit:564  %phi2 = phi ptr [ %phi1, %loop2 ], [ null, %entry ]565  ret void566}567 568define i32 @PR13906(i1 %c1, i1 %c2) {569; Another pattern which can lead to crashes due to failing to clear out dead570; PHI nodes or select nodes. This triggers subtly differently from the above571; cases because the PHI node is (recursively) alive, but the select is dead.572;573; CHECK-LABEL: @PR13906(574; CHECK-NEXT:  entry:575; CHECK-NEXT:    br label [[FOR_COND:%.*]]576; CHECK:       for.cond:577; CHECK-NEXT:    br i1 [[C1:%.*]], label [[IF_THEN:%.*]], label [[FOR_COND]]578; CHECK:       if.then:579; CHECK-NEXT:    br label [[FOR_COND]]580;581entry:582  %c = alloca i32583  store i32 0, ptr %c584  br label %for.cond585 586for.cond:587  %d.0 = phi ptr [ poison, %entry ], [ %c, %if.then ], [ %d.0, %for.cond ]588  br i1 %c1, label %if.then, label %for.cond589 590if.then:591  %tmpcast.d.0 = select i1 %c2, ptr %c, ptr %d.0592  br label %for.cond593}594 595define i64 @PR14132(i1 %flag) {596; Here we form a PHI-node by promoting the pointer alloca first, and then in597; order to promote the other two allocas, we speculate the load of the598; now-phi-node-pointer. In doing so we end up loading a 64-bit value from an i8599; alloca. While this is a bit dubious, we were asserting on trying to600; rewrite it. The trick is that the code using the value may carefully take601; steps to only use the not-undef bits, and so we need to at least loosely602; support this..603; CHECK-LABEL: @PR14132(604; CHECK-NEXT:  entry:605; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]606; CHECK:       if.then:607; CHECK-NEXT:    [[B_0_LOAD_EXT:%.*]] = zext i8 1 to i64608; CHECK-NEXT:    br label [[IF_END]]609; CHECK:       if.end:610; CHECK-NEXT:    [[PTR_0_SROA_SPECULATED:%.*]] = phi i64 [ [[B_0_LOAD_EXT]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]611; CHECK-NEXT:    ret i64 [[PTR_0_SROA_SPECULATED]]612;613entry:614  %a = alloca i64, align 8615  %b = alloca i8, align 8616  %ptr = alloca ptr, align 8617 618  store i64 0, ptr %a, align 8619  store i8 1, ptr %b, align 8620  store ptr %a, ptr %ptr, align 8621  br i1 %flag, label %if.then, label %if.end622 623if.then:624  store ptr %b, ptr %ptr, align 8625  br label %if.end626 627if.end:628  %tmp = load ptr, ptr %ptr, align 8629  %result = load i64, ptr %tmp, align 8630 631  ret i64 %result632}633 634define float @PR16687(i64 %x, i1 %flag) {635; Check that even when we try to speculate the same phi twice (in two slices)636; on an otherwise promotable construct, we don't get ahead of ourselves and try637; to promote one of the slices prior to speculating it.638; CHECK-LABEL: @PR16687(639; CHECK-NEXT:  entry:640; CHECK-NEXT:    [[A_SROA_0_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[X:%.*]] to i32641; CHECK-NEXT:    [[A_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[X]], 32642; CHECK-NEXT:    [[A_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A_SROA_2_0_EXTRACT_SHIFT]] to i32643; CHECK-NEXT:    br i1 [[FLAG:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]644; CHECK:       then:645; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32 [[A_SROA_0_0_EXTRACT_TRUNC]] to float646; CHECK-NEXT:    br label [[END:%.*]]647; CHECK:       else:648; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32 [[A_SROA_2_0_EXTRACT_TRUNC]] to float649; CHECK-NEXT:    br label [[END]]650; CHECK:       end:651; CHECK-NEXT:    [[A_PHI_F_SROA_SPECULATED:%.*]] = phi float [ [[TMP0]], [[THEN]] ], [ [[TMP1]], [[ELSE]] ]652; CHECK-NEXT:    ret float [[A_PHI_F_SROA_SPECULATED]]653;654entry:655  %a = alloca i64, align 8656  store i64 %x, ptr %a657  br i1 %flag, label %then, label %else658 659then:660  br label %end661 662else:663  %a.raw.4 = getelementptr i8, ptr %a, i64 4664  br label %end665 666end:667  %a.phi.f = phi ptr [ %a, %then ], [ %a.raw.4, %else ]668  %f = load float, ptr %a.phi.f669  ret float %f670}671 672; Verifies we fixed PR20425. We should be able to promote all alloca's to673; registers in this test.674;675; %0 = slice676; %1 = slice677; %2 = phi(%0, %1) // == slice678define float @simplify_phi_nodes_that_equal_slice(i1 %cond, ptr %temp) {679; CHECK-LABEL: @simplify_phi_nodes_that_equal_slice(680; CHECK-NEXT:  entry:681; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]682; CHECK:       then:683; CHECK-NEXT:    br label [[MERGE:%.*]]684; CHECK:       else:685; CHECK-NEXT:    br label [[MERGE]]686; CHECK:       merge:687; CHECK-NEXT:    [[ARR_SROA_0_0:%.*]] = phi float [ 1.000000e+00, [[THEN]] ], [ 2.000000e+00, [[ELSE]] ]688; CHECK-NEXT:    store float 0.000000e+00, ptr [[TEMP:%.*]], align 4689; CHECK-NEXT:    ret float [[ARR_SROA_0_0]]690;691entry:692  %arr = alloca [4 x float], align 4693  br i1 %cond, label %then, label %else694 695then:696  %0 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3697  store float 1.000000e+00, ptr %0, align 4698  br label %merge699 700else:701  %1 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3702  store float 2.000000e+00, ptr %1, align 4703  br label %merge704 705merge:706  %2 = phi ptr [ %0, %then ], [ %1, %else ]707  store float 0.000000e+00, ptr %temp, align 4708  %3 = load float, ptr %2, align 4709  ret float %3710}711 712; A slightly complicated example for PR20425.713;714; %0 = slice715; %1 = phi(%0) // == slice716; %2 = slice717; %3 = phi(%1, %2) // == slice718define float @simplify_phi_nodes_that_equal_slice_2(i1 %cond, ptr %temp) {719; CHECK-LABEL: @simplify_phi_nodes_that_equal_slice_2(720; CHECK-NEXT:  entry:721; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]722; CHECK:       then:723; CHECK-NEXT:    br label [[THEN2:%.*]]724; CHECK:       then2:725; CHECK-NEXT:    br label [[MERGE:%.*]]726; CHECK:       else:727; CHECK-NEXT:    br label [[MERGE]]728; CHECK:       merge:729; CHECK-NEXT:    [[ARR_SROA_0_0:%.*]] = phi float [ 2.000000e+00, [[THEN2]] ], [ 3.000000e+00, [[ELSE]] ]730; CHECK-NEXT:    store float 0.000000e+00, ptr [[TEMP:%.*]], align 4731; CHECK-NEXT:    ret float [[ARR_SROA_0_0]]732;733entry:734  %arr = alloca [4 x float], align 4735  br i1 %cond, label %then, label %else736 737then:738  %0 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3739  store float 1.000000e+00, ptr %0, align 4740  br label %then2741 742then2:743  %1 = phi ptr [ %0, %then ]744  store float 2.000000e+00, ptr %1, align 4745  br label %merge746 747else:748  %2 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3749  store float 3.000000e+00, ptr %2, align 4750  br label %merge751 752merge:753  %3 = phi ptr [ %1, %then2 ], [ %2, %else ]754  store float 0.000000e+00, ptr %temp, align 4755  %4 = load float, ptr %3, align 4756  ret float %4757}758 759%struct.S = type { i32 }760 761; Verifies we fixed PR20822. We have a foldable PHI feeding a speculatable PHI762; which requires the rewriting of the speculated PHI to handle insertion763; when the incoming pointer is itself from a PHI node. We would previously764; insert a bitcast instruction *before* a PHI, producing an invalid module;765; make sure we insert *after* the first non-PHI instruction.766define void @PR20822(i1 %c1, i1 %c2, ptr %ptr) {767; CHECK-LABEL: @PR20822(768; CHECK-NEXT:  entry:769; CHECK-NEXT:    [[F_SROA_0:%.*]] = alloca i32, align 4770; CHECK-NEXT:    [[F1_SROA_GEP:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[PTR:%.*]], i32 0, i32 0771; CHECK-NEXT:    br i1 [[C1:%.*]], label [[IF_END:%.*]], label [[FOR_COND:%.*]]772; CHECK:       for.cond:773; CHECK-NEXT:    br label [[IF_END]]774; CHECK:       if.end:775; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ poison, [[ENTRY:%.*]] ], [ poison, [[FOR_COND]] ]776; CHECK-NEXT:    br i1 [[C2:%.*]], label [[IF_THEN5:%.*]], label [[IF_THEN2:%.*]]777; CHECK:       if.then2:778; CHECK-NEXT:    br label [[IF_THEN5]]779; CHECK:       if.then5:780; CHECK-NEXT:    [[F1_SROA_PHI:%.*]] = phi ptr [ [[F1_SROA_GEP]], [[IF_THEN2]] ], [ [[F_SROA_0]], [[IF_END]] ]781; CHECK-NEXT:    store i32 0, ptr [[F1_SROA_PHI]], align 4782; CHECK-NEXT:    ret void783;784entry:785  %f = alloca %struct.S, align 4786  br i1 %c1, label %if.end, label %for.cond787 788for.cond:                                         ; preds = %for.cond, %entry789  br label %if.end790 791if.end:                                           ; preds = %for.cond, %entry792  %f2 = phi ptr [ %f, %entry ], [ %f, %for.cond ]793  phi i32 [ poison, %entry ], [ poison, %for.cond ]794  br i1 %c2, label %if.then5, label %if.then2795 796if.then2:                                         ; preds = %if.end797  br label %if.then5798 799if.then5:                                         ; preds = %if.then2, %if.end800  %f1 = phi ptr [ %ptr, %if.then2 ], [ %f2, %if.end ]801  store %struct.S zeroinitializer, ptr %f1, align 4802  ret void803}804 805define i32 @phi_align(ptr %z) {806; CHECK-LABEL: @phi_align(807; CHECK-NEXT:  entry:808; CHECK-NEXT:    [[A_SROA_0:%.*]] = alloca [7 x i8], align 1809; CHECK-NEXT:    [[A_SROA_0_3_A1X_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3810; CHECK-NEXT:    store i32 0, ptr [[A_SROA_0]], align 1811; CHECK-NEXT:    [[A_SROA_0_3_A1X_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3812; CHECK-NEXT:    store i32 1, ptr [[A_SROA_0_3_A1X_SROA_IDX3]], align 1813; CHECK-NEXT:    [[A_SROA_0_0_A_SROA_0_1_V0:%.*]] = load i32, ptr [[A_SROA_0]], align 1814; CHECK-NEXT:    [[A_SROA_0_3_A1X_SROA_IDX4:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3815; CHECK-NEXT:    [[A_SROA_0_3_A_SROA_0_4_V1:%.*]] = load i32, ptr [[A_SROA_0_3_A1X_SROA_IDX4]], align 1816; CHECK-NEXT:    [[COND:%.*]] = icmp sle i32 [[A_SROA_0_0_A_SROA_0_1_V0]], [[A_SROA_0_3_A_SROA_0_4_V1]]817; CHECK-NEXT:    br i1 [[COND]], label [[THEN:%.*]], label [[EXIT:%.*]]818; CHECK:       then:819; CHECK-NEXT:    br label [[EXIT]]820; CHECK:       exit:821; CHECK-NEXT:    [[PHI:%.*]] = phi ptr [ [[A_SROA_0_3_A1X_SROA_IDX]], [[THEN]] ], [ [[Z:%.*]], [[ENTRY:%.*]] ]822; CHECK-NEXT:    [[RESULT:%.*]] = load i32, ptr [[PHI]], align 1823; CHECK-NEXT:    ret i32 [[RESULT]]824;825entry:826  %a = alloca [8 x i8], align 8827 828  %a0x = getelementptr [8 x i8], ptr %a, i64 0, i32 1829  %a1x = getelementptr [8 x i8], ptr %a, i64 0, i32 4830  store i32 0, ptr %a0x, align 1831  store i32 1, ptr %a1x, align 4832  %v0 = load i32, ptr %a0x, align 1833  %v1 = load i32, ptr %a1x, align 4834  %cond = icmp sle i32 %v0, %v1835  br i1 %cond, label %then, label %exit836 837then:838  br label %exit839 840exit:841  %phi = phi ptr [ %a1x, %then ], [ %z, %entry ]842  %result = load i32, ptr %phi, align 4843  ret i32 %result844}845 846; Don't speculate a load based on an earlier volatile operation.847define i8 @volatile_select(ptr %p, i1 %b) {848; CHECK-PRESERVE-CFG-LABEL: @volatile_select(849; CHECK-PRESERVE-CFG-NEXT:    [[P2:%.*]] = alloca i8, align 1850; CHECK-PRESERVE-CFG-NEXT:    store i8 0, ptr [[P2]], align 1851; CHECK-PRESERVE-CFG-NEXT:    store volatile i8 0, ptr [[P:%.*]], align 1852; CHECK-PRESERVE-CFG-NEXT:    [[PX:%.*]] = select i1 [[B:%.*]], ptr [[P]], ptr [[P2]]853; CHECK-PRESERVE-CFG-NEXT:    [[V2:%.*]] = load i8, ptr [[PX]], align 1854; CHECK-PRESERVE-CFG-NEXT:    ret i8 [[V2]]855;856; CHECK-MODIFY-CFG-LABEL: @volatile_select(857; CHECK-MODIFY-CFG-NEXT:    store volatile i8 0, ptr [[P:%.*]], align 1858; CHECK-MODIFY-CFG-NEXT:    br i1 [[B:%.*]], label [[DOTTHEN:%.*]], label [[DOTCONT:%.*]]859; CHECK-MODIFY-CFG:       .then:860; CHECK-MODIFY-CFG-NEXT:    [[V2_THEN_VAL:%.*]] = load i8, ptr [[P]], align 1861; CHECK-MODIFY-CFG-NEXT:    br label [[DOTCONT]]862; CHECK-MODIFY-CFG:       .cont:863; CHECK-MODIFY-CFG-NEXT:    [[V2:%.*]] = phi i8 [ [[V2_THEN_VAL]], [[DOTTHEN]] ], [ 0, [[TMP0:%.*]] ]864; CHECK-MODIFY-CFG-NEXT:    ret i8 [[V2]]865;866  %p2 = alloca i8867  store i8 0, ptr %p2868  store volatile i8 0, ptr %p869  %px = select i1 %b, ptr %p, ptr %p2870  %v2 = load i8, ptr %px871  ret i8 %v2872}873 874!0 = !{!"function_entry_count", i32 10}875!1 = !{!"branch_weights", i32 3, i32 5}876;.877; CHECK-PRESERVE-CFG: attributes #[[ATTR0:[0-9]+]] = { sanitize_address }878;.879; CHECK-MODIFY-CFG: attributes #[[ATTR0:[0-9]+]] = { sanitize_address }880;.881; CHECK-PRESERVE-CFG: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}882; CHECK-PRESERVE-CFG: [[PROF1]] = !{!"branch_weights", i32 3, i32 5}883;.884; CHECK-MODIFY-CFG: [[META0:![0-9]+]] = !{!"function_entry_count", i32 10}885; CHECK-MODIFY-CFG: [[PROF1]] = !{!"branch_weights", i32 3, i32 5}886;.887