ScalarEvolution: Construct SCEVDivision's Derived type instead of itself
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 17 Nov 2014 11:27:45 +0000 (11:27 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 17 Nov 2014 11:27:45 +0000 (11:27 +0000)
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.

llvm-svn: 222126

llvm/lib/Analysis/ScalarEvolution.cpp

index 4a6d028..3877f9c 100644 (file)
@@ -767,7 +767,7 @@ public:
                      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.
@@ -808,17 +808,6 @@ public:
     *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) {}
@@ -953,6 +942,18 @@ public:
   }
 
 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;
 
@@ -961,6 +962,10 @@ private:
 };
 
 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));
@@ -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));