mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-21 03:37:47 +00:00
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:
parent
01381b0e95
commit
f2e7bb5d2f
@ -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;
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user