[llvm] r293584 - InferAddressSpaces: Support atomics
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 30 17:40:38 PST 2017
Author: arsenm
Date: Mon Jan 30 19:40:38 2017
New Revision: 293584
URL: http://llvm.org/viewvc/llvm-project?rev=293584&view=rev
Log:
InferAddressSpaces: Support atomics
Modified:
llvm/trunk/lib/Transforms/Scalar/InferAddressSpaces.cpp
llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/basic.ll
llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/volatile.ll
Modified: llvm/trunk/lib/Transforms/Scalar/InferAddressSpaces.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InferAddressSpaces.cpp?rev=293584&r1=293583&r2=293584&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InferAddressSpaces.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InferAddressSpaces.cpp Mon Jan 30 19:40:38 2017
@@ -232,16 +232,25 @@ InferAddressSpaces::collectFlatAddressEx
std::vector<std::pair<Value*, bool>> PostorderStack;
// The set of visited expressions.
DenseSet<Value*> Visited;
+
+ auto PushPtrOperand = [&](Value *Ptr) {
+ appendsFlatAddressExpressionToPostorderStack(
+ Ptr, &PostorderStack, &Visited);
+ };
+
// We only explore address expressions that are reachable from loads and
// stores for now because we aim at generating faster loads and stores.
for (Instruction &I : instructions(F)) {
- if (isa<LoadInst>(I)) {
- appendsFlatAddressExpressionToPostorderStack(
- I.getOperand(0), &PostorderStack, &Visited);
- } else if (isa<StoreInst>(I)) {
- appendsFlatAddressExpressionToPostorderStack(
- I.getOperand(1), &PostorderStack, &Visited);
- }
+ if (auto *LI = dyn_cast<LoadInst>(&I))
+ PushPtrOperand(LI->getPointerOperand());
+ else if (auto *SI = dyn_cast<StoreInst>(&I))
+ PushPtrOperand(SI->getPointerOperand());
+ else if (auto *RMW = dyn_cast<AtomicRMWInst>(&I))
+ PushPtrOperand(RMW->getPointerOperand());
+ else if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(&I))
+ PushPtrOperand(CmpX->getPointerOperand());
+
+ // TODO: Support intrinsics
}
std::vector<Value *> Postorder; // The resultant postorder.
@@ -527,6 +536,30 @@ Optional<unsigned> InferAddressSpaces::u
return NewAS;
}
+/// \p returns true if \p U is the pointer operand of a memory instruction with
+/// a single pointer operand that can have its address space changed by simply
+/// mutating the use to a new value.
+static bool isSimplePointerUseValidToReplace(Use &U) {
+ User *Inst = U.getUser();
+ unsigned OpNo = U.getOperandNo();
+
+ if (auto *LI = dyn_cast<LoadInst>(Inst))
+ return OpNo == LoadInst::getPointerOperandIndex() && !LI->isVolatile();
+
+ if (auto *SI = dyn_cast<StoreInst>(Inst))
+ return OpNo == StoreInst::getPointerOperandIndex() && !SI->isVolatile();
+
+ if (auto *RMW = dyn_cast<AtomicRMWInst>(Inst))
+ return OpNo == AtomicRMWInst::getPointerOperandIndex() && !RMW->isVolatile();
+
+ if (auto *CmpX = dyn_cast<AtomicCmpXchgInst>(Inst)) {
+ return OpNo == AtomicCmpXchgInst::getPointerOperandIndex() &&
+ !CmpX->isVolatile();
+ }
+
+ return false;
+}
+
bool InferAddressSpaces::rewriteWithNewAddressSpaces(
const std::vector<Value *> &Postorder,
const ValueToAddrSpaceMapTy &InferredAddrSpace, Function *F) const {
@@ -570,15 +603,10 @@ bool InferAddressSpaces::rewriteWithNewA
<< "\n with\n " << *NewV << '\n');
for (Use *U : Uses) {
- LoadInst *LI = dyn_cast<LoadInst>(U->getUser());
- StoreInst *SI = dyn_cast<StoreInst>(U->getUser());
-
- if ((LI && !LI->isVolatile()) ||
- (SI && !SI->isVolatile() &&
- U->getOperandNo() == StoreInst::getPointerOperandIndex())) {
- // If V is used as the pointer operand of a load/store, sets the pointer
- // operand to NewV. This replacement does not change the element type,
- // so the resultant load/store is still valid.
+ if (isSimplePointerUseValidToReplace(*U)) {
+ // If V is used as the pointer operand of a compatible memory operation,
+ // sets the pointer operand to NewV. This replacement does not change
+ // the element type, so the resultant load/store is still valid.
U->set(NewV);
} else if (isa<Instruction>(U->getUser())) {
// Otherwise, replaces the use with flat(NewV).
Modified: llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/basic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/basic.ll?rev=293584&r1=293583&r2=293584&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/basic.ll (original)
+++ llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/basic.ll Mon Jan 30 19:40:38 2017
@@ -128,4 +128,46 @@ define void @store_addrspacecast_ptr_val
ret void
}
+; CHECK-LABEL: @atomicrmw_add_global_to_flat(
+; CHECK-NEXT: %ret = atomicrmw add i32 addrspace(1)* %global.ptr, i32 %y seq_cst
+define i32 @atomicrmw_add_global_to_flat(i32 addrspace(1)* %global.ptr, i32 %y) #0 {
+ %cast = addrspacecast i32 addrspace(1)* %global.ptr to i32 addrspace(4)*
+ %ret = atomicrmw add i32 addrspace(4)* %cast, i32 %y seq_cst
+ ret i32 %ret
+}
+
+; CHECK-LABEL: @atomicrmw_add_group_to_flat(
+; CHECK-NEXT: %ret = atomicrmw add i32 addrspace(3)* %group.ptr, i32 %y seq_cst
+define i32 @atomicrmw_add_group_to_flat(i32 addrspace(3)* %group.ptr, i32 %y) #0 {
+ %cast = addrspacecast i32 addrspace(3)* %group.ptr to i32 addrspace(4)*
+ %ret = atomicrmw add i32 addrspace(4)* %cast, i32 %y seq_cst
+ ret i32 %ret
+}
+
+; CHECK-LABEL: @cmpxchg_global_to_flat(
+; CHECK: %ret = cmpxchg i32 addrspace(1)* %global.ptr, i32 %cmp, i32 %val seq_cst monotonic
+define { i32, i1 } @cmpxchg_global_to_flat(i32 addrspace(1)* %global.ptr, i32 %cmp, i32 %val) #0 {
+ %cast = addrspacecast i32 addrspace(1)* %global.ptr to i32 addrspace(4)*
+ %ret = cmpxchg i32 addrspace(4)* %cast, i32 %cmp, i32 %val seq_cst monotonic
+ ret { i32, i1 } %ret
+}
+
+; CHECK-LABEL: @cmpxchg_group_to_flat(
+; CHECK: %ret = cmpxchg i32 addrspace(3)* %group.ptr, i32 %cmp, i32 %val seq_cst monotonic
+define { i32, i1 } @cmpxchg_group_to_flat(i32 addrspace(3)* %group.ptr, i32 %cmp, i32 %val) #0 {
+ %cast = addrspacecast i32 addrspace(3)* %group.ptr to i32 addrspace(4)*
+ %ret = cmpxchg i32 addrspace(4)* %cast, i32 %cmp, i32 %val seq_cst monotonic
+ ret { i32, i1 } %ret
+}
+
+; Not pointer operand
+; CHECK-LABEL: @cmpxchg_group_to_flat_wrong_operand(
+; CHECK: %cast.cmp = addrspacecast i32 addrspace(3)* %cmp.ptr to i32 addrspace(4)*
+; CHECK: %ret = cmpxchg i32 addrspace(4)* addrspace(3)* %cas.ptr, i32 addrspace(4)* %cast.cmp, i32 addrspace(4)* %val seq_cst monotonic
+define { i32 addrspace(4)*, i1 } @cmpxchg_group_to_flat_wrong_operand(i32 addrspace(4)* addrspace(3)* %cas.ptr, i32 addrspace(3)* %cmp.ptr, i32 addrspace(4)* %val) #0 {
+ %cast.cmp = addrspacecast i32 addrspace(3)* %cmp.ptr to i32 addrspace(4)*
+ %ret = cmpxchg i32 addrspace(4)* addrspace(3)* %cas.ptr, i32 addrspace(4)* %cast.cmp, i32 addrspace(4)* %val seq_cst monotonic
+ ret { i32 addrspace(4)*, i1 } %ret
+}
+
attributes #0 = { nounwind }
Modified: llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/volatile.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/volatile.ll?rev=293584&r1=293583&r2=293584&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/volatile.ll (original)
+++ llvm/trunk/test/Transforms/InferAddressSpaces/AMDGPU/volatile.ll Mon Jan 30 19:40:38 2017
@@ -79,4 +79,40 @@ define void @volatile_store_flat_to_priv
ret void
}
+; CHECK-LABEL: @volatile_atomicrmw_add_group_to_flat(
+; CHECK: addrspacecast i32 addrspace(3)* %group.ptr to i32 addrspace(4)*
+; CHECK: atomicrmw volatile add i32 addrspace(4)*
+define i32 @volatile_atomicrmw_add_group_to_flat(i32 addrspace(3)* %group.ptr, i32 %y) #0 {
+ %cast = addrspacecast i32 addrspace(3)* %group.ptr to i32 addrspace(4)*
+ %ret = atomicrmw volatile add i32 addrspace(4)* %cast, i32 %y seq_cst
+ ret i32 %ret
+}
+
+; CHECK-LABEL: @volatile_atomicrmw_add_global_to_flat(
+; CHECK: addrspacecast i32 addrspace(1)* %global.ptr to i32 addrspace(4)*
+; CHECK: %ret = atomicrmw volatile add i32 addrspace(4)*
+define i32 @volatile_atomicrmw_add_global_to_flat(i32 addrspace(1)* %global.ptr, i32 %y) #0 {
+ %cast = addrspacecast i32 addrspace(1)* %global.ptr to i32 addrspace(4)*
+ %ret = atomicrmw volatile add i32 addrspace(4)* %cast, i32 %y seq_cst
+ ret i32 %ret
+}
+
+; CHECK-LABEL: @volatile_cmpxchg_global_to_flat(
+; CHECK: addrspacecast i32 addrspace(1)* %global.ptr to i32 addrspace(4)*
+; CHECK: cmpxchg volatile i32 addrspace(4)*
+define { i32, i1 } @volatile_cmpxchg_global_to_flat(i32 addrspace(1)* %global.ptr, i32 %cmp, i32 %val) #0 {
+ %cast = addrspacecast i32 addrspace(1)* %global.ptr to i32 addrspace(4)*
+ %ret = cmpxchg volatile i32 addrspace(4)* %cast, i32 %cmp, i32 %val seq_cst monotonic
+ ret { i32, i1 } %ret
+}
+
+; CHECK-LABEL: @volatile_cmpxchg_group_to_flat(
+; CHECK: addrspacecast i32 addrspace(3)* %group.ptr to i32 addrspace(4)*
+; CHECK: cmpxchg volatile i32 addrspace(4)*
+define { i32, i1 } @volatile_cmpxchg_group_to_flat(i32 addrspace(3)* %group.ptr, i32 %cmp, i32 %val) #0 {
+ %cast = addrspacecast i32 addrspace(3)* %group.ptr to i32 addrspace(4)*
+ %ret = cmpxchg volatile i32 addrspace(4)* %cast, i32 %cmp, i32 %val seq_cst monotonic
+ ret { i32, i1 } %ret
+}
+
attributes #0 = { nounwind }
\ No newline at end of file
More information about the llvm-commits
mailing list