mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
[InstCombine] Refactor out OptimizeOverflowCheck. NFCI.
Summary: This patch adds an enum `OverflowCheckFlavor` and a function `OptimizeOverflowCheck`. This will allow InstCombine to optimize overflow checks without directly introducing an intermediate call to the `llvm.$op.with.overflow` instrinsics. This specific change is a refactoring and does not intend to change behavior. Reviewers: majnemer, atrick Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8888 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234388 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -110,6 +110,41 @@ static inline bool IsFreeToInvert(Value *V, bool WillInvertAllUses) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Specific patterns of overflow check idioms that we match.
|
||||
enum OverflowCheckFlavor {
|
||||
OCF_UNSIGNED_ADD,
|
||||
OCF_SIGNED_ADD,
|
||||
OCF_UNSIGNED_SUB,
|
||||
OCF_SIGNED_SUB,
|
||||
OCF_UNSIGNED_MUL,
|
||||
OCF_SIGNED_MUL,
|
||||
|
||||
OCF_INVALID
|
||||
};
|
||||
|
||||
/// \brief Returns the OverflowCheckFlavor corresponding to a overflow_with_op
|
||||
/// intrinsic.
|
||||
static inline OverflowCheckFlavor
|
||||
IntrinsicIDToOverflowCheckFlavor(unsigned ID) {
|
||||
switch (ID) {
|
||||
default:
|
||||
return OCF_INVALID;
|
||||
case Intrinsic::uadd_with_overflow:
|
||||
return OCF_UNSIGNED_ADD;
|
||||
case Intrinsic::sadd_with_overflow:
|
||||
return OCF_SIGNED_ADD;
|
||||
case Intrinsic::usub_with_overflow:
|
||||
return OCF_UNSIGNED_SUB;
|
||||
case Intrinsic::ssub_with_overflow:
|
||||
return OCF_SIGNED_SUB;
|
||||
case Intrinsic::umul_with_overflow:
|
||||
return OCF_UNSIGNED_MUL;
|
||||
case Intrinsic::smul_with_overflow:
|
||||
return OCF_SIGNED_MUL;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief An IRBuilder inserter that adds new instructions to the instcombine
|
||||
/// worklist.
|
||||
class LLVM_LIBRARY_VISIBILITY InstCombineIRInserter
|
||||
@@ -329,6 +364,17 @@ private:
|
||||
bool ShouldOptimizeCast(Instruction::CastOps opcode, const Value *V,
|
||||
Type *Ty);
|
||||
|
||||
/// \brief Try to optimize a sequence of instructions checking if an operation
|
||||
/// on LHS and RHS overflows.
|
||||
///
|
||||
/// If a simplification is possible, stores the simplified result of the
|
||||
/// operation in OperationResult and result of the overflow check in
|
||||
/// OverflowResult, and return true. If no simplification is possible,
|
||||
/// returns false.
|
||||
bool OptimizeOverflowCheck(OverflowCheckFlavor OCF, Value *LHS, Value *RHS,
|
||||
Instruction &CtxI, Value *&OperationResult,
|
||||
Constant *&OverflowResult);
|
||||
|
||||
Instruction *visitCallSite(CallSite CS);
|
||||
Instruction *tryOptimizeCall(CallInst *CI);
|
||||
bool transformConstExprCastCall(CallSite CS);
|
||||
@@ -391,14 +437,10 @@ public:
|
||||
}
|
||||
|
||||
/// Creates a result tuple for an overflow intrinsic \p II with a given
|
||||
/// \p Result and a constant \p Overflow value. If \p ReUseName is true the
|
||||
/// \p Result's name is taken from \p II.
|
||||
/// \p Result and a constant \p Overflow value.
|
||||
Instruction *CreateOverflowTuple(IntrinsicInst *II, Value *Result,
|
||||
bool Overflow, bool ReUseName = true) {
|
||||
if (ReUseName)
|
||||
Result->takeName(II);
|
||||
Constant *V[] = {UndefValue::get(Result->getType()),
|
||||
Overflow ? Builder->getTrue() : Builder->getFalse()};
|
||||
Constant *Overflow) {
|
||||
Constant *V[] = {UndefValue::get(Result->getType()), Overflow};
|
||||
StructType *ST = cast<StructType>(II->getType());
|
||||
Constant *Struct = ConstantStruct::get(ST, V);
|
||||
return InsertValueInst::Create(Struct, Result, 0);
|
||||
|
Reference in New Issue
Block a user