Skip to content

Commit e004566

Browse files
authored
[NVPTX][AA] Traverse use-def chain to find non-generic addrspace (#106477)
Address space information may be encoded anywhere along the use-def chain. Take advantage of this by traversing the chain until we find a non-generic addrspace.
1 parent ddaf2e2 commit e004566

File tree

2 files changed

+64
-7
lines changed

2 files changed

+64
-7
lines changed

llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,17 @@
1515
#include "llvm/Analysis/ValueTracking.h"
1616
#include "llvm/IR/CallingConv.h"
1717
#include "llvm/IR/Instructions.h"
18+
#include "llvm/Support/CommandLine.h"
1819

1920
using namespace llvm;
2021

2122
#define DEBUG_TYPE "NVPTX-aa"
2223

24+
static cl::opt<unsigned> TraverseAddressSpacesLimit(
25+
"nvptx-traverse-address-aliasing-limit", cl::Hidden,
26+
cl::desc("Depth limit for finding address space through traversal"),
27+
cl::init(6));
28+
2329
AnalysisKey NVPTXAA::Key;
2430

2531
char NVPTXAAWrapperPass::ID = 0;
@@ -47,6 +53,24 @@ void NVPTXAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
4753
AU.setPreservesAll();
4854
}
4955

56+
static unsigned getAddressSpace(const Value *V, unsigned MaxLookup) {
57+
// Find the first non-generic address space traversing the UD chain.
58+
// It is undefined behaviour if a pointer belongs to more than one
59+
// non-overlapping address spaces along a valid execution path.
60+
auto GetAS = [](const Value *V) -> unsigned {
61+
if (const auto *PTy = dyn_cast<PointerType>(V->getType()))
62+
return PTy->getAddressSpace();
63+
return ADDRESS_SPACE_GENERIC;
64+
};
65+
while (MaxLookup-- && GetAS(V) == ADDRESS_SPACE_GENERIC) {
66+
const Value *NewV = getUnderlyingObject(V, 1);
67+
if (NewV == V)
68+
break;
69+
V = NewV;
70+
}
71+
return GetAS(V);
72+
}
73+
5074
static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {
5175
if ((AS1 == ADDRESS_SPACE_GENERIC) || (AS2 == ADDRESS_SPACE_GENERIC))
5276
return AliasResult::MayAlias;
@@ -70,8 +94,8 @@ static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {
7094
AliasResult NVPTXAAResult::alias(const MemoryLocation &Loc1,
7195
const MemoryLocation &Loc2, AAQueryInfo &AAQI,
7296
const Instruction *) {
73-
unsigned AS1 = Loc1.Ptr->getType()->getPointerAddressSpace();
74-
unsigned AS2 = Loc2.Ptr->getType()->getPointerAddressSpace();
97+
unsigned AS1 = getAddressSpace(Loc1.Ptr, TraverseAddressSpacesLimit);
98+
unsigned AS2 = getAddressSpace(Loc2.Ptr, TraverseAddressSpacesLimit);
7599

76100
return getAliasResult(AS1, AS2);
77101
}
@@ -87,11 +111,7 @@ static bool isConstOrParam(unsigned AS) {
87111
ModRefInfo NVPTXAAResult::getModRefInfoMask(const MemoryLocation &Loc,
88112
AAQueryInfo &AAQI,
89113
bool IgnoreLocals) {
90-
if (isConstOrParam(Loc.Ptr->getType()->getPointerAddressSpace()))
91-
return ModRefInfo::NoModRef;
92-
93-
const Value *Base = getUnderlyingObject(Loc.Ptr);
94-
if (isConstOrParam(Base->getType()->getPointerAddressSpace()))
114+
if (isConstOrParam(getAddressSpace(Loc.Ptr, TraverseAddressSpacesLimit)))
95115
return ModRefInfo::NoModRef;
96116

97117
return ModRefInfo::ModRef;

llvm/test/CodeGen/NVPTX/nvptx-aa.ll

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,40 @@ loop:
111111
done:
112112
ret i8 %v2
113113
}
114+
115+
;; Address space information may be encoded anywhere along the UD chain.
116+
;; We define a set of tests that:
117+
;; 1. Perform some number of address space casts on pointer A and B
118+
;; 2. Store a value to address A
119+
;; 3. Store a value to address B (that we know does not alias with A)
120+
121+
;; generic->space
122+
; CHECK-ALIAS-LABEL: Function: test_traversal_gen_space
123+
; CHECK-ALIAS: NoAlias: i32 addrspace(1)* %global, i32 addrspace(5)* %local
124+
define void @test_traversal_gen_space(ptr %gen, ptr addrspace(1) %global) {
125+
%local = addrspacecast ptr %gen to ptr addrspace(5)
126+
store i32 1, ptr addrspace(5) %local, align 8
127+
store i32 5, ptr addrspace(1) %global, align 8
128+
ret void
129+
}
130+
131+
;; space->generic
132+
; CHECK-ALIAS-LABEL: Function: test_traversal_space_gen
133+
; CHECK-ALIAS: NoAlias: i32* %gen, i32 addrspace(1)* %global
134+
define void @test_traversal_space_gen(ptr addrspace(5) %local, ptr addrspace(1) %global) {
135+
%gen = addrspacecast ptr addrspace(5) %local to ptr
136+
store i32 2, ptr %gen, align 8
137+
store i32 5, ptr addrspace(1) %global, align 8
138+
ret void
139+
}
140+
141+
;; generic->space->generic
142+
; CHECK-ALIAS-LABEL: Function: test_traversal_gen_space_gen
143+
; CHECK-ALIAS: NoAlias: i32* %gen2, i32 addrspace(1)* %global
144+
define void @test_traversal_gen_space_gen(ptr %gen1, ptr addrspace(1) %global) {
145+
%local = addrspacecast ptr %gen1 to ptr addrspace(5)
146+
%gen2 = addrspacecast ptr addrspace(5) %local to ptr
147+
store i32 3, ptr %gen2, align 8
148+
store i32 5, ptr addrspace(1) %global, align 8
149+
ret void
150+
}

0 commit comments

Comments
 (0)