[libc-commits] [libc] 3ec60e8 - [libc] Optimize the GPU printf implementation with size hints (#222474)

via libc-commits libc-commits at lists.llvm.org
Thu Sep 10 05:36:44 PDT 2026


Author: Joseph Huber
Date: 2026-09-10T07:36:39-05:00
New Revision: 3ec60e826f522bbe6b0af7c9392968a9f6c660c5

URL: https://github.com/llvm/llvm-project/commit/3ec60e826f522bbe6b0af7c9392968a9f6c660c5
DIFF: https://github.com/llvm/llvm-project/commit/3ec60e826f522bbe6b0af7c9392968a9f6c660c5.diff

LOG: [libc] Optimize the GPU printf implementation with size hints (#222474)

Summary:
The GPU printf interface is functionally a shim to pass a `va_list` and
format string to the CPU for formatting. The size of the argument list
isn't exposed by the C ABI, but we can use `__builtin_object_size` to
try to look it up. This will bind to the `alloca` holding our arguments
in the ABI and return a positive size if it is known.

We do this opportunistically, as the check is lossy. In cases where it
is known, this saves a stack spill to store the true size. Additionally,
we can use this to detect cases where `printf` is being used as a simple
`puts`.

This saves 10 VGPRs for the `printf("string")` case. It also saves 8
bytes of stack in most all cases.

Added: 
    

Modified: 
    libc/src/stdio/gpu/vfprintf_utils.h

Removed: 
    


################################################################################
diff  --git a/libc/src/stdio/gpu/vfprintf_utils.h b/libc/src/stdio/gpu/vfprintf_utils.h
index 70eb98c838bec..a4d2ec8487b09 100644
--- a/libc/src/stdio/gpu/vfprintf_utils.h
+++ b/libc/src/stdio/gpu/vfprintf_utils.h
@@ -34,6 +34,11 @@ LIBC_INLINE int vfprintf_impl(::FILE *__restrict file,
   port.recv([&](rpc::Buffer *buffer, uint32_t) {
     args_size = static_cast<size_t>(buffer->data[0]);
   });
+  // If the underlying argument buffer is of known size we use it directly. A
+  // value of one uniquely indicates an empty argument list.
+  if (size_t arg_max = __builtin_object_size(vlist, /*max=*/0b00);
+      arg_max == __builtin_object_size(vlist, /*min=*/0b10))
+    args_size = arg_max;
   port.send_n(vlist, args_size);
 
   uint32_t ret = 0;
@@ -44,7 +49,7 @@ LIBC_INLINE int vfprintf_impl(::FILE *__restrict file,
       str = reinterpret_cast<const char *>(buffer->data[1]);
     });
     // If any lanes have a string argument it needs to be copied back.
-    if (!gpu::ballot(mask, str))
+    if (!gpu::ballot(mask, str && args_size != 1))
       break;
 
     uint64_t size = str ? internal::string_length(str) + 1 : 0;


        


More information about the libc-commits mailing list