1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00

[SCEV] Compute ranges for ashr recurrences

Straight forward extension to the recently added infrastructure which was pioneered with shl. This was originally posted as part of D99687, but split off for ease of review.

(I also decided to exclude the unknown start sign case explicitly for simplicity of understanding.)

Differential Revision: https://reviews.llvm.org/D101181
This commit is contained in:
Philip Reames 2021-04-28 12:35:22 -07:00
parent 939b677f1c
commit cf98cdf20e
2 changed files with 27 additions and 5 deletions

View File

@ -5692,10 +5692,11 @@ getRangeForUnknownRecurrence(const SCEVUnknown *U) {
// until the caller issue can be fixed. PR49566 tracks the bug.
return CR;
// TODO: Extend to other opcodes such as ashr, mul, and div
// TODO: Extend to other opcodes such as mul, and div
switch (BO->getOpcode()) {
default:
return CR;
case Instruction::AShr:
case Instruction::LShr:
case Instruction::Shl:
break;
@ -5725,6 +5726,27 @@ getRangeForUnknownRecurrence(const SCEVUnknown *U) {
switch (BO->getOpcode()) {
default:
llvm_unreachable("filtered out above");
case Instruction::AShr: {
// For each ashr, three cases:
// shift = 0 => unchanged value
// saturation => 0 or -1
// other => a value closer to zero (of the same sign)
// Thus, the end value is closer to zero than the start.
auto KnownEnd = KnownBits::ashr(KnownStart,
KnownBits::makeConstant(TotalShift));
if (KnownStart.isNonNegative()) {
// Analogous to lshr (simply not yet canonicalized)
auto R = ConstantRange::getNonEmpty(KnownEnd.getMinValue(),
KnownStart.getMaxValue() + 1);
CR = CR.intersectWith(R);
} else if (KnownStart.isNegative()) {
// End >=u Start && End <=s Start
auto R = ConstantRange::getNonEmpty(KnownStart.getMinValue(),
KnownEnd.getMaxValue() + 1);
CR = CR.intersectWith(R);
}
break;
}
case Instruction::LShr: {
// For each lshr, three cases:
// shift = 0 => unchanged value

View File

@ -503,7 +503,7 @@ define void @test_ashr_tc_positive() {
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,5) S: [0,5) Exits: 4 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.ashr = phi i64 [ 1023, %entry ], [ %iv.ashr.next, %loop ]
; CHECK-NEXT: --> %iv.ashr U: [0,1024) S: [0,1024) Exits: 63 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: --> %iv.ashr U: [63,1024) S: [63,1024) Exits: 63 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.next = add i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,6) S: [1,6) Exits: 5 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.ashr.next = ashr i64 %iv.ashr, 1
@ -534,7 +534,7 @@ define void @test_ashr_tc_negative() {
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,5) S: [0,5) Exits: 4 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.ashr = phi i8 [ -128, %entry ], [ %iv.ashr.next, %loop ]
; CHECK-NEXT: --> %iv.ashr U: [-128,0) S: [-128,0) Exits: -8 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: --> %iv.ashr U: [-128,-7) S: [-128,-7) Exits: -8 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.next = add i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,6) S: [1,6) Exits: 5 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.ashr.next = ashr i8 %iv.ashr, 1
@ -599,11 +599,11 @@ define void @test_ashr_zero_shift() {
; CHECK-NEXT: %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,5) S: [0,5) Exits: 4 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.ashr = phi i64 [ 1023, %entry ], [ %iv.ashr.next, %loop ]
; CHECK-NEXT: --> %iv.ashr U: [0,1024) S: [0,1024) Exits: 1023 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: --> %iv.ashr U: [1023,1024) S: [1023,1024) Exits: 1023 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: %iv.next = add i64 %iv, 1
; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,6) S: [1,6) Exits: 5 LoopDispositions: { %loop: Computable }
; CHECK-NEXT: %iv.ashr.next = ashr i64 %iv.ashr, 0
; CHECK-NEXT: --> %iv.ashr U: [0,1024) S: [0,1024) Exits: 1023 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: --> %iv.ashr U: [1023,1024) S: [1023,1024) Exits: 1023 LoopDispositions: { %loop: Variant }
; CHECK-NEXT: Determining loop execution counts for: @test_ashr_zero_shift
; CHECK-NEXT: Loop %loop: backedge-taken count is 4
; CHECK-NEXT: Loop %loop: max backedge-taken count is 4