mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-20 10:24:12 +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:
@ -65,6 +65,12 @@ static bool AreEquivalentAddressValues(const Value *A, const Value *B) {
|
|||||||
bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
|
bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
|
||||||
unsigned Align) {
|
unsigned Align) {
|
||||||
const DataLayout &DL = ScanFrom->getModule()->getDataLayout();
|
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;
|
int64_t ByteOffset = 0;
|
||||||
Value *Base = V;
|
Value *Base = V;
|
||||||
Base = GetPointerBaseWithConstantOffset(V, ByteOffset, DL);
|
Base = GetPointerBaseWithConstantOffset(V, ByteOffset, DL);
|
||||||
@ -102,7 +108,7 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
|
|||||||
if (Align <= BaseAlign) {
|
if (Align <= BaseAlign) {
|
||||||
// Check if the load is within the bounds of the underlying object.
|
// Check if the load is within the bounds of the underlying object.
|
||||||
if (ByteOffset + LoadSize <= DL.getTypeAllocSize(BaseType) &&
|
if (ByteOffset + LoadSize <= DL.getTypeAllocSize(BaseType) &&
|
||||||
(Align == 0 || (ByteOffset % Align) == 0))
|
((ByteOffset % Align) == 0))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,20 +134,28 @@ bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
Value *AccessedPtr;
|
Value *AccessedPtr;
|
||||||
if (LoadInst *LI = dyn_cast<LoadInst>(BBI))
|
unsigned AccessedAlign;
|
||||||
|
if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
|
||||||
AccessedPtr = LI->getPointerOperand();
|
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();
|
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;
|
continue;
|
||||||
|
|
||||||
// Handle trivial cases.
|
// Handle trivial cases.
|
||||||
if (AccessedPtr == V)
|
if (AccessedPtr == V)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto *AccessedTy = cast<PointerType>(AccessedPtr->getType());
|
|
||||||
if (AreEquivalentAddressValues(AccessedPtr->stripPointerCasts(), V) &&
|
if (AreEquivalentAddressValues(AccessedPtr->stripPointerCasts(), V) &&
|
||||||
LoadSize <= DL.getTypeStoreSize(AccessedTy->getElementType()))
|
LoadSize <= DL.getTypeStoreSize(AccessedTy))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1296,6 +1296,23 @@ entry:
|
|||||||
ret i32 %v
|
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) {
|
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
|
; Test that we can speculate the loads around the select even when we can't
|
||||||
; fold the load completely away.
|
; fold the load completely away.
|
||||||
|
Reference in New Issue
Block a user