summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2010-07-11 20:36:29 +0000
committerNick Lewycky <nicholas@mxc.ca>2010-07-11 20:36:29 +0000
commit5d373c2141b33920dd97d3fc8888cab022f72d15 (patch)
tree0a898cb59f66a845f5420b83d0be7e3907eba3bd /llvm/lib
parent31bd2de24e1f4ec29ab33cbdc288327a252f75da (diff)
downloadbcm5719-llvm-5d373c2141b33920dd97d3fc8888cab022f72d15.tar.gz
bcm5719-llvm-5d373c2141b33920dd97d3fc8888cab022f72d15.zip
If it's safe to speculatively execute load(alloca) the it's safe to execute
load(gep(alloca)) where the gep is all-zeros. There's more we could do here but this is a common case. llvm-svn: 108101
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/VMCore/Instruction.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/llvm/lib/VMCore/Instruction.cpp b/llvm/lib/VMCore/Instruction.cpp
index e8d2814c44f..d3f62d0d08f 100644
--- a/llvm/lib/VMCore/Instruction.cpp
+++ b/llvm/lib/VMCore/Instruction.cpp
@@ -401,12 +401,20 @@ bool Instruction::isSafeToSpeculativelyExecute() const {
return false;
// Note that it is not safe to speculate into a malloc'd region because
// malloc may return null.
- if (isa<AllocaInst>(getOperand(0)))
+ // It's also not safe to follow a bitcast, for example:
+ // bitcast i8* (alloca i8) to i32*
+ // would result in a 4-byte load from a 1-byte alloca.
+ Value *Op0 = getOperand(0);
+ if (GEPOperator *GEP = dyn_cast<GEPOperator>(Op0)) {
+ // TODO: it's safe to do this for any GEP with constant indices that
+ // compute inside the allocated type, but not for any inbounds gep.
+ if (GEP->hasAllZeroIndices())
+ Op0 = GEP->getPointerOperand();
+ }
+ if (isa<AllocaInst>(Op0))
return true;
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(getOperand(0)))
return !GV->hasExternalWeakLinkage();
- // FIXME: Handle cases involving GEPs. We have to be careful because
- // a load of a out-of-bounds GEP has undefined behavior.
return false;
}
case Call:
OpenPOWER on IntegriCloud