Let scalar-evolution analyze loops with an unsigned comparison for the exit

condition. Fixes 1597.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40867 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky 2007-08-06 19:21:00 +00:00
parent 06323bfe03
commit d6dac0eebc
2 changed files with 64 additions and 17 deletions

View File

@ -1220,8 +1220,9 @@ namespace {
/// HowManyLessThans - Return the number of times a backedge containing the
/// specified less-than comparison will execute. If not computable, return
/// UnknownValue.
SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L);
/// UnknownValue. isSigned specifies whether the less-than is signed.
SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L,
bool isSigned);
/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
/// in the header of its containing loop, we know the loop executes a
@ -1690,13 +1691,24 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
break;
}
case ICmpInst::ICMP_SLT: {
SCEVHandle TC = HowManyLessThans(LHS, RHS, L);
SCEVHandle TC = HowManyLessThans(LHS, RHS, L, true);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
break;
}
case ICmpInst::ICMP_SGT: {
SCEVHandle TC = HowManyLessThans(SCEV::getNegativeSCEV(LHS),
SCEV::getNegativeSCEV(RHS), L);
SCEV::getNegativeSCEV(RHS), L, true);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
break;
}
case ICmpInst::ICMP_ULT: {
SCEVHandle TC = HowManyLessThans(LHS, RHS, L, false);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
break;
}
case ICmpInst::ICMP_UGT: {
SCEVHandle TC = HowManyLessThans(SCEV::getNegativeSCEV(LHS),
SCEV::getNegativeSCEV(RHS), L, false);
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
break;
}
@ -2310,7 +2322,7 @@ SCEVHandle ScalarEvolutionsImpl::HowFarToNonZero(SCEV *V, const Loop *L) {
/// specified less-than comparison will execute. If not computable, return
/// UnknownValue.
SCEVHandle ScalarEvolutionsImpl::
HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L) {
HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool isSigned) {
// Only handle: "ADDREC < LoopInvariant".
if (!RHS->isLoopInvariant(L)) return UnknownValue;
@ -2367,28 +2379,34 @@ HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L) {
switch (Cond) {
case ICmpInst::ICMP_UGT:
if (isSigned) return UnknownValue;
std::swap(PreCondLHS, PreCondRHS);
Cond = ICmpInst::ICMP_ULT;
break;
case ICmpInst::ICMP_SGT:
if (!isSigned) return UnknownValue;
std::swap(PreCondLHS, PreCondRHS);
Cond = ICmpInst::ICMP_SLT;
break;
default: break;
case ICmpInst::ICMP_ULT:
if (isSigned) return UnknownValue;
break;
case ICmpInst::ICMP_SLT:
if (!isSigned) return UnknownValue;
break;
default:
return UnknownValue;
}
if (Cond == ICmpInst::ICMP_SLT) {
if (PreCondLHS->getType()->isInteger()) {
if (RHS != getSCEV(PreCondRHS))
return UnknownValue; // Not a comparison against 'm'.
if (PreCondLHS->getType()->isInteger()) {
if (RHS != getSCEV(PreCondRHS))
return UnknownValue; // Not a comparison against 'm'.
if (SCEV::getMinusSCEV(AddRec->getOperand(0), One)
!= getSCEV(PreCondLHS))
return UnknownValue; // Not a comparison against 'n-1'.
}
else return UnknownValue;
} else
return UnknownValue;
if (SCEV::getMinusSCEV(AddRec->getOperand(0), One)
!= getSCEV(PreCondLHS))
return UnknownValue; // Not a comparison against 'n-1'.
}
else return UnknownValue;
// cerr << "Computed Loop Trip Count as: "
// << // *SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n";

View File

@ -0,0 +1,29 @@
; RUN: llvm-as < %s | opt -scalar-evolution -analyze |& grep "Loop bb: ( -1 + ( -1 * %x) + %y) iterations!"
define i32 @f(i32 %x, i32 %y) {
entry:
%tmp63 = icmp ult i32 %x, %y ; <i1> [#uses=1]
br i1 %tmp63, label %bb.preheader, label %bb8
bb.preheader: ; preds = %entry
br label %bb
bb: ; preds = %bb3, %bb.preheader
%x_addr.0 = phi i32 [ %tmp2, %bb3 ], [ %x, %bb.preheader ] ; <i32> [#uses=1]
%tmp2 = add i32 %x_addr.0, 1 ; <i32> [#uses=3]
br label %bb3
bb3: ; preds = %bb
%tmp6 = icmp ult i32 %tmp2, %y ; <i1> [#uses=1]
br i1 %tmp6, label %bb, label %bb8.loopexit
bb8.loopexit: ; preds = %bb3
br label %bb8
bb8: ; preds = %bb8.loopexit, %entry
%x_addr.1 = phi i32 [ %x, %entry ], [ %tmp2, %bb8.loopexit ] ; <i32> [#uses=1]
br label %return
return: ; preds = %bb8
ret i32 %x_addr.1
}