[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