Skip to content

Conversation

@jofrn
Copy link
Contributor

@jofrn jofrn commented Sep 18, 2024

Ensure store to const addrspace is not allowed by Linter.

@llvmbot
Copy link
Member

llvmbot commented Sep 18, 2024

@llvm/pr-subscribers-llvm-support
@llvm/pr-subscribers-llvm-analysis
@llvm/pr-subscribers-llvm-ir

@llvm/pr-subscribers-backend-amdgpu

Author: None (jofrn)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/109181.diff

2 Files Affected:

  • (modified) llvm/lib/IR/Verifier.cpp (+17)
  • (added) llvm/test/CodeGen/AMDGPU/const-store.ll (+9)
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 06a67346fbf959..805c9ef7b72729 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4224,6 +4224,19 @@ void Verifier::visitLoadInst(LoadInst &LI) {
   visitInstruction(LI);
 }
 
+static bool isConstantAddressSpace(unsigned AS) {
+  switch (AS) {
+    using namespace AMDGPUAS;
+    case CONSTANT_ADDRESS: case CONSTANT_ADDRESS_32BIT:
+    case CONSTANT_BUFFER_0: case CONSTANT_BUFFER_1: case CONSTANT_BUFFER_2: case CONSTANT_BUFFER_3:
+    case CONSTANT_BUFFER_4: case CONSTANT_BUFFER_5: case CONSTANT_BUFFER_6: case CONSTANT_BUFFER_7:
+    case CONSTANT_BUFFER_8: case CONSTANT_BUFFER_9: case CONSTANT_BUFFER_10: case CONSTANT_BUFFER_11:
+    case CONSTANT_BUFFER_12: case CONSTANT_BUFFER_13: case CONSTANT_BUFFER_14: case CONSTANT_BUFFER_15:
+    return true;
+    default: return false;
+  }
+}
+
 void Verifier::visitStoreInst(StoreInst &SI) {
   PointerType *PTy = dyn_cast<PointerType>(SI.getOperand(1)->getType());
   Check(PTy, "Store operand must be a pointer.", &SI);
@@ -4246,6 +4259,10 @@ void Verifier::visitStoreInst(StoreInst &SI) {
     Check(SI.getSyncScopeID() == SyncScope::System,
           "Non-atomic store cannot have SynchronizationScope specified", &SI);
   }
+  if (TT.isAMDGPU()) {
+    Check(!isConstantAddressSpace(SI.getPointerAddressSpace()),
+          "Store cannot be to constant addrspace", &SI);
+  }
   visitInstruction(SI);
 }
 
diff --git a/llvm/test/CodeGen/AMDGPU/const-store.ll b/llvm/test/CodeGen/AMDGPU/const-store.ll
new file mode 100644
index 00000000000000..9447ef9db59986
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/const-store.ll
@@ -0,0 +1,9 @@
+; RUN: not llc -mtriple=amdgcn < %s |& FileCheck %s
+
+define amdgpu_kernel void @store_const(ptr addrspace(4) %out, i32 %a, i32 %b) {
+; CHECK: Store cannot be to constant addrspace
+; CHECK-NEXT: store i32 %r, ptr addrspace(4) %out
+  %r = add i32 %a, %b
+  store i32 %r, ptr addrspace(4) %out
+  ret void
+}

@jofrn jofrn requested a review from shiltian September 18, 2024 19:41
@github-actions
Copy link

github-actions bot commented Sep 18, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Ensure store to const addrspace is not allowed by IR Verifier.
visitInstruction(LI);
}

static bool isConstantAddressSpace(unsigned AS) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constant address space is not an AMD only thing. I'm thinking probably we can split this function into target dependent (for example, to query whether an AS is a constant AS) and independent part.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would the independent part contain if we do not have a use case for it yet?

@jayfoad
Copy link
Contributor

jayfoad commented Sep 19, 2024

Was there any discussion about this? I'm not sure if it should be a verifier error or just undefined behaviour at run time. Also there are other instructions that write to memory, like atomicrmw.

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must be UB, and not a verifier error. For example, we allow constant->flat casts. We do not want to have to consider the address spaces involved when folding something like store (addrspacecast ptr addrspace(4) %val to ptr)

@arsenm
Copy link
Contributor

