diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 52 | ||||
| -rw-r--r-- | llvm/test/Analysis/ScalarEvolution/2007-09-06-Unsigned.ll | 29 | 
2 files changed, 64 insertions, 17 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 879347f7f72..31facd182a7 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -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"; diff --git a/llvm/test/Analysis/ScalarEvolution/2007-09-06-Unsigned.ll b/llvm/test/Analysis/ScalarEvolution/2007-09-06-Unsigned.ll new file mode 100644 index 00000000000..1b8dc4dfaae --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/2007-09-06-Unsigned.ll @@ -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 +}  | 

