Skip to content

Commit 1eb0659

Browse files
committed
[TSAR, Memory] Fix SCEV comparison.
1 parent b129553 commit 1eb0659

File tree

1 file changed

+45
-3
lines changed

1 file changed

+45
-3
lines changed

lib/Support/SCEVUtils.cpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -714,16 +714,58 @@ const SCEV *evaluateAtIteration(const SCEVAddRecExpr *ARE, const SCEV *It,
714714
return S;
715715
}
716716

717-
Optional<int64_t> compareSCEVs(const SCEV *LHS,
718-
const SCEV *RHS,
717+
Optional<int64_t> compareSCEVs(const SCEV *LHS, const SCEV *RHS,
719718
ScalarEvolution *SE) {
720719
assert(SE && "ScalarEvolution must be specified!");
721720
assert(LHS && RHS && "SCEV must be specified!");
722721
TypeQueue TQLHS, TQRHS;
723722
auto InnerLHS = getTypeQueue(TQLHS, LHS);
724723
auto InnerRHS = getTypeQueue(TQRHS, RHS);
725-
if (TQLHS != TQRHS)
724+
if (TQLHS != TQRHS) {
725+
// For cases like LHS = { zext(%v) - Const1 }, RHS = { zext(%v - Const2) }
726+
// TODO ([email protected]): can we extend this check for sext?
727+
if (isa<SCEVZeroExtendExpr>(LHS) && isa<SCEVAddExpr>(RHS) ||
728+
isa<SCEVAddExpr>(LHS) && isa<SCEVZeroExtendExpr>(RHS)) {
729+
int SwapMult = 1;
730+
auto First{LHS}, Second{RHS};
731+
// Let the first SCEV be of kind { zext(%v) - Const1 } and the second
732+
// be of kind { zext(%v - Const2) }.
733+
if (isa<SCEVZeroExtendExpr>(LHS) && isa<SCEVAddExpr>(RHS)) {
734+
std::swap(First, Second);
735+
SwapMult = -1;
736+
}
737+
auto *FirstAdd = cast<SCEVAddExpr>(First);
738+
auto *FirstOp0 = FirstAdd->getOperand(0);
739+
auto *FirstOp1 = FirstAdd->getOperand(1);
740+
// Let the first operand always be a non-constant value.
741+
if (isa<SCEVConstant>(FirstOp0))
742+
std::swap(FirstOp0, FirstOp1);
743+
auto *FirstCast = dyn_cast<SCEVZeroExtendExpr>(FirstOp0);
744+
if (!FirstCast)
745+
return None;
746+
auto *FirstVar = FirstCast->getOperand();
747+
if (!isa<SCEVUnknown>(FirstVar))
748+
return None;
749+
auto *SecondCast = dyn_cast<SCEVZeroExtendExpr>(Second);
750+
if (!SecondCast || !isa<SCEVAddExpr>(SecondCast->getOperand()))
751+
return None;
752+
auto *SecondAdd = cast<SCEVAddExpr>(SecondCast->getOperand());
753+
auto *SecondOp0 = SecondAdd->getOperand(0);
754+
auto *SecondOp1 = SecondAdd->getOperand(1);
755+
if (isa<SCEVConstant>(SecondOp0))
756+
std::swap(SecondOp0, SecondOp1);
757+
if (!isa<SCEVUnknown>(SecondOp0))
758+
return None;
759+
auto FirstVarVal = cast<SCEVUnknown>(FirstVar)->getValue();
760+
auto FirstConst = cast<SCEVConstant>(FirstOp1)->getAPInt().getSExtValue();
761+
auto SecondVarVal = cast<SCEVUnknown>(SecondOp0)->getValue();
762+
auto SecondConst =
763+
cast<SCEVConstant>(SecondOp1)->getAPInt().getSExtValue();
764+
if (FirstVarVal == SecondVarVal)
765+
return (FirstConst - SecondConst) * SwapMult;
766+
}
726767
return None;
768+
}
727769
if (auto Const = llvm::dyn_cast<llvm::SCEVConstant>(
728770
SE->getMinusSCEV(InnerLHS, InnerRHS)))
729771
return Const->getAPInt().getSExtValue();

0 commit comments

Comments
 (0)