Skip to content

Commit

Permalink
ScalarEvolution: Construct SCEVDivision's Derived type instead of itself
Browse files Browse the repository at this point in the history
SCEVDivision::divide constructed an object of SCEVDivision<Derived>
instead of Derived.  divide would call visit which would cast the
SCEVDivision<Derived> to type Derived.  As it happens,
SCEVDivision<Derived> and Derived currently have the same layout but
this is fragile and grounds for UB.

Instead, just construct Derived.  No functional change intended.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222126 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
majnemer committed Nov 17, 2014
1 parent 8f832fc commit 2014c91
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions lib/Analysis/ScalarEvolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ struct SCEVDivision : public SCEVVisitor<Derived, void> {
const SCEV **Remainder) {
assert(Numerator && Denominator && "Uninitialized SCEV");

SCEVDivision<Derived> D(SE, Numerator, Denominator);
Derived D(SE, Numerator, Denominator);

// Check for the trivial case here to avoid having to check for it in the
// rest of the code.
Expand Down Expand Up @@ -808,17 +808,6 @@ struct SCEVDivision : public SCEVVisitor<Derived, void> {
*Remainder = D.Remainder;
}

SCEVDivision(ScalarEvolution &S, const SCEV *Numerator, const SCEV *Denominator)
: SE(S), Denominator(Denominator) {
Zero = SE.getConstant(Denominator->getType(), 0);
One = SE.getConstant(Denominator->getType(), 1);

// By default, we don't know how to divide Expr by Denominator.
// Providing the default here simplifies the rest of the code.
Quotient = Zero;
Remainder = Numerator;
}

// Except in the trivial case described above, we do not know how to divide
// Expr by Denominator for the following functions with empty implementation.
void visitTruncateExpr(const SCEVTruncateExpr *Numerator) {}
Expand Down Expand Up @@ -953,6 +942,18 @@ struct SCEVDivision : public SCEVVisitor<Derived, void> {
}

private:
SCEVDivision(ScalarEvolution &S, const SCEV *Numerator,
const SCEV *Denominator)
: SE(S), Denominator(Denominator) {
Zero = SE.getConstant(Denominator->getType(), 0);
One = SE.getConstant(Denominator->getType(), 1);

// By default, we don't know how to divide Expr by Denominator.
// Providing the default here simplifies the rest of the code.
Quotient = Zero;
Remainder = Numerator;
}

ScalarEvolution &SE;
const SCEV *Denominator, *Quotient, *Remainder, *Zero, *One;

Expand All @@ -961,6 +962,10 @@ struct SCEVDivision : public SCEVVisitor<Derived, void> {
};

struct SCEVSDivision : public SCEVDivision<SCEVSDivision> {
SCEVSDivision(ScalarEvolution &S, const SCEV *Numerator,
const SCEV *Denominator)
: SCEVDivision(S, Numerator, Denominator) {}

void visitConstant(const SCEVConstant *Numerator) {
if (const SCEVConstant *D = dyn_cast<SCEVConstant>(Denominator)) {
Quotient = SE.getConstant(sdiv(Numerator, D));
Expand All @@ -971,6 +976,10 @@ struct SCEVSDivision : public SCEVDivision<SCEVSDivision> {
};

struct SCEVUDivision : public SCEVDivision<SCEVUDivision> {
SCEVUDivision(ScalarEvolution &S, const SCEV *Numerator,
const SCEV *Denominator)
: SCEVDivision(S, Numerator, Denominator) {}

void visitConstant(const SCEVConstant *Numerator) {
if (const SCEVConstant *D = dyn_cast<SCEVConstant>(Denominator)) {
Quotient = SE.getConstant(udiv(Numerator, D));
Expand Down

0 comments on commit 2014c91

Please sign in to comment.