diff options
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 13 | ||||
-rw-r--r-- | lib/Transforms/Scalar/GVN.cpp | 3 | ||||
-rw-r--r-- | lib/Transforms/Scalar/TailRecursionElimination.cpp | 3 | ||||
-rw-r--r-- | lib/Transforms/Utils/Local.cpp | 21 |
4 files changed, 25 insertions, 15 deletions
diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 422ffd03a8..2d13298300 100644 --- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -200,14 +200,15 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { // if (SelectInst *SI = dyn_cast<SelectInst>(Op)) { // load (select (Cond, &V1, &V2)) --> select(Cond, load &V1, load &V2). - if (isSafeToLoadUnconditionally(SI->getOperand(1), SI, TD) && - isSafeToLoadUnconditionally(SI->getOperand(2), SI, TD)) { + unsigned Align = LI.getAlignment(); + if (isSafeToLoadUnconditionally(SI->getOperand(1), SI, Align, TD) && + isSafeToLoadUnconditionally(SI->getOperand(2), SI, Align, TD)) { LoadInst *V1 = Builder->CreateLoad(SI->getOperand(1), - SI->getOperand(1)->getName()+".val"); + SI->getOperand(1)->getName()+".val"); LoadInst *V2 = Builder->CreateLoad(SI->getOperand(2), - SI->getOperand(2)->getName()+".val"); - V1->setAlignment(LI.getAlignment()); - V2->setAlignment(LI.getAlignment()); + SI->getOperand(2)->getName()+".val"); + V1->setAlignment(Align); + V2->setAlignment(Align); return SelectInst::Create(SI->getCondition(), V1, V2); } diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 9c18452665..6e709523af 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1651,7 +1651,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI, if (!allSingleSucc && // FIXME: REEVALUTE THIS. !isSafeToLoadUnconditionally(LoadPtr, - UnavailablePred->getTerminator(), TD)) { + UnavailablePred->getTerminator(), + LI->getAlignment(), TD)) { assert(NewInsts.empty() && "Should not have inserted instructions"); return false; } diff --git a/lib/Transforms/Scalar/TailRecursionElimination.cpp b/lib/Transforms/Scalar/TailRecursionElimination.cpp index 4119cb9db4..162d902cfa 100644 --- a/lib/Transforms/Scalar/TailRecursionElimination.cpp +++ b/lib/Transforms/Scalar/TailRecursionElimination.cpp @@ -211,7 +211,8 @@ bool TailCallElim::CanMoveAboveCall(Instruction *I, CallInst *CI) { // FIXME: Writes to memory only matter if they may alias the pointer // being loaded from. if (CI->mayWriteToMemory() || - !isSafeToLoadUnconditionally(L->getPointerOperand(), L)) + !isSafeToLoadUnconditionally(L->getPointerOperand(), L, + L->getAlignment())) return false; } } diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 425f557296..62c0ae0d84 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -75,31 +75,38 @@ static Value *getUnderlyingObjectWithOffset(Value *V, const TargetData *TD, /// specified pointer, we do a quick local scan of the basic block containing /// ScanFrom, to determine if the address is already accessed. bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, - const TargetData *TD) { + unsigned Align, const TargetData *TD) { uint64_t ByteOffset = 0; Value *Base = V; if (TD) Base = getUnderlyingObjectWithOffset(V, TD, ByteOffset); const Type *BaseType = 0; - if (const AllocaInst *AI = dyn_cast<AllocaInst>(Base)) - // If it is an alloca it is always safe to load from. + unsigned BaseAlign = 0; + if (const AllocaInst *AI = dyn_cast<AllocaInst>(Base)) { + // An alloca is safe to load from as load as it is suitably aligned. BaseType = AI->getAllocatedType(); - else if (const GlobalValue *GV = dyn_cast<GlobalValue>(Base)) { + BaseAlign = AI->getAlignment(); + } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(Base)) { // Global variables are safe to load from but their size cannot be // guaranteed if they are overridden. - if (!isa<GlobalAlias>(GV) && !GV->mayBeOverridden()) + if (!isa<GlobalAlias>(GV) && !GV->mayBeOverridden()) { BaseType = GV->getType()->getElementType(); + BaseAlign = GV->getAlignment(); + } } + if (TD && BaseType && BaseAlign == 0) + BaseAlign = TD->getPrefTypeAlignment(BaseType); - if (BaseType) { + if (BaseType && Align <= BaseAlign) { if (!TD) return true; // Loading directly from an alloca or global is OK. if (BaseType->isSized()) { // Check if the load is within the bounds of the underlying object. const PointerType *AddrTy = cast<PointerType>(V->getType()); uint64_t LoadSize = TD->getTypeStoreSize(AddrTy->getElementType()); - if (ByteOffset + LoadSize <= TD->getTypeAllocSize(BaseType)) + if (ByteOffset + LoadSize <= TD->getTypeAllocSize(BaseType) && + (Align == 0 || (ByteOffset % Align) == 0)) return true; } } |