Skip to content

[IR] Add TargetExtType::CanBeLocal property #99016

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Nov 22, 2024
Merged

Conversation

jayfoad
Copy link
Contributor

@jayfoad jayfoad commented Jul 16, 2024

Add a property to allow marking target extension types that cannot be
used in an alloca instruction or byval argument, similar to CanBeGlobal
for global variables.

@llvmbot
Copy link
Member

llvmbot commented Jul 16, 2024

@llvm/pr-subscribers-clang
@llvm/pr-subscribers-backend-amdgpu

@llvm/pr-subscribers-llvm-ir

Author: Jay Foad (jayfoad)

Changes

Add a property to allow marking target extension types that cannot be
used in an alloca instruction, similar to CanBeGlobal for global
variables.


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

4 Files Affected:

  • (modified) llvm/include/llvm/IR/DerivedTypes.h (+2)
  • (modified) llvm/lib/IR/Type.cpp (+4-2)
  • (modified) llvm/lib/IR/Verifier.cpp (+6)
  • (modified) llvm/test/Assembler/target-type-properties.ll (+8)
diff --git a/llvm/include/llvm/IR/DerivedTypes.h b/llvm/include/llvm/IR/DerivedTypes.h
index 01f76d4932780..054cb370bc316 100644
--- a/llvm/include/llvm/IR/DerivedTypes.h
+++ b/llvm/include/llvm/IR/DerivedTypes.h
@@ -769,6 +769,8 @@ class TargetExtType : public Type {
     HasZeroInit = 1U << 0,
     /// This type may be used as the value type of a global variable.
     CanBeGlobal = 1U << 1,
+    /// This type may be used as the allocated type of an alloca instruction.
+    CanBeAlloca = 1U << 2,
   };
 
   /// Returns true if the target extension type contains the given property.
diff --git a/llvm/lib/IR/Type.cpp b/llvm/lib/IR/Type.cpp
index 5c61ad9f000b0..3f982ef520e92 100644
--- a/llvm/lib/IR/Type.cpp
+++ b/llvm/lib/IR/Type.cpp
@@ -838,12 +838,14 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
     return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::CanBeGlobal);
   if (Name.starts_with("spirv."))
     return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::HasZeroInit,
