[llvm-branch-commits] [llvm] release/23.x: [ExpandVariadics] Don't lower unmangled C printf on SPIR-V (#206998) (PR #213893)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Aug 4 02:58:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: llvmbot
<details>
<summary>Changes</summary>
Backport b1d21c6d3121898dc13c0df8cf9e4410bee75cfb
Requested by: @<!-- -->pvelesko
---
Full diff: https://github.com/llvm/llvm-project/pull/213893.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/IPO/ExpandVariadics.cpp (+6-1)
- (added) llvm/test/Transforms/ExpandVariadics/spirv-printf.ll (+35)
``````````diff
diff --git a/llvm/lib/Transforms/IPO/ExpandVariadics.cpp b/llvm/lib/Transforms/IPO/ExpandVariadics.cpp
index 4a45e8d5137a4..948752718fde6 100644
--- a/llvm/lib/Transforms/IPO/ExpandVariadics.cpp
+++ b/llvm/lib/Transforms/IPO/ExpandVariadics.cpp
@@ -1067,8 +1067,13 @@ struct SPIRV final : public VariadicABIInfo {
StringRef DemangledName(Demangled);
// Skip any SPIR-V builtins.
+ // Note: an unmangled C `printf` declaration demangles to "printf" with no
+ // argument list, so the "printf(" prefix check below misses it. Match the
+ // bare name as well so OpenCL/HIP printf (emitted unmangled) is left as a
+ // variadic call for the backend's OpenCL.std printf lowering to expand
+ // inline, rather than being packed into a vararg buffer here.
if (DemangledName.starts_with("__spirv_") ||
- DemangledName.starts_with("printf("))
+ DemangledName.starts_with("printf(") || F->getName() == "printf")
return true;
return false;
diff --git a/llvm/test/Transforms/ExpandVariadics/spirv-printf.ll b/llvm/test/Transforms/ExpandVariadics/spirv-printf.ll
new file mode 100644
index 0000000000000..c9be77a405243
--- /dev/null
+++ b/llvm/test/Transforms/ExpandVariadics/spirv-printf.ll
@@ -0,0 +1,35 @@
+; RUN: opt -mtriple=spirv64-unknown-unknown -S --passes=expand-variadics --expand-variadics-override=lowering %s | FileCheck %s
+;
+; An unmangled C `printf` declaration demangles to bare "printf" (no argument
+; list). On SPIR-V it must be left as a variadic call so the backend can lower
+; it to the OpenCL.std printf ExtInst with inline operands, instead of having
+; its arguments packed into a vararg buffer here. A user-defined variadic
+; function with a body is still expanded as usual.
+
+ at .str = private unnamed_addr addrspace(2) constant [4 x i8] c"%d\0A\00"
+
+declare spir_func i32 @printf(ptr addrspace(2), ...)
+
+; printf is left untouched: the call stays variadic and nothing is packed
+; (CHECK-NEXT pins that ret immediately follows the call).
+; CHECK-LABEL: define spir_kernel void @uses_printf(
+; CHECK-NEXT: {{%.*}} = call spir_func i32 (ptr addrspace(2), ...) @printf(ptr addrspace(2) @.str, i32 42)
+; CHECK-NEXT: ret void
+define spir_kernel void @uses_printf() {
+ %r = call spir_func i32 (ptr addrspace(2), ...) @printf(ptr addrspace(2) @.str, i32 42)
+ ret void
+}
+
+; Control: an ordinary variadic function with a body is still expanded, i.e.
+; its caller packs the arguments into a vararg buffer.
+define spir_func i32 @my_variadic(...) {
+ ret i32 0
+}
+
+; CHECK-LABEL: define spir_kernel void @uses_my_variadic(
+; CHECK: %vararg_buffer = alloca %uses_my_variadic.vararg
+; CHECK: call spir_func i32 @my_variadic(ptr %vararg_buffer)
+define spir_kernel void @uses_my_variadic() {
+ %r = call spir_func i32 (...) @my_variadic(i32 7)
+ ret void
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/213893
More information about the llvm-branch-commits
mailing list