From 54ef895137cb57262680b627f83687e499b6ba67 Mon Sep 17 00:00:00 2001 From: Sanjoy Das Date: Thu, 26 Feb 2015 19:51:35 +0000 Subject: [PATCH] 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 --- llvm/lib/Analysis/ScalarEvolutionExpander.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp index 61527283f687..2625cf3f9584 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());