|
2 | 2 | ; RUN: opt < %s -passes=correlated-propagation -S | FileCheck %s
|
3 | 3 |
|
4 | 4 | declare void @llvm.assume(i1)
|
| 5 | +declare i32 @llvm.abs.i32(i32, i1) |
5 | 6 | declare i8 @llvm.abs.i8(i8, i1)
|
6 | 7 | declare i1 @llvm.abs.i1(i1, i1)
|
7 | 8 |
|
@@ -379,11 +380,139 @@ define i8 @test27(i8 %x) {
|
379 | 380 |
|
380 | 381 | define i1 @pr59887(i1 %x, i1 %c) {
|
381 | 382 | ; CHECK-LABEL: @pr59887(
|
382 |
| -; CHECK-NEXT: [[ABS:%.*]] = call i1 @llvm.abs.i1(i1 [[X:%.*]], i1 false) |
383 |
| -; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i1 [[ABS]], i1 false |
| 383 | +; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i1 [[X:%.*]], i1 false |
384 | 384 | ; CHECK-NEXT: ret i1 [[RES]]
|
385 | 385 | ;
|
386 | 386 | %abs = call i1 @llvm.abs.i1(i1 %x, i1 false)
|
387 | 387 | %res = select i1 %c, i1 %abs, i1 false
|
388 | 388 | ret i1 %res
|
389 | 389 | }
|
| 390 | + |
| 391 | +; Because of `undef`, We can't delete `abs`. |
| 392 | +; We can't replace the `abs` argument with true either. |
| 393 | +define i32 @pr68381_undef_abs_false(i1 %c0, i1 %c1, i8 %v1) { |
| 394 | +; CHECK-LABEL: @pr68381_undef_abs_false( |
| 395 | +; CHECK-NEXT: start: |
| 396 | +; CHECK-NEXT: br i1 [[C0:%.*]], label [[BB0:%.*]], label [[BB1:%.*]] |
| 397 | +; CHECK: bb0: |
| 398 | +; CHECK-NEXT: [[V1_I32:%.*]] = zext i8 [[V1:%.*]] to i32 |
| 399 | +; CHECK-NEXT: br label [[BB1]] |
| 400 | +; CHECK: bb1: |
| 401 | +; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ] |
| 402 | +; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]] |
| 403 | +; CHECK: bb2: |
| 404 | +; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false) |
| 405 | +; CHECK-NEXT: ret i32 [[Z]] |
| 406 | +; |
| 407 | +start: |
| 408 | + br i1 %c0, label %bb0, label %bb1 |
| 409 | + |
| 410 | +bb0: |
| 411 | + %v1_i32 = zext i8 %v1 to i32 |
| 412 | + br label %bb1 |
| 413 | + |
| 414 | +bb1: |
| 415 | + %x = phi i32 [ %v1_i32, %bb0 ], [ undef, %start ] |
| 416 | + br i1 %c1, label %bb0, label %bb2 |
| 417 | + |
| 418 | +bb2: |
| 419 | + %z = call i32 @llvm.abs.i32(i32 %x, i1 false) |
| 420 | + ret i32 %z |
| 421 | +} |
| 422 | + |
| 423 | +; Because of `and`, we can delete `abs`. |
| 424 | +define i32 @pr68381_undef_abs_false_and(i1 %c0, i1 %c1, i8 %v1) { |
| 425 | +; CHECK-LABEL: @pr68381_undef_abs_false_and( |
| 426 | +; CHECK-NEXT: start: |
| 427 | +; CHECK-NEXT: br i1 [[C0:%.*]], label [[BB0:%.*]], label [[BB1:%.*]] |
| 428 | +; CHECK: bb0: |
| 429 | +; CHECK-NEXT: [[V1_I32:%.*]] = zext i8 [[V1:%.*]] to i32 |
| 430 | +; CHECK-NEXT: br label [[BB1]] |
| 431 | +; CHECK: bb1: |
| 432 | +; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ] |
| 433 | +; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]] |
| 434 | +; CHECK: bb2: |
| 435 | +; CHECK-NEXT: [[Y:%.*]] = and i32 [[X]], 255 |
| 436 | +; CHECK-NEXT: ret i32 [[Y]] |
| 437 | +; |
| 438 | +start: |
| 439 | + br i1 %c0, label %bb0, label %bb1 |
| 440 | + |
| 441 | +bb0: |
| 442 | + %v1_i32 = zext i8 %v1 to i32 |
| 443 | + br label %bb1 |
| 444 | + |
| 445 | +bb1: |
| 446 | + %x = phi i32 [ %v1_i32, %bb0 ], [ undef, %start ] |
| 447 | + br i1 %c1, label %bb0, label %bb2 |
| 448 | + |
| 449 | +bb2: |
| 450 | + %y = and i32 %x, 255 |
| 451 | + %z = call i32 @llvm.abs.i32(i32 %y, i1 false) |
| 452 | + ret i32 %z |
| 453 | +} |
| 454 | + |
| 455 | +; Because of `undef`, we can't replace `abs` with `sub`. |
| 456 | +define i32 @pr68381_undef_abs_false_sub(i1 %c0, i1 %c1, i32 %v1, i32 %v2) { |
| 457 | +; CHECK-LABEL: @pr68381_undef_abs_false_sub( |
| 458 | +; CHECK-NEXT: start: |
| 459 | +; CHECK-NEXT: br i1 [[C0:%.*]], label [[BB0:%.*]], label [[BB1:%.*]] |
| 460 | +; CHECK: bb0: |
| 461 | +; CHECK-NEXT: [[V3:%.*]] = add i32 [[V1:%.*]], [[V2:%.*]] |
| 462 | +; CHECK-NEXT: [[LIM:%.*]] = icmp sle i32 [[V3]], -1 |
| 463 | +; CHECK-NEXT: call void @llvm.assume(i1 [[LIM]]) |
| 464 | +; CHECK-NEXT: br label [[BB1]] |
| 465 | +; CHECK: bb1: |
| 466 | +; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V3]], [[BB0]] ], [ undef, [[START:%.*]] ] |
| 467 | +; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]] |
| 468 | +; CHECK: bb2: |
| 469 | +; CHECK-NEXT: [[Z:%.*]] = call i32 @llvm.abs.i32(i32 [[X]], i1 false) |
| 470 | +; CHECK-NEXT: ret i32 [[Z]] |
| 471 | +; |
| 472 | +start: |
| 473 | + br i1 %c0, label %bb0, label %bb1 |
| 474 | + |
| 475 | +bb0: |
| 476 | + %v3 = add i32 %v1, %v2 |
| 477 | + %lim = icmp sle i32 %v3, -1 |
| 478 | + call void @llvm.assume(i1 %lim) |
| 479 | + br label %bb1 |
| 480 | + |
| 481 | +bb1: |
| 482 | + %x = phi i32 [ %v3, %bb0 ], [ undef, %start ] |
| 483 | + br i1 %c1, label %bb0, label %bb2 |
| 484 | + |
| 485 | +bb2: |
| 486 | + %z = call i32 @llvm.abs.i32(i32 %x, i1 false) |
| 487 | + ret i32 %z |
| 488 | +} |
| 489 | + |
| 490 | +; We can delete `abs`. |
| 491 | +define i32 @pr68381_undef_abs_true(i1 %c0, i1 %c1, i8 %v1) { |
| 492 | +; CHECK-LABEL: @pr68381_undef_abs_true( |
| 493 | +; CHECK-NEXT: start: |
| 494 | +; CHECK-NEXT: br i1 [[C0:%.*]], label [[BB0:%.*]], label [[BB1:%.*]] |
| 495 | +; CHECK: bb0: |
| 496 | +; CHECK-NEXT: [[V1_I32:%.*]] = zext i8 [[V1:%.*]] to i32 |
| 497 | +; CHECK-NEXT: br label [[BB1]] |
| 498 | +; CHECK: bb1: |
| 499 | +; CHECK-NEXT: [[X:%.*]] = phi i32 [ [[V1_I32]], [[BB0]] ], [ undef, [[START:%.*]] ] |
| 500 | +; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB0]], label [[BB2:%.*]] |
| 501 | +; CHECK: bb2: |
| 502 | +; CHECK-NEXT: ret i32 [[X]] |
| 503 | +; |
| 504 | +start: |
| 505 | + br i1 %c0, label %bb0, label %bb1 |
| 506 | + |
| 507 | +bb0: |
| 508 | + %v1_i32 = zext i8 %v1 to i32 |
| 509 | + br label %bb1 |
| 510 | + |
| 511 | +bb1: |
| 512 | + %x = phi i32 [ %v1_i32, %bb0 ], [ undef, %start ] |
| 513 | + br i1 %c1, label %bb0, label %bb2 |
| 514 | + |
| 515 | +bb2: |
| 516 | + %z = call i32 @llvm.abs.i32(i32 %x, i1 true) |
| 517 | + ret i32 %z |
| 518 | +} |
0 commit comments