If it's safe to speculatively execute load(alloca) the it's safe to execute
authorNick Lewycky <nicholas@mxc.ca>
Sun, 11 Jul 2010 20:36:29 +0000 (20:36 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Sun, 11 Jul 2010 20:36:29 +0000 (20:36 +0000)
load(gep(alloca)) where the gep is all-zeros. There's more we could do here but
this is a common case.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108101 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/Instruction.cpp

index e8d2814c44fe540f75c2f78461acb8d988aec2e2..d3f62d0d08fa81b8ced9f9507a699e8118da6430 100644 (file)
@@ -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: