[llvm] r218867 - [BUG][INDVAR] Fix for PR21014: wrong SCEV operands commuting for non-commutative instructions
Zinovy Nis
zinovy.nis at gmail.com
Thu Oct 2 06:01:16 PDT 2014
Author: zinovy.nis
Date: Thu Oct 2 08:01:15 2014
New Revision: 218867
URL: http://llvm.org/viewvc/llvm-project?rev=218867&view=rev
Log:
[BUG][INDVAR] Fix for PR21014: wrong SCEV operands commuting for non-commutative instructions
My commit rL216160 introduced a bug PR21014: IndVars widens code 'for (i = ; i < ...; i++) arr[ CONST - i]' into 'for (i = ; i < ...; i++) arr[ i - CONST]'
thus inverting index expression. This patch fixes it.
Thanks to Jörg Sonnenberger for pointing.
Differential Revision: http://reviews.llvm.org/D5576
Modified:
llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
llvm/trunk/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=218867&r1=218866&r2=218867&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Thu Oct 2 08:01:15 2014
@@ -865,7 +865,8 @@ const SCEVAddRecExpr* WidenIV::GetExtend
// One operand (NarrowDef) has already been extended to WideDef. Now determine
// if extending the other will lead to a recurrence.
- unsigned ExtendOperIdx = DU.NarrowUse->getOperand(0) == DU.NarrowDef ? 1 : 0;
+ const unsigned ExtendOperIdx =
+ DU.NarrowUse->getOperand(0) == DU.NarrowDef ? 1 : 0;
assert(DU.NarrowUse->getOperand(1-ExtendOperIdx) == DU.NarrowDef && "bad DU");
const SCEV *ExtendOperExpr = nullptr;
@@ -885,8 +886,16 @@ const SCEVAddRecExpr* WidenIV::GetExtend
// behavior depends on. Non-control-equivalent instructions can be mapped to
// the same SCEV expression, and it would be incorrect to transfer NSW/NUW
// semantics to those operations.
- const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(
- GetSCEVByOpCode(SE->getSCEV(DU.WideDef), ExtendOperExpr, OpCode));
+ const SCEV *lhs = SE->getSCEV(DU.WideDef);
+ const SCEV *rhs = ExtendOperExpr;
+
+ // Let's swap operands to the initial order for the case of non-commutative
+ // operations, like SUB. See PR21014.
+ if (ExtendOperIdx == 0)
+ std::swap(lhs, rhs);
+ const SCEVAddRecExpr *AddRec =
+ dyn_cast<SCEVAddRecExpr>(GetSCEVByOpCode(lhs, rhs, OpCode));
+
if (!AddRec || AddRec->getLoop() != L)
return nullptr;
return AddRec;
Modified: llvm/trunk/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll?rev=218867&r1=218866&r2=218867&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll (original)
+++ llvm/trunk/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll Thu Oct 2 08:01:15 2014
@@ -19,7 +19,8 @@ for.body153:
; CHECK: add nsw i64 %indvars.iv, 1
; CHECK: sub nsw i64 %indvars.iv, 2
-; CHECK: mul nsw i64 %indvars.iv, 4
+; CHECK: sub nsw i64 4, %indvars.iv
+; CHECK: mul nsw i64 %indvars.iv, 8
for.body170: ; preds = %for.body170, %for.body153
%i2.19 = phi i32 [ %add249, %for.body170 ], [ 0, %for.body153 ]
@@ -29,7 +30,10 @@ for.body170:
%sub = sub nsw i32 %i2.19, 2
%sub.idxprom = sext i32 %sub to i64
- %mul = mul nsw i32 %i2.19, 4
+ %sub.neg = sub nsw i32 4, %i2.19
+ %sub.neg.idxprom = sext i32 %sub.neg to i64
+
+ %mul = mul nsw i32 %i2.19, 8
%mul.idxprom = sext i32 %mul to i64
%add249 = add nsw i32 %i2.19, %shl132
More information about the llvm-commits
mailing list