diff options
Diffstat (limited to 'llvm/lib/Transforms')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 52a779520a5..4ed0f2e16c8 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -473,8 +473,10 @@ static void setDeducedOverflowingFlags(Value *V, Instruction::BinaryOps Opcode, } } +static bool processBinOp(BinaryOperator *BinOp, LazyValueInfo *LVI); + // Rewrite this with.overflow intrinsic as non-overflowing. -static void processOverflowIntrinsic(WithOverflowInst *WO) { +static void processOverflowIntrinsic(WithOverflowInst *WO, LazyValueInfo *LVI) { IRBuilder<> B(WO); Instruction::BinaryOps Opcode = WO->getBinaryOp(); bool NSW = WO->isSigned(); @@ -492,9 +494,13 @@ static void processOverflowIntrinsic(WithOverflowInst *WO) { WO->replaceAllUsesWith(NewI); WO->eraseFromParent(); ++NumOverflows; + + // See if we can infer the other no-wrap too. + if (auto *BO = dyn_cast<BinaryOperator>(NewOp)) + processBinOp(BO, LVI); } -static void processSaturatingInst(SaturatingInst *SI) { +static void processSaturatingInst(SaturatingInst *SI, LazyValueInfo *LVI) { Instruction::BinaryOps Opcode = SI->getBinaryOp(); bool NSW = SI->isSigned(); bool NUW = !SI->isSigned(); @@ -506,6 +512,10 @@ static void processSaturatingInst(SaturatingInst *SI) { SI->replaceAllUsesWith(BinOp); SI->eraseFromParent(); ++NumSaturating; + + // See if we can infer the other no-wrap too. + if (auto *BO = dyn_cast<BinaryOperator>(BinOp)) + processBinOp(BO, LVI); } /// Infer nonnull attributes for the arguments at the specified callsite. @@ -515,14 +525,14 @@ static bool processCallSite(CallSite CS, LazyValueInfo *LVI) { if (auto *WO = dyn_cast<WithOverflowInst>(CS.getInstruction())) { if (WO->getLHS()->getType()->isIntegerTy() && willNotOverflow(WO, LVI)) { - processOverflowIntrinsic(WO); + processOverflowIntrinsic(WO, LVI); return true; } } if (auto *SI = dyn_cast<SaturatingInst>(CS.getInstruction())) { if (SI->getType()->isIntegerTy() && willNotOverflow(SI, LVI)) { - processSaturatingInst(SI); + processSaturatingInst(SI, LVI); return true; } } |

