[llvm] [NVPTX][AA] Traverse use-def chain to find non-generic addrspace (PR #106477)
Alex MacLean via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 29 16:23:08 PDT 2024
https://github.com/AlexMaclean updated https://github.com/llvm/llvm-project/pull/106477
>From 8781e9153994b59f2bb21355acb0c14cde23a5a8 Mon Sep 17 00:00:00 2001
From: Alex MacLean <amaclean at nvidia.com>
Date: Fri, 23 Aug 2024 16:18:46 +0000
Subject: [PATCH 1/4] [NVPTXAA] Traverse use-def chain to find non-generic
addrspace
---
llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp | 38 ++++++++++++++++----
llvm/test/CodeGen/NVPTX/nvptx-aa.ll | 37 +++++++++++++++++++
2 files changed, 68 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
index 4f106584eb0a94..e86dfee875fd89 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
@@ -15,11 +15,17 @@
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/Support/CommandLine.h"
using namespace llvm;
#define DEBUG_TYPE "NVPTX-aa"
+static cl::opt<unsigned> TraverseAddressSpacesLimit(
+ "nvptx-traverse-address-aliasing-limit", cl::Hidden,
+ cl::desc("Depth limit for finding address space through traversal"),
+ cl::init(6));
+
AnalysisKey NVPTXAA::Key;
char NVPTXAAWrapperPass::ID = 0;
@@ -47,6 +53,28 @@ void NVPTXAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}
+static unsigned getAddressSpace(const Value *V, unsigned MaxLookup) {
+ // Find the first non-generic address space traversing the UD chain.
+ // It is undefined behaviour if a pointer belongs to more than one
+ // non-overlapping address spaces along a valid execution path.
+ for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
+ const auto *PTy = dyn_cast<PointerType>(V->getType());
+ if (!PTy)
+ return AddressSpace::ADDRESS_SPACE_GENERIC;
+
+ const unsigned AS = PTy->getAddressSpace();
+ if (AS != AddressSpace::ADDRESS_SPACE_GENERIC)
+ return AS;
+
+ // Continue traversing if address space is generic
+ const Value *VNext = getUnderlyingObject(V, 1);
+ if (VNext == V)
+ return AddressSpace::ADDRESS_SPACE_GENERIC;
+ V = VNext;
+ }
+ return AddressSpace::ADDRESS_SPACE_GENERIC;
+}
+
static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {
if ((AS1 == ADDRESS_SPACE_GENERIC) || (AS2 == ADDRESS_SPACE_GENERIC))
return AliasResult::MayAlias;
@@ -70,8 +98,8 @@ static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {
AliasResult NVPTXAAResult::alias(const MemoryLocation &Loc1,
const MemoryLocation &Loc2, AAQueryInfo &AAQI,
const Instruction *) {
- unsigned AS1 = Loc1.Ptr->getType()->getPointerAddressSpace();
- unsigned AS2 = Loc2.Ptr->getType()->getPointerAddressSpace();
+ unsigned AS1 = getAddressSpace(Loc1.Ptr, TraverseAddressSpacesLimit);
+ unsigned AS2 = getAddressSpace(Loc2.Ptr, TraverseAddressSpacesLimit);
return getAliasResult(AS1, AS2);
}
@@ -87,11 +115,7 @@ static bool isConstOrParam(unsigned AS) {
ModRefInfo NVPTXAAResult::getModRefInfoMask(const MemoryLocation &Loc,
AAQueryInfo &AAQI,
bool IgnoreLocals) {
- if (isConstOrParam(Loc.Ptr->getType()->getPointerAddressSpace()))
- return ModRefInfo::NoModRef;
-
- const Value *Base = getUnderlyingObject(Loc.Ptr);
- if (isConstOrParam(Base->getType()->getPointerAddressSpace()))
+ if (isConstOrParam(getAddressSpace(Loc.Ptr, TraverseAddressSpacesLimit)))
return ModRefInfo::NoModRef;
return ModRefInfo::ModRef;
diff --git a/llvm/test/CodeGen/NVPTX/nvptx-aa.ll b/llvm/test/CodeGen/NVPTX/nvptx-aa.ll
index 79bd06ee677ac0..074e741dc3e949 100644
--- a/llvm/test/CodeGen/NVPTX/nvptx-aa.ll
+++ b/llvm/test/CodeGen/NVPTX/nvptx-aa.ll
@@ -111,3 +111,40 @@ loop:
done:
ret i8 %v2
}
+
+;; Address space information may be encoded anywhere along the UD chain.
+;; We define a set of tests that:
+;; 1. Perform some number of address space casts on pointer A and B
+;; 2. Store a value to address A
+;; 3. Store a value to address B (that we know does not alias with A)
+
+;; generic->space
+; CHECK-ALIAS-LABEL: Function: test_traversal_gen_space
+; CHECK-ALIAS: NoAlias: i32 addrspace(1)* %global, i32 addrspace(5)* %local
+define void @test_traversal_gen_space(ptr %gen, ptr addrspace(1) %global) {
+ %local = addrspacecast ptr %gen to ptr addrspace(5)
+ store i32 1, ptr addrspace(5) %local, align 8
+ store i32 5, ptr addrspace(1) %global, align 8
+ ret void
+}
+
+;; space->generic
+; CHECK-ALIAS-LABEL: Function: test_traversal_space_gen
+; CHECK-ALIAS: NoAlias: i32* %gen, i32 addrspace(1)* %global
+define void @test_traversal_space_gen(ptr addrspace(5) %local, ptr addrspace(1) %global) {
+ %gen = addrspacecast ptr addrspace(5) %local to ptr
+ store i32 2, ptr %gen, align 8
+ store i32 5, ptr addrspace(1) %global, align 8
+ ret void
+}
+
+;; generic->space->generic
+; CHECK-ALIAS-LABEL: Function: test_traversal_gen_space_gen
+; CHECK-ALIAS: NoAlias: i32* %gen2, i32 addrspace(1)* %global
+define void @test_traversal_gen_space_gen(ptr %gen1, ptr addrspace(1) %global) {
+ %local = addrspacecast ptr %gen1 to ptr addrspace(5)
+ %gen2 = addrspacecast ptr addrspace(5) %local to ptr
+ store i32 3, ptr %gen2, align 8
+ store i32 5, ptr addrspace(1) %global, align 8
+ ret void
+}
>From 067f1578cc192f694e91c9192ccf439bedf713da Mon Sep 17 00:00:00 2001
From: Alex MacLean <amaclean at nvidia.com>
Date: Thu, 29 Aug 2024 21:39:11 +0000
Subject: [PATCH 2/4] address comments
---
llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
index e86dfee875fd89..a026fe46170d13 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
@@ -72,6 +72,9 @@ static unsigned getAddressSpace(const Value *V, unsigned MaxLookup) {
return AddressSpace::ADDRESS_SPACE_GENERIC;
V = VNext;
}
+ // If V's AS is not generic it should be returned above
+ assert(V->getType()->getPointerAddressSpace() ==
+ AddressSpace::ADDRESS_SPACE_GENERIC);
return AddressSpace::ADDRESS_SPACE_GENERIC;
}
>From de229c22959311416c28397b62627ed1a1ca73b4 Mon Sep 17 00:00:00 2001
From: Alex MacLean <amaclean at nvidia.com>
Date: Thu, 29 Aug 2024 22:25:49 +0000
Subject: [PATCH 3/4] fixup
---
llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
index a026fe46170d13..82a4a2870c1f3d 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
@@ -57,13 +57,13 @@ static unsigned getAddressSpace(const Value *V, unsigned MaxLookup) {
// Find the first non-generic address space traversing the UD chain.
// It is undefined behaviour if a pointer belongs to more than one
// non-overlapping address spaces along a valid execution path.
- for (unsigned Count = 0; MaxLookup == 0 || Count < MaxLookup; ++Count) {
+ for (unsigned Count = 0;; ++Count) {
const auto *PTy = dyn_cast<PointerType>(V->getType());
if (!PTy)
return AddressSpace::ADDRESS_SPACE_GENERIC;
const unsigned AS = PTy->getAddressSpace();
- if (AS != AddressSpace::ADDRESS_SPACE_GENERIC)
+ if (AS != AddressSpace::ADDRESS_SPACE_GENERIC || Count >= MaxLookup)
return AS;
// Continue traversing if address space is generic
@@ -72,10 +72,6 @@ static unsigned getAddressSpace(const Value *V, unsigned MaxLookup) {
return AddressSpace::ADDRESS_SPACE_GENERIC;
V = VNext;
}
- // If V's AS is not generic it should be returned above
- assert(V->getType()->getPointerAddressSpace() ==
- AddressSpace::ADDRESS_SPACE_GENERIC);
- return AddressSpace::ADDRESS_SPACE_GENERIC;
}
static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {
>From a1ef0408ce674f2aeaba713308a8fbf355e62a22 Mon Sep 17 00:00:00 2001
From: Alex MacLean <amaclean at nvidia.com>
Date: Thu, 29 Aug 2024 23:22:50 +0000
Subject: [PATCH 4/4] address comments
---
llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp | 25 +++++++++-----------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
index 82a4a2870c1f3d..eb03561bab1e52 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAliasAnalysis.cpp
@@ -57,21 +57,18 @@ static unsigned getAddressSpace(const Value *V, unsigned MaxLookup) {
// Find the first non-generic address space traversing the UD chain.
// It is undefined behaviour if a pointer belongs to more than one
// non-overlapping address spaces along a valid execution path.
- for (unsigned Count = 0;; ++Count) {
- const auto *PTy = dyn_cast<PointerType>(V->getType());
- if (!PTy)
- return AddressSpace::ADDRESS_SPACE_GENERIC;
-
- const unsigned AS = PTy->getAddressSpace();
- if (AS != AddressSpace::ADDRESS_SPACE_GENERIC || Count >= MaxLookup)
- return AS;
-
- // Continue traversing if address space is generic
- const Value *VNext = getUnderlyingObject(V, 1);
- if (VNext == V)
- return AddressSpace::ADDRESS_SPACE_GENERIC;
- V = VNext;
+ auto GetAs = [](const Value *V) -> unsigned {
+ if (const auto *PTy = dyn_cast<PointerType>(V->getType()))
+ return PTy->getAddressSpace();
+ return ADDRESS_SPACE_GENERIC;
+ };
+ while (MaxLookup-- && GetAs(V) == ADDRESS_SPACE_GENERIC) {
+ const Value *NewV = getUnderlyingObject(V, 1);
+ if (NewV == V)
+ break;
+ V = NewV;
}
+ return GetAs(V);
}
static AliasResult::Kind getAliasResult(unsigned AS1, unsigned AS2) {
More information about the llvm-commits
mailing list