diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyIndVar.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyIndVar.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp index 1b142f1..5aa6df4 100644 --- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -1985,7 +1985,28 @@ PHINode *WidenIV::createWideIV(SCEVExpander &Rewriter) { // increment to the new (widened) increment. auto *OrigInc = cast<Instruction>(OrigPhi->getIncomingValueForBlock(LatchBlock)); + WideInc->setDebugLoc(OrigInc->getDebugLoc()); + // We are replacing a narrow IV increment with a wider IV increment. If + // the original (narrow) increment did not wrap, the wider increment one + // should not wrap either. Set the flags to be the union of both wide + // increment and original increment; this ensures we preserve flags SCEV + // could infer for the wider increment. Limit this only to cases where + // both increments directly increment the corresponding PHI nodes and have + // the same opcode. It is not safe to re-use the flags from the original + // increment, if it is more complex and SCEV expansion may have yielded a + // more simplified wider increment. + bool MatchingOps = + match(OrigInc, m_c_BinOp(m_Specific(OrigPhi), m_Value())) && + match(WideInc, m_c_BinOp(m_Specific(WidePhi), m_Value())) && + OrigInc->getOpcode() == WideInc->getOpcode(); + if (MatchingOps && isa<OverflowingBinaryOperator>(OrigInc) && + isa<OverflowingBinaryOperator>(WideInc)) { + WideInc->setHasNoUnsignedWrap(WideInc->hasNoUnsignedWrap() || + OrigInc->hasNoUnsignedWrap()); + WideInc->setHasNoSignedWrap(WideInc->hasNoSignedWrap() || + OrigInc->hasNoSignedWrap()); + } } } |