[llvm] 7087ea3 - [SPIR-V] Look up printf format string type in the correct function (#201523)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 10 02:01:50 PDT 2026
Author: Tim Besard
Date: 2026-06-10T11:01:45+02:00
New Revision: 7087ea37449027cc4c73a375b542cdc397c4474b
URL: https://github.com/llvm/llvm-project/commit/7087ea37449027cc4c73a375b542cdc397c4474b
DIFF: https://github.com/llvm/llvm-project/commit/7087ea37449027cc4c73a375b542cdc397c4474b.diff
LOG: [SPIR-V] Look up printf format string type in the correct function (#201523)
addPrintfRequirements() resolved the SPIR-V type of the format string
operand via getSPIRVTypeForVReg() without passing the instruction's
parent MachineFunction, so the lookup defaulted to the registry's CurMF:
whichever function happened to be processed last. Virtual register
numbers are only unique within a function, so in multi-function modules
the check could inspect an unrelated function's type, misreading its
second operand as the format string's storage class (an OpTypeInt's
width immediate, in the added test). For a format string in the constant
address space this spuriously triggered the fatal
"SPV_EXT_relaxed_printf_string_address_space is required" error, or
silently added the unnecessary extension when it was available;
conversely, the requirement could be silently omitted when the colliding
vreg had no recorded type.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply at anthropic.com>
Added:
llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_relaxed_printf_string_address_space/multi-function-printf.ll
Modified:
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index dbaf42ecb4b12..bb6245778b2ea 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -1481,7 +1481,8 @@ void addPrintfRequirements(const MachineInstr &MI,
SPIRV::RequirementHandler &Reqs,
const SPIRVSubtarget &ST) {
SPIRVGlobalRegistry *GR = ST.getSPIRVGlobalRegistry();
- SPIRVTypeInst PtrType = GR->getSPIRVTypeForVReg(MI.getOperand(4).getReg());
+ SPIRVTypeInst PtrType =
+ GR->getSPIRVTypeForVReg(MI.getOperand(4).getReg(), MI.getMF());
if (PtrType) {
MachineOperand ASOp = PtrType->getOperand(1);
if (ASOp.isImm()) {
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_relaxed_printf_string_address_space/multi-function-printf.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_relaxed_printf_string_address_space/multi-function-printf.ll
new file mode 100644
index 0000000000000..dfabcc47f07ae
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_EXT_relaxed_printf_string_address_space/multi-function-printf.ll
@@ -0,0 +1,44 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_EXT_relaxed_printf_string_address_space %s -o - | FileCheck %s
+; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; The format string is in the constant address space, so no extension is
+; required. The pointer type of the format string used to be looked up in
+; whichever function was processed last instead of the calling function,
+; spuriously requiring the extension when an unrelated function's colliding
+; virtual register had a non-UniformConstant pointer type. The loads in @last
+; only exist to populate its vreg-to-type map with non-UniformConstant types
+; at the vreg numbers that collide with the format string's vreg in @kern.
+
+; CHECK-NOT: OpExtension "SPV_EXT_relaxed_printf_string_address_space"
+; CHECK: OpExtInstImport "OpenCL.std"
+
+ at .str = private unnamed_addr addrspace(2) constant [6 x i8] c"hello\00", align 1
+
+declare i32 @printf(ptr addrspace(2), ...)
+
+define spir_kernel void @kern() {
+entry:
+ %r = call i32 (ptr addrspace(2), ...) @printf(ptr addrspace(2) @.str)
+ ret void
+}
+
+define void @last(ptr addrspace(3) %p) {
+entry:
+ %g1 = getelementptr inbounds i32, ptr addrspace(3) %p, i64 1
+ %v1 = load i32, ptr addrspace(3) %g1, align 4
+ %g2 = getelementptr inbounds i32, ptr addrspace(3) %p, i64 2
+ %v2 = load i32, ptr addrspace(3) %g2, align 4
+ %g3 = getelementptr inbounds i32, ptr addrspace(3) %p, i64 3
+ %v3 = load i32, ptr addrspace(3) %g3, align 4
+ %g4 = getelementptr inbounds i32, ptr addrspace(3) %p, i64 4
+ %v4 = load i32, ptr addrspace(3) %g4, align 4
+ %g5 = getelementptr inbounds i32, ptr addrspace(3) %p, i64 5
+ %v5 = load i32, ptr addrspace(3) %g5, align 4
+ %s1 = add i32 %v1, %v2
+ %s2 = add i32 %s1, %v3
+ %s3 = add i32 %s2, %v4
+ %s4 = add i32 %s3, %v5
+ store i32 %s4, ptr addrspace(3) %p, align 4
+ ret void
+}
More information about the llvm-commits
mailing list