mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
Fix for PR2607: SCEV miscomputing the loop count for loops with an
SGT exit condition. Essentially, the correct way to flip an inequality in 2's complement is the not operator, not the negation operator. That said, the difference only affects cases involving INT_MIN. Also, enhance the pre-test search logic to be a bit smarter about inequalities flipped with a not operator, so it can eliminate the smax from the iteration count for simple loops. llvm-svn: 54184
This commit is contained in:
parent
ab575176fc
commit
81169f2e1b
@ -1976,8 +1976,8 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
|
||||
break;
|
||||
}
|
||||
case ICmpInst::ICMP_SGT: {
|
||||
SCEVHandle TC = HowManyLessThans(SE.getNegativeSCEV(LHS),
|
||||
SE.getNegativeSCEV(RHS), L, true);
|
||||
SCEVHandle TC = HowManyLessThans(SE.getNotSCEV(LHS),
|
||||
SE.getNotSCEV(RHS), L, true);
|
||||
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
|
||||
break;
|
||||
}
|
||||
@ -2724,7 +2724,11 @@ bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool isSigned,
|
||||
|
||||
if (!PreCondLHS->getType()->isInteger()) return false;
|
||||
|
||||
return LHS == getSCEV(PreCondLHS) && RHS == getSCEV(PreCondRHS);
|
||||
SCEVHandle PreCondLHSSCEV = getSCEV(PreCondLHS);
|
||||
SCEVHandle PreCondRHSSCEV = getSCEV(PreCondRHS);
|
||||
return (LHS == PreCondLHSSCEV && RHS == PreCondRHSSCEV) ||
|
||||
(LHS == SE.getNotSCEV(PreCondRHSSCEV) &&
|
||||
RHS == SE.getNotSCEV(PreCondLHSSCEV));
|
||||
}
|
||||
|
||||
/// HowManyLessThans - Return the number of times a backedge containing the
|
||||
|
27
test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll
Normal file
27
test/Analysis/ScalarEvolution/2008-07-29-SGTTripCount.ll
Normal file
@ -0,0 +1,27 @@
|
||||
; RUN: llvm-as < %s | opt -analyze -scalar-evolution -disable-output \
|
||||
; RUN: -scalar-evolution-max-iterations=0 | \
|
||||
; RUN: grep -F "( -1 + ( -1 * %j)) iterations"
|
||||
; PR2607
|
||||
|
||||
define i32 @_Z1aj(i32 %j) nounwind {
|
||||
entry:
|
||||
icmp sgt i32 0, %j ; <i1>:0 [#uses=1]
|
||||
br i1 %0, label %bb.preheader, label %return
|
||||
|
||||
bb.preheader: ; preds = %entry
|
||||
br label %bb
|
||||
|
||||
bb: ; preds = %bb, %bb.preheader
|
||||
%i.01 = phi i32 [ %1, %bb ], [ 0, %bb.preheader ] ; <i32> [#uses=1]
|
||||
add i32 %i.01, -1 ; <i32>:1 [#uses=3]
|
||||
icmp sgt i32 %1, %j ; <i1>:2 [#uses=1]
|
||||
br i1 %2, label %bb, label %return.loopexit
|
||||
|
||||
return.loopexit: ; preds = %bb
|
||||
br label %return
|
||||
|
||||
return: ; preds = %return.loopexit, %entry
|
||||
%i.0.lcssa = phi i32 [ 0, %entry ], [ %1, %return.loopexit ] ; <i32> [#uses=1]
|
||||
ret i32 %i.0.lcssa
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user