summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2013-10-25 21:35:52 +0000
committerAndrew Trick <atrick@apple.com>2013-10-25 21:35:52 +0000
commit29abce3189af936b74f880ab1ba7114eb6de7ac9 (patch)
treeafc5451903bfbeb087accd3b72dfd8d4e0aa0f18 /llvm/lib/Analysis/ScalarEvolutionNormalization.cpp
parent7749d7ccc7b45573eb360d0bda21b32e470eb134 (diff)
downloadbcm5719-llvm-29abce3189af936b74f880ab1ba7114eb6de7ac9.tar.gz
bcm5719-llvm-29abce3189af936b74f880ab1ba7114eb6de7ac9.zip
Fix LSR: don't normalize quadratic recurrences.
Partial fix for PR17459: wrong code at -O3 on x86_64-linux-gnu (affecting trunk and 3.3) ScalarEvolutionNormalization was attempting to normalize by adding and subtracting strides. Chained recurrences don't work that way. llvm-svn: 193437
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolutionNormalization.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolutionNormalization.cpp18
1 files changed, 13 insertions, 5 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp b/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp
index dd2ed4ff831..f1106168440 100644
--- a/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp
+++ b/llvm/lib/Analysis/ScalarEvolutionNormalization.cpp
@@ -119,11 +119,19 @@ TransformImpl(const SCEV *S, Instruction *User, Value *OperandValToReplace) {
const SCEV *Result = SE.getAddRecExpr(Operands, L, SCEV::FlagAnyWrap);
switch (Kind) {
case NormalizeAutodetect:
- if (IVUseShouldUsePostIncValue(User, OperandValToReplace, L, &DT)) {
- const SCEV *TransformedStep =
- TransformSubExpr(AR->getStepRecurrence(SE),
- User, OperandValToReplace);
- Result = SE.getMinusSCEV(Result, TransformedStep);
+ // Normalize this SCEV by subtracting the expression for the final step.
+ // We only allow affine AddRecs to be normalized, otherwise we would not
+ // be able to correctly denormalize.
+ // e.g. {1,+,3,+,2} == {-2,+,1,+,2} + {3,+,2}
+ // Normalized form: {-2,+,1,+,2}
+ // Denormalized form: {1,+,3,+,2}
+ //
+ // However, denormalization would use the a different step expression than
+ // normalization (see getPostIncExpr), generating the wrong final
+ // expression: {-2,+,1,+,2} + {1,+,2} => {-1,+,3,+,2}
+ if (AR->isAffine() &&
+ IVUseShouldUsePostIncValue(User, OperandValToReplace, L, &DT)) {
+ Result = SE.getMinusSCEV(Result, AR->getStepRecurrence(SE));
Loops.insert(L);
}
#if 0
OpenPOWER on IntegriCloud