1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG 3; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG 4target 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, 1 10; 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 1 21 store i32 0, ptr %a 22 store i32 1, ptr %a1 23 %v0 = load i32, ptr %a 24 %v1 = load i32, ptr %a1 25 26 %cond = icmp sle i32 %v0, %v1 27 br i1 %cond, label %then, label %exit 28 29then: 30 br label %exit 31 32exit: 33 %phi = phi ptr [ %a1, %then ], [ %a, %entry ] 34 35 %result = load i32, ptr %phi 36 ret i32 %result 37} 38 39define i32 @test2() { 40; CHECK-LABEL: @test2( 41; CHECK-NEXT: entry: 42; CHECK-NEXT: [[COND:%.*]] = icmp sle i32 0, 1 43; CHECK-NEXT: [[RESULT_SROA_SPECULATED:%.*]] = select i1 [[COND]], i32 1, i32 0 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 1 50 store i32 0, ptr %a 51 store i32 1, ptr %a1 52 %v0 = load i32, ptr %a 53 %v1 = load i32, ptr %a1 54 55 %cond = icmp sle i32 %v0, %v1 56 %select = select i1 %cond, ptr %a1, ptr %a 57 58 %result = load i32, ptr %select 59 ret i32 %result 60} 61 62define float @test2_bitcast() { 63; CHECK-LABEL: @test2_bitcast( 64; CHECK-NEXT: entry: 65; CHECK-NEXT: [[COND:%.*]] = icmp sle i32 0, 1 66; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 1 to float 67; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 0 to float 68; 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 1 74 store i32 0, ptr %a 75 store i32 1, ptr %a1 76 %v0 = load i32, ptr %a 77 %v1 = load i32, ptr %a1 78 %cond = icmp sle i32 %v0, %v1 79 %select = select i1 %cond, ptr %a1, ptr %a 80 %result = load float, ptr %select 81 ret float %result 82} 83 84define i32 @test2_addrspacecast() { 85; CHECK-LABEL: @test2_addrspacecast( 86; CHECK-NEXT: entry: 87; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4 88; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca i32, align 4 89; CHECK-NEXT: store i32 0, ptr [[A_SROA_0]], align 4 90; CHECK-NEXT: store i32 1, ptr [[A_SROA_3]], align 4 91; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_V0:%.*]] = load i32, ptr [[A_SROA_0]], align 4 92; CHECK-NEXT: [[A_SROA_3_0_A_SROA_3_4_V1:%.*]] = load i32, ptr [[A_SROA_3]], align 4 93; 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 4 97; CHECK-NEXT: ret i32 [[RESULT]] 98; 99entry: 100 %a = alloca [2 x i32] 101 %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1 102 store i32 0, ptr %a 103 store i32 1, ptr %a1 104 %v0 = load i32, ptr %a 105 %v1 = load i32, ptr %a1 106 %cond = icmp sle i32 %v0, %v1 107 %select = select i1 %cond, ptr %a1, ptr %a 108 %select.asc = addrspacecast ptr %select to ptr addrspace(1) 109 %result = load i32, ptr addrspace(1) %select.asc 110 ret i32 %result 111} 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 GEPs 149 ; into the same alloca partation continues to work with PHI speculation. This 150 ; was the underlying cause of PR13926. 151 %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1 152 %a1b = getelementptr [2 x i32], ptr %a, i64 0, i32 1 153 store i32 0, ptr %a 154 store i32 1, ptr %a1 155 156 switch i32 %x, label %bb0 [ i32 1, label %bb1 157 i32 2, label %bb2 158 i32 3, label %bb3 159 i32 4, label %bb4 160 i32 5, label %bb5 161 i32 6, label %bb6 162 i32 7, label %bb7 ] 163 164bb0: 165 br label %exit 166bb1: 167 br label %exit 168bb2: 169 br label %exit 170bb3: 171 br label %exit 172bb4: 173 br label %exit 174bb5: 175 br label %exit 176bb6: 177 br label %exit 178bb7: 179 br label %exit 180 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 %phi 186 ret i32 %result 187} 188 189define i32 @test4() { 190; CHECK-LABEL: @test4( 191; CHECK-NEXT: entry: 192; CHECK-NEXT: ret i32 0 193; 194entry: 195 %a = alloca [2 x i32] 196 197 %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1 198 store i32 0, ptr %a 199 store i32 1, ptr %a1 200 %v0 = load i32, ptr %a 201 %v1 = load i32, ptr %a1 202 203 %cond = icmp sle i32 %v0, %v1 204 %select = select i1 %cond, ptr %a, ptr %a 205 206 %result = load i32, ptr %select 207 ret i32 %result 208} 209 210define i32 @test5(ptr %b) { 211; CHECK-LABEL: @test5( 212; CHECK-NEXT: entry: 213; CHECK-NEXT: ret i32 1 214; 215entry: 216 %a = alloca [2 x i32] 217 218 %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1 219 store i32 1, ptr %a1 220 221 %select = select i1 true, ptr %a1, ptr %b 222 223 %result = load i32, ptr %select 224 225 ret i32 %result 226} 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 1 237; 238entry: 239 %a = alloca [2 x i32] 240 %c = alloca i32 241 242 %a1 = getelementptr [2 x i32], ptr %a, i64 0, i32 1 243 store i32 1, ptr %a1 244 245 %select = select i1 true, ptr %a1, ptr %b 246 %select2 = select i1 false, ptr %a1, ptr %b 247 %select3 = select i1 false, ptr %c, ptr %b 248 249 ; Note, this would potentially escape the alloca pointer except for the 250 ; constant folding of the select. 251 call void @f(ptr %select2, ptr %select3) 252 253 254 %result = load i32, ptr %select 255 256 %dead = load i32, ptr %c 257 258 ret i32 %result 259} 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 4 269; 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 i32 276 br i1 %c1, label %good, label %bad 277 278good: 279 store i32 0, ptr %X 280 br label %exit 281 282bad: 283 %Y2 = getelementptr i32, ptr %X, i64 1 284 store i32 0, ptr %Y2 285 br label %exit 286 287exit: 288 %P = phi ptr [ %X, %good ], [ %Y2, %bad ] 289 %Z2 = load i32, ptr %P 290 ret i32 %Z2 291} 292 293define i32 @test8(i32 %b, ptr %ptr) { 294; Ensure that we rewrite allocas to the used type when that use is hidden by 295; a PHI that can be speculated. 296; 297; CHECK-LABEL: @test8( 298; CHECK-NEXT: entry: 299; CHECK-NEXT: [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0 300; 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 4 303; 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 float 312 %test = icmp ne i32 %b, 0 313 br i1 %test, label %then, label %else 314 315then: 316 br label %exit 317 318else: 319 br label %exit 320 321exit: 322 %phi = phi ptr [ %f, %else ], [ %ptr, %then ] 323 %loaded = load i32, ptr %phi, align 4 324 ret i32 %loaded 325} 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 4 333; CHECK-NEXT: [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0 334; CHECK-NEXT: [[LOADED_SROA_SPECULATE_LOAD_FALSE:%.*]] = load i32, ptr [[PTR]], align 4 335; 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 float 340 store i32 0, ptr %ptr 341 %test = icmp ne i32 %b, 0 342 %select = select i1 %test, ptr %f, ptr %ptr 343 %loaded = load i32, ptr %select, align 4 344 ret i32 %loaded 345} 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 4 354; CHECK-PRESERVE-CFG-NEXT: store i32 0, ptr [[PTR:%.*]], align 4 355; CHECK-PRESERVE-CFG-NEXT: [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0 356; CHECK-PRESERVE-CFG-NEXT: [[SELECT:%.*]] = select i1 [[TEST]], ptr [[F]], ptr [[PTR]] 357; CHECK-PRESERVE-CFG-NEXT: [[LOADED:%.*]] = load i32, ptr [[SELECT]], align 4 358; 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 4 363; CHECK-MODIFY-CFG-NEXT: [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0 364; CHECK-MODIFY-CFG-NEXT: [[LOADED_ELSE_VAL:%.*]] = load i32, ptr [[PTR]], align 4 365; 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 float 374 store i32 0, ptr %ptr 375 %test = icmp ne i32 %b, 0 376 %select = select i1 %test, ptr %f, ptr %ptr 377 %loaded = load i32, ptr %select, align 4 378 ret i32 %loaded 379} 380 381define float @test10(i32 %b, ptr %ptr) { 382; Don't try to promote allocas which are not elligible for it even after 383; rewriting due to the necessity of inserting bitcasts when speculating a PHI 384; node. 385; 386; CHECK-LABEL: @test10( 387; CHECK-NEXT: entry: 388; CHECK-NEXT: [[F:%.*]] = alloca double, align 8 389; CHECK-NEXT: store double 0.000000e+00, ptr [[F]], align 8 390; CHECK-NEXT: [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0 391; 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 4 394; CHECK-NEXT: br label [[EXIT:%.*]] 395; CHECK: else: 396; CHECK-NEXT: [[F_0_PHI_SROA_SPECULATE_LOAD_ELSE:%.*]] = load float, ptr [[F]], align 8 397; 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 double 404 store double 0.0, ptr %f 405 %test = icmp ne i32 %b, 0 406 br i1 %test, label %then, label %else 407 408then: 409 br label %exit 410 411else: 412 br label %exit 413 414exit: 415 %phi = phi ptr [ %f, %else ], [ %ptr, %then ] 416 %loaded = load float, ptr %phi, align 4 417 ret float %loaded 418} 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 8 426; CHECK-NEXT: store double 0.000000e+00, ptr [[F]], align 8 427; CHECK-NEXT: store float 0.000000e+00, ptr [[PTR:%.*]], align 4 428; CHECK-NEXT: [[TEST:%.*]] = icmp ne i32 [[B:%.*]], 0 429; CHECK-NEXT: [[F_0_LOADED_SROA_SPECULATE_LOAD_TRUE:%.*]] = load float, ptr [[F]], align 8 430; CHECK-NEXT: [[LOADED_SROA_SPECULATE_LOAD_FALSE:%.*]] = load float, ptr [[PTR]], align 4 431; 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 double 436 store double 0.0, ptr %f 437 store float 0.0, ptr %ptr 438 %test = icmp ne i32 %b, 0 439 %select = select i1 %test, ptr %f, ptr %ptr 440 %loaded = load float, ptr %select, align 4 441 ret float %loaded 442} 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 is 446; never found. 447; 448; CHECK-LABEL: @test12( 449; CHECK-NEXT: entry: 450; CHECK-NEXT: ret i32 [[X:%.*]] 451; 452entry: 453 %a = alloca i32 454 store i32 %x, ptr %a 455 %dead = select i1 %c1, ptr %a, ptr %p 456 %load = load i32, ptr %a 457 ret i32 %load 458} 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 ever 462; 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 i32 474 store i32 %x, ptr %a 475 br label %loop 476 477loop: 478 %phi = phi ptr [ %p, %entry ], [ %a, %loop ] 479 br i1 %c1, label %loop, label %exit 480 481exit: 482 %load = load i32, ptr %a 483 ret i32 %load 484} 485 486define i32 @test14(i1 %b1, i1 %b2, ptr %ptr) { 487; Check for problems when there are both selects and phis and one is 488; speculatable toward promotion but the other is not. That should block all of 489; the speculation. 490; 491; CHECK-LABEL: @test14( 492; CHECK-NEXT: entry: 493; CHECK-NEXT: [[F:%.*]] = alloca i32, align 4 494; CHECK-NEXT: [[G:%.*]] = alloca i32, align 4 495; CHECK-NEXT: store i32 0, ptr [[F]], align 4 496; CHECK-NEXT: store i32 0, ptr [[G]], align 4 497; 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 4 507; CHECK-NEXT: [[G_SELECT:%.*]] = select i1 [[B1]], ptr [[G]], ptr [[G_PHI]] 508; CHECK-NEXT: [[G_LOADED:%.*]] = load i32, ptr [[G_SELECT]], align 4 509; CHECK-NEXT: [[RESULT:%.*]] = add i32 [[F_LOADED]], [[G_LOADED]] 510; CHECK-NEXT: ret i32 [[RESULT]] 511; 512entry: 513 %f = alloca i32 514 %g = alloca i32 515 store i32 0, ptr %f 516 store i32 0, ptr %g 517 %f.select = select i1 %b1, ptr %f, ptr %ptr 518 br i1 %b2, label %then, label %else 519 520then: 521 br label %exit 522 523else: 524 br label %exit 525 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.phi 530 %g.select = select i1 %b1, ptr %g, ptr %g.phi 531 %g.loaded = load i32, ptr %g.select 532 %result = add i32 %f.loaded, %g.loaded 533 ret i32 %result 534} 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 are 538; 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 void 550; 551entry: 552 %h = alloca i32 553 store i32 0, ptr %h 554 br i1 %c1, label %loop1, label %exit 555 556loop1: 557 %phi1 = phi ptr [ null, %entry ], [ %h, %loop1 ], [ %h, %loop2 ] 558 br i1 %c2, label %loop1, label %loop2 559 560loop2: 561 br i1 %c3, label %loop1, label %exit 562 563exit: 564 %phi2 = phi ptr [ %phi1, %loop2 ], [ null, %entry ] 565 ret void 566} 567 568define i32 @PR13906(i1 %c1, i1 %c2) { 569; Another pattern which can lead to crashes due to failing to clear out dead 570; PHI nodes or select nodes. This triggers subtly differently from the above 571; 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 i32 583 store i32 0, ptr %c 584 br label %for.cond 585 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.cond 589 590if.then: 591 %tmpcast.d.0 = select i1 %c2, ptr %c, ptr %d.0 592 br label %for.cond 593} 594 595define i64 @PR14132(i1 %flag) { 596; Here we form a PHI-node by promoting the pointer alloca first, and then in 597; order to promote the other two allocas, we speculate the load of the 598; now-phi-node-pointer. In doing so we end up loading a 64-bit value from an i8 599; alloca. While this is a bit dubious, we were asserting on trying to 600; rewrite it. The trick is that the code using the value may carefully take 601; steps to only use the not-undef bits, and so we need to at least loosely 602; 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 i64 608; 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 8 615 %b = alloca i8, align 8 616 %ptr = alloca ptr, align 8 617 618 store i64 0, ptr %a, align 8 619 store i8 1, ptr %b, align 8 620 store ptr %a, ptr %ptr, align 8 621 br i1 %flag, label %if.then, label %if.end 622 623if.then: 624 store ptr %b, ptr %ptr, align 8 625 br label %if.end 626 627if.end: 628 %tmp = load ptr, ptr %ptr, align 8 629 %result = load i64, ptr %tmp, align 8 630 631 ret i64 %result 632} 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 try 637; 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 i32 641; CHECK-NEXT: [[A_SROA_2_0_EXTRACT_SHIFT:%.*]] = lshr i64 [[X]], 32 642; CHECK-NEXT: [[A_SROA_2_0_EXTRACT_TRUNC:%.*]] = trunc i64 [[A_SROA_2_0_EXTRACT_SHIFT]] to i32 643; 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 float 646; CHECK-NEXT: br label [[END:%.*]] 647; CHECK: else: 648; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32 [[A_SROA_2_0_EXTRACT_TRUNC]] to float 649; 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 8 656 store i64 %x, ptr %a 657 br i1 %flag, label %then, label %else 658 659then: 660 br label %end 661 662else: 663 %a.raw.4 = getelementptr i8, ptr %a, i64 4 664 br label %end 665 666end: 667 %a.phi.f = phi ptr [ %a, %then ], [ %a.raw.4, %else ] 668 %f = load float, ptr %a.phi.f 669 ret float %f 670} 671 672; Verifies we fixed PR20425. We should be able to promote all alloca's to 673; registers in this test. 674; 675; %0 = slice 676; %1 = slice 677; %2 = phi(%0, %1) // == slice 678define 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 4 689; CHECK-NEXT: ret float [[ARR_SROA_0_0]] 690; 691entry: 692 %arr = alloca [4 x float], align 4 693 br i1 %cond, label %then, label %else 694 695then: 696 %0 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3 697 store float 1.000000e+00, ptr %0, align 4 698 br label %merge 699 700else: 701 %1 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3 702 store float 2.000000e+00, ptr %1, align 4 703 br label %merge 704 705merge: 706 %2 = phi ptr [ %0, %then ], [ %1, %else ] 707 store float 0.000000e+00, ptr %temp, align 4 708 %3 = load float, ptr %2, align 4 709 ret float %3 710} 711 712; A slightly complicated example for PR20425. 713; 714; %0 = slice 715; %1 = phi(%0) // == slice 716; %2 = slice 717; %3 = phi(%1, %2) // == slice 718define 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 4 731; CHECK-NEXT: ret float [[ARR_SROA_0_0]] 732; 733entry: 734 %arr = alloca [4 x float], align 4 735 br i1 %cond, label %then, label %else 736 737then: 738 %0 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3 739 store float 1.000000e+00, ptr %0, align 4 740 br label %then2 741 742then2: 743 %1 = phi ptr [ %0, %then ] 744 store float 2.000000e+00, ptr %1, align 4 745 br label %merge 746 747else: 748 %2 = getelementptr inbounds [4 x float], ptr %arr, i64 0, i64 3 749 store float 3.000000e+00, ptr %2, align 4 750 br label %merge 751 752merge: 753 %3 = phi ptr [ %1, %then2 ], [ %2, %else ] 754 store float 0.000000e+00, ptr %temp, align 4 755 %4 = load float, ptr %3, align 4 756 ret float %4 757} 758 759%struct.S = type { i32 } 760 761; Verifies we fixed PR20822. We have a foldable PHI feeding a speculatable PHI 762; which requires the rewriting of the speculated PHI to handle insertion 763; when the incoming pointer is itself from a PHI node. We would previously 764; 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 4 770; CHECK-NEXT: [[F1_SROA_GEP:%.*]] = getelementptr inbounds [[STRUCT_S:%.*]], ptr [[PTR:%.*]], i32 0, i32 0 771; 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 4 782; CHECK-NEXT: ret void 783; 784entry: 785 %f = alloca %struct.S, align 4 786 br i1 %c1, label %if.end, label %for.cond 787 788for.cond: ; preds = %for.cond, %entry 789 br label %if.end 790 791if.end: ; preds = %for.cond, %entry 792 %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.then2 795 796if.then2: ; preds = %if.end 797 br label %if.then5 798 799if.then5: ; preds = %if.then2, %if.end 800 %f1 = phi ptr [ %ptr, %if.then2 ], [ %f2, %if.end ] 801 store %struct.S zeroinitializer, ptr %f1, align 4 802 ret void 803} 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 1 809; CHECK-NEXT: [[A_SROA_0_3_A1X_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3 810; CHECK-NEXT: store i32 0, ptr [[A_SROA_0]], align 1 811; CHECK-NEXT: [[A_SROA_0_3_A1X_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3 812; CHECK-NEXT: store i32 1, ptr [[A_SROA_0_3_A1X_SROA_IDX3]], align 1 813; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_1_V0:%.*]] = load i32, ptr [[A_SROA_0]], align 1 814; CHECK-NEXT: [[A_SROA_0_3_A1X_SROA_IDX4:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 3 815; CHECK-NEXT: [[A_SROA_0_3_A_SROA_0_4_V1:%.*]] = load i32, ptr [[A_SROA_0_3_A1X_SROA_IDX4]], align 1 816; 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 1 823; CHECK-NEXT: ret i32 [[RESULT]] 824; 825entry: 826 %a = alloca [8 x i8], align 8 827 828 %a0x = getelementptr [8 x i8], ptr %a, i64 0, i32 1 829 %a1x = getelementptr [8 x i8], ptr %a, i64 0, i32 4 830 store i32 0, ptr %a0x, align 1 831 store i32 1, ptr %a1x, align 4 832 %v0 = load i32, ptr %a0x, align 1 833 %v1 = load i32, ptr %a1x, align 4 834 %cond = icmp sle i32 %v0, %v1 835 br i1 %cond, label %then, label %exit 836 837then: 838 br label %exit 839 840exit: 841 %phi = phi ptr [ %a1x, %then ], [ %z, %entry ] 842 %result = load i32, ptr %phi, align 4 843 ret i32 %result 844} 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 1 850; CHECK-PRESERVE-CFG-NEXT: store i8 0, ptr [[P2]], align 1 851; CHECK-PRESERVE-CFG-NEXT: store volatile i8 0, ptr [[P:%.*]], align 1 852; CHECK-PRESERVE-CFG-NEXT: [[PX:%.*]] = select i1 [[B:%.*]], ptr [[P]], ptr [[P2]] 853; CHECK-PRESERVE-CFG-NEXT: [[V2:%.*]] = load i8, ptr [[PX]], align 1 854; 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 1 858; 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 1 861; 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 i8 867 store i8 0, ptr %p2 868 store volatile i8 0, ptr %p 869 %px = select i1 %b, ptr %p, ptr %p2 870 %v2 = load i8, ptr %px 871 ret i8 %v2 872} 873