Take alignment into account in isSafeToLoadUnconditionally

Reviewed By: hfinkel

Differential Revision: http://reviews.llvm.org/D10475


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240636 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Artur Pilipenko 2015-06-25 12:18:43 +00:00
parent 01381b0e95
commit f2e7bb5d2f
2 changed files with 37 additions and 6 deletions

View File

@ -65,6 +65,12 @@ static bool AreEquivalentAddressValues(const Value *A, const Value *B) {
bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
unsigned Align) {
const DataLayout &DL = ScanFrom->getModule()->getDataLayout();
// Zero alignment means that the load has the ABI alignment for the target
if (Align == 0)
Align = DL.getABITypeAlignment(V->getType()->getPointerElementType());
assert(isPowerOf2_32(Align));
int64_t ByteOffset = 0;
Value *Base = V;
Base = GetPointerBaseWithConstantOffset(V, ByteOffset, DL);
@ -102,7 +108,7 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
if (Align <= BaseAlign) {
// Check if the load is within the bounds of the underlying object.
if (ByteOffset + LoadSize <= DL.getTypeAllocSize(BaseType) &&
(Align == 0 || (ByteOffset % Align) == 0))
((ByteOffset % Align) == 0))
return true;
}
}
@ -128,20 +134,28 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
return false;
Value *AccessedPtr;
if (LoadInst *LI = dyn_cast<LoadInst>(BBI))
unsigned AccessedAlign;
if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
AccessedPtr = LI->getPointerOperand();
else if (StoreInst *SI = dyn_cast<StoreInst>(BBI))
AccessedAlign = LI->getAlignment();
} else if (StoreInst *SI = dyn_cast<StoreInst>(BBI)) {
AccessedPtr = SI->getPointerOperand();
else
AccessedAlign = SI->getAlignment();
} else
continue;
Type *AccessedTy = AccessedPtr->getType()->getPointerElementType();
if (AccessedAlign == 0)
AccessedAlign = DL.getABITypeAlignment(AccessedTy);
if (AccessedAlign < Align)
continue;
// Handle trivial cases.
if (AccessedPtr == V)
return true;
auto *AccessedTy = cast<PointerType>(AccessedPtr->getType());
if (AreEquivalentAddressValues(AccessedPtr->stripPointerCasts(), V) &&
LoadSize <= DL.getTypeStoreSize(AccessedTy->getElementType()))
LoadSize <= DL.getTypeStoreSize(AccessedTy))
return true;
}
return false;

View File

@ -1296,6 +1296,23 @@ entry:
ret i32 %v
}
define i32 @test78_neg(i1 %flag, i32* %x, i32* %y, i32* %z) {
; The same as @test78 but we can't speculate the load because it can trap
; if under-aligned.
; CHECK-LABEL: @test78_neg(
; CHECK: %p = select i1 %flag, i32* %x, i32* %y
; CHECK-NEXT: %v = load i32, i32* %p, align 16
; CHECK-NEXT: ret i32 %v
entry:
store i32 0, i32* %x
store i32 0, i32* %y
; Block forwarding by storing to %z which could alias either %x or %y.
store i32 42, i32* %z
%p = select i1 %flag, i32* %x, i32* %y
%v = load i32, i32* %p, align 16
ret i32 %v
}
define float @test79(i1 %flag, float* %x, i32* %y, i32* %z) {
; Test that we can speculate the loads around the select even when we can't
; fold the load completely away.