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 7 define 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. 13 define void @test-add-nsw(float* %input, i32 %offset, i32 %numIterations) { 14 ; CHECK-LABEL: @test-add-nsw 15 entry: 16 br label %loop 17 loop: 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 34 exit: 35 ret void 36 } 37 38 ; Example where an add should get the nuw flag. 39 define void @test-add-nuw(float* %input, i32 %offset, i32 %numIterations) { 40 ; CHECK-LABEL: @test-add-nuw 41 entry: 42 br label %loop 43 loop: 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 56 exit: 57 ret void 58 } 59 60 define void @test-add-nuw-from-icmp(float* %input, i32 %offset, 61 i32 %numIterations) { 62 ; CHECK-LABEL: @test-add-nuw-from-icmp 63 entry: 64 br label %loop 65 loop: 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 80 exit: 81 ret void 82 } 83 84 ; With no load to trigger UB from poison, we cannot infer nsw. 85 define void @test-add-no-load(float* %input, i32 %offset, i32 %numIterations) { 86 ; CHECK-LABEL: @test-add-no-load 87 entry: 88 br label %loop 89 loop: 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 101 exit: 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. 108 define void @test-add-not-header(float* %input, i32 %offset, i32 %numIterations) { 109 ; CHECK-LABEL: @test-add-not-header 110 entry: 111 br label %loop 112 loop: 113 %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] 114 br label %loop2 115 loop2: 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 126 exit: 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. 132 define void @test-add-not-header2(float* %input, i32 %offset, i32 %numIterations) { 133 ; CHECK-LABEL: @test-add-not-header2 134 entry: 135 br label %loop 136 loop: 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 146 loop2: 147 %f = load float, float* %ptr, align 4 148 %exitcond = icmp eq i32 %nexti, %numIterations 149 br i1 %exitcond, label %exit, label %loop 150 exit: 151 ret void 152 } 153 154 ; Similar to test-add-not-header, but in this case the load 155 ; instruction may not be executed. 156 define void @test-add-not-header3(float* %input, i32 %offset, i32 %numIterations, 157 i1* %cond_buf) { 158 ; CHECK-LABEL: @test-add-not-header3 159 entry: 160 br label %loop 161 loop: 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 172 loop2: 173 %f = load float, float* %ptr, align 4 174 %exitcond = icmp eq i32 %nexti, %numIterations 175 br i1 %exitcond, label %exit, label %loop 176 exit: 177 ret void 178 } 179 180 ; Same thing as test-add-not-header2, except we have a few extra 181 ; blocks. 182 define void @test-add-not-header4(float* %input, i32 %offset, i32 %numIterations) { 183 ; CHECK-LABEL: @test-add-not-header4 184 entry: 185 br label %loop 186 loop: 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 196 loop3: 197 br label %loop4 198 loop4: 199 br label %loop2 200 loop2: 201 %f = load float, float* %ptr, align 4 202 %exitcond = icmp eq i32 %nexti, %numIterations 203 br i1 %exitcond, label %exit, label %loop 204 exit: 205 ret void 206 } 207 208 ; Demonstrate why we need a Visited set in llvm::isKnownNotFullPoison. 209 define void @test-add-not-header5(float* %input, i32 %offset) { 210 ; CHECK-LABEL: @test-add-not-header5 211 entry: 212 br label %loop 213 loop: 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 224 exit: 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. 231 define void @test-add-call(float* %input, i32 %offset, i32 %numIterations) { 232 ; CHECK-LABEL: @test-add-call 233 entry: 234 br label %loop 235 loop: 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 248 exit: 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. 254 define void @test-add-call2(float* %input, i32 %offset, i32 %numIterations) { 255 ; CHECK-LABEL: @test-add-call2 256 entry: 257 br label %loop 258 loop: 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 271 exit: 272 ret void 273 } 274 275 ; Without inbounds, GEP does not propagate poison in the very 276 ; conservative approach used here. 277 define void @test-add-no-inbounds(float* %input, i32 %offset, i32 %numIterations) { 278 ; CHECK-LABEL: @test-add-no-inbounds 279 entry: 280 br label %loop 281 loop: 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 293 exit: 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. 299 define void @test-add-mul-propagates(float* %input, i32 %offset, i32 %numIterations) { 300 ; CHECK-LABEL: @test-add-mul-propagates 301 entry: 302 br label %loop 303 loop: 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 316 exit: 317 ret void 318 } 319 320 ; Multiplication by a non-constant should not propagate poison in the 321 ; very conservative approach used here. 322 define void @test-add-mul-no-propagation(float* %input, i32 %offset, i32 %numIterations) { 323 ; CHECK-LABEL: @test-add-mul-no-propagation 324 entry: 325 br label %loop 326 loop: 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 339 exit: 340 ret void 341 } 342 343 ; Multiplication by a non-zero constant does not propagate poison 344 ; without a no-wrap flag. 345 define void @test-add-mul-no-propagation2(float* %input, i32 %offset, i32 %numIterations) { 346 ; CHECK-LABEL: @test-add-mul-no-propagation2 347 entry: 348 br label %loop 349 loop: 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 362 exit: 363 ret void 364 } 365 366 ; Division by poison triggers UB. 367 define void @test-add-div(float* %input, i32 %offset, i32 %numIterations) { 368 ; CHECK-LABEL: @test-add-div 369 entry: 370 br label %loop 371 loop: 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 382 exit: 383 ret void 384 } 385 386 ; Remainder of poison by non-poison divisor does not trigger UB. 387 define void @test-add-div2(float* %input, i32 %offset, i32 %numIterations) { 388 ; CHECK-LABEL: @test-add-div2 389 entry: 390 br label %loop 391 loop: 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 402 exit: 403 ret void 404 } 405 406 ; Store to poison address triggers UB. 407 define void @test-add-store(float* %input, i32 %offset, i32 %numIterations) { 408 ; CHECK-LABEL: @test-add-store 409 entry: 410 br label %loop 411 loop: 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 423 exit: 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. 431 define void @test-add-twice(float* %input, i32 %offset, i32 %numIterations) { 432 ; CHECK-LABEL: @test-add-twice 433 entry: 434 br label %loop 435 loop2: 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 442 loop: 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 454 exit: 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. 460 define void @test-mul-nsw(float* %input, i32 %stride, i32 %numIterations) { 461 ; CHECK-LABEL: @test-mul-nsw 462 entry: 463 br label %loop 464 loop: 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 480 exit: 481 ret void 482 } 483 484 ; Example where a mul should get the nuw flag. 485 define void @test-mul-nuw(float* %input, i32 %stride, i32 %numIterations) { 486 ; CHECK-LABEL: @test-mul-nuw 487 entry: 488 br label %loop 489 loop: 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 502 exit: 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. 508 define void @test-shl-nsw(float* %input, i32 %start, i32 %numIterations) { 509 ; CHECK-LABEL: @test-shl-nsw 510 entry: 511 br label %loop 512 loop: 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 528 exit: 529 ret void 530 } 531 532 ; Example where a shl should get the nuw flag. 533 define void @test-shl-nuw(float* %input, i32 %numIterations) { 534 ; CHECK-LABEL: @test-shl-nuw 535 entry: 536 br label %loop 537 loop: 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 550 exit: 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. 557 define void @test-sub-no-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) { 558 ; CHECK-LABEL: @test-sub-no-nsw 559 entry: 560 br label %loop 561 loop: 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 574 exit: 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. 580 define void @test-sub-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) { 581 ; CHECK-LABEL: @test-sub-nsw 582 entry: 583 %halfsub = ashr i32 %sub, 1 584 br label %loop 585 loop: 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 598 exit: 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. 604 define void @test-sub-nsw-lhs-non-negative(float* %input, i32 %sub, i32 %numIterations) { 605 ; CHECK-LABEL: @test-sub-nsw-lhs-non-negative 606 entry: 607 br label %loop 608 loop: 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 624 exit: 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. 632 define void @test-sub-with-add(float* %input, i32 %offset, i32 %numIterations) { 633 ; CHECK-LABEL: @test-sub-with-add 634 entry: 635 br label %loop 636 loop2: 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 643 loop: 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 655 exit: 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. 663 define void @subrecurrences(i32 %outer_l, i32 %inner_l, i32 %val) { 664 ; CHECK-LABEL: @subrecurrences 665 entry: 666 br label %outer 667 668 outer: 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 674 inner: 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 684 outer.be: 685 %cond3 = icmp eq i32 %o_idx, %outer_l 686 br i1 %cond3, label %exit, label %outer 687 688 exit: 689 ret void 690 } 691