[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