================
@@ -1008,3 +1009,105 @@ CIRGenFunction::emitNVPTXBuiltinExpr(unsigned
builtinId, const CallExpr *expr) {
return std::nullopt;
}
}
+
+// vprintf takes two args: A format string, and a pointer to a buffer
containing
+// the varargs.
+//
+// For example, the call
+//
+// printf("format string", arg1, arg2, arg3);
+//
+// is converted into something resembling
+//
+// struct Tmp {
+// Arg1 a1;
+// Arg2 a2;
+// Arg3 a3;
+// };
+// char* buf = alloca(sizeof(Tmp));
+// *(Tmp*)buf = {a1, a2, a3};
+// vprintf("format string", buf);
+//
+// `buf` is aligned to the max of {alignof(Arg1), ...}. Furthermore, each of
+// the args is itself aligned to its preferred alignment.
+//
+// Note that by the time this function runs, the arguments have already
+// undergone the standard C vararg promotion (short -> int, float -> double
+// etc). In this function we pack the arguments into the buffer described
above.
+static mlir::Value packArgsIntoNVPTXFormatBuffer(CIRGenFunction &cgf,
+ const CallArgList &args,
+ mlir::Location loc) {
+ const cir::CIRDataLayout dataLayout = cgf.cgm.getDataLayout();
+ CIRGenBuilderTy &builder = cgf.getBuilder();
+
+ if (args.size() <= 1)
+ // If there are no arguments other than the format string,
+ // pass a nullptr to vprintf.
+ return builder.getNullPtr(builder.getVoidPtrTy(), loc);
+
+ llvm::SmallVector<mlir::Type> argTypes;
+ for (const auto &arg : llvm::drop_begin(args))
+ argTypes.push_back(arg.getKnownRValue(cgf, loc).getValue().getType());
+
+ // We can directly store the arguments into a struct, and the alignment
+ // would automatically be correct. That's because vprintf does not
+ // accept aggregates.
+ mlir::Type allocaTy = builder.getAnonRecordTy(argTypes);
+ auto allocaAlign = clang::CharUnits::fromQuantity(
+ dataLayout.getABITypeAlign(allocaTy).value());
+ Address allocaAddr =
+ cgf.createTempAlloca(allocaTy, allocaAlign, loc, "printf_args");
+ mlir::Value alloca = allocaAddr.getPointer();
+
+ for (auto [i, arg] : llvm::enumerate(llvm::drop_begin(args))) {
+ mlir::Value member = builder.createGetMember(
+ loc, cir::PointerType::get(argTypes[i]), alloca, /*name=*/"",
+ /*index=*/i);
+ auto abiAlign = clang::CharUnits::fromQuantity(
+ dataLayout.getABITypeAlign(argTypes[i]).value());
+ cir::StoreOp::create(builder, loc, arg.getRValue(cgf, loc).getValue(),
----------------
andykaylor wrote:
This should also be `getKnownRValue`
https://github.com/llvm/llvm-project/pull/196573
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits