1 ; Test the basic functionality of speculating around PHI nodes based on reduced 2 ; cost of the constant operands to the PHI nodes using the x86 cost model. 3 ; 4 ; REQUIRES: x86-registered-target 5 ; RUN: opt -S -passes=spec-phis < %s | FileCheck %s 6 7 target triple = "x86_64-unknown-unknown" 8 9 define i32 @test_basic(i1 %flag, i32 %arg) { 10 ; CHECK-LABEL: define i32 @test_basic( 11 entry: 12 br i1 %flag, label %a, label %b 13 ; CHECK: br i1 %flag, label %a, label %b 14 15 a: 16 br label %exit 17 ; CHECK: a: 18 ; CHECK-NEXT: %[[SUM_A:.*]] = add i32 %arg, 7 19 ; CHECK-NEXT: br label %exit 20 21 b: 22 br label %exit 23 ; CHECK: b: 24 ; CHECK-NEXT: %[[SUM_B:.*]] = add i32 %arg, 11 25 ; CHECK-NEXT: br label %exit 26 27 exit: 28 %p = phi i32 [ 7, %a ], [ 11, %b ] 29 %sum = add i32 %arg, %p 30 ret i32 %sum 31 ; CHECK: exit: 32 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %[[SUM_A]], %a ], [ %[[SUM_B]], %b ] 33 ; CHECK-NEXT: ret i32 %[[PHI]] 34 } 35 36 ; Check that we handle commuted operands and get the constant onto the RHS. 37 define i32 @test_commuted(i1 %flag, i32 %arg) { 38 ; CHECK-LABEL: define i32 @test_commuted( 39 entry: 40 br i1 %flag, label %a, label %b 41 ; CHECK: br i1 %flag, label %a, label %b 42 43 a: 44 br label %exit 45 ; CHECK: a: 46 ; CHECK-NEXT: %[[SUM_A:.*]] = add i32 %arg, 7 47 ; CHECK-NEXT: br label %exit 48 49 b: 50 br label %exit 51 ; CHECK: b: 52 ; CHECK-NEXT: %[[SUM_B:.*]] = add i32 %arg, 11 53 ; CHECK-NEXT: br label %exit 54 55 exit: 56 %p = phi i32 [ 7, %a ], [ 11, %b ] 57 %sum = add i32 %p, %arg 58 ret i32 %sum 59 ; CHECK: exit: 60 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %[[SUM_A]], %a ], [ %[[SUM_B]], %b ] 61 ; CHECK-NEXT: ret i32 %[[PHI]] 62 } 63 64 define i32 @test_split_crit_edge(i1 %flag, i32 %arg) { 65 ; CHECK-LABEL: define i32 @test_split_crit_edge( 66 entry: 67 br i1 %flag, label %exit, label %a 68 ; CHECK: entry: 69 ; CHECK-NEXT: br i1 %flag, label %[[ENTRY_SPLIT:.*]], label %a 70 ; 71 ; CHECK: [[ENTRY_SPLIT]]: 72 ; CHECK-NEXT: %[[SUM_ENTRY_SPLIT:.*]] = add i32 %arg, 7 73 ; CHECK-NEXT: br label %exit 74 75 a: 76 br label %exit 77 ; CHECK: a: 78 ; CHECK-NEXT: %[[SUM_A:.*]] = add i32 %arg, 11 79 ; CHECK-NEXT: br label %exit 80 81 exit: 82 %p = phi i32 [ 7, %entry ], [ 11, %a ] 83 %sum = add i32 %arg, %p 84 ret i32 %sum 85 ; CHECK: exit: 86 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %[[SUM_ENTRY_SPLIT]], %[[ENTRY_SPLIT]] ], [ %[[SUM_A]], %a ] 87 ; CHECK-NEXT: ret i32 %[[PHI]] 88 } 89 90 define i32 @test_no_spec_dominating_inst(i1 %flag, i32* %ptr) { 91 ; CHECK-LABEL: define i32 @test_no_spec_dominating_inst( 92 entry: 93 %load = load i32, i32* %ptr 94 br i1 %flag, label %a, label %b 95 ; CHECK: %[[LOAD:.*]] = load i32, i32* %ptr 96 ; CHECK-NEXT: br i1 %flag, label %a, label %b 97 98 a: 99 br label %exit 100 ; CHECK: a: 101 ; CHECK-NEXT: %[[SUM_A:.*]] = add i32 %[[LOAD]], 7 102 ; CHECK-NEXT: br label %exit 103 104 b: 105 br label %exit 106 ; CHECK: b: 107 ; CHECK-NEXT: %[[SUM_B:.*]] = add i32 %[[LOAD]], 11 108 ; CHECK-NEXT: br label %exit 109 110 exit: 111 %p = phi i32 [ 7, %a ], [ 11, %b ] 112 %sum = add i32 %load, %p 113 ret i32 %sum 114 ; CHECK: exit: 115 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %[[SUM_A]], %a ], [ %[[SUM_B]], %b ] 116 ; CHECK-NEXT: ret i32 %[[PHI]] 117 } 118 119 ; We have special logic handling PHI nodes, make sure it doesn't get confused 120 ; by a dominating PHI. 121 define i32 @test_no_spec_dominating_phi(i1 %flag1, i1 %flag2, i32 %x, i32 %y) { 122 ; CHECK-LABEL: define i32 @test_no_spec_dominating_phi( 123 entry: 124 br i1 %flag1, label %x.block, label %y.block 125 ; CHECK: entry: 126 ; CHECK-NEXT: br i1 %flag1, label %x.block, label %y.block 127 128 x.block: 129 br label %merge 130 ; CHECK: x.block: 131 ; CHECK-NEXT: br label %merge 132 133 y.block: 134 br label %merge 135 ; CHECK: y.block: 136 ; CHECK-NEXT: br label %merge 137 138 merge: 139 %xy.phi = phi i32 [ %x, %x.block ], [ %y, %y.block ] 140 br i1 %flag2, label %a, label %b 141 ; CHECK: merge: 142 ; CHECK-NEXT: %[[XY_PHI:.*]] = phi i32 [ %x, %x.block ], [ %y, %y.block ] 143 ; CHECK-NEXT: br i1 %flag2, label %a, label %b 144 145 a: 146 br label %exit 147 ; CHECK: a: 148 ; CHECK-NEXT: %[[SUM_A:.*]] = add i32 %[[XY_PHI]], 7 149 ; CHECK-NEXT: br label %exit 150 151 b: 152 br label %exit 153 ; CHECK: b: 154 ; CHECK-NEXT: %[[SUM_B:.*]] = add i32 %[[XY_PHI]], 11 155 ; CHECK-NEXT: br label %exit 156 157 exit: 158 %p = phi i32 [ 7, %a ], [ 11, %b ] 159 %sum = add i32 %xy.phi, %p 160 ret i32 %sum 161 ; CHECK: exit: 162 ; CHECK-NEXT: %[[SUM_PHI:.*]] = phi i32 [ %[[SUM_A]], %a ], [ %[[SUM_B]], %b ] 163 ; CHECK-NEXT: ret i32 %[[SUM_PHI]] 164 } 165 166 ; Ensure that we will speculate some number of "free" instructions on the given 167 ; architecture even though they are unrelated to the PHI itself. 168 define i32 @test_speculate_free_insts(i1 %flag, i64 %arg) { 169 ; CHECK-LABEL: define i32 @test_speculate_free_insts( 170 entry: 171 br i1 %flag, label %a, label %b 172 ; CHECK: br i1 %flag, label %a, label %b 173 174 a: 175 br label %exit 176 ; CHECK: a: 177 ; CHECK-NEXT: %[[T1_A:.*]] = trunc i64 %arg to i48 178 ; CHECK-NEXT: %[[T2_A:.*]] = trunc i48 %[[T1_A]] to i32 179 ; CHECK-NEXT: %[[SUM_A:.*]] = add i32 %[[T2_A]], 7 180 ; CHECK-NEXT: br label %exit 181 182 b: 183 br label %exit 184 ; CHECK: b: 185 ; CHECK-NEXT: %[[T1_B:.*]] = trunc i64 %arg to i48 186 ; CHECK-NEXT: %[[T2_B:.*]] = trunc i48 %[[T1_B]] to i32 187 ; CHECK-NEXT: %[[SUM_B:.*]] = add i32 %[[T2_B]], 11 188 ; CHECK-NEXT: br label %exit 189 190 exit: 191 %p = phi i32 [ 7, %a ], [ 11, %b ] 192 %t1 = trunc i64 %arg to i48 193 %t2 = trunc i48 %t1 to i32 194 %sum = add i32 %t2, %p 195 ret i32 %sum 196 ; CHECK: exit: 197 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %[[SUM_A]], %a ], [ %[[SUM_B]], %b ] 198 ; CHECK-NEXT: ret i32 %[[PHI]] 199 } 200 201 define i32 @test_speculate_free_phis(i1 %flag, i32 %arg1, i32 %arg2) { 202 ; CHECK-LABEL: define i32 @test_speculate_free_phis( 203 entry: 204 br i1 %flag, label %a, label %b 205 ; CHECK: br i1 %flag, label %a, label %b 206 207 a: 208 br label %exit 209 ; CHECK: a: 210 ; CHECK-NEXT: %[[SUM_A:.*]] = add i32 %arg1, 7 211 ; CHECK-NEXT: br label %exit 212 213 b: 214 br label %exit 215 ; CHECK: b: 216 ; CHECK-NEXT: %[[SUM_B:.*]] = add i32 %arg2, 11 217 ; CHECK-NEXT: br label %exit 218 219 exit: 220 %p1 = phi i32 [ 7, %a ], [ 11, %b ] 221 %p2 = phi i32 [ %arg1, %a ], [ %arg2, %b ] 222 %sum = add i32 %p2, %p1 223 ret i32 %sum 224 ; CHECK: exit: 225 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %[[SUM_A]], %a ], [ %[[SUM_B]], %b ] 226 ; We don't DCE the now unused PHI node... 227 ; CHECK-NEXT: %{{.*}} = phi i32 [ %arg1, %a ], [ %arg2, %b ] 228 ; CHECK-NEXT: ret i32 %[[PHI]] 229 } 230 231 ; We shouldn't speculate multiple uses even if each individually looks 232 ; profitable because of the total cost. 233 define i32 @test_no_spec_multi_uses(i1 %flag, i32 %arg1, i32 %arg2, i32 %arg3) { 234 ; CHECK-LABEL: define i32 @test_no_spec_multi_uses( 235 entry: 236 br i1 %flag, label %a, label %b 237 ; CHECK: br i1 %flag, label %a, label %b 238 239 a: 240 br label %exit 241 ; CHECK: a: 242 ; CHECK-NEXT: br label %exit 243 244 b: 245 br label %exit 246 ; CHECK: b: 247 ; CHECK-NEXT: br label %exit 248 249 exit: 250 %p = phi i32 [ 7, %a ], [ 11, %b ] 251 %add1 = add i32 %arg1, %p 252 %add2 = add i32 %arg2, %p 253 %add3 = add i32 %arg3, %p 254 %sum1 = add i32 %add1, %add2 255 %sum2 = add i32 %sum1, %add3 256 ret i32 %sum2 257 ; CHECK: exit: 258 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ 7, %a ], [ 11, %b ] 259 ; CHECK-NEXT: %[[ADD1:.*]] = add i32 %arg1, %[[PHI]] 260 ; CHECK-NEXT: %[[ADD2:.*]] = add i32 %arg2, %[[PHI]] 261 ; CHECK-NEXT: %[[ADD3:.*]] = add i32 %arg3, %[[PHI]] 262 ; CHECK-NEXT: %[[SUM1:.*]] = add i32 %[[ADD1]], %[[ADD2]] 263 ; CHECK-NEXT: %[[SUM2:.*]] = add i32 %[[SUM1]], %[[ADD3]] 264 ; CHECK-NEXT: ret i32 %[[SUM2]] 265 } 266 267 define i32 @test_multi_phis1(i1 %flag, i32 %arg) { 268 ; CHECK-LABEL: define i32 @test_multi_phis1( 269 entry: 270 br i1 %flag, label %a, label %b 271 ; CHECK: br i1 %flag, label %a, label %b 272 273 a: 274 br label %exit 275 ; CHECK: a: 276 ; CHECK-NEXT: %[[SUM_A1:.*]] = add i32 %arg, 1 277 ; CHECK-NEXT: %[[SUM_A2:.*]] = add i32 %[[SUM_A1]], 3 278 ; CHECK-NEXT: %[[SUM_A3:.*]] = add i32 %[[SUM_A2]], 5 279 ; CHECK-NEXT: br label %exit 280 281 b: 282 br label %exit 283 ; CHECK: b: 284 ; CHECK-NEXT: %[[SUM_B1:.*]] = add i32 %arg, 2 285 ; CHECK-NEXT: %[[SUM_B2:.*]] = add i32 %[[SUM_B1]], 4 286 ; CHECK-NEXT: %[[SUM_B3:.*]] = add i32 %[[SUM_B2]], 6 287 ; CHECK-NEXT: br label %exit 288 289 exit: 290 %p1 = phi i32 [ 1, %a ], [ 2, %b ] 291 %p2 = phi i32 [ 3, %a ], [ 4, %b ] 292 %p3 = phi i32 [ 5, %a ], [ 6, %b ] 293 %sum1 = add i32 %arg, %p1 294 %sum2 = add i32 %sum1, %p2 295 %sum3 = add i32 %sum2, %p3 296 ret i32 %sum3 297 ; CHECK: exit: 298 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %[[SUM_A3]], %a ], [ %[[SUM_B3]], %b ] 299 ; CHECK-NEXT: ret i32 %[[PHI]] 300 } 301 302 ; Check that the order of the PHIs doesn't impact the behavior. 303 define i32 @test_multi_phis2(i1 %flag, i32 %arg) { 304 ; CHECK-LABEL: define i32 @test_multi_phis2( 305 entry: 306 br i1 %flag, label %a, label %b 307 ; CHECK: br i1 %flag, label %a, label %b 308 309 a: 310 br label %exit 311 ; CHECK: a: 312 ; CHECK-NEXT: %[[SUM_A1:.*]] = add i32 %arg, 1 313 ; CHECK-NEXT: %[[SUM_A2:.*]] = add i32 %[[SUM_A1]], 3 314 ; CHECK-NEXT: %[[SUM_A3:.*]] = add i32 %[[SUM_A2]], 5 315 ; CHECK-NEXT: br label %exit 316 317 b: 318 br label %exit 319 ; CHECK: b: 320 ; CHECK-NEXT: %[[SUM_B1:.*]] = add i32 %arg, 2 321 ; CHECK-NEXT: %[[SUM_B2:.*]] = add i32 %[[SUM_B1]], 4 322 ; CHECK-NEXT: %[[SUM_B3:.*]] = add i32 %[[SUM_B2]], 6 323 ; CHECK-NEXT: br label %exit 324 325 exit: 326 %p3 = phi i32 [ 5, %a ], [ 6, %b ] 327 %p2 = phi i32 [ 3, %a ], [ 4, %b ] 328 %p1 = phi i32 [ 1, %a ], [ 2, %b ] 329 %sum1 = add i32 %arg, %p1 330 %sum2 = add i32 %sum1, %p2 331 %sum3 = add i32 %sum2, %p3 332 ret i32 %sum3 333 ; CHECK: exit: 334 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ %[[SUM_A3]], %a ], [ %[[SUM_B3]], %b ] 335 ; CHECK-NEXT: ret i32 %[[PHI]] 336 } 337 338 define i32 @test_no_spec_indirectbr(i1 %flag, i32 %arg) { 339 ; CHECK-LABEL: define i32 @test_no_spec_indirectbr( 340 entry: 341 br i1 %flag, label %a, label %b 342 ; CHECK: entry: 343 ; CHECK-NEXT: br i1 %flag, label %a, label %b 344 345 a: 346 indirectbr i8* undef, [label %exit] 347 ; CHECK: a: 348 ; CHECK-NEXT: indirectbr i8* undef, [label %exit] 349 350 b: 351 indirectbr i8* undef, [label %exit] 352 ; CHECK: b: 353 ; CHECK-NEXT: indirectbr i8* undef, [label %exit] 354 355 exit: 356 %p = phi i32 [ 7, %a ], [ 11, %b ] 357 %sum = add i32 %arg, %p 358 ret i32 %sum 359 ; CHECK: exit: 360 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ 7, %a ], [ 11, %b ] 361 ; CHECK-NEXT: %[[SUM:.*]] = add i32 %arg, %[[PHI]] 362 ; CHECK-NEXT: ret i32 %[[SUM]] 363 } 364 365 declare void @g() 366 367 declare i32 @__gxx_personality_v0(...) 368 369 ; FIXME: We should be able to handle this case -- only the exceptional edge is 370 ; impossible to split. 371 define i32 @test_no_spec_invoke_continue(i1 %flag, i32 %arg) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 372 ; CHECK-LABEL: define i32 @test_no_spec_invoke_continue( 373 entry: 374 br i1 %flag, label %a, label %b 375 ; CHECK: entry: 376 ; CHECK-NEXT: br i1 %flag, label %a, label %b 377 378 a: 379 invoke void @g() 380 to label %exit unwind label %lpad 381 ; CHECK: a: 382 ; CHECK-NEXT: invoke void @g() 383 ; CHECK-NEXT: to label %exit unwind label %lpad 384 385 b: 386 invoke void @g() 387 to label %exit unwind label %lpad 388 ; CHECK: b: 389 ; CHECK-NEXT: invoke void @g() 390 ; CHECK-NEXT: to label %exit unwind label %lpad 391 392 exit: 393 %p = phi i32 [ 7, %a ], [ 11, %b ] 394 %sum = add i32 %arg, %p 395 ret i32 %sum 396 ; CHECK: exit: 397 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ 7, %a ], [ 11, %b ] 398 ; CHECK-NEXT: %[[SUM:.*]] = add i32 %arg, %[[PHI]] 399 ; CHECK-NEXT: ret i32 %[[SUM]] 400 401 lpad: 402 %lp = landingpad { i8*, i32 } 403 cleanup 404 resume { i8*, i32 } undef 405 } 406 407 define i32 @test_no_spec_landingpad(i32 %arg, i32* %ptr) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 408 ; CHECK-LABEL: define i32 @test_no_spec_landingpad( 409 entry: 410 invoke void @g() 411 to label %invoke.cont unwind label %lpad 412 ; CHECK: entry: 413 ; CHECK-NEXT: invoke void @g() 414 ; CHECK-NEXT: to label %invoke.cont unwind label %lpad 415 416 invoke.cont: 417 invoke void @g() 418 to label %exit unwind label %lpad 419 ; CHECK: invoke.cont: 420 ; CHECK-NEXT: invoke void @g() 421 ; CHECK-NEXT: to label %exit unwind label %lpad 422 423 lpad: 424 %p = phi i32 [ 7, %entry ], [ 11, %invoke.cont ] 425 %lp = landingpad { i8*, i32 } 426 cleanup 427 %sum = add i32 %arg, %p 428 store i32 %sum, i32* %ptr 429 resume { i8*, i32 } undef 430 ; CHECK: lpad: 431 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ 7, %entry ], [ 11, %invoke.cont ] 432 433 exit: 434 ret i32 0 435 } 436 437 declare i32 @__CxxFrameHandler3(...) 438 439 define i32 @test_no_spec_cleanuppad(i32 %arg, i32* %ptr) personality i32 (...)* @__CxxFrameHandler3 { 440 ; CHECK-LABEL: define i32 @test_no_spec_cleanuppad( 441 entry: 442 invoke void @g() 443 to label %invoke.cont unwind label %lpad 444 ; CHECK: entry: 445 ; CHECK-NEXT: invoke void @g() 446 ; CHECK-NEXT: to label %invoke.cont unwind label %lpad 447 448 invoke.cont: 449 invoke void @g() 450 to label %exit unwind label %lpad 451 ; CHECK: invoke.cont: 452 ; CHECK-NEXT: invoke void @g() 453 ; CHECK-NEXT: to label %exit unwind label %lpad 454 455 lpad: 456 %p = phi i32 [ 7, %entry ], [ 11, %invoke.cont ] 457 %cp = cleanuppad within none [] 458 %sum = add i32 %arg, %p 459 store i32 %sum, i32* %ptr 460 cleanupret from %cp unwind to caller 461 ; CHECK: lpad: 462 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ 7, %entry ], [ 11, %invoke.cont ] 463 464 exit: 465 ret i32 0 466 } 467 468 ; Check that we don't fall over when confronted with seemingly reasonable code 469 ; for us to handle but in an unreachable region and with non-PHI use-def 470 ; cycles. 471 define i32 @test_unreachable_non_phi_cycles(i1 %flag, i32 %arg) { 472 ; CHECK-LABEL: define i32 @test_unreachable_non_phi_cycles( 473 entry: 474 ret i32 42 475 ; CHECK: entry: 476 ; CHECK-NEXT: ret i32 42 477 478 a: 479 br label %exit 480 ; CHECK: a: 481 ; CHECK-NEXT: br label %exit 482 483 b: 484 br label %exit 485 ; CHECK: b: 486 ; CHECK-NEXT: br label %exit 487 488 exit: 489 %p = phi i32 [ 7, %a ], [ 11, %b ] 490 %zext = zext i32 %sum to i64 491 %trunc = trunc i64 %zext to i32 492 %sum = add i32 %trunc, %p 493 br i1 %flag, label %a, label %b 494 ; CHECK: exit: 495 ; CHECK-NEXT: %[[PHI:.*]] = phi i32 [ 7, %a ], [ 11, %b ] 496 ; CHECK-NEXT: %[[ZEXT:.*]] = zext i32 %[[SUM:.*]] to i64 497 ; CHECK-NEXT: %[[TRUNC:.*]] = trunc i64 %[[ZEXT]] to i32 498 ; CHECK-NEXT: %[[SUM]] = add i32 %[[TRUNC]], %[[PHI]] 499 ; CHECK-NEXT: br i1 %flag, label %a, label %b 500 } 501 502 ; Check that we don't speculate in the face of an expensive immediate. There 503 ; are two reasons this should never speculate. First, even a local analysis 504 ; should fail because it makes some paths (%a) potentially more expensive due 505 ; to multiple uses of the immediate. Additionally, when we go to speculate the 506 ; instructions, their cost will also be too high. 507 ; FIXME: The goal is really to test the first property, but there doesn't 508 ; happen to be any way to use free-to-speculate instructions here so that it 509 ; would be the only interesting property. 510 define i64 @test_expensive_imm(i32 %flag, i64 %arg) { 511 ; CHECK-LABEL: define i64 @test_expensive_imm( 512 entry: 513 switch i32 %flag, label %a [ 514 i32 1, label %b 515 i32 2, label %c 516 i32 3, label %d 517 ] 518 ; CHECK: switch i32 %flag, label %a [ 519 ; CHECK-NEXT: i32 1, label %b 520 ; CHECK-NEXT: i32 2, label %c 521 ; CHECK-NEXT: i32 3, label %d 522 ; CHECK-NEXT: ] 523 524 a: 525 br label %exit 526 ; CHECK: a: 527 ; CHECK-NEXT: br label %exit 528 529 b: 530 br label %exit 531 ; CHECK: b: 532 ; CHECK-NEXT: br label %exit 533 534 c: 535 br label %exit 536 ; CHECK: c: 537 ; CHECK-NEXT: br label %exit 538 539 d: 540 br label %exit 541 ; CHECK: d: 542 ; CHECK-NEXT: br label %exit 543 544 exit: 545 %p = phi i64 [ 4294967296, %a ], [ 1, %b ], [ 1, %c ], [ 1, %d ] 546 %sum1 = add i64 %arg, %p 547 %sum2 = add i64 %sum1, %p 548 ret i64 %sum2 549 ; CHECK: exit: 550 ; CHECK-NEXT: %[[PHI:.*]] = phi i64 [ {{[0-9]+}}, %a ], [ 1, %b ], [ 1, %c ], [ 1, %d ] 551 ; CHECK-NEXT: %[[SUM1:.*]] = add i64 %arg, %[[PHI]] 552 ; CHECK-NEXT: %[[SUM2:.*]] = add i64 %[[SUM1]], %[[PHI]] 553 ; CHECK-NEXT: ret i64 %[[SUM2]] 554 } 555 556 define i32 @test_no_spec_non_postdominating_uses(i1 %flag1, i1 %flag2, i32 %arg) { 557 ; CHECK-LABEL: define i32 @test_no_spec_non_postdominating_uses( 558 entry: 559 br i1 %flag1, label %a, label %b 560 ; CHECK: br i1 %flag1, label %a, label %b 561 562 a: 563 br label %merge 564 ; CHECK: a: 565 ; CHECK-NEXT: %[[SUM_A:.*]] = add i32 %arg, 7 566 ; CHECK-NEXT: br label %merge 567 568 b: 569 br label %merge 570 ; CHECK: b: 571 ; CHECK-NEXT: %[[SUM_B:.*]] = add i32 %arg, 11 572 ; CHECK-NEXT: br label %merge 573 574 merge: 575 %p1 = phi i32 [ 7, %a ], [ 11, %b ] 576 %p2 = phi i32 [ 13, %a ], [ 42, %b ] 577 %sum1 = add i32 %arg, %p1 578 br i1 %flag2, label %exit1, label %exit2 579 ; CHECK: merge: 580 ; CHECK-NEXT: %[[PHI1:.*]] = phi i32 [ %[[SUM_A]], %a ], [ %[[SUM_B]], %b ] 581 ; CHECK-NEXT: %[[PHI2:.*]] = phi i32 [ 13, %a ], [ 42, %b ] 582 ; CHECK-NEXT: br i1 %flag2, label %exit1, label %exit2 583 584 exit1: 585 ret i32 %sum1 586 ; CHECK: exit1: 587 ; CHECK-NEXT: ret i32 %[[PHI1]] 588 589 exit2: 590 %sum2 = add i32 %arg, %p2 591 ret i32 %sum2 592 ; CHECK: exit2: 593 ; CHECK-NEXT: %[[SUM2:.*]] = add i32 %arg, %[[PHI2]] 594 ; CHECK-NEXT: ret i32 %[[SUM2]] 595 } 596