mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-21 23:17:16 +00:00
Move Instruction::isSafeToSpeculativelyExecute out of VMCore and
into Analysis as a standalone function, since there's no need for it to be in VMCore. Also, update it to use isKnownNonZero and other goodies available in Analysis, making it more precise, enabling more aggressive optimization. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146610 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1875,3 +1875,64 @@ bool llvm::onlyUsedByLifetimeMarkers(const Value *V) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool llvm::isSafeToSpeculativelyExecute(const Instruction *Inst,
|
||||
const TargetData *TD) {
|
||||
for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i)
|
||||
if (Constant *C = dyn_cast<Constant>(Inst->getOperand(i)))
|
||||
if (C->canTrap())
|
||||
return false;
|
||||
|
||||
switch (Inst->getOpcode()) {
|
||||
default:
|
||||
return true;
|
||||
case Instruction::UDiv:
|
||||
case Instruction::URem:
|
||||
// x / y is undefined if y == 0, but calcuations like x / 3 are safe.
|
||||
return isKnownNonZero(Inst->getOperand(1), TD);
|
||||
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);
|
||||
ComputeMaskedBits(Op, APInt::getAllOnesValue(BitWidth),
|
||||
KnownZero, KnownOne, TD);
|
||||
return !!KnownZero;
|
||||
}
|
||||
case Instruction::Load: {
|
||||
const LoadInst *LI = cast<LoadInst>(Inst);
|
||||
if (!LI->isUnordered())
|
||||
return false;
|
||||
return LI->getPointerOperand()->isDereferenceablePointer();
|
||||
}
|
||||
case Instruction::Call:
|
||||
return false; // The called function could have undefined behavior or
|
||||
// side-effects.
|
||||
// FIXME: We should special-case some intrinsics (bswap,
|
||||
// overflow-checking arithmetic, etc.)
|
||||
case Instruction::VAArg:
|
||||
case Instruction::Alloca:
|
||||
case Instruction::Invoke:
|
||||
case Instruction::PHI:
|
||||
case Instruction::Store:
|
||||
case Instruction::Ret:
|
||||
case Instruction::Br:
|
||||
case Instruction::IndirectBr:
|
||||
case Instruction::Switch:
|
||||
case Instruction::Unwind:
|
||||
case Instruction::Unreachable:
|
||||
case Instruction::Fence:
|
||||
case Instruction::LandingPad:
|
||||
case Instruction::AtomicRMW:
|
||||
case Instruction::AtomicCmpXchg:
|
||||
case Instruction::Resume:
|
||||
return false; // Misc instructions which have effects
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user