[llvm-commits] [llvm] r72250 - in /llvm/trunk: lib/Analysis/ScalarEvolutionExpander.cpp test/Transforms/IndVarSimplify/gep-with-mul-base.ll

Dan Gohman gohman at apple.com
Fri May 22 00:14:21 PDT 2009


Author: djg
Date: Fri May 22 02:14:20 2009
New Revision: 72250

URL: http://llvm.org/viewvc/llvm-project?rev=72250&view=rev
Log:
Fix a thinko in the code that adapted SCEVMulExpr operands for
use in expanding SCEVAddExprs with GEPs. The operands of a
SCEVMulExpr need to be multiplied together, not added.

Added:
    llvm/trunk/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
Modified:
    llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp

Modified: llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp?rev=72250&r1=72249&r2=72250&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp (original)
+++ llvm/trunk/lib/Analysis/ScalarEvolutionExpander.cpp Fri May 22 02:14:20 2009
@@ -168,6 +168,8 @@
     std::vector<SCEVHandle> ScaledOps;
     for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
       if (ElSize != 0) {
+        // For a Constant, check for a multiple of the pointer type's
+        // scale size.
         if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Ops[i]))
           if (!C->getValue()->getValue().srem(ElSize)) {
             ConstantInt *CI =
@@ -176,13 +178,19 @@
             ScaledOps.push_back(Div);
             continue;
           }
+        // In a Mul, check if there is a constant operand which is a multiple
+        // of the pointer type's scale size.
         if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(Ops[i]))
           if (const SCEVConstant *C = dyn_cast<SCEVConstant>(M->getOperand(0)))
-            if (C->getValue()->getValue() == ElSize) {
-              for (unsigned j = 1, f = M->getNumOperands(); j != f; ++j)
-                ScaledOps.push_back(M->getOperand(j));
+            if (!C->getValue()->getValue().srem(ElSize)) {
+              std::vector<SCEVHandle> NewMulOps(M->getOperands());
+              NewMulOps[0] =
+                SE.getConstant(C->getValue()->getValue().sdiv(ElSize));
+              ScaledOps.push_back(SE.getMulExpr(NewMulOps));
               continue;
             }
+        // In an Unknown, check if the underlying value is a Mul by a constant
+        // which is equal to the pointer type's scale size.
         if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(Ops[i]))
           if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U->getValue()))
             if (BO->getOpcode() == Instruction::Mul)
@@ -191,6 +199,8 @@
                   ScaledOps.push_back(SE.getUnknown(BO->getOperand(0)));
                   continue;
                 }
+        // If the pointer type's scale size is 1, no scaling is necessary
+        // and any value can be used.
         if (ElSize == 1) {
           ScaledOps.push_back(Ops[i]);
           continue;

Added: llvm/trunk/test/Transforms/IndVarSimplify/gep-with-mul-base.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/gep-with-mul-base.ll?rev=72250&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/gep-with-mul-base.ll (added)
+++ llvm/trunk/test/Transforms/IndVarSimplify/gep-with-mul-base.ll Fri May 22 02:14:20 2009
@@ -0,0 +1,58 @@
+; RUN: llvm-as < %s | opt -indvars | llvm-dis > %t
+; RUN: grep add %t | count 8
+; RUN: grep mul %t | count 9
+
+define void @foo(i64 %n, i64 %m, i64 %o, double* nocapture %p) nounwind {
+entry:
+	%tmp = icmp sgt i64 %n, 0		; <i1> [#uses=1]
+	br i1 %tmp, label %bb.nph, label %return
+
+bb.nph:		; preds = %entry
+	%tmp1 = mul i64 %n, 37		; <i64> [#uses=1]
+	%tmp2 = mul i64 %tmp1, %m		; <i64> [#uses=1]
+	%tmp3 = mul i64 %tmp2, %o		; <i64> [#uses=1]
+	br label %bb
+
+bb:		; preds = %bb, %bb.nph
+	%i.01 = phi i64 [ %tmp3, %bb.nph ], [ %tmp13, %bb ]		; <i64> [#uses=3]
+	%tmp9 = getelementptr double* %p, i64 %i.01		; <double*> [#uses=1]
+	%tmp10 = load double* %tmp9, align 8		; <double> [#uses=1]
+	%tmp11 = fdiv double %tmp10, 2.100000e+00		; <double> [#uses=1]
+	store double %tmp11, double* %tmp9, align 8
+	%tmp13 = add i64 %i.01, 1		; <i64> [#uses=2]
+	%tmp14 = icmp slt i64 %tmp13, %n		; <i1> [#uses=1]
+	br i1 %tmp14, label %bb, label %return.loopexit
+
+return.loopexit:		; preds = %bb
+	br label %return
+
+return:		; preds = %return.loopexit, %entry
+	ret void
+}
+define void @bar(i64 %n, i64 %m, i64 %o, i64 %q, double* nocapture %p) nounwind {
+entry:
+	%tmp = icmp sgt i64 %n, 0		; <i1> [#uses=1]
+	br i1 %tmp, label %bb.nph, label %return
+
+bb.nph:		; preds = %entry
+	%tmp1 = mul i64 %n, %q		; <i64> [#uses=1]
+	%tmp2 = mul i64 %tmp1, %m		; <i64> [#uses=1]
+	%tmp3 = mul i64 %tmp2, %o		; <i64> [#uses=1]
+	br label %bb
+
+bb:		; preds = %bb, %bb.nph
+	%i.01 = phi i64 [ %tmp3, %bb.nph ], [ %tmp13, %bb ]		; <i64> [#uses=3]
+	%tmp9 = getelementptr double* %p, i64 %i.01		; <double*> [#uses=1]
+	%tmp10 = load double* %tmp9, align 8		; <double> [#uses=1]
+	%tmp11 = fdiv double %tmp10, 2.100000e+00		; <double> [#uses=1]
+	store double %tmp11, double* %tmp9, align 8
+	%tmp13 = add i64 %i.01, 1		; <i64> [#uses=2]
+	%tmp14 = icmp slt i64 %tmp13, %n		; <i1> [#uses=1]
+	br i1 %tmp14, label %bb, label %return.loopexit
+
+return.loopexit:		; preds = %bb
+	br label %return
+
+return:		; preds = %return.loopexit, %entry
+	ret void
+}





More information about the llvm-commits mailing list