From a09f79d2275f29b927b6f9c0472d49f6f1bfd029 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Sat, 10 Jun 2023 13:03:22 -0400 Subject: [PATCH] TargetTransformInfo: Add addrspacesMayAlias For some reason we used to only handle address space aliasing through chaining a target specific AA pass. We need never-fail simple queries in order to lower memmove intrinsics based purely on the address spaces. I also think it would be better if BasicAA checked this, rather than relying on the target AA passes. Currently we go through the more expensive AA analyses before getting to the trivial address space checks. --- llvm/include/llvm/Analysis/TargetTransformInfo.h | 8 +++++ .../llvm/Analysis/TargetTransformInfoImpl.h | 4 +++ llvm/include/llvm/CodeGen/BasicTTIImpl.h | 4 +++ llvm/lib/Analysis/TargetTransformInfo.cpp | 5 ++++ llvm/lib/Target/AMDGPU/AMDGPU.h | 26 +++++++++++++++++ llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp | 34 ++-------------------- llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h | 4 +++ 7 files changed, 53 insertions(+), 32 deletions(-) diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h index 2a5953f..dc1e5a3 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -419,6 +419,9 @@ public: /// ToAS is valid. bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const; + /// Return false if a \p AS0 address cannot possibly alias a \p AS1 address. + bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const; + /// Returns the address space ID for a target's 'flat' address space. Note /// this is not necessarily the same as addrspace(0), which LLVM sometimes /// refers to as the generic address space. The flat address space is a @@ -1690,6 +1693,7 @@ public: virtual bool isSourceOfDivergence(const Value *V) = 0; virtual bool isAlwaysUniform(const Value *V) = 0; virtual bool isValidAddrSpaceCast(unsigned FromAS, unsigned ToAS) const = 0; + virtual bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const = 0; virtual unsigned getFlatAddressSpace() = 0; virtual bool collectFlatAddressOperands(SmallVectorImpl &OpIndexes, Intrinsic::ID IID) const = 0; @@ -2075,6 +2079,10 @@ public: return Impl.isValidAddrSpaceCast(FromAS, ToAS); } + bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const override { + return Impl.addrspacesMayAlias(AS0, AS1); + } + unsigned getFlatAddressSpace() override { return Impl.getFlatAddressSpace(); } bool collectFlatAddressOperands(SmallVectorImpl &OpIndexes, diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h index de94e33..fe133b3 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -101,6 +101,10 @@ public: return false; } + bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const { + return true; + } + unsigned getFlatAddressSpace() const { return -1; } bool collectFlatAddressOperands(SmallVectorImpl &OpIndexes, diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 1c64577..a824fd4 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -286,6 +286,10 @@ public: return false; } + bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const { + return true; + } + unsigned getFlatAddressSpace() { // Return an invalid address space. return -1; diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp index e1bb963..06d97b5 100644 --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -276,6 +276,11 @@ bool llvm::TargetTransformInfo::isValidAddrSpaceCast(unsigned FromAS, return TTIImpl->isValidAddrSpaceCast(FromAS, ToAS); } +bool llvm::TargetTransformInfo::addrspacesMayAlias(unsigned FromAS, + unsigned ToAS) const { + return TTIImpl->addrspacesMayAlias(FromAS, ToAS); +} + unsigned TargetTransformInfo::getFlatAddressSpace() const { return TTIImpl->getFlatAddressSpace(); } diff --git a/llvm/lib/Target/AMDGPU/AMDGPU.h b/llvm/lib/Target/AMDGPU/AMDGPU.h index 3e15fc0..07d50df 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPU.h +++ b/llvm/lib/Target/AMDGPU/AMDGPU.h @@ -451,6 +451,32 @@ inline bool isExtendedGlobalAddrSpace(unsigned AS) { AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT || AS > AMDGPUAS::MAX_AMDGPU_ADDRESS; } + +static inline bool addrspacesMayAlias(unsigned AS1, unsigned AS2) { + static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 8, "Addr space out of range"); + + if (AS1 > AMDGPUAS::MAX_AMDGPU_ADDRESS || AS2 > AMDGPUAS::MAX_AMDGPU_ADDRESS) + return true; + + // This array is indexed by address space value enum elements 0 ... to 8 + // clang-format off + static const bool ASAliasRules[9][9] = { + /* Flat Global Region Group Constant Private Const32 BufFatPtr BufRsrc */ + /* Flat */ {true, true, false, true, true, true, true, true, true}, + /* Global */ {true, true, false, false, true, false, true, true, true}, + /* Region */ {false, false, true, false, false, false, false, false, false}, + /* Group */ {true, false, false, true, false, false, false, false, false}, + /* Constant */ {true, true, false, false, false, false, true, true, true}, + /* Private */ {true, false, false, false, false, true, false, false, false}, + /* Constant 32-bit */ {true, true, false, false, true, false, false, true, true}, + /* Buffer Fat Ptr */ {true, true, false, false, true, false, true, true, true}, + /* Buffer Resource */ {true, true, false, false, true, false, true, true, true}, + }; + // clang-format on + + return ASAliasRules[AS1][AS2]; +} + } } // End namespace llvm diff --git a/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp index 4f90f21..6394241 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUAliasAnalysis.cpp @@ -46,44 +46,14 @@ void AMDGPUAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); } -static AliasResult getAliasResult(unsigned AS1, unsigned AS2) { - static_assert(AMDGPUAS::MAX_AMDGPU_ADDRESS <= 8, "Addr space out of range"); - - if (AS1 > AMDGPUAS::MAX_AMDGPU_ADDRESS || AS2 > AMDGPUAS::MAX_AMDGPU_ADDRESS) - return AliasResult::MayAlias; - -#define ASMay AliasResult::MayAlias -#define ASNo AliasResult::NoAlias - // This array is indexed by address space value enum elements 0 ... to 8 - // clang-format off - static const AliasResult ASAliasRules[9][9] = { - /* Flat Global Region Group Constant Private Const32 BufFatPtr BufRsrc */ - /* Flat */ {ASMay, ASMay, ASNo, ASMay, ASMay, ASMay, ASMay, ASMay, ASMay}, - /* Global */ {ASMay, ASMay, ASNo, ASNo, ASMay, ASNo, ASMay, ASMay, ASMay}, - /* Region */ {ASNo, ASNo, ASMay, ASNo, ASNo, ASNo, ASNo, ASNo, ASNo}, - /* Group */ {ASMay, ASNo, ASNo, ASMay, ASNo, ASNo, ASNo, ASNo, ASNo}, - /* Constant */ {ASMay, ASMay, ASNo, ASNo, ASNo, ASNo, ASMay, ASMay, ASMay}, - /* Private */ {ASMay, ASNo, ASNo, ASNo, ASNo, ASMay, ASNo, ASNo, ASNo}, - /* Constant 32-bit */ {ASMay, ASMay, ASNo, ASNo, ASMay, ASNo, ASNo, ASMay, ASMay}, - /* Buffer Fat Ptr */ {ASMay, ASMay, ASNo, ASNo, ASMay, ASNo, ASMay, ASMay, ASMay}, - /* Buffer Resource */ {ASMay, ASMay, ASNo, ASNo, ASMay, ASNo, ASMay, ASMay, ASMay}, - }; - // clang-format on -#undef ASMay -#undef ASNo - - return ASAliasRules[AS1][AS2]; -} - AliasResult AMDGPUAAResult::alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI, const Instruction *) { unsigned asA = LocA.Ptr->getType()->getPointerAddressSpace(); unsigned asB = LocB.Ptr->getType()->getPointerAddressSpace(); - AliasResult Result = getAliasResult(asA, asB); - if (Result == AliasResult::NoAlias) - return Result; + if (!AMDGPU::addrspacesMayAlias(asA, asB)) + return AliasResult::NoAlias; // In general, FLAT (generic) pointers could be aliased to LOCAL or PRIVATE // pointers. However, as LOCAL or PRIVATE pointers point to local objects, in diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h index 27fb651..7c61429 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h @@ -194,6 +194,10 @@ public: return false; } + bool addrspacesMayAlias(unsigned AS0, unsigned AS1) const { + return AMDGPU::addrspacesMayAlias(AS0, AS1); + } + unsigned getFlatAddressSpace() const { // Don't bother running InferAddressSpaces pass on graphics shaders which // don't use flat addressing. -- 2.7.4