arsenm commented Sep 20, 2024

Plus long term I don't think we should have a constant address space at all.

@jofrn
Copy link
Contributor Author

jofrn commented Sep 20, 2024

Was there any discussion about this? I'm not sure if it should be a verifier error or just undefined behaviour at run time. Also there are other instructions that write to memory, like atomicrmw.

It can be guarded with a flag perhaps. There was discussion to catch this in some way or another since it leads to more confusing error messages later on. Alternatively, we can have these checks go in a separate pass.

@jofrn
Copy link
Contributor Author

jofrn commented Sep 20, 2024

This must be UB, and not a verifier error. For example, we allow constant->flat casts. We do not want to have to consider the address spaces involved when folding something like store (addrspacecast ptr addrspace(4) %val to ptr)

The addrspace in store (addrspacecast ptr addrspace(4) %val to ptr) won't be affected by getPointerAddressSpace since this function asks about the second operand to the store, store i32 %val, ptr addrspace(4) %ptr, in particular, ptr addrspace(4) %ptr. Your example gives a complex expression on the value source, the first operand.

@nikic
Copy link
Contributor

nikic commented Sep 20, 2024

These kinds of checks should go into the Lint pass instead of the Verifier pass.

@arsenm
Copy link
Contributor

arsenm commented Sep 20, 2024

The addrspace in store (addrspacecast ptr addrspace(4) %val to ptr) won't be affected by getPointerAddressSpace since this function asks about the second operand to the store, store i32 %val, ptr addrspace(4) %ptr, in particular, ptr addrspace(4) %ptr. Your example gives a complex expression on the value source, the first operand.

You're reading the example too literally. It should be valid for a pass to strip away the cast, and store directly to the original address space of the pointer without considering any special information. It would be a target specific burden placed on any IR transformation, which is not OK.

This type of check belongs in Lint, which hardly ever gets used and I'm not sure is worth the effort

@llvmbot llvmbot added the llvm:analysis Includes value tracking, cost tables and constant folding label Sep 20, 2024
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test atomicrmw, cmpxchg, and a memset, memcpy? Also at least the addrspace(6) case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no reason to set the address space of the function

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

negative test with a different target

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should move this to test/Analysis/Lint

@jofrn jofrn force-pushed the amdgpu-irverifier branch 2 times, most recently from 0b69206 to b1c3d38 Compare September 20, 2024 19:52
@jofrn jofrn changed the title [Verifier][AMDGPU] No store to const addrspace [Lint][AMDGPU] No store to const addrspace Sep 20, 2024
Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New approach looks reasonable to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a helper in AMDGPUAddrSpace.h? I'd expect this logic to already exist somewhere, but it looks like AMDGPUAA is only looking for CONSTANT_ADDRESS and nothing else:

if (LI->getPointerAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS)


if (Flags & MemRef::Write) {
if (TT.isAMDGPU())
Check(!AMDGPU::isConstantAddressSpace(UnderlyingObject->getType()->getPointerAddressSpace()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible or better to do the check via TTI? I'm not sure if it's a good idea to do the check based on triple.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of verification doesn't really fit in with TTI

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear, the "check" I meant here was AMDGPU::isConstantAddressSpace.


if (Flags & MemRef::Write) {
if (TT.isAMDGPU())
Check(!AMDGPU::isConstantAddressSpace(UnderlyingObject->getType()->getPointerAddressSpace()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of verification doesn't really fit in with TTI

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the actual address spaces, not x y

@jofrn jofrn force-pushed the amdgpu-irverifier branch 3 times, most recently from 8fa566a to 251171b Compare September 23, 2024 18:45
Comment on lines +98 to +99
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
switch (AS) {
using namespace AMDGPUAS;
using namespace AMDGPUAS;
switch (AS) {

Copy link
Contributor

@arsenm arsenm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with nit

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe test arbitrary call that may write (those probably should not fail )

@jofrn jofrn merged commit 3e65c30 into llvm:main Sep 25, 2024
4 checks passed
Sterling-Augustine pushed a commit to Sterling-Augustine/llvm-project that referenced this pull request Sep 27, 2024
Ensure store to const addrspace is not allowed by Linter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend:AMDGPU llvm:analysis Includes value tracking, cost tables and constant folding llvm:ir llvm:support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants