1; RUN: opt < %s -S -analyze -scalar-evolution | FileCheck %s 2 3; Positive and negative tests for inferring flags like nsw from 4; reasoning about how a poison value from overflow would trigger 5; undefined behavior. 6 7define void @foo() { 8 ret void 9} 10 11; Example where an add should get the nsw flag, so that a sext can be 12; distributed over the add. 13define void @test-add-nsw(float* %input, i32 %offset, i32 %numIterations) { 14; CHECK-LABEL: @test-add-nsw 15entry: 16 br label %loop 17loop: 18 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 19 20; CHECK: %index32 = 21; CHECK: --> {%offset,+,1}<nsw> 22 %index32 = add nsw i32 %i, %offset 23 24; CHECK: %index64 = 25; CHECK: --> {(sext i32 %offset to i64),+,1}<nsw> 26 %index64 = sext i32 %index32 to i64 27 28 %ptr = getelementptr inbounds float, float* %input, i64 %index64 29 %nexti = add nsw i32 %i, 1 30 %f = load float, float* %ptr, align 4 31 call void @foo() 32 %exitcond = icmp eq i32 %nexti, %numIterations 33 br i1 %exitcond, label %exit, label %loop 34exit: 35 ret void 36} 37 38; Example where an add should get the nuw flag. 39define void @test-add-nuw(float* %input, i32 %offset, i32 %numIterations) { 40; CHECK-LABEL: @test-add-nuw 41entry: 42 br label %loop 43loop: 44 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 45 46; CHECK: %index32 = 47; CHECK: --> {%offset,+,1}<nuw> 48 %index32 = add nuw i32 %i, %offset 49 50 %ptr = getelementptr inbounds float, float* %input, i32 %index32 51 %nexti = add nuw i32 %i, 1 52 %f = load float, float* %ptr, align 4 53 %exitcond = icmp eq i32 %nexti, %numIterations 54 br i1 %exitcond, label %exit, label %loop 55 56exit: 57 ret void 58} 59 60define void @test-add-nuw-from-icmp(float* %input, i32 %offset, 61 i32 %numIterations) { 62; CHECK-LABEL: @test-add-nuw-from-icmp 63entry: 64 br label %loop 65loop: 66 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 67 68; CHECK: %index32 = 69; CHECK: --> {%offset,+,1}<nuw> 70 %index32 = add nuw i32 %i, %offset 71 %cmp = icmp sgt i32 %index32, 0 72 %cmp.idx = sext i1 %cmp to i32 73 74 %ptr = getelementptr inbounds float, float* %input, i32 %cmp.idx 75 %nexti = add nuw i32 %i, 1 76 %f = load float, float* %ptr, align 4 77 %exitcond = icmp eq i32 %nexti, %numIterations 78 br i1 %exitcond, label %exit, label %loop 79 80exit: 81 ret void 82} 83 84; With no load to trigger UB from poison, we cannot infer nsw. 85define void @test-add-no-load(float* %input, i32 %offset, i32 %numIterations) { 86; CHECK-LABEL: @test-add-no-load 87entry: 88 br label %loop 89loop: 90 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 91 92; CHECK: %index32 = 93; CHECK: --> {%offset,+,1}<nw> 94 %index32 = add nsw i32 %i, %offset 95 96 %ptr = getelementptr inbounds float, float* %input, i32 %index32 97 %nexti = add nuw i32 %i, 1 98 %exitcond = icmp eq i32 %nexti, %numIterations 99 br i1 %exitcond, label %exit, label %loop 100 101exit: 102 ret void 103} 104 105; The current code is only supposed to look at the loop header, so 106; it should not infer nsw in this case, as that would require looking 107; outside the loop header. 108define void @test-add-not-header(float* %input, i32 %offset, i32 %numIterations) { 109; CHECK-LABEL: @test-add-not-header 110entry: 111 br label %loop 112loop: 113 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 114 br label %loop2 115loop2: 116 117; CHECK: %index32 = 118; CHECK: --> {%offset,+,1}<nw> 119 %index32 = add nsw i32 %i, %offset 120 121 %ptr = getelementptr inbounds float, float* %input, i32 %index32 122 %nexti = add nsw i32 %i, 1 123 %f = load float, float* %ptr, align 4 124 %exitcond = icmp eq i32 %nexti, %numIterations 125 br i1 %exitcond, label %exit, label %loop 126exit: 127 ret void 128} 129 130; Same thing as test-add-not-header, but in this case only the load 131; instruction is outside the loop header. 132define void @test-add-not-header2(float* %input, i32 %offset, i32 %numIterations) { 133; CHECK-LABEL: @test-add-not-header2 134entry: 135 br label %loop 136loop: 137 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 138 139; CHECK: %index32 = 140; CHECK: --> {%offset,+,1}<nsw> 141 %index32 = add nsw i32 %i, %offset 142 143 %ptr = getelementptr inbounds float, float* %input, i32 %index32 144 %nexti = add nsw i32 %i, 1 145 br label %loop2 146loop2: 147 %f = load float, float* %ptr, align 4 148 %exitcond = icmp eq i32 %nexti, %numIterations 149 br i1 %exitcond, label %exit, label %loop 150exit: 151 ret void 152} 153 154; Similar to test-add-not-header, but in this case the load 155; instruction may not be executed. 156define void @test-add-not-header3(float* %input, i32 %offset, i32 %numIterations, 157 i1* %cond_buf) { 158; CHECK-LABEL: @test-add-not-header3 159entry: 160 br label %loop 161loop: 162 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 163 164; CHECK: %index32 = 165; CHECK: --> {%offset,+,1}<nw> 166 %index32 = add nsw i32 %i, %offset 167 168 %ptr = getelementptr inbounds float, float* %input, i32 %index32 169 %nexti = add nsw i32 %i, 1 170 %cond = load volatile i1, i1* %cond_buf 171 br i1 %cond, label %loop2, label %exit 172loop2: 173 %f = load float, float* %ptr, align 4 174 %exitcond = icmp eq i32 %nexti, %numIterations 175 br i1 %exitcond, label %exit, label %loop 176exit: 177 ret void 178} 179 180; Same thing as test-add-not-header2, except we have a few extra 181; blocks. 182define void @test-add-not-header4(float* %input, i32 %offset, i32 %numIterations) { 183; CHECK-LABEL: @test-add-not-header4 184entry: 185 br label %loop 186loop: 187 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 188 189; CHECK: %index32 = 190; CHECK: --> {%offset,+,1}<nsw> 191 %index32 = add nsw i32 %i, %offset 192 193 %ptr = getelementptr inbounds float, float* %input, i32 %index32 194 %nexti = add nsw i32 %i, 1 195 br label %loop3 196loop3: 197 br label %loop4 198loop4: 199 br label %loop2 200loop2: 201 %f = load float, float* %ptr, align 4 202 %exitcond = icmp eq i32 %nexti, %numIterations 203 br i1 %exitcond, label %exit, label %loop 204exit: 205 ret void 206} 207 208; Demonstrate why we need a Visited set in llvm::isKnownNotFullPoison. 209define void @test-add-not-header5(float* %input, i32 %offset) { 210; CHECK-LABEL: @test-add-not-header5 211entry: 212 br label %loop 213loop: 214 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 215 216; CHECK: %index32 = 217; CHECK: --> {%offset,+,1}<nw> 218 %index32 = add nsw i32 %i, %offset 219 220 %ptr = getelementptr inbounds float, float* %input, i32 %index32 221 %nexti = add nsw i32 %i, 1 222 br label %loop 223 224exit: 225 ret void 226} 227 228; The call instruction makes it not guaranteed that the add will be 229; executed, since it could run forever or throw an exception, so we 230; cannot assume that the UB is realized. 231define void @test-add-call(float* %input, i32 %offset, i32 %numIterations) { 232; CHECK-LABEL: @test-add-call 233entry: 234 br label %loop 235loop: 236 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 237 238; CHECK: %index32 = 239; CHECK: --> {%offset,+,1}<nw> 240 call void @foo() 241 %index32 = add nsw i32 %i, %offset 242 243 %ptr = getelementptr inbounds float, float* %input, i32 %index32 244 %nexti = add nsw i32 %i, 1 245 %f = load float, float* %ptr, align 4 246 %exitcond = icmp eq i32 %nexti, %numIterations 247 br i1 %exitcond, label %exit, label %loop 248exit: 249 ret void 250} 251 252; Same issue as test-add-call, but this time the call is between the 253; producer of poison and the load that consumes it. 254define void @test-add-call2(float* %input, i32 %offset, i32 %numIterations) { 255; CHECK-LABEL: @test-add-call2 256entry: 257 br label %loop 258loop: 259 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 260 261; CHECK: %index32 = 262; CHECK: --> {%offset,+,1}<nw> 263 %index32 = add nsw i32 %i, %offset 264 265 %ptr = getelementptr inbounds float, float* %input, i32 %index32 266 %nexti = add nsw i32 %i, 1 267 call void @foo() 268 %f = load float, float* %ptr, align 4 269 %exitcond = icmp eq i32 %nexti, %numIterations 270 br i1 %exitcond, label %exit, label %loop 271exit: 272 ret void 273} 274 275; Without inbounds, GEP does not propagate poison in the very 276; conservative approach used here. 277define void @test-add-no-inbounds(float* %input, i32 %offset, i32 %numIterations) { 278; CHECK-LABEL: @test-add-no-inbounds 279entry: 280 br label %loop 281loop: 282 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 283 284; CHECK: %index32 = 285; CHECK: --> {%offset,+,1}<nw> 286 %index32 = add nsw i32 %i, %offset 287 288 %ptr = getelementptr float, float* %input, i32 %index32 289 %nexti = add nsw i32 %i, 1 290 %f = load float, float* %ptr, align 4 291 %exitcond = icmp eq i32 %nexti, %numIterations 292 br i1 %exitcond, label %exit, label %loop 293exit: 294 ret void 295} 296 297; Multiplication by a non-zero constant propagates poison if there is 298; a nuw or nsw flag on the multiplication. 299define void @test-add-mul-propagates(float* %input, i32 %offset, i32 %numIterations) { 300; CHECK-LABEL: @test-add-mul-propagates 301entry: 302 br label %loop 303loop: 304 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 305 306; CHECK: %index32 = 307; CHECK: --> {%offset,+,1}<nsw> 308 %index32 = add nsw i32 %i, %offset 309 310 %indexmul = mul nuw i32 %index32, 2 311 %ptr = getelementptr inbounds float, float* %input, i32 %indexmul 312 %nexti = add nsw i32 %i, 1 313 %f = load float, float* %ptr, align 4 314 %exitcond = icmp eq i32 %nexti, %numIterations 315 br i1 %exitcond, label %exit, label %loop 316exit: 317 ret void 318} 319 320; Multiplication by a non-constant should not propagate poison in the 321; very conservative approach used here. 322define void @test-add-mul-no-propagation(float* %input, i32 %offset, i32 %numIterations) { 323; CHECK-LABEL: @test-add-mul-no-propagation 324entry: 325 br label %loop 326loop: 327 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 328 329; CHECK: %index32 = 330; CHECK: --> {%offset,+,1}<nw> 331 %index32 = add nsw i32 %i, %offset 332 333 %indexmul = mul nsw i32 %index32, %offset 334 %ptr = getelementptr inbounds float, float* %input, i32 %indexmul 335 %nexti = add nsw i32 %i, 1 336 %f = load float, float* %ptr, align 4 337 %exitcond = icmp eq i32 %nexti, %numIterations 338 br i1 %exitcond, label %exit, label %loop 339exit: 340 ret void 341} 342 343; Multiplication by a non-zero constant does not propagate poison 344; without a no-wrap flag. 345define void @test-add-mul-no-propagation2(float* %input, i32 %offset, i32 %numIterations) { 346; CHECK-LABEL: @test-add-mul-no-propagation2 347entry: 348 br label %loop 349loop: 350 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 351 352; CHECK: %index32 = 353; CHECK: --> {%offset,+,1}<nw> 354 %index32 = add nsw i32 %i, %offset 355 356 %indexmul = mul i32 %index32, 2 357 %ptr = getelementptr inbounds float, float* %input, i32 %indexmul 358 %nexti = add nsw i32 %i, 1 359 %f = load float, float* %ptr, align 4 360 %exitcond = icmp eq i32 %nexti, %numIterations 361 br i1 %exitcond, label %exit, label %loop 362exit: 363 ret void 364} 365 366; Division by poison triggers UB. 367define void @test-add-div(float* %input, i32 %offset, i32 %numIterations) { 368; CHECK-LABEL: @test-add-div 369entry: 370 br label %loop 371loop: 372 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 373 374; CHECK: %j = 375; CHECK: --> {%offset,+,1}<nsw> 376 %j = add nsw i32 %i, %offset 377 378 %q = sdiv i32 %numIterations, %j 379 %nexti = add nsw i32 %i, 1 380 %exitcond = icmp eq i32 %nexti, %numIterations 381 br i1 %exitcond, label %exit, label %loop 382exit: 383 ret void 384} 385 386; Remainder of poison by non-poison divisor does not trigger UB. 387define void @test-add-div2(float* %input, i32 %offset, i32 %numIterations) { 388; CHECK-LABEL: @test-add-div2 389entry: 390 br label %loop 391loop: 392 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 393 394; CHECK: %j = 395; CHECK: --> {%offset,+,1}<nw> 396 %j = add nsw i32 %i, %offset 397 398 %q = sdiv i32 %j, %numIterations 399 %nexti = add nsw i32 %i, 1 400 %exitcond = icmp eq i32 %nexti, %numIterations 401 br i1 %exitcond, label %exit, label %loop 402exit: 403 ret void 404} 405 406; Store to poison address triggers UB. 407define void @test-add-store(float* %input, i32 %offset, i32 %numIterations) { 408; CHECK-LABEL: @test-add-store 409entry: 410 br label %loop 411loop: 412 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 413 414; CHECK: %index32 = 415; CHECK: --> {%offset,+,1}<nsw> 416 %index32 = add nsw i32 %i, %offset 417 418 %ptr = getelementptr inbounds float, float* %input, i32 %index32 419 %nexti = add nsw i32 %i, 1 420 store float 1.0, float* %ptr, align 4 421 %exitcond = icmp eq i32 %nexti, %numIterations 422 br i1 %exitcond, label %exit, label %loop 423exit: 424 ret void 425} 426 427; Three sequential adds where the middle add should have nsw. There is 428; a special case for sequential adds and this test covers that. We have to 429; put the final add first in the program since otherwise the special case 430; is not triggered, hence the strange basic block ordering. 431define void @test-add-twice(float* %input, i32 %offset, i32 %numIterations) { 432; CHECK-LABEL: @test-add-twice 433entry: 434 br label %loop 435loop2: 436; CHECK: %seq = 437; CHECK: --> {(2 + %offset),+,1}<nw> 438 %seq = add nsw nuw i32 %index32, 1 439 %exitcond = icmp eq i32 %nexti, %numIterations 440 br i1 %exitcond, label %exit, label %loop 441 442loop: 443 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 444 445 %j = add nsw i32 %i, 1 446; CHECK: %index32 = 447; CHECK: --> {(1 + %offset)<nsw>,+,1}<nsw> 448 %index32 = add nsw i32 %j, %offset 449 450 %ptr = getelementptr inbounds float, float* %input, i32 %index32 451 %nexti = add nsw i32 %i, 1 452 store float 1.0, float* %ptr, align 4 453 br label %loop2 454exit: 455 ret void 456} 457 458; Example where a mul should get the nsw flag, so that a sext can be 459; distributed over the mul. 460define void @test-mul-nsw(float* %input, i32 %stride, i32 %numIterations) { 461; CHECK-LABEL: @test-mul-nsw 462entry: 463 br label %loop 464loop: 465 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 466 467; CHECK: %index32 = 468; CHECK: --> {0,+,%stride}<nsw> 469 %index32 = mul nsw i32 %i, %stride 470 471; CHECK: %index64 = 472; CHECK: --> {0,+,(sext i32 %stride to i64)}<nsw> 473 %index64 = sext i32 %index32 to i64 474 475 %ptr = getelementptr inbounds float, float* %input, i64 %index64 476 %nexti = add nsw i32 %i, 1 477 %f = load float, float* %ptr, align 4 478 %exitcond = icmp eq i32 %nexti, %numIterations 479 br i1 %exitcond, label %exit, label %loop 480exit: 481 ret void 482} 483 484; Example where a mul should get the nuw flag. 485define void @test-mul-nuw(float* %input, i32 %stride, i32 %numIterations) { 486; CHECK-LABEL: @test-mul-nuw 487entry: 488 br label %loop 489loop: 490 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 491 492; CHECK: %index32 = 493; CHECK: --> {0,+,%stride}<nuw> 494 %index32 = mul nuw i32 %i, %stride 495 496 %ptr = getelementptr inbounds float, float* %input, i32 %index32 497 %nexti = add nuw i32 %i, 1 498 %f = load float, float* %ptr, align 4 499 %exitcond = icmp eq i32 %nexti, %numIterations 500 br i1 %exitcond, label %exit, label %loop 501 502exit: 503 ret void 504} 505 506; Example where a shl should get the nsw flag, so that a sext can be 507; distributed over the shl. 508define void @test-shl-nsw(float* %input, i32 %start, i32 %numIterations) { 509; CHECK-LABEL: @test-shl-nsw 510entry: 511 br label %loop 512loop: 513 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] 514 515; CHECK: %index32 = 516; CHECK: --> {(256 * %start),+,256}<nsw> 517 %index32 = shl nsw i32 %i, 8 518 519; CHECK: %index64 = 520; CHECK: --> {(sext i32 (256 * %start) to i64),+,256}<nsw> 521 %index64 = sext i32 %index32 to i64 522 523 %ptr = getelementptr inbounds float, float* %input, i64 %index64 524 %nexti = add nsw i32 %i, 1 525 %f = load float, float* %ptr, align 4 526 %exitcond = icmp eq i32 %nexti, %numIterations 527 br i1 %exitcond, label %exit, label %loop 528exit: 529 ret void 530} 531 532; Example where a shl should get the nuw flag. 533define void @test-shl-nuw(float* %input, i32 %numIterations) { 534; CHECK-LABEL: @test-shl-nuw 535entry: 536 br label %loop 537loop: 538 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 539 540; CHECK: %index32 = 541; CHECK: --> {0,+,512}<nuw> 542 %index32 = shl nuw i32 %i, 9 543 544 %ptr = getelementptr inbounds float, float* %input, i32 %index32 545 %nexti = add nuw i32 %i, 1 546 %f = load float, float* %ptr, align 4 547 %exitcond = icmp eq i32 %nexti, %numIterations 548 br i1 %exitcond, label %exit, label %loop 549 550exit: 551 ret void 552} 553 554; Example where a sub should *not* get the nsw flag, because of how 555; scalar evolution represents A - B as A + (-B) and -B can wrap even 556; in cases where A - B does not. 557define void @test-sub-no-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) { 558; CHECK-LABEL: @test-sub-no-nsw 559entry: 560 br label %loop 561loop: 562 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] 563 564; CHECK: %index32 = 565; CHECK: --> {((-1 * %sub) + %start),+,1}<nw> 566 %index32 = sub nsw i32 %i, %sub 567 %index64 = sext i32 %index32 to i64 568 569 %ptr = getelementptr inbounds float, float* %input, i64 %index64 570 %nexti = add nsw i32 %i, 1 571 %f = load float, float* %ptr, align 4 572 %exitcond = icmp eq i32 %nexti, %numIterations 573 br i1 %exitcond, label %exit, label %loop 574exit: 575 ret void 576} 577 578; Example where a sub should get the nsw flag as the RHS cannot be the 579; minimal signed value. 580define void @test-sub-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) { 581; CHECK-LABEL: @test-sub-nsw 582entry: 583 %halfsub = ashr i32 %sub, 1 584 br label %loop 585loop: 586 %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] 587 588; CHECK: %index32 = 589; CHECK: --> {((-1 * %halfsub)<nsw> + %start)<nsw>,+,1}<nsw> 590 %index32 = sub nsw i32 %i, %halfsub 591 %index64 = sext i32 %index32 to i64 592 593 %ptr = getelementptr inbounds float, float* %input, i64 %index64 594 %nexti = add nsw i32 %i, 1 595 %f = load float, float* %ptr, align 4 596 %exitcond = icmp eq i32 %nexti, %numIterations 597 br i1 %exitcond, label %exit, label %loop 598exit: 599 ret void 600} 601 602; Example where a sub should get the nsw flag, since the LHS is non-negative, 603; which implies that the RHS cannot be the minimal signed value. 604define void @test-sub-nsw-lhs-non-negative(float* %input, i32 %sub, i32 %numIterations) { 605; CHECK-LABEL: @test-sub-nsw-lhs-non-negative 606entry: 607 br label %loop 608loop: 609 %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] 610 611; CHECK: %index32 = 612; CHECK: --> {(-1 * %sub),+,1}<nsw> 613 %index32 = sub nsw i32 %i, %sub 614 615; CHECK: %index64 = 616; CHECK: --> {(sext i32 (-1 * %sub) to i64),+,1}<nsw> 617 %index64 = sext i32 %index32 to i64 618 619 %ptr = getelementptr inbounds float, float* %input, i64 %index64 620 %nexti = add nsw i32 %i, 1 621 %f = load float, float* %ptr, align 4 622 %exitcond = icmp eq i32 %nexti, %numIterations 623 br i1 %exitcond, label %exit, label %loop 624exit: 625 ret void 626} 627 628; Two adds with a sub in the middle and the sub should have nsw. There is 629; a special case for sequential adds/subs and this test covers that. We have to 630; put the final add first in the program since otherwise the special case 631; is not triggered, hence the strange basic block ordering. 632define void @test-sub-with-add(float* %input, i32 %offset, i32 %numIterations) { 633; CHECK-LABEL: @test-sub-with-add 634entry: 635 br label %loop 636loop2: 637; CHECK: %seq = 638; CHECK: --> {(2 + (-1 * %offset)),+,1}<nw> 639 %seq = add nsw nuw i32 %index32, 1 640 %exitcond = icmp eq i32 %nexti, %numIterations 641 br i1 %exitcond, label %exit, label %loop 642 643loop: 644 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 645 646 %j = add nsw i32 %i, 1 647; CHECK: %index32 = 648; CHECK: --> {(1 + (-1 * %offset))<nsw>,+,1}<nsw> 649 %index32 = sub nsw i32 %j, %offset 650 651 %ptr = getelementptr inbounds float, float* %input, i32 %index32 652 %nexti = add nsw i32 %i, 1 653 store float 1.0, float* %ptr, align 4 654 br label %loop2 655exit: 656 ret void 657} 658 659 660; Subtraction of two recurrences. The addition in the SCEV that this 661; maps to is NSW, but the negation of the RHS does not since that 662; recurrence could be the most negative representable value. 663define void @subrecurrences(i32 %outer_l, i32 %inner_l, i32 %val) { 664; CHECK-LABEL: @subrecurrences 665 entry: 666 br label %outer 667 668outer: 669 %o_idx = phi i32 [ 0, %entry ], [ %o_idx.inc, %outer.be ] 670 %o_idx.inc = add nsw i32 %o_idx, 1 671 %cond = icmp eq i32 %o_idx, %val 672 br i1 %cond, label %inner, label %outer.be 673 674inner: 675 %i_idx = phi i32 [ 0, %outer ], [ %i_idx.inc, %inner ] 676 %i_idx.inc = add nsw i32 %i_idx, 1 677; CHECK: %v = 678; CHECK-NEXT: --> {{[{][{]}}-1,+,-1}<nw><%outer>,+,1}<nsw><%inner> 679 %v = sub nsw i32 %i_idx, %o_idx.inc 680 %forub = udiv i32 1, %v 681 %cond2 = icmp eq i32 %i_idx, %inner_l 682 br i1 %cond2, label %outer.be, label %inner 683 684outer.be: 685 %cond3 = icmp eq i32 %o_idx, %outer_l 686 br i1 %cond3, label %exit, label %outer 687 688exit: 689 ret void 690} 691