1; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -disable-complex-addr-modes=false -addr-sink-new-phis=true -addr-sink-new-select=true -disable-cgp-delete-phis %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-YES 2; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -disable-complex-addr-modes=false -addr-sink-new-phis=false -addr-sink-new-select=true -disable-cgp-delete-phis %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO 3target datalayout = 4"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" 5target triple = "x86_64-unknown-linux-gnu" 6 7; Can we sink for different base if there is no phi for base? 8define i32 @test1(i1 %cond, ptr %b1, ptr %b2) { 9; CHECK-LABEL: @test1 10entry: 11 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 12 br i1 %cond, label %if.then, label %fallthrough 13 14if.then: 15 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 16 br label %fallthrough 17 18fallthrough: 19; CHECK-YES: sunk_phi 20; CHECK-NO-LABEL: fallthrough: 21; CHECK-NO: phi 22; CHECK-NO-NEXT: load 23 %c = phi ptr [%a1, %entry], [%a2, %if.then] 24 %v = load i32, ptr %c, align 4 25 ret i32 %v 26} 27 28; Can we sink for different base if there is phi for base? 29define i32 @test2(i1 %cond, ptr %b1, ptr %b2) { 30; CHECK-LABEL: @test2 31entry: 32 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 33 br i1 %cond, label %if.then, label %fallthrough 34 35if.then: 36 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 37 br label %fallthrough 38 39fallthrough: 40; CHECK: getelementptr inbounds i8, {{.+}} 40 41 %b = phi ptr [%b1, %entry], [%b2, %if.then] 42 %c = phi ptr [%a1, %entry], [%a2, %if.then] 43 %v = load i32, ptr %c, align 4 44 ret i32 %v 45} 46 47; Can we sink for different base if there is phi for base but not valid one? 48define i32 @test3(i1 %cond, ptr %b1, ptr %b2) { 49; CHECK-LABEL: @test3 50entry: 51 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 52 br i1 %cond, label %if.then, label %fallthrough 53 54if.then: 55 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 56 br label %fallthrough 57 58fallthrough: 59; CHECK-YES: sunk_phi 60; CHECK-NO-LABEL: fallthrough: 61; CHECK-NO: phi 62; CHECK-NO: phi 63; CHECK-NO-NEXT: load 64 %b = phi ptr [%b2, %entry], [%b1, %if.then] 65 %c = phi ptr [%a1, %entry], [%a2, %if.then] 66 %v = load i32, ptr %c, align 4 67 ret i32 %v 68} 69 70; Can we sink for different base if both addresses are in the same block? 71define i32 @test4(i1 %cond, ptr %b1, ptr %b2) { 72; CHECK-LABEL: @test4 73entry: 74 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 75 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 76 br i1 %cond, label %if.then, label %fallthrough 77 78if.then: 79 br label %fallthrough 80 81fallthrough: 82; CHECK-YES: sunk_phi 83; CHECK-NO-LABEL: fallthrough: 84; CHECK-NO: phi 85; CHECK-NO-NEXT: load 86 %c = phi ptr [%a1, %entry], [%a2, %if.then] 87 %v = load i32, ptr %c, align 4 88 ret i32 %v 89} 90 91; Can we sink for different base if there is phi for base? 92; Both addresses are in the same block. 93define i32 @test5(i1 %cond, ptr %b1, ptr %b2) { 94; CHECK-LABEL: @test5 95entry: 96 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 97 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 98 br i1 %cond, label %if.then, label %fallthrough 99 100if.then: 101 br label %fallthrough 102 103fallthrough: 104; CHECK: getelementptr inbounds i8, {{.+}} 40 105 %b = phi ptr [%b1, %entry], [%b2, %if.then] 106 %c = phi ptr [%a1, %entry], [%a2, %if.then] 107 %v = load i32, ptr %c, align 4 108 ret i32 %v 109} 110 111; Can we sink for different base if there is phi for base but not valid one? 112; Both addresses are in the same block. 113define i32 @test6(i1 %cond, ptr %b1, ptr %b2) { 114; CHECK-LABEL: @test6 115entry: 116 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 117 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 118 br i1 %cond, label %if.then, label %fallthrough 119 120if.then: 121 br label %fallthrough 122 123fallthrough: 124; CHECK-YES: sunk_phi 125; CHECK-NO-LABEL: fallthrough: 126; CHECK-NO: phi 127; CHECK-NO-NEXT: phi 128; CHECK-NO-NEXT: load 129 %b = phi ptr [%b2, %entry], [%b1, %if.then] 130 %c = phi ptr [%a1, %entry], [%a2, %if.then] 131 %v = load i32, ptr %c, align 4 132 ret i32 %v 133} 134 135; case with a loop. No phi node. 136define i32 @test7(i32 %N, i1 %cond, ptr %b1, ptr %b2) { 137; CHECK-LABEL: @test7 138entry: 139 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 140 br label %loop 141 142loop: 143; CHECK-LABEL: loop: 144; CHECK-YES: sunk_phi 145 %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough] 146 %c3 = phi ptr [%a1, %entry], [%c, %fallthrough] 147 br i1 %cond, label %if.then, label %fallthrough 148 149if.then: 150 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 151 br label %fallthrough 152 153fallthrough: 154; CHECK-YES: sunk_phi 155; CHECK-NO-LABEL: fallthrough: 156; CHECK-NO: phi 157; CHECK-NO-NEXT: load 158 %c = phi ptr [%c3, %loop], [%a2, %if.then] 159 %v = load volatile i32, ptr %c, align 4 160 %iv.inc = add i32 %iv, 1 161 %cmp = icmp slt i32 %iv.inc, %N 162 br i1 %cmp, label %loop, label %exit 163 164exit: 165 ret i32 %v 166} 167 168; case with a loop. There is phi node. 169define i32 @test8(i32 %N, i1 %cond, ptr %b1, ptr %b2) { 170; CHECK-LABEL: @test8 171entry: 172 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 173 br label %loop 174 175loop: 176 %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough] 177 %c3 = phi ptr [%a1, %entry], [%c, %fallthrough] 178 %b3 = phi ptr [%b1, %entry], [%b, %fallthrough] 179 br i1 %cond, label %if.then, label %fallthrough 180 181if.then: 182 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 183 br label %fallthrough 184 185fallthrough: 186; CHECK: getelementptr inbounds i8, {{.+}} 40 187 %c = phi ptr [%c3, %loop], [%a2, %if.then] 188 %b = phi ptr [%b3, %loop], [%b2, %if.then] 189 %v = load volatile i32, ptr %c, align 4 190 %iv.inc = add i32 %iv, 1 191 %cmp = icmp slt i32 %iv.inc, %N 192 br i1 %cmp, label %loop, label %exit 193 194exit: 195 ret i32 %v 196} 197 198; case with a loop. There is phi node but it does not fit. 199define i32 @test9(i32 %N, i1 %cond, ptr %b1, ptr %b2) { 200; CHECK-LABEL: @test9 201entry: 202 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 203 br label %loop 204 205loop: 206; CHECK-LABEL: loop: 207; CHECK-YES: sunk_phi 208 %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough] 209 %c3 = phi ptr [%a1, %entry], [%c, %fallthrough] 210 %b3 = phi ptr [%b1, %entry], [%b2, %fallthrough] 211 br i1 %cond, label %if.then, label %fallthrough 212 213if.then: 214 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 215 br label %fallthrough 216 217fallthrough: 218; CHECK-YES: sunk_phi 219; CHECK-NO-LABEL: fallthrough: 220; CHECK-NO: phi 221; CHECK-NO-NEXT: phi 222; CHECK-NO-NEXT: load 223 %c = phi ptr [%c3, %loop], [%a2, %if.then] 224 %b = phi ptr [%b3, %loop], [%b2, %if.then] 225 %v = load volatile i32, ptr %c, align 4 226 %iv.inc = add i32 %iv, 1 227 %cmp = icmp slt i32 %iv.inc, %N 228 br i1 %cmp, label %loop, label %exit 229 230exit: 231 ret i32 %v 232} 233 234; Case through a loop. No phi node. 235define i32 @test10(i32 %N, i1 %cond, ptr %b1, ptr %b2) { 236; CHECK-LABEL: @test10 237entry: 238 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 239 br i1 %cond, label %if.then, label %fallthrough 240 241if.then: 242 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 243 br label %fallthrough 244 245fallthrough: 246; CHECK-YES: sunk_phi 247; CHECK-NO-LABEL: fallthrough: 248; CHECK-NO-NEXT: phi 249; CHECK-NO-NEXT: br 250 %c = phi ptr [%a1, %entry], [%a2, %if.then] 251 br label %loop 252 253loop: 254 %iv = phi i32 [0, %fallthrough], [%iv.inc, %loop] 255 %iv.inc = add i32 %iv, 1 256 %cmp = icmp slt i32 %iv.inc, %N 257 br i1 %cmp, label %loop, label %exit 258 259exit: 260; CHECK-YES: sunkaddr 261 %v = load volatile i32, ptr %c, align 4 262 ret i32 %v 263} 264 265; Case through a loop. There is a phi. 266define i32 @test11(i32 %N, i1 %cond, ptr %b1, ptr %b2) { 267; CHECK-LABEL: @test11 268entry: 269 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 270 br i1 %cond, label %if.then, label %fallthrough 271 272if.then: 273 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 274 br label %fallthrough 275 276fallthrough: 277; CHECK: phi 278; CHECK: phi 279; CHECK: br 280 %c = phi ptr [%a1, %entry], [%a2, %if.then] 281 %b = phi ptr [%b1, %entry], [%b2, %if.then] 282 br label %loop 283 284loop: 285 %iv = phi i32 [0, %fallthrough], [%iv.inc, %loop] 286 %iv.inc = add i32 %iv, 1 287 %cmp = icmp slt i32 %iv.inc, %N 288 br i1 %cmp, label %loop, label %exit 289 290exit: 291; CHECK: sunkaddr 292 %v = load volatile i32, ptr %c, align 4 293 ret i32 %v 294} 295 296; Complex case with address value from previous iteration. 297define i32 @test12(i32 %N, i1 %cond, ptr %b1, ptr %b2, ptr %b3) { 298; CHECK-LABEL: @test12 299entry: 300 %a1 = getelementptr inbounds i64, ptr %b1, i64 5 301 br label %loop 302 303loop: 304; CHECK-LABEL: loop: 305; CHECK-YES: sunk_phi 306; CHECK-NO: phi 307; CHECK-NO-NEXT: phi 308; CHECK-NO-NEXT: phi 309; CHECK-NO-NEXT: br 310 %iv = phi i32 [0, %entry], [%iv.inc, %backedge] 311 %c3 = phi ptr [%a1, %entry], [%c, %backedge] 312 %b4 = phi ptr [%b1, %entry], [%b5, %backedge] 313 br i1 %cond, label %if.then, label %fallthrough 314 315if.then: 316 %a2 = getelementptr inbounds i64, ptr %b2, i64 5 317 br label %fallthrough 318 319fallthrough: 320; CHECK-LABEL: fallthrough: 321; CHECK-YES: sunk_phi 322; CHECK-NO: phi 323; CHECK-NO-NEXT: phi 324; CHECK-NO-NEXT: load 325 %c = phi ptr [%c3, %loop], [%a2, %if.then] 326 %b6 = phi ptr [%b4, %loop], [%b2, %if.then] 327 %v = load volatile i32, ptr %c, align 4 328 %a4 = getelementptr inbounds i64, ptr %b4, i64 5 329 %cmp = icmp slt i32 %iv, 20 330 br i1 %cmp, label %backedge, label %if.then.2 331 332if.then.2: 333 br label %backedge 334 335backedge: 336 %b5 = phi ptr [%b4, %fallthrough], [%b6, %if.then.2] 337 %iv.inc = add i32 %iv, 1 338 %cmp2 = icmp slt i32 %iv.inc, %N 339 br i1 %cmp2, label %loop, label %exit 340 341exit: 342 ret i32 %v 343} 344 345%struct.S = type {i32, i32} 346; Case with index 347define i32 @test13(i1 %cond, ptr %b1, ptr %b2, i64 %Index) { 348; CHECK-LABEL: @test13 349entry: 350 %a1 = getelementptr inbounds %struct.S, ptr %b1, i64 %Index, i32 1 351 br i1 %cond, label %if.then, label %fallthrough 352 353if.then: 354 %i2 = mul i64 %Index, 2 355 %a2 = getelementptr inbounds %struct.S, ptr %b2, i64 %Index, i32 1 356 br label %fallthrough 357 358fallthrough: 359; CHECK-YES: sunk_phi 360; CHECK-NO-LABEL: fallthrough: 361; CHECK-NO-NEXT: phi 362; CHECK-NO-NEXT: load 363 %a = phi ptr [%a1, %entry], [%a2, %if.then] 364 %v = load i32, ptr %a, align 4 365 ret i32 %v 366} 367 368; Select of Select case. 369define i64 @test14(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) { 370; CHECK-LABEL: @test14 371entry: 372; CHECK-LABEL: entry: 373 %g1 = getelementptr inbounds i64, ptr %b1, i64 5 374 %g2 = getelementptr inbounds i64, ptr %b2, i64 5 375 %g3 = getelementptr inbounds i64, ptr %b3, i64 5 376 %s1 = select i1 %c1, ptr %g1, ptr %g2 377 %s2 = select i1 %c2, ptr %s1, ptr %g3 378; CHECK: sunkaddr 379 %v = load i64 , ptr %s2, align 8 380 ret i64 %v 381} 382 383; Select of Phi case. 384define i64 @test15(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) { 385; CHECK-LABEL: @test15 386entry: 387 %g1 = getelementptr inbounds i64, ptr %b1, i64 5 388 %g2 = getelementptr inbounds i64, ptr %b2, i64 5 389 %g3 = getelementptr inbounds i64, ptr %b3, i64 5 390 br i1 %c1, label %if.then, label %fallthrough 391 392if.then: 393 br label %fallthrough 394 395fallthrough: 396; CHECK-LABEL: fallthrough: 397 %p1 = phi ptr [%g1, %entry], [%g2, %if.then] 398 %s1 = select i1 %c2, ptr %p1, ptr %g3 399; CHECK-YES: sunkaddr 400; CHECK-NO: phi 401; CHECK-NO-NEXT: select 402; CHECK-NO-NEXT: load 403 %v = load i64 , ptr %s1, align 8 404 ret i64 %v 405} 406 407; Select of Phi case. Phi exists 408define i64 @test16(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) { 409; CHECK-LABEL: @test16 410entry: 411 %g1 = getelementptr inbounds i64, ptr %b1, i64 5 412 %g2 = getelementptr inbounds i64, ptr %b2, i64 5 413 %g3 = getelementptr inbounds i64, ptr %b3, i64 5 414 br i1 %c1, label %if.then, label %fallthrough 415 416if.then: 417 br label %fallthrough 418 419fallthrough: 420; CHECK-LABEL: fallthrough: 421 %p = phi ptr [%b1, %entry], [%b2, %if.then] 422 %p1 = phi ptr [%g1, %entry], [%g2, %if.then] 423 %s1 = select i1 %c2, ptr %p1, ptr %g3 424; CHECK: sunkaddr 425 %v = load i64 , ptr %s1, align 8 426 ret i64 %v 427} 428 429; Phi of Select case. 430define i64 @test17(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) { 431; CHECK-LABEL: @test17 432entry: 433 %g1 = getelementptr inbounds i64, ptr %b1, i64 5 434 %g2 = getelementptr inbounds i64, ptr %b2, i64 5 435 %g3 = getelementptr inbounds i64, ptr %b3, i64 5 436 %s1 = select i1 %c2, ptr %g1, ptr %g2 437 br i1 %c1, label %if.then, label %fallthrough 438 439if.then: 440 br label %fallthrough 441 442fallthrough: 443; CHECK-LABEL: fallthrough: 444 %p1 = phi ptr [%s1, %entry], [%g3, %if.then] 445; CHECK-YES: sunkaddr 446; CHECK-NO: phi 447; CHECK-NO-NEXT: load 448 %v = load i64 , ptr %p1, align 8 449 ret i64 %v 450} 451 452; The same two addr modes by different paths 453define i32 @test18(i1 %cond1, i1 %cond2, ptr %b1, ptr %b2) { 454; CHECK-LABEL: @test18 455entry: 456 %g1 = getelementptr inbounds i64, ptr %b2, i64 5 457 br i1 %cond1, label %if.then1, label %if.then2 458 459if.then1: 460 %g2 = getelementptr inbounds i64, ptr %b1, i64 5 461 br label %fallthrough 462 463if.then2: 464 br i1 %cond2, label %fallthrough, label %if.then3 465 466if.then3: 467 br label %fallthrough 468 469fallthrough: 470; CHECK-YES: sunk_phi 471; CHECK-NO-LABEL: fallthrough: 472; CHECK-NO: phi 473; CHECK-NO-NEXT: load 474 %c = phi ptr [%g2, %if.then1], [%g1, %if.then2], [%g1, %if.then3] 475 %v1 = load i32, ptr %c, align 4 476 %g1_1 = getelementptr inbounds i64, ptr %b2, i64 5 477 %v2 = load i32, ptr %g1_1, align 4 478 %v = add i32 %v1, %v2 479 ret i32 %v 480} 481 482; Different types but null is the first? 483define i32 @test19(i1 %cond1, i1 %cond2, ptr %b2, ptr %b1) { 484; CHECK-LABEL: @test19 485entry: 486 %g1 = getelementptr inbounds i64, ptr %b2, i64 5 487 %bc1 = bitcast ptr %g1 to ptr 488 br i1 %cond1, label %if.then1, label %if.then2 489 490if.then1: 491 %g2 = getelementptr inbounds i8, ptr %b1, i64 40 492 %bc2 = bitcast ptr %g2 to ptr 493 br label %fallthrough 494 495if.then2: 496 %bc1_1 = bitcast ptr %g1 to ptr 497 br i1 %cond2, label %fallthrough, label %if.then3 498 499if.then3: 500 %g3 = getelementptr inbounds i64, ptr null, i64 5 501 %bc1_2 = bitcast ptr %g3 to ptr 502 br label %fallthrough 503 504fallthrough: 505; CHECK-NOT: sunk_phi 506 %c = phi ptr [%bc2, %if.then1], [%bc1_1, %if.then2], [%bc1_2, %if.then3] 507 %v1 = load i32, ptr %c, align 4 508 %g1_1 = getelementptr inbounds i64, ptr %b2, i64 5 509 %bc1_1_1 = bitcast ptr %g1_1 to ptr 510 %v2 = load i32, ptr %bc1_1_1, align 4 511 %v = add i32 %v1, %v2 512 ret i32 %v 513} 514