mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-19 02:25:01 +00:00
Merging r221318:
------------------------------------------------------------------------ r221318 | majnemer | 2014-11-04 15:49:08 -0800 (Tue, 04 Nov 2014) | 10 lines Analysis: Make isSafeToSpeculativelyExecute fire less for divides Divides and remainder operations do not behave like other operations when they are given poison: they turn into undefined behavior. It's really hard to know if the operands going into a div are or are not poison. Because of this, we should only choose to speculate if there are constant operands which we can easily reason about. This fixes PR21412. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@223647 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1987,23 +1987,31 @@ bool llvm::isSafeToSpeculativelyExecute(const Value *V,
|
||||
default:
|
||||
return true;
|
||||
case Instruction::UDiv:
|
||||
case Instruction::URem:
|
||||
// x / y is undefined if y == 0, but calculations like x / 3 are safe.
|
||||
return isKnownNonZero(Inst->getOperand(1), TD);
|
||||
case Instruction::URem: {
|
||||
// x / y is undefined if y == 0.
|
||||
const APInt *V;
|
||||
if (match(Inst->getOperand(1), m_APInt(V)))
|
||||
return *V != 0;
|
||||
return false;
|
||||
}
|
||||
case Instruction::SDiv:
|
||||
case Instruction::SRem: {
|
||||
Value *Op = Inst->getOperand(1);
|
||||
// x / y is undefined if y == 0
|
||||
if (!isKnownNonZero(Op, TD))
|
||||
return false;
|
||||
// x / y might be undefined if y == -1
|
||||
unsigned BitWidth = getBitWidth(Op->getType(), TD);
|
||||
if (BitWidth == 0)
|
||||
return false;
|
||||
APInt KnownZero(BitWidth, 0);
|
||||
APInt KnownOne(BitWidth, 0);
|
||||
computeKnownBits(Op, KnownZero, KnownOne, TD);
|
||||
return !!KnownZero;
|
||||
// x / y is undefined if y == 0 or x == INT_MIN and y == -1
|
||||
const APInt *X, *Y;
|
||||
if (match(Inst->getOperand(1), m_APInt(Y))) {
|
||||
if (*Y != 0) {
|
||||
if (*Y == -1) {
|
||||
// The numerator can't be MinSignedValue if the denominator is -1.
|
||||
if (match(Inst->getOperand(0), m_APInt(X)))
|
||||
return !Y->isMinSignedValue();
|
||||
// The numerator *might* be MinSignedValue.
|
||||
return false;
|
||||
}
|
||||
// The denominator is not 0 or -1, it's safe to proceed.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case Instruction::Load: {
|
||||
const LoadInst *LI = cast<LoadInst>(Inst);
|
||||
|
Reference in New Issue
Block a user