[clang] [llvm] [CIR][AMDGPU] Route printf in device code through the OpenCL runtime (PR #226435)

Steffen Larsen via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 02:02:54 PDT 2026


================
@@ -1096,3 +1096,45 @@ CIRGenFunction::emitAMDGPUBuiltinExpr(unsigned builtinId,
     return std::nullopt;
   }
 }
+
+// Emit AMDGPU printf CIR stand-in function call. This stand-in function call is
+// lowered to the appropriate call structure during LLVM IR lowering.
+mlir::Value
+CIRGenFunction::emitAMDGPUDevicePrintfCallExpr(const CallExpr *expr) {
+  assert(cgm.getTriple().isAMDGCN() ||
+         (cgm.getTriple().isSPIRV() &&
+          cgm.getTriple().getVendor() == llvm::Triple::AMD));
+  assert(expr->getBuiltinCallee() == Builtin::BIprintf ||
+         expr->getBuiltinCallee() == Builtin::BI__builtin_printf);
+  assert(expr->getNumArgs() >= 1);
+
+  const FunctionProtoType *funcPrototype =
+      expr->getDirectCallee()->getType()->getAs<FunctionProtoType>();
+  CallArgList args;
+  emitCallArgs(args, funcPrototype, expr->arguments(), expr->getDirectCallee());
+
+  mlir::Location loc = getLoc(expr->getBeginLoc());
+
+  // We don't know how to emit non-scalar varargs.
+  bool hasNonScalar = llvm::any_of(args, [&](const CallArg &a) {
+    return a.hasLValue() || !a.getKnownRValue().isScalar();
+  });
+  if (hasNonScalar) {
+    cgm.errorUnsupported(expr, "non-scalar args to printf");
+    return builder.getConstInt(loc, builder.getSInt32Ty(), 0);
+  }
+
+  llvm::SmallVector<mlir::Value, 8> callArgs;
+  for (const CallArg &a : args)
+    callArgs.push_back(a.getKnownRValue().getValue());
+
+  // int __cir_amdgpu_printf(char *format, ...);
+  auto fnTy = cir::FuncType::get({cir::PointerType::get(builder.getSInt8Ty())},
+                                 builder.getSInt32Ty(),
+                                 /*isVarArg=*/true);
+  cir::FuncOp fn = cgm.createRuntimeFunction(fnTy, "__cir_amdgpu_printf");
----------------
steffenlarsen wrote:

I've added the CIR Op and migrated the logic from llvm/lib/Transforms/Utils/AMDGPUEmitPrintf.cpp to a new CIR lowering file.

> You might also want to add a corresponding operation to the LLVM dialect. The fact that classic codegen is calling a function in the LLVM library to emit this feels more than a little hacky.

Agreed. I'll investigate the possibility of this, though it might be a little too aggressive to include such a refactoring in this patch.

https://github.com/llvm/llvm-project/pull/226435


More information about the llvm-commits mailing list