[llvm] r248107 - [IndVars] Fix a bug in r248045.
Sanjoy Das via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 19 18:52:19 PDT 2015
Author: sanjoy
Date: Sat Sep 19 20:52:18 2015
New Revision: 248107
URL: http://llvm.org/viewvc/llvm-project?rev=248107&view=rev
Log:
[IndVars] Fix a bug in r248045.
Because -indvars widens induction variables through arithmetic,
`NeverNegative` cannot be a property of the `WidenIV` (a `WidenIV`
manages information for all transitive uses of an IV being widened,
including uses of `-1 * IV`). Instead it must live on `NarrowIVDefUse`
which manages information for a specific def-use edge in the transitive
use list of an induction variable.
This change also adds a test case that demonstrates the problem with
r248045.
Modified:
llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll
Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=248107&r1=248106&r2=248107&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Sat Sep 19 20:52:18 2015
@@ -832,10 +832,19 @@ struct NarrowIVDefUse {
Instruction *NarrowUse;
Instruction *WideDef;
- NarrowIVDefUse(): NarrowDef(nullptr), NarrowUse(nullptr), WideDef(nullptr) {}
+ // True if the narrow def is never negative. Tracking this information lets
+ // us use a sign extension instead of a zero extension or vice versa, when
+ // profitable and legal.
+ bool NeverNegative;
- NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD):
- NarrowDef(ND), NarrowUse(NU), WideDef(WD) {}
+ NarrowIVDefUse()
+ : NarrowDef(nullptr), NarrowUse(nullptr), WideDef(nullptr),
+ NeverNegative(false) {}
+
+ NarrowIVDefUse(Instruction *ND, Instruction *NU, Instruction *WD,
+ bool NeverNegative)
+ : NarrowDef(ND), NarrowUse(NU), WideDef(WD),
+ NeverNegative(NeverNegative) {}
};
/// WidenIV - The goal of this transform is to remove sign and zero extends
@@ -849,11 +858,6 @@ class WidenIV {
Type *WideType;
bool IsSigned;
- // True if the narrow induction variable is never negative. Tracking this
- // information lets us use a sign extension instead of a zero extension or
- // vice versa, when profitable and legal.
- bool NeverNegative;
-
// Context
LoopInfo *LI;
Loop *L;
@@ -876,7 +880,6 @@ public:
OrigPhi(WI.NarrowIV),
WideType(WI.WidestNativeType),
IsSigned(WI.IsSigned),
- NeverNegative(false),
LI(LInfo),
L(LI->getLoopFor(OrigPhi->getParent())),
SE(SEv),
@@ -1103,7 +1106,7 @@ bool WidenIV::WidenLoopCompare(NarrowIVD
// (A) == icmp slt i32 sext(%narrow), sext(%val)
// == icmp slt i32 zext(%narrow), sext(%val)
- if (!(NeverNegative || IsSigned == Cmp->isSigned()))
+ if (!(DU.NeverNegative || IsSigned == Cmp->isSigned()))
return false;
Value *Op = Cmp->getOperand(Cmp->getOperand(0) == DU.NarrowDef ? 1 : 0);
@@ -1240,6 +1243,10 @@ Instruction *WidenIV::WidenIVUse(NarrowI
/// pushNarrowIVUsers - Add eligible users of NarrowDef to NarrowIVUsers.
///
void WidenIV::pushNarrowIVUsers(Instruction *NarrowDef, Instruction *WideDef) {
+ const SCEV *NarrowSCEV = SE->getSCEV(NarrowDef);
+ bool NeverNegative =
+ SE->isKnownPredicate(ICmpInst::ICMP_SGE, NarrowSCEV,
+ SE->getConstant(NarrowSCEV->getType(), 0));
for (User *U : NarrowDef->users()) {
Instruction *NarrowUser = cast<Instruction>(U);
@@ -1247,7 +1254,8 @@ void WidenIV::pushNarrowIVUsers(Instruct
if (!Widened.insert(NarrowUser).second)
continue;
- NarrowIVUsers.push_back(NarrowIVDefUse(NarrowDef, NarrowUser, WideDef));
+ NarrowIVUsers.push_back(
+ NarrowIVDefUse(NarrowDef, NarrowUser, WideDef, NeverNegative));
}
}
@@ -1267,9 +1275,6 @@ PHINode *WidenIV::CreateWideIV(SCEVExpan
if (!AddRec)
return nullptr;
- NeverNegative = SE->isKnownPredicate(ICmpInst::ICMP_SGE, AddRec,
- SE->getConstant(AddRec->getType(), 0));
-
// Widen the induction variable expression.
const SCEV *WideIVExpr = IsSigned ?
SE->getSignExtendExpr(AddRec, WideType) :
Modified: llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll?rev=248107&r1=248106&r2=248107&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll (original)
+++ llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll Sat Sep 19 20:52:18 2015
@@ -321,3 +321,35 @@ for.end:
leave:
ret i32 0
}
+
+declare void @consume.i64(i64)
+declare void @consume.i1(i1)
+
+define i32 @test10(i32 %v) {
+; CHECK-LABEL: @test10(
+ entry:
+; CHECK-NOT: zext
+ br label %loop
+
+ loop:
+; CHECK: loop:
+; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ]
+; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+; CHECK: [[MUL:%[a-z0-9]+]] = mul nsw i64 %indvars.iv, -1
+; CHECK: [[MUL_TRUNC:%[a-z0-9]+]] = trunc i64 [[MUL]] to i32
+; CHECK: [[CMP:%[a-z0-9]+]] = icmp eq i32 [[MUL_TRUNC]], %v
+; CHECK: call void @consume.i1(i1 [[CMP]])
+
+ %i = phi i32 [ 0, %entry ], [ %i.inc, %loop ]
+ %i.inc = add i32 %i, 1
+ %iv = mul i32 %i, -1
+ %cmp = icmp eq i32 %iv, %v
+ call void @consume.i1(i1 %cmp)
+ %be.cond = icmp slt i32 %i.inc, 11
+ %ext = sext i32 %iv to i64
+ call void @consume.i64(i64 %ext)
+ br i1 %be.cond, label %loop, label %leave
+
+ leave:
+ ret i32 22
+}
More information about the llvm-commits
mailing list