diff options
Diffstat (limited to 'llvm/lib/Analysis/Loads.cpp')
-rw-r--r-- | llvm/lib/Analysis/Loads.cpp | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp index 5aa6068b56a..f5eb7055726 100644 --- a/llvm/lib/Analysis/Loads.cpp +++ b/llvm/lib/Analysis/Loads.cpp @@ -73,26 +73,39 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, Type *BaseType = nullptr; unsigned BaseAlign = 0; if (const AllocaInst *AI = dyn_cast<AllocaInst>(Base)) { + // Loading directly from an alloca is trivially safe. We can't even look + // through pointer casts here though, as that might change the size loaded. + if (AI == V) + return true; + // An alloca is safe to load from as load as it is suitably aligned. BaseType = AI->getAllocatedType(); BaseAlign = AI->getAlignment(); } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) { - // Global variables are safe to load from but their size cannot be - // guaranteed if they are overridden. + // Global variables are not necessarily safe to load from if they are + // overridden. Their size may change or they may be weak and require a test + // to determine if they were in fact provided. if (!GV->mayBeOverridden()) { + // Loading directly from the non-overridden global is trivially safe. We + // can't even look through pointer casts here though, as that might change + // the size loaded. + if (GV == V) + return true; + BaseType = GV->getType()->getElementType(); BaseAlign = GV->getAlignment(); } } - if (BaseType && BaseType->isSized()) { - if (DL && BaseAlign == 0) + // If we found a base allocated type from either an alloca or global variable, + // try to see if we are definitively within the allocated region. We need to + // know the size of the base type and the loaded type to do anything in this + // case, so only try this when we have the DataLayout available. + if (BaseType && BaseType->isSized() && DL) { + if (BaseAlign == 0) BaseAlign = DL->getPrefTypeAlignment(BaseType); if (Align <= BaseAlign) { - if (!DL) - return true; // Loading directly from an alloca or global is OK. - // Check if the load is within the bounds of the underlying object. PointerType *AddrTy = cast<PointerType>(V->getType()); uint64_t LoadSize = DL->getTypeStoreSize(AddrTy->getElementType()); |