mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
Analysis: Reformulate WillNotOverflowUnsignedAdd for reusability
WillNotOverflowUnsignedAdd's smarts will live in ValueTracking as computeOverflowForUnsignedAdd. It now returns a tri-state result: never overflows, always overflows and sometimes overflows. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225329 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -352,33 +352,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
|
||||
break;
|
||||
case Intrinsic::uadd_with_overflow: {
|
||||
Value *LHS = II->getArgOperand(0), *RHS = II->getArgOperand(1);
|
||||
IntegerType *IT = cast<IntegerType>(II->getArgOperand(0)->getType());
|
||||
uint32_t BitWidth = IT->getBitWidth();
|
||||
APInt LHSKnownZero(BitWidth, 0);
|
||||
APInt LHSKnownOne(BitWidth, 0);
|
||||
computeKnownBits(LHS, LHSKnownZero, LHSKnownOne, 0, II);
|
||||
bool LHSKnownNegative = LHSKnownOne[BitWidth - 1];
|
||||
bool LHSKnownPositive = LHSKnownZero[BitWidth - 1];
|
||||
|
||||
if (LHSKnownNegative || LHSKnownPositive) {
|
||||
APInt RHSKnownZero(BitWidth, 0);
|
||||
APInt RHSKnownOne(BitWidth, 0);
|
||||
computeKnownBits(RHS, RHSKnownZero, RHSKnownOne, 0, II);
|
||||
bool RHSKnownNegative = RHSKnownOne[BitWidth - 1];
|
||||
bool RHSKnownPositive = RHSKnownZero[BitWidth - 1];
|
||||
if (LHSKnownNegative && RHSKnownNegative) {
|
||||
// The sign bit is set in both cases: this MUST overflow.
|
||||
// Create a simple add instruction, and insert it into the struct.
|
||||
return CreateOverflowTuple(II, Builder->CreateAdd(LHS, RHS), true,
|
||||
/*ReUseName*/true);
|
||||
}
|
||||
|
||||
if (LHSKnownPositive && RHSKnownPositive) {
|
||||
// The sign bit is clear in both cases: this CANNOT overflow.
|
||||
// Create a simple add instruction, and insert it into the struct.
|
||||
return CreateOverflowTuple(II, Builder->CreateNUWAdd(LHS, RHS), false);
|
||||
}
|
||||
}
|
||||
OverflowResult OR = computeOverflowForUnsignedAdd(LHS, RHS, II);
|
||||
if (OR == OverflowResult::NeverOverflows)
|
||||
return CreateOverflowTuple(II, Builder->CreateNUWAdd(LHS, RHS), false);
|
||||
if (OR == OverflowResult::AlwaysOverflows)
|
||||
return CreateOverflowTuple(II, Builder->CreateAdd(LHS, RHS), true);
|
||||
}
|
||||
// FALL THROUGH uadd into sadd
|
||||
case Intrinsic::sadd_with_overflow:
|
||||
|
Reference in New Issue
Block a user