llvm.org GIT mirror llvm / 3171394
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218867 91177308-0d34-0410-b5e6-96231b3b80d8 Zinovy Nis 5 years ago
2 changed file(s) with 18 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
864864
865865 // One operand (NarrowDef) has already been extended to WideDef. Now determine
866866 // if extending the other will lead to a recurrence.
867 unsigned ExtendOperIdx = DU.NarrowUse->getOperand(0) == DU.NarrowDef ? 1 : 0;
867 const unsigned ExtendOperIdx =
868 DU.NarrowUse->getOperand(0) == DU.NarrowDef ? 1 : 0;
868869 assert(DU.NarrowUse->getOperand(1-ExtendOperIdx) == DU.NarrowDef && "bad DU");
869870
870871 const SCEV *ExtendOperExpr = nullptr;
884885 // behavior depends on. Non-control-equivalent instructions can be mapped to
885886 // the same SCEV expression, and it would be incorrect to transfer NSW/NUW
886887 // semantics to those operations.
887 const SCEVAddRecExpr *AddRec = dyn_cast(
888 GetSCEVByOpCode(SE->getSCEV(DU.WideDef), ExtendOperExpr, OpCode));
888 const SCEV *lhs = SE->getSCEV(DU.WideDef);
889 const SCEV *rhs = ExtendOperExpr;
890
891 // Let's swap operands to the initial order for the case of non-commutative
892 // operations, like SUB. See PR21014.
893 if (ExtendOperIdx == 0)
894 std::swap(lhs, rhs);
895 const SCEVAddRecExpr *AddRec =
896 dyn_cast(GetSCEVByOpCode(lhs, rhs, OpCode));
897
889898 if (!AddRec || AddRec->getLoop() != L)
890899 return nullptr;
891900 return AddRec;
1818
1919 ; CHECK: add nsw i64 %indvars.iv, 1
2020 ; CHECK: sub nsw i64 %indvars.iv, 2
21 ; CHECK: mul nsw i64 %indvars.iv, 4
21 ; CHECK: sub nsw i64 4, %indvars.iv
22 ; CHECK: mul nsw i64 %indvars.iv, 8
2223 for.body170: ; preds = %for.body170, %for.body153
2324 %i2.19 = phi i32 [ %add249, %for.body170 ], [ 0, %for.body153 ]
2425
2829 %sub = sub nsw i32 %i2.19, 2
2930 %sub.idxprom = sext i32 %sub to i64
3031
31 %mul = mul nsw i32 %i2.19, 4
32 %sub.neg = sub nsw i32 4, %i2.19
33 %sub.neg.idxprom = sext i32 %sub.neg to i64
34
35 %mul = mul nsw i32 %i2.19, 8
3236 %mul.idxprom = sext i32 %mul to i64
3337
3438 %add249 = add nsw i32 %i2.19, %shl132