1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -sroa < %s | FileCheck %s 3 4%pair = type { i32, i32 } 5 6define i32 @test_sroa_phi_gep(i1 %cond) { 7; CHECK-LABEL: @test_sroa_phi_gep( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]] 10; CHECK: if.then: 11; CHECK-NEXT: br label [[END]] 12; CHECK: end: 13; CHECK-NEXT: [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ] 14; CHECK-NEXT: ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]] 15; 16entry: 17 %a = alloca %pair, align 4 18 %b = alloca %pair, align 4 19 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 20 %gep_b = getelementptr inbounds %pair, %pair* %b, i32 0, i32 1 21 store i32 1, i32* %gep_a, align 4 22 store i32 2, i32* %gep_b, align 4 23 br i1 %cond, label %if.then, label %end 24 25if.then: 26 br label %end 27 28end: 29 %phi = phi %pair* [ %a, %entry], [ %b, %if.then ] 30 %gep = getelementptr inbounds %pair, %pair* %phi, i32 0, i32 1 31 %load = load i32, i32* %gep, align 4 32 ret i32 %load 33} 34 35define i32 @test_sroa_phi_gep_non_inbound(i1 %cond) { 36; CHECK-LABEL: @test_sroa_phi_gep_non_inbound( 37; CHECK-NEXT: entry: 38; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]] 39; CHECK: if.then: 40; CHECK-NEXT: br label [[END]] 41; CHECK: end: 42; CHECK-NEXT: [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY:%.*]] ], [ 2, [[IF_THEN]] ] 43; CHECK-NEXT: ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]] 44; 45entry: 46 %a = alloca %pair, align 4 47 %b = alloca %pair, align 4 48 %gep_a = getelementptr %pair, %pair* %a, i32 0, i32 1 49 %gep_b = getelementptr %pair, %pair* %b, i32 0, i32 1 50 store i32 1, i32* %gep_a, align 4 51 store i32 2, i32* %gep_b, align 4 52 br i1 %cond, label %if.then, label %end 53 54if.then: 55 br label %end 56 57end: 58 %phi = phi %pair* [ %a, %entry], [ %b, %if.then ] 59 %gep = getelementptr %pair, %pair* %phi, i32 0, i32 1 60 %load = load i32, i32* %gep, align 4 61 ret i32 %load 62} 63 64define i32 @test_sroa_phi_gep_undef(i1 %cond) { 65; CHECK-LABEL: @test_sroa_phi_gep_undef( 66; CHECK-NEXT: entry: 67; CHECK-NEXT: [[A:%.*]] = alloca [[PAIR:%.*]], align 4 68; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]] 69; CHECK: if.then: 70; CHECK-NEXT: br label [[END]] 71; CHECK: end: 72; CHECK-NEXT: [[PHI:%.*]] = phi %pair* [ [[A]], [[ENTRY:%.*]] ], [ undef, [[IF_THEN]] ] 73; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[PHI]], i32 0, i32 1 74; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[GEP]], align 4 75; CHECK-NEXT: ret i32 [[LOAD]] 76; 77entry: 78 %a = alloca %pair, align 4 79 br i1 %cond, label %if.then, label %end 80 81if.then: 82 br label %end 83 84end: 85 %phi = phi %pair* [ %a, %entry], [ undef, %if.then ] 86 %gep = getelementptr inbounds %pair, %pair* %phi, i32 0, i32 1 87 %load = load i32, i32* %gep, align 4 88 ret i32 %load 89} 90 91@g = global %pair zeroinitializer, align 4 92 93define i32 @test_sroa_phi_gep_global(i1 %cond) { 94; CHECK-LABEL: @test_sroa_phi_gep_global( 95; CHECK-NEXT: entry: 96; CHECK-NEXT: [[A:%.*]] = alloca [[PAIR:%.*]], align 4 97; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[A]], i32 0, i32 1 98; CHECK-NEXT: store i32 1, i32* [[GEP_A]], align 4 99; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]] 100; CHECK: if.then: 101; CHECK-NEXT: br label [[END]] 102; CHECK: end: 103; CHECK-NEXT: [[PHI:%.*]] = phi %pair* [ [[A]], [[ENTRY:%.*]] ], [ @g, [[IF_THEN]] ] 104; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[PHI]], i32 0, i32 1 105; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[GEP]], align 4 106; CHECK-NEXT: ret i32 [[LOAD]] 107; 108entry: 109 %a = alloca %pair, align 4 110 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 111 store i32 1, i32* %gep_a, align 4 112 br i1 %cond, label %if.then, label %end 113 114if.then: 115 br label %end 116 117end: 118 %phi = phi %pair* [ %a, %entry], [ @g, %if.then ] 119 %gep = getelementptr inbounds %pair, %pair* %phi, i32 0, i32 1 120 %load = load i32, i32* %gep, align 4 121 ret i32 %load 122} 123 124define i32 @test_sroa_phi_gep_arg_phi_inspt(i1 %cond) { 125; CHECK-LABEL: @test_sroa_phi_gep_arg_phi_inspt( 126; CHECK-NEXT: entry: 127; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]] 128; CHECK: for: 129; CHECK-NEXT: [[PHI_INSPT:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ] 130; CHECK-NEXT: [[I]] = add i32 [[PHI_INSPT]], 1 131; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10 132; CHECK-NEXT: br i1 [[LOOP_COND]], label [[FOR]], label [[END]] 133; CHECK: end: 134; CHECK-NEXT: [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ 2, [[FOR]] ] 135; CHECK-NEXT: ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]] 136; 137entry: 138 %a = alloca %pair, align 4 139 %b = alloca %pair, align 4 140 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 141 %gep_b = getelementptr inbounds %pair, %pair* %b, i32 0, i32 1 142 store i32 1, i32* %gep_a, align 4 143 store i32 2, i32* %gep_b, align 4 144 br i1 %cond, label %for, label %end 145 146for: 147 %phi_inspt = phi i32 [ 0, %entry ], [ %i, %for ] 148 %i = add i32 %phi_inspt, 1 149 %loop.cond = icmp ult i32 %i, 10 150 br i1 %loop.cond, label %for, label %end 151 152end: 153 %phi = phi %pair* [ %a, %entry], [ %b, %for ] 154 %gep = getelementptr inbounds %pair, %pair* %phi, i32 0, i32 1 155 %load = load i32, i32* %gep, align 4 156 ret i32 %load 157} 158 159define i32 @test_sroa_phi_gep_phi_inspt(i1 %cond) { 160; CHECK-LABEL: @test_sroa_phi_gep_phi_inspt( 161; CHECK-NEXT: entry: 162; CHECK-NEXT: [[A:%.*]] = alloca [[PAIR:%.*]], align 4 163; CHECK-NEXT: [[B:%.*]] = alloca [[PAIR]], align 4 164; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[A]], i32 0, i32 1 165; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[B]], i32 0, i32 1 166; CHECK-NEXT: store i32 1, i32* [[GEP_A]], align 4 167; CHECK-NEXT: store i32 2, i32* [[GEP_B]], align 4 168; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]] 169; CHECK: for: 170; CHECK-NEXT: [[PHI_IN:%.*]] = phi %pair* [ null, [[ENTRY:%.*]] ], [ [[B]], [[FOR]] ] 171; CHECK-NEXT: [[PHI_INSPT:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[I:%.*]], [[FOR]] ] 172; CHECK-NEXT: [[I]] = add i32 [[PHI_INSPT]], 1 173; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10 174; CHECK-NEXT: br i1 [[LOOP_COND]], label [[FOR]], label [[END]] 175; CHECK: end: 176; CHECK-NEXT: [[PHI:%.*]] = phi %pair* [ [[A]], [[ENTRY]] ], [ [[PHI_IN]], [[FOR]] ] 177; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[PHI]], i32 0, i32 1 178; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[GEP]], align 4 179; CHECK-NEXT: ret i32 [[LOAD]] 180; 181entry: 182 %a = alloca %pair, align 4 183 %b = alloca %pair, align 4 184 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 185 %gep_b = getelementptr inbounds %pair, %pair* %b, i32 0, i32 1 186 store i32 1, i32* %gep_a, align 4 187 store i32 2, i32* %gep_b, align 4 188 br i1 %cond, label %for, label %end 189 190for: 191 %phi_in = phi %pair * [ null, %entry ], [ %b, %for ] 192 %phi_inspt = phi i32 [ 0, %entry ], [ %i, %for ] 193 %i = add i32 %phi_inspt, 1 194 %loop.cond = icmp ult i32 %i, 10 195 br i1 %loop.cond, label %for, label %end 196 197end: 198 %phi = phi %pair* [ %a, %entry], [ %phi_in, %for ] 199 %gep = getelementptr inbounds %pair, %pair* %phi, i32 0, i32 1 200 %load = load i32, i32* %gep, align 4 201 ret i32 %load 202} 203 204define i32 @test_sroa_gep_phi_gep(i1 %cond) { 205; CHECK-LABEL: @test_sroa_gep_phi_gep( 206; CHECK-NEXT: entry: 207; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 208; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]] 209; CHECK: for: 210; CHECK-NEXT: [[PHI_I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ] 211; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[A_SROA_0]], [[ENTRY]] ], [ [[GEP_FOR:%.*]], [[FOR]] ] 212; CHECK-NEXT: [[I]] = add i32 [[PHI_I]], 1 213; CHECK-NEXT: [[GEP_FOR]] = getelementptr inbounds i32, i32* [[PHI]], i32 0 214; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10 215; CHECK-NEXT: br i1 [[LOOP_COND]], label [[FOR]], label [[END]] 216; CHECK: end: 217; CHECK-NEXT: [[PHI_END:%.*]] = phi i32* [ [[A_SROA_0]], [[ENTRY]] ], [ [[PHI]], [[FOR]] ] 218; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[PHI_END]], align 4 219; CHECK-NEXT: ret i32 [[LOAD]] 220; 221entry: 222 %a = alloca %pair, align 4 223 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 224 br i1 %cond, label %for, label %end 225 226for: 227 %phi_i = phi i32 [ 0, %entry ], [ %i, %for ] 228 %phi = phi i32* [ %gep_a, %entry], [ %gep_for, %for ] 229 %i = add i32 %phi_i, 1 230 %gep_for = getelementptr inbounds i32, i32* %phi, i32 0 231 %loop.cond = icmp ult i32 %i, 10 232 br i1 %loop.cond, label %for, label %end 233 234end: 235 %phi_end = phi i32* [ %gep_a, %entry], [ %phi, %for ] 236 %load = load i32, i32* %phi_end, align 4 237 ret i32 %load 238} 239 240define i32 @test_sroa_invoke_phi_gep(i1 %cond) personality i32 (...)* @__gxx_personality_v0 { 241; CHECK-LABEL: @test_sroa_invoke_phi_gep( 242; CHECK-NEXT: entry: 243; CHECK-NEXT: [[A:%.*]] = alloca [[PAIR:%.*]], align 4 244; CHECK-NEXT: br i1 [[COND:%.*]], label [[CALL:%.*]], label [[END:%.*]] 245; CHECK: call: 246; CHECK-NEXT: [[B:%.*]] = invoke %pair* @foo() 247; CHECK-NEXT: to label [[END]] unwind label [[INVOKE_CATCH:%.*]] 248; CHECK: end: 249; CHECK-NEXT: [[PHI:%.*]] = phi %pair* [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[CALL]] ] 250; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[PHI]], i32 0, i32 1 251; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[GEP]], align 4 252; CHECK-NEXT: ret i32 [[LOAD]] 253; CHECK: invoke_catch: 254; CHECK-NEXT: [[RES:%.*]] = landingpad { i8*, i32 } 255; CHECK-NEXT: catch i8* null 256; CHECK-NEXT: ret i32 0 257; 258entry: 259 %a = alloca %pair, align 4 260 br i1 %cond, label %call, label %end 261 262call: 263 %b = invoke %pair* @foo() 264 to label %end unwind label %invoke_catch 265 266end: 267 %phi = phi %pair* [ %a, %entry], [ %b, %call ] 268 %gep = getelementptr inbounds %pair, %pair* %phi, i32 0, i32 1 269 %load = load i32, i32* %gep, align 4 270 ret i32 %load 271 272invoke_catch: 273 %res = landingpad { i8*, i32 } 274 catch i8* null 275 ret i32 0 276} 277 278define i32 @test_sroa_phi_gep_nonconst_idx(i1 %cond, i32 %idx) { 279; CHECK-LABEL: @test_sroa_phi_gep_nonconst_idx( 280; CHECK-NEXT: entry: 281; CHECK-NEXT: [[A:%.*]] = alloca [[PAIR:%.*]], align 4 282; CHECK-NEXT: [[B:%.*]] = alloca [[PAIR]], align 4 283; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[A]], i32 0, i32 1 284; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[B]], i32 0, i32 1 285; CHECK-NEXT: store i32 1, i32* [[GEP_A]], align 4 286; CHECK-NEXT: store i32 2, i32* [[GEP_B]], align 4 287; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[END:%.*]] 288; CHECK: if.then: 289; CHECK-NEXT: br label [[END]] 290; CHECK: end: 291; CHECK-NEXT: [[PHI:%.*]] = phi %pair* [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[IF_THEN]] ] 292; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[PHI]], i32 [[IDX:%.*]], i32 1 293; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[GEP]], align 4 294; CHECK-NEXT: ret i32 [[LOAD]] 295; 296entry: 297 %a = alloca %pair, align 4 298 %b = alloca %pair, align 4 299 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 300 %gep_b = getelementptr inbounds %pair, %pair* %b, i32 0, i32 1 301 store i32 1, i32* %gep_a, align 4 302 store i32 2, i32* %gep_b, align 4 303 br i1 %cond, label %if.then, label %end 304 305if.then: 306 br label %end 307 308end: 309 %phi = phi %pair* [ %a, %entry], [ %b, %if.then ] 310 %gep = getelementptr inbounds %pair, %pair* %phi, i32 %idx, i32 1 311 %load = load i32, i32* %gep, align 4 312 ret i32 %load 313} 314 315define void @test_sroa_gep_phi_select_other_block() { 316; CHECK-LABEL: @test_sroa_gep_phi_select_other_block( 317; CHECK-NEXT: entry: 318; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8 319; CHECK-NEXT: br label [[WHILE_BODY:%.*]] 320; CHECK: while.body: 321; CHECK-NEXT: [[PHI:%.*]] = phi %pair* [ [[ALLOCA]], [[ENTRY:%.*]] ], [ [[SELECT:%.*]], [[WHILE_BODY]] ] 322; CHECK-NEXT: [[SELECT]] = select i1 undef, %pair* [[PHI]], %pair* undef 323; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[WHILE_BODY]] 324; CHECK: exit: 325; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[PHI]], i64 1 326; CHECK-NEXT: unreachable 327; 328entry: 329 %alloca = alloca %pair, align 8 330 br label %while.body 331 332while.body: 333 %phi = phi %pair* [ %alloca, %entry ], [ %select, %while.body ] 334 %select = select i1 undef, %pair* %phi, %pair* undef 335 br i1 undef, label %exit, label %while.body 336 337exit: 338 %gep = getelementptr inbounds %pair, %pair* %phi, i64 1 339 unreachable 340} 341 342define void @test_sroa_gep_phi_select_same_block() { 343; CHECK-LABEL: @test_sroa_gep_phi_select_same_block( 344; CHECK-NEXT: entry: 345; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [[PAIR:%.*]], align 8 346; CHECK-NEXT: br label [[WHILE_BODY:%.*]] 347; CHECK: while.body: 348; CHECK-NEXT: [[PHI:%.*]] = phi %pair* [ [[ALLOCA]], [[ENTRY:%.*]] ], [ [[SELECT:%.*]], [[WHILE_BODY]] ] 349; CHECK-NEXT: [[SELECT]] = select i1 undef, %pair* [[PHI]], %pair* undef 350; CHECK-NEXT: [[PHI_SROA_GEP:%.*]] = getelementptr inbounds [[PAIR]], %pair* [[PHI]], i64 1 351; CHECK-NEXT: [[SELECT_SROA_SEL:%.*]] = select i1 undef, %pair* [[PHI_SROA_GEP]], %pair* poison 352; CHECK-NEXT: br i1 undef, label [[EXIT:%.*]], label [[WHILE_BODY]] 353; CHECK: exit: 354; CHECK-NEXT: unreachable 355; 356entry: 357 %alloca = alloca %pair, align 8 358 br label %while.body 359 360while.body: 361 %phi = phi %pair* [ %alloca, %entry ], [ %select, %while.body ] 362 %select = select i1 undef, %pair* %phi, %pair* undef 363 %gep = getelementptr inbounds %pair, %pair* %select, i64 1 364 br i1 undef, label %exit, label %while.body 365 366exit: 367 unreachable 368} 369 370define i32 @test_sroa_gep_cast_phi_gep(i1 %cond) { 371; CHECK-LABEL: @test_sroa_gep_cast_phi_gep( 372; CHECK-NEXT: entry: 373; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 374; CHECK-NEXT: [[A_SROA_0_0_GEP_A_CAST_TO_FLOAT_SROA_CAST:%.*]] = bitcast i32* [[A_SROA_0]] to float* 375; CHECK-NEXT: [[A_SROA_0_0_GEP_A_CAST_TO_FLOAT_SROA_CAST2:%.*]] = bitcast i32* [[A_SROA_0]] to float* 376; CHECK-NEXT: [[A_SROA_0_0_GEP_SROA_CAST:%.*]] = bitcast i32* [[A_SROA_0]] to float* 377; CHECK-NEXT: store i32 1065353216, i32* [[A_SROA_0]], align 4 378; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR:%.*]], label [[END:%.*]] 379; CHECK: for: 380; CHECK-NEXT: [[PHI_I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I:%.*]], [[FOR]] ] 381; CHECK-NEXT: [[PHI:%.*]] = phi float* [ [[A_SROA_0_0_GEP_A_CAST_TO_FLOAT_SROA_CAST]], [[ENTRY]] ], [ [[GEP_FOR_CAST_TO_FLOAT:%.*]], [[FOR]] ] 382; CHECK-NEXT: [[PHI_SROA_PHI:%.*]] = phi float* [ [[A_SROA_0_0_GEP_SROA_CAST]], [[ENTRY]] ], [ [[GEP_FOR_CAST_TO_FLOAT_SROA_GEP:%.*]], [[FOR]] ] 383; CHECK-NEXT: [[I]] = add i32 [[PHI_I]], 1 384; CHECK-NEXT: [[GEP_FOR_CAST:%.*]] = bitcast float* [[PHI_SROA_PHI]] to i32* 385; CHECK-NEXT: [[GEP_FOR_CAST_TO_FLOAT]] = bitcast i32* [[GEP_FOR_CAST]] to float* 386; CHECK-NEXT: [[GEP_FOR_CAST_TO_FLOAT_SROA_GEP]] = getelementptr inbounds float, float* [[GEP_FOR_CAST_TO_FLOAT]], i32 0 387; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[I]], 10 388; CHECK-NEXT: br i1 [[LOOP_COND]], label [[FOR]], label [[END]] 389; CHECK: end: 390; CHECK-NEXT: [[PHI_END:%.*]] = phi float* [ [[A_SROA_0_0_GEP_A_CAST_TO_FLOAT_SROA_CAST2]], [[ENTRY]] ], [ [[PHI]], [[FOR]] ] 391; CHECK-NEXT: [[PHI_END_1:%.*]] = bitcast float* [[PHI_END]] to i32* 392; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[PHI_END_1]], align 4 393; CHECK-NEXT: ret i32 [[LOAD]] 394; 395entry: 396 %a = alloca %pair, align 4 397 %gep_a = getelementptr inbounds %pair, %pair* %a, i32 0, i32 1 398 %gep_a_cast_to_float = bitcast i32* %gep_a to float* 399 store float 1.0, float* %gep_a_cast_to_float, align 4 400 br i1 %cond, label %for, label %end 401 402for: 403 %phi_i = phi i32 [ 0, %entry ], [ %i, %for ] 404 %phi = phi float* [ %gep_a_cast_to_float, %entry], [ %gep_for_cast_to_float, %for ] 405 %i = add i32 %phi_i, 1 406 %gep_for = getelementptr inbounds float, float* %phi, i32 0 407 %gep_for_cast = bitcast float* %gep_for to i32* 408 %gep_for_cast_to_float = bitcast i32* %gep_for_cast to float* 409 %loop.cond = icmp ult i32 %i, 10 410 br i1 %loop.cond, label %for, label %end 411 412end: 413 %phi_end = phi float* [ %gep_a_cast_to_float, %entry], [ %phi, %for ] 414 %phi_end.1 = bitcast float* %phi_end to i32* 415 %load = load i32, i32* %phi_end.1, align 4 416 ret i32 %load 417} 418 419define void @unreachable_term() { 420; CHECK-LABEL: @unreachable_term( 421; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 422; CHECK-NEXT: [[A_SROA_0_0_A_SROA_CAST1:%.*]] = bitcast i32* [[A_SROA_0]] to [3 x i32]* 423; CHECK-NEXT: unreachable 424; CHECK: bb1: 425; CHECK-NEXT: br label [[BB1_I:%.*]] 426; CHECK: bb1.i: 427; CHECK-NEXT: [[PHI:%.*]] = phi [3 x i32]* [ [[A_SROA_0_0_A_SROA_CAST1]], [[BB1:%.*]] ], [ null, [[BB1_I]] ] 428; CHECK-NEXT: [[GEP:%.*]] = getelementptr [3 x i32], [3 x i32]* [[PHI]], i64 0, i64 0 429; CHECK-NEXT: store i32 0, i32* [[GEP]], align 1 430; CHECK-NEXT: br i1 undef, label [[BB1_I]], label [[EXIT:%.*]] 431; CHECK: exit: 432; CHECK-NEXT: br label [[BB2:%.*]] 433; CHECK: bb2: 434; CHECK-NEXT: ret void 435; 436 %a = alloca [3 x i32], align 1 437 unreachable 438 439bb1: 440 br label %bb1.i 441 442bb1.i: 443 %phi = phi [3 x i32]* [ %a, %bb1 ], [ null, %bb1.i ] 444 %gep = getelementptr [3 x i32], [3 x i32]* %phi, i64 0, i64 0 445 store i32 0, i32* %gep, align 1 446 br i1 undef, label %bb1.i, label %exit 447 448exit: 449 br label %bb2 450 451bb2: 452 ret void 453} 454 455define void @constant_value_phi() { 456; CHECK-LABEL: @constant_value_phi( 457; CHECK-NEXT: entry: 458; CHECK-NEXT: br label [[LAND_LHS_TRUE_I:%.*]] 459; CHECK: land.lhs.true.i: 460; CHECK-NEXT: br i1 undef, label [[COND_END_I:%.*]], label [[COND_END_I]] 461; CHECK: cond.end.i: 462; CHECK-NEXT: unreachable 463; 464entry: 465 %s1 = alloca [3 x i16] 466 %s = alloca [3 x i16] 467 %cast = bitcast [3 x i16]* %s1 to i16* 468 br label %land.lhs.true.i 469 470land.lhs.true.i: ; preds = %entry 471 br i1 undef, label %cond.end.i, label %cond.end.i 472 473cond.end.i: ; preds = %land.lhs.true.i, %land.lhs.true.i 474 %.pre-phi1 = phi i16* [ %cast, %land.lhs.true.i ], [ %cast, %land.lhs.true.i ] 475 %cast2 = bitcast [3 x i16]* %s to i16* 476 call void @llvm.memcpy.p0i16.p0i16.i64(i16* %.pre-phi1, i16* %cast2, i64 3, i1 false) 477 %gep = getelementptr inbounds [3 x i16], [3 x i16]* %s, i32 0, i32 0 478 %load = load i16, i16* %gep 479 unreachable 480} 481 482define i32 @test_sroa_phi_gep_multiple_values_from_same_block(i32 %arg) { 483; CHECK-LABEL: @test_sroa_phi_gep_multiple_values_from_same_block( 484; CHECK-NEXT: bb.1: 485; CHECK-NEXT: switch i32 [[ARG:%.*]], label [[BB_3:%.*]] [ 486; CHECK-NEXT: i32 1, label [[BB_2:%.*]] 487; CHECK-NEXT: i32 2, label [[BB_2]] 488; CHECK-NEXT: i32 3, label [[BB_4:%.*]] 489; CHECK-NEXT: i32 4, label [[BB_4]] 490; CHECK-NEXT: ] 491; CHECK: bb.2: 492; CHECK-NEXT: br label [[BB_4]] 493; CHECK: bb.3: 494; CHECK-NEXT: br label [[BB_4]] 495; CHECK: bb.4: 496; CHECK-NEXT: [[PHI_SROA_PHI_SROA_SPECULATED:%.*]] = phi i32 [ undef, [[BB_3]] ], [ undef, [[BB_2]] ], [ undef, [[BB_1:%.*]] ], [ undef, [[BB_1]] ] 497; CHECK-NEXT: ret i32 [[PHI_SROA_PHI_SROA_SPECULATED]] 498; 499bb.1: 500 %a = alloca %pair, align 4 501 %b = alloca %pair, align 4 502 switch i32 %arg, label %bb.3 [ 503 i32 1, label %bb.2 504 i32 2, label %bb.2 505 i32 3, label %bb.4 506 i32 4, label %bb.4 507 ] 508 509bb.2: ; preds = %bb.1, %bb.1 510 br label %bb.4 511 512bb.3: ; preds = %bb.1 513 br label %bb.4 514 515bb.4: ; preds = %bb.1, %bb.1, %bb.3, %bb.2 516 %phi = phi %pair* [ %a, %bb.3 ], [ %a, %bb.2 ], [ %b, %bb.1 ], [ %b, %bb.1 ] 517 %gep = getelementptr inbounds %pair, %pair* %phi, i32 0, i32 1 518 %load = load i32, i32* %gep, align 4 519 ret i32 %load 520} 521 522declare %pair* @foo() 523 524declare i32 @__gxx_personality_v0(...) 525 526declare void @llvm.memcpy.p0i16.p0i16.i64(i16* noalias nocapture writeonly, i16* noalias nocapture readonly, i64, i1 immarg) 527