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