[llvm] [SPIR-V] Rewrite extractvalue over aggregate spv_extractv result (PR #200065)
Arseniy Obolenskiy via llvm-commits
llvm-commits at lists.llvm.org
Thu May 28 07:29:38 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/200065
>From 6f11cfde1230a6e90a679d4de748ffbda93623c0 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 27 May 2026 23:37:13 +0200
Subject: [PATCH 1/2] [SPIR-V] Rewrite extractvalue over aggregate spv_extractv
result
Chained extractvalue from an aggregate-returning call left raw IR over a multi-register spv_extractv, crashing later in foldImm. Mutate the producer to i32 and convert the user too
---
llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 10 ++++++--
.../extractvalue-aggregate-chain.ll | 23 +++++++++++++++++++
2 files changed, 31 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/instructions/extractvalue-aggregate-chain.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index b6e71c7b76348..08d80851cda8a 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -2254,10 +2254,16 @@ Instruction *SPIRVEmitIntrinsics::visitInsertValueInst(InsertValueInst &I) {
}
Instruction *SPIRVEmitIntrinsics::visitExtractValueInst(ExtractValueInst &I) {
- if (I.getAggregateOperand()->getType()->isAggregateType())
- return &I;
IRBuilder<> B(I.getParent());
B.SetInsertPoint(&I);
+ if (I.getAggregateOperand()->getType()->isAggregateType()) {
+ // Mutate an aggregate-returning spv_extractv producer to i32 so
+ // IRTranslator does not see a multi-register value.
+ CallBase *CB = dyn_cast<CallBase>(I.getAggregateOperand());
+ if (!CB || CB->getIntrinsicID() != Intrinsic::spv_extractv)
+ return &I;
+ CB->mutateType(B.getInt32Ty());
+ }
SmallVector<Value *> Args(I.operands());
for (auto &Op : I.indices())
Args.push_back(B.getInt32(Op));
diff --git a/llvm/test/CodeGen/SPIRV/instructions/extractvalue-aggregate-chain.ll b/llvm/test/CodeGen/SPIRV/instructions/extractvalue-aggregate-chain.ll
new file mode 100644
index 0000000000000..64364a5d88ace
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/instructions/extractvalue-aggregate-chain.ll
@@ -0,0 +1,23 @@
+; RUN: llc -verify-machineinstrs -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; Chained extractvalue from an aggregate-returning call used to crash in
+; foldImm because the outer extractvalue was left as raw IR over a
+; multi-register spv_extractv result.
+
+%ty = type { ptr addrspace(4), ptr addrspace(4), [8 x i8] }
+
+declare %ty @arr_ret()
+
+; CHECK: OpFunction
+; CHECK: [[AGG:%[0-9]+]] = OpFunctionCall {{%[0-9]+}} {{%[0-9]+}}
+; CHECK: [[ARR:%[0-9]+]] = OpCompositeExtract {{%[0-9]+}} [[AGG]] 2
+; CHECK: [[ELT:%[0-9]+]] = OpCompositeExtract {{%[0-9]+}} [[ARR]] 0
+; CHECK: OpStore {{%[0-9]+}} [[ELT]]
+define void @chain(ptr addrspace(4) %p) {
+ %1 = call %ty @arr_ret()
+ %2 = extractvalue %ty %1, 2
+ %3 = extractvalue [8 x i8] %2, 0
+ store i8 %3, ptr addrspace(4) %p, align 1
+ ret void
+}
>From 6755f334c77c2f9e58ca3ff998e463ecdd0454f7 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Thu, 28 May 2026 16:29:26 +0200
Subject: [PATCH 2/2] Address comments
---
.../SPIRV/instructions/extractvalue-aggregate-chain.ll | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/test/CodeGen/SPIRV/instructions/extractvalue-aggregate-chain.ll b/llvm/test/CodeGen/SPIRV/instructions/extractvalue-aggregate-chain.ll
index 64364a5d88ace..c7391a54db12f 100644
--- a/llvm/test/CodeGen/SPIRV/instructions/extractvalue-aggregate-chain.ll
+++ b/llvm/test/CodeGen/SPIRV/instructions/extractvalue-aggregate-chain.ll
@@ -10,10 +10,10 @@
declare %ty @arr_ret()
; CHECK: OpFunction
-; CHECK: [[AGG:%[0-9]+]] = OpFunctionCall {{%[0-9]+}} {{%[0-9]+}}
-; CHECK: [[ARR:%[0-9]+]] = OpCompositeExtract {{%[0-9]+}} [[AGG]] 2
-; CHECK: [[ELT:%[0-9]+]] = OpCompositeExtract {{%[0-9]+}} [[ARR]] 0
-; CHECK: OpStore {{%[0-9]+}} [[ELT]]
+; CHECK: %[[#AGG:]] = OpFunctionCall %[[#]] %[[#]]
+; CHECK: %[[#ARR:]] = OpCompositeExtract %[[#]] %[[#AGG]] 2
+; CHECK: %[[#ELT:]] = OpCompositeExtract %[[#]] %[[#ARR]] 0
+; CHECK: OpStore %[[#]] %[[#ELT]]
define void @chain(ptr addrspace(4) %p) {
%1 = call %ty @arr_ret()
%2 = extractvalue %ty %1, 2
More information about the llvm-commits
mailing list