Skip to content

[SPIR-V] Consistent handling of TargetExtTypes in emit-intrinsics #135682

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 5 commits into from
May 29, 2025

Conversation

cassiebeckley
Copy link
Member

TargetExtType values are replaced with calls to llvm.spv.track.constant, with a poison value, but llvm.spv.assign.type was called with their original value. This PR updates the assign.type call to be consistent with the track.constant call.

Fixes #134417.

TargetExtType values are replaced with calls to
`llvm.spv.track.constant`, with a `poison` value, but
`llvm.spv.assign.type` was called with their original value. This PR
updates the `assign.type` call to be consistent with the
`track.constant` call.

Fixes llvm#134417.
@llvmbot
Copy link
Member

llvmbot commented Apr 14, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Cassandra Beckley (cassiebeckley)

Changes

TargetExtType values are replaced with calls to llvm.spv.track.constant, with a poison value, but llvm.spv.assign.type was called with their original value. This PR updates the assign.type call to be consistent with the track.constant call.

Fixes #134417.


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

2 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp (+7-13)
  • (added) llvm/test/CodeGen/SPIRV/inline/type.undef.ll (+20)
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 0067d2400529a..b72de93d041f7 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -1947,10 +1947,14 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
           GR->buildAssignPtr(B, ElemTy ? ElemTy : deduceElementType(Op, true),
                              Op);
         } else {
+          Value *OpTyVal = Op;
+          if (OpTy->isTargetExtTy()) {
+            OpTyVal = getNormalizedPoisonValue(OpTy);
+          }
           CallInst *AssignCI =
               buildIntrWithMD(Intrinsic::spv_assign_type, {OpTy},
-                              getNormalizedPoisonValue(OpTy), Op, {}, B);
-          GR->addAssignPtrTypeInstr(Op, AssignCI);
+                              getNormalizedPoisonValue(OpTy), OpTyVal, {}, B);
+          GR->addAssignPtrTypeInstr(OpTyVal, AssignCI);
         }
       }
     }
@@ -2061,22 +2065,12 @@ void SPIRVEmitIntrinsics::processInstrAfterVisit(Instruction *I,
       BPrepared = true;
     }
     Type *OpTy = Op->getType();
-    Value *OpTyVal = Op;
-    if (OpTy->isTargetExtTy())
-      OpTyVal = getNormalizedPoisonValue(OpTy);
     Type *OpElemTy = GR->findDeducedElementType(Op);
     Value *NewOp = Op;
     if (OpTy->isTargetExtTy()) {
+      Value *OpTyVal = getNormalizedPoisonValue(OpTy);
       NewOp = buildIntrWithMD(Intrinsic::spv_track_constant,
                               {OpTy, OpTyVal->getType()}, Op, OpTyVal, {}, B);
-      if (isPointerTy(OpTy)) {
-        if (OpElemTy) {
-          GR->buildAssignPtr(B, OpElemTy, NewOp);
-        } else {
-          insertTodoType(NewOp);
-          GR->buildAssignPtr(B, OpTy, NewOp);
-        }
-      }
     }
     if (!IsConstComposite && isPointerTy(OpTy) && OpElemTy != nullptr &&
         OpElemTy != IntegerType::getInt8Ty(I->getContext())) {
diff --git a/llvm/test/CodeGen/SPIRV/inline/type.undef.ll b/llvm/test/CodeGen/SPIRV/inline/type.undef.ll
new file mode 100644
index 0000000000000..8cb90007c9aba
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/inline/type.undef.ll
@@ -0,0 +1,20 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv-unknown-unknown %s -o - | spirv-as - -o - | spirv-val %}
+
+%literal_32 = type target("spirv.Literal", 32)
+%literal_true = type target("spirv.Literal", 1)
+
+; CHECK-DAG: OpUnknown(21, 4) [[int_t:%[0-9]+]] 32 1
+%int_t = type target("spirv.Type", %literal_32, %literal_true, 21, 4, 32)
+
+; CHECK-DAG: {{%[0-9]+}} = OpTypeFunction [[int_t]]
+define %int_t @foo() {
+entry:
+  %v = alloca %int_t
+  %i = load %int_t, ptr %v
+
+; CHECK-DAG: [[i:%[0-9]+]] = OpUndef [[int_t]]
+; CHECK-DAG: OpReturnValue [[i]]
+  ret %int_t %i
+}

@@ -1947,10 +1947,14 @@ void SPIRVEmitIntrinsics::insertAssignTypeIntrs(Instruction *I,
GR->buildAssignPtr(B, ElemTy ? ElemTy : deduceElementType(Op, true),
Op);
} else {
Value *OpTyVal = Op;
if (OpTy->isTargetExtTy()) {
OpTyVal = getNormalizedPoisonValue(OpTy);
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's please document this explicitly in comments.

A wider context is that in #130605 we have started elimination of spv_track_constant intrinsics, and this is a work in progress. I understand this change and its need to resolve the issue, however, it introduces a hidden relations between this point in the code and SPIRVEmitIntrinsics::processInstrAfterVisit() where Intrinsic::spv_track_constant is inserted. This create a pitfall for anyone who will try to untangle type inference logic from emit-intrinsic logic.

I think it's ok to introduce this change, but please add a longer comment here and in SPIRVEmitIntrinsics::processInstrAfterVisit(), referencing another occurrence of the spv_track_constant/spv_assign_type pair implicitly linked by isTargetExtTy(), so that we do not forget to address this after the prospective rework of type inference vs. emit-intrinsic starts.

Copy link

github-actions bot commented May 23, 2025

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

@s-perron s-perron self-assigned this May 29, 2025
@s-perron s-perron merged commit e60b633 into llvm:main May 29, 2025
12 checks passed
google-yfyang pushed a commit to google-yfyang/llvm-project that referenced this pull request May 29, 2025
…vm#135682)

TargetExtType values are replaced with calls to
`llvm.spv.track.constant`, with a `poison` value, but
`llvm.spv.assign.type` was called with their original value. This PR
updates the `assign.type` call to be consistent with the
`track.constant` call.

Fixes llvm#134417.

---------

Co-authored-by: Steven Perron <stevenperron@google.com>
sivan-shani pushed a commit to sivan-shani/llvm-project that referenced this pull request Jun 3, 2025
…vm#135682)

TargetExtType values are replaced with calls to
`llvm.spv.track.constant`, with a `poison` value, but
`llvm.spv.assign.type` was called with their original value. This PR
updates the `assign.type` call to be consistent with the
`track.constant` call.

Fixes llvm#134417.

---------

Co-authored-by: Steven Perron <stevenperron@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SPIR-V] Returning undef from a function with a spirv.Type return type crashes
5 participants