diff options
| author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-02-26 19:51:35 +0000 |
|---|---|---|
| committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2015-02-26 19:51:35 +0000 |
| commit | 54ef895137cb57262680b627f83687e499b6ba67 (patch) | |
| tree | 0422558cae4e2e122b415b380f6b73e5e8176c20 /llvm/lib/Analysis | |
| parent | fa147e02d8584d10143ecceff62de834239a622c (diff) | |
| download | bcm5719-llvm-54ef895137cb57262680b627f83687e499b6ba67.tar.gz bcm5719-llvm-54ef895137cb57262680b627f83687e499b6ba67.zip | |
SCEVExpander incorrectly marks generated subtractions as nuw/nsw
It is not sound to mark the increment operation as `nuw` or `nsw`
based on a proof off of the add recurrence if the increment operation
we emit happens to be a `sub` instruction.
I could not come up with a test case for this -- the cases where
SCEVExpander decides to emit a `sub` instruction is quite small, and I
cannot think of a way I'd be able to get SCEV to prove that the
increment does not overflow in those cases.
Differential Revision: http://reviews.llvm.org/D7899
llvm-svn: 230673
Diffstat (limited to 'llvm/lib/Analysis')
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolutionExpander.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp index 61527283f68..2625cf3f958 100644 --- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp @@ -1182,9 +1182,6 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, } } - bool IncrementIsNUW = IsIncrementNUW(SE, Normalized); - bool IncrementIsNSW = IsIncrementNSW(SE, Normalized); - // Save the original insertion point so we can restore it when we're done. BuilderType::InsertPointGuard Guard(Builder); @@ -1219,6 +1216,12 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, // Expand the step somewhere that dominates the loop header. Value *StepV = expandCodeFor(Step, IntTy, L->getHeader()->begin()); + // The no-wrap behavior proved by IsIncrement(NUW|NSW) is only applicable if + // we actually do emit an addition. It does not apply if we emit a + // subtraction. + bool IncrementIsNUW = !useSubtract && IsIncrementNUW(SE, Normalized); + bool IncrementIsNSW = !useSubtract && IsIncrementNSW(SE, Normalized); + // Create the PHI. BasicBlock *Header = L->getHeader(); Builder.SetInsertPoint(Header, Header->begin()); |

