[llvm] r240636 - Take alignment into account in isSafeToLoadUnconditionally
Artur Pilipenko
apilipenko at azulsystems.com
Thu Jun 25 05:18:44 PDT 2015
Author: apilipenko
Date: Thu Jun 25 07:18:43 2015
New Revision: 240636
URL: http://llvm.org/viewvc/llvm-project?rev=240636&view=rev
Log:
Take alignment into account in isSafeToLoadUnconditionally
Reviewed By: hfinkel
Differential Revision: http://reviews.llvm.org/D10475
Modified:
llvm/trunk/lib/Analysis/Loads.cpp
llvm/trunk/test/Transforms/InstCombine/select.ll
Modified: llvm/trunk/lib/Analysis/Loads.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Loads.cpp?rev=240636&r1=240635&r2=240636&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Loads.cpp (original)
+++ llvm/trunk/lib/Analysis/Loads.cpp Thu Jun 25 07:18:43 2015
@@ -65,6 +65,12 @@ static bool AreEquivalentAddressValues(c
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(V
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(V
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;
Modified: llvm/trunk/test/Transforms/InstCombine/select.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/select.ll?rev=240636&r1=240635&r2=240636&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/select.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/select.ll Thu Jun 25 07:18:43 2015
@@ -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.
More information about the llvm-commits
mailing list