[unordered] Add tests and conservative handling in support of future changes [NFCI]

This change adds a couple of test cases to make sure FindAvailableLoadedValue does the right thing.  At the moment, the code added is dead, but separating it makes follow on changes far more obvious.

llvm-svn: 266999
This commit is contained in:
Philip Reames 2016-04-21 16:51:08 +00:00
parent 99bc480bc3
commit 92c43699bc
2 changed files with 68 additions and 2 deletions

View File

@ -416,6 +416,14 @@ Value *llvm::FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB,
Value *Ptr = Load->getPointerOperand();
Type *AccessTy = Load->getType();
// We can never remove a volatile load
if (Load->isVolatile())
return nullptr;
// Anything stronger than unordered is currently unimplemented.
if (!Load->isUnordered())
return nullptr;
const DataLayout &DL = ScanBB->getModule()->getDataLayout();
// Try to get the store size for the type.
@ -445,6 +453,12 @@ Value *llvm::FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB,
if (AreEquivalentAddressValues(
LI->getPointerOperand()->stripPointerCasts(), StrippedPtr) &&
CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) {
// We can value forward from an atomic to a non-atomic, but not the
// other way around.
if (LI->isAtomic() < Load->isAtomic())
return nullptr;
if (AATags)
LI->getAAMetadata(*AATags);
return LI;
@ -458,6 +472,12 @@ Value *llvm::FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB,
if (AreEquivalentAddressValues(StorePtr, StrippedPtr) &&
CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(),
AccessTy, DL)) {
// We can value forward from an atomic to a non-atomic, but not the
// other way around.
if (SI->isAtomic() < Load->isAtomic())
return nullptr;
if (AATags)
SI->getAAMetadata(*AATags);
return SI->getOperand(0);

View File

@ -5,8 +5,8 @@ target triple = "x86_64-apple-macosx10.7.0"
; Check transforms involving atomic operations
define i32 @test2(i32* %p) {
; CHECK-LABEL: define i32 @test2(
define i32 @test1(i32* %p) {
; CHECK-LABEL: define i32 @test1(
; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4
; CHECK: shl i32 %x, 1
%x = load atomic i32, i32* %p seq_cst, align 4
@ -14,3 +14,49 @@ define i32 @test2(i32* %p) {
%z = add i32 %x, %y
ret i32 %z
}
define i32 @test2(i32* %p) {
; CHECK-LABEL: define i32 @test2(
; CHECK: %x = load volatile i32, i32* %p, align 4
; CHECK: %y = load volatile i32, i32* %p, align 4
%x = load volatile i32, i32* %p, align 4
%y = load volatile i32, i32* %p, align 4
%z = add i32 %x, %y
ret i32 %z
}
; The exact semantics of mixing volatile and non-volatile on the same
; memory location are a bit unclear, but conservatively, we know we don't
; want to remove the volatile.
define i32 @test3(i32* %p) {
; CHECK-LABEL: define i32 @test3(
; CHECK: %x = load volatile i32, i32* %p, align 4
%x = load volatile i32, i32* %p, align 4
%y = load i32, i32* %p, align 4
%z = add i32 %x, %y
ret i32 %z
}
; FIXME: Forwarding from a stronger atomic is fine
define i32 @test4(i32* %p) {
; CHECK-LABEL: define i32 @test4(
; CHECK: %x = load atomic i32, i32* %p seq_cst, align 4
; CHECK: %y = load atomic i32, i32* %p unordered, align 4
%x = load atomic i32, i32* %p seq_cst, align 4
%y = load atomic i32, i32* %p unordered, align 4
%z = add i32 %x, %y
ret i32 %z
}
; Forwarding from a non-atomic is not. (The earlier load
; could in priciple be promoted to atomic and then forwarded,
; but we can't just drop the atomic from the load.)
define i32 @test5(i32* %p) {
; CHECK-LABEL: define i32 @test5(
; CHECK: %x = load atomic i32, i32* %p unordered, align 4
%x = load atomic i32, i32* %p unordered, align 4
%y = load i32, i32* %p, align 4
%z = add i32 %x, %y
ret i32 %z
}