-                          TargetExtType::CanBeGlobal);
+                          TargetExtType::CanBeGlobal,
+                          TargetExtType::CanBeAlloca);
 
   // Opaque types in the AArch64 name space.
   if (Name == "aarch64.svcount")
     return TargetTypeInfo(ScalableVectorType::get(Type::getInt1Ty(C), 16),
-                          TargetExtType::HasZeroInit);
+                          TargetExtType::HasZeroInit,
+                          TargetExtType::CanBeAlloca);
 
   return TargetTypeInfo(Type::getVoidTy(C));
 }
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 75a53c1c99734..e59dc6bf24d38 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -4273,6 +4273,12 @@ void Verifier::visitAllocaInst(AllocaInst &AI) {
   SmallPtrSet<Type*, 4> Visited;
   Check(AI.getAllocatedType()->isSized(&Visited),
         "Cannot allocate unsized type", &AI);
+  // Check if it's a target extension type that disallows being used in an
+  // alloca.
+  if (auto *TTy = dyn_cast<TargetExtType>(AI.getAllocatedType())) {
+    Check(TTy->hasProperty(TargetExtType::CanBeAlloca),
+          "Alloca has illegal target extension type", &AI);
+  }
   Check(AI.getArraySize()->getType()->isIntegerTy(),
         "Alloca array size must have integer type", &AI);
   if (MaybeAlign A = AI.getAlign()) {
diff --git a/llvm/test/Assembler/target-type-properties.ll b/llvm/test/Assembler/target-type-properties.ll
index 49c9d812f1cf4..eae5eec04da85 100644
--- a/llvm/test/Assembler/target-type-properties.ll
+++ b/llvm/test/Assembler/target-type-properties.ll
@@ -1,6 +1,7 @@
 ; RUN: split-file %s %t
 ; RUN: not llvm-as < %t/zeroinit-error.ll -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-ZEROINIT %s
 ; RUN: not llvm-as < %t/global-var.ll -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-GLOBALVAR %s
+; RUN: not llvm-as < %t/alloca.ll -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-ALLOCA %s
 ; Check target extension type properties are verified in the assembler.
 
 ;--- zeroinit-error.ll
@@ -14,3 +15,10 @@ define void @foo() {
 ;--- global-var.ll
 @global = external global target("unknown_target_type")
 ; CHECK-GLOBALVAR: Global @global has illegal target extension type
+
+;--- alloca.ll
+define void @foo() {
+  %val = alloca target("spirv.Image")
+; CHECK-ALLOCA: Alloca has illegal target extension type
+  ret void
+}

@@ -838,12 +838,14 @@ static TargetTypeInfo getTargetTypeInfo(const TargetExtType *Ty) {
return TargetTypeInfo(PointerType::get(C, 0), TargetExtType::CanBeGlobal);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made a complete guess here that spirv.Image should not be used in allocas, so that I could use it as a test case. Please let me know if I got that wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe @jcranmer-intel can comment on which spirv. types can/cannot be used in allocas.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are now some tests which do use spirv.Image in allocas:

test/CodeGen/SPIRV/transcoding/image_with_access_qualifiers.ll
test/CodeGen/SPIRV/transcoding/get_image_num_mip_levels.ll
test/CodeGen/SPIRV/image-unoptimized.ll
test/CodeGen/SPIRV/read_image.ll

@jcranmer-intel any comments on the validity of this? Is it a supported use of spirv.Image, or just something that was conventient for these test cases?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because of this I don't have any non-CanBeLocal types to test with, so the tests I added in type/Assembler/target-type-properties.ll are currently failing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm now using the newly added amdgcn.named.barrier for testing.

@jayfoad jayfoad requested a review from nhaehnle July 16, 2024 10:40
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.

The use case here is specifically a type that is sized but cannot be used in alloca?

What about use in byval?

@jayfoad
Copy link
Contributor Author

jayfoad commented Jul 17, 2024

The use case here is specifically a type that is sized but cannot be used in alloca?

Yes. The use case I am interested in is special global objects that correspond to hardware resources that will be statically allocated by the backend. They can never be dynamically allocated.

What about use in byval?

We definitely don't want them in byval - thanks!

Perhaps MustBeGlobal would be a better name to describe this property?

@nhaehnle
Copy link
Collaborator

What's the status of this? It seems reasonable to me. In terms of the name, I would slightly prefer something that relaxes restrictions instead of adding them, so perhaps CanBeStack (to cover both byval and alloca)?

Add a property to allow marking target extension types that cannot be
used in an alloca instruction, similar to CanBeGlobal for global
variables.
@jayfoad jayfoad changed the title [IR] Add TargetExtType::CanBeAlloca property [IR] Add TargetExtType::CanBeLocal property Aug 21, 2024
@jayfoad
Copy link
Contributor Author

jayfoad commented Aug 21, 2024

so perhaps CanBeStack (to cover both byval and alloca)?

I went for CanBeLocal but I'm happy to change it again if reviewers want.

// stack.
if (auto *TTy = dyn_cast<TargetExtType>(AI.getAllocatedType())) {
Check(TTy->hasProperty(TargetExtType::CanBeLocal),
"Alloca has illegal target extension type", &AI);
Copy link
Contributor

Choose a reason for hiding this comment

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

Also applies to the existing CanBeGlobal check, but this probably needs to be recursive? We'd not want to forbid target("foo") but then allow { target("foo") }.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I asked about that here: https://discourse.llvm.org/t/rfc-adding-opaque-types-to-llvm-ir/65326/25

I might work on it but I want to keep that separate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

#116639 does this for CanBeGlobal.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've now added the recursive checks to this patch too.

@llvmbot llvmbot added clang Clang issues not falling into any other category backend:AMDGPU labels Nov 19, 2024
@jayfoad
Copy link
Contributor Author

jayfoad commented Nov 21, 2024

Ping. This is ready again for review.

Comment on lines +231 to +232
SCDB_ContainsNonLocalTargetExtType = 64,
SCDB_NotContainsNonLocalTargetExtType = 128,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TBH I'm not sure if it's really worth adding these flags, just for an IR verifier check. I guess it accelerates recursive checking of pathological struct types with lots of repeated element types.

@jayfoad jayfoad requested a review from cmc-rep November 21, 2024 12:04
@jayfoad jayfoad merged commit 294c5cb into llvm:main Nov 22, 2024
6 of 8 checks passed
@jayfoad jayfoad deleted the canbealloca branch November 22, 2024 10:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AMDGPU clang Clang issues not falling into any other category llvm:ir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants