diff --git a/lib/Analysis/ScalarEvolutionNormalization.cpp b/lib/Analysis/ScalarEvolutionNormalization.cpp index 33036761a0b..1e4c0bdc7be 100644 --- a/lib/Analysis/ScalarEvolutionNormalization.cpp +++ b/lib/Analysis/ScalarEvolutionNormalization.cpp @@ -131,7 +131,10 @@ TransformImpl(const SCEV *S, Instruction *User, Value *OperandValToReplace) { // expression: {-2,+,1,+,2} + {1,+,2} => {-1,+,3,+,2} if (AR->isAffine() && IVUseShouldUsePostIncValue(User, OperandValToReplace, L, &DT)) { - Result = SE.getMinusSCEV(Result, AR->getStepRecurrence(SE)); + const SCEV *TransformedStep = + TransformSubExpr(AR->getStepRecurrence(SE), + User, OperandValToReplace); + Result = SE.getMinusSCEV(Result, TransformedStep); Loops.insert(L); } #if 0 @@ -144,6 +147,20 @@ TransformImpl(const SCEV *S, Instruction *User, Value *OperandValToReplace) { #endif break; case Normalize: + // We want to normalize step expression, because otherwise we might not be + // able to denormalize to the original expression. + // + // Here is an example what will happen if we don't normalize step: + // ORIGINAL ISE: + // {(100 /u {1,+,1}<%bb16>),+,(100 /u {1,+,1}<%bb16>)}<%bb25> + // NORMALIZED ISE: + // {((-1 * (100 /u {1,+,1}<%bb16>)) + (100 /u {0,+,1}<%bb16>)),+, + // (100 /u {0,+,1}<%bb16>)}<%bb25> + // DENORMALIZED BACK ISE: + // {((2 * (100 /u {1,+,1}<%bb16>)) + (-1 * (100 /u {2,+,1}<%bb16>))),+, + // (100 /u {1,+,1}<%bb16>)}<%bb25> + // Note that the initial value changes after normalization + + // denormalization, which isn't correct. if (Loops.count(L)) { const SCEV *TransformedStep = TransformSubExpr(AR->getStepRecurrence(SE), @@ -157,8 +174,14 @@ TransformImpl(const SCEV *S, Instruction *User, Value *OperandValToReplace) { #endif break; case Denormalize: - if (Loops.count(L)) - Result = cast(Result)->getPostIncExpr(SE); + // Here we want to normalize step expressions for the same reasons, as + // stated above. + if (Loops.count(L)) { + const SCEV *TransformedStep = + TransformSubExpr(AR->getStepRecurrence(SE), + User, OperandValToReplace); + Result = SE.getAddExpr(Result, TransformedStep); + } break; } return Result; diff --git a/test/CodeGen/X86/lsr-normalization.ll b/test/CodeGen/X86/lsr-normalization.ll index bbf8f010efd..2c667349953 100644 --- a/test/CodeGen/X86/lsr-normalization.ll +++ b/test/CodeGen/X86/lsr-normalization.ll @@ -1,4 +1,5 @@ -; RUN: llc < %s -march=x86-64 | FileCheck %s +; REQUIRES: asserts +; RUN: llc -debug < %s -march=x86-64 2>&1 | FileCheck %s ; rdar://8168938 ; This testcase involves SCEV normalization with the exit value from @@ -6,6 +7,8 @@ ; loop. The expression should be properly normalized and simplified, ; and require only a single division. +; CHECK-NOT: DISCARDING (NORMALIZATION ISN'T INVERTIBLE) +; CHECK: _main: ; CHECK: div ; CHECK-NOT: div