Skip to content

Commit 64c6861

Browse files
committed
[Clang][OpenCL][NVPTX] using vprintf to implement builtin printf on OpenCL with NVPTX
1 parent ecc3e28 commit 64c6861

File tree

5 files changed

+24
-6
lines changed

5 files changed

+24
-6
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11481,6 +11481,11 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
1148111481
// FIXME: There's no way to have a built-in with an rvalue ref arg.
1148211482
case 'C':
1148311483
Type = Type.withConst();
11484+
// adjust 'const char *' to 'const char __constant *' on OpenCL
11485+
if (Context.getLangOpts().OpenCL &&
11486+
Type.getTypePtr() == Context.CharTy.getTypePtr()) {
11487+
Type = Context.getAddrSpaceQualType(Type, LangAS::opencl_constant);
11488+
}
1148411489
break;
1148511490
case 'D':
1148611491
Type = Context.getVolatileType(Type);

clang/lib/AST/Decl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3600,8 +3600,10 @@ unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
36003600

36013601
// OpenCL v1.2 s6.9.f - The library functions defined in
36023602
// the C99 standard headers are not available.
3603+
// EXCEPTION: printf is supported for AMDGPU
36033604
if (Context.getLangOpts().OpenCL &&
3604-
Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
3605+
Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID) &&
3606+
BuiltinID != Builtin::BIprintf)
36053607
return 0;
36063608

36073609
// CUDA does not have device-side standard library. printf and malloc are the

clang/lib/CodeGen/CGGPUBuiltin.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ bool containsNonScalarVarargs(CodeGenFunction *CGF, const CallArgList &Args) {
135135
RValue EmitDevicePrintfCallExpr(const CallExpr *E, CodeGenFunction *CGF,
136136
llvm::Function *Decl, bool WithSizeArg) {
137137
CodeGenModule &CGM = CGF->CGM;
138+
llvm::LLVMContext &Ctx = CGM.getLLVMContext();
138139
CGBuilderTy &Builder = CGF->Builder;
139140
assert(E->getBuiltinCallee() == Builtin::BIprintf);
140141
assert(E->getNumArgs() >= 1); // printf always has at least one arg.
@@ -155,9 +156,15 @@ RValue EmitDevicePrintfCallExpr(const CallExpr *E, CodeGenFunction *CGF,
155156

156157
auto r = packArgsIntoNVPTXFormatBuffer(CGF, Args);
157158
llvm::Value *BufferPtr = r.first;
159+
llvm::Value *Fmt = Args[0].getRValue(*CGF).getScalarVal();
158160

159-
llvm::SmallVector<llvm::Value *, 3> Vec = {
160-
Args[0].getRValue(*CGF).getScalarVal(), BufferPtr};
161+
// For OpenCL, the default addrspace of 'format' argument is LangAS::opencl_constant,
162+
// however, the 'vprintf' requires it to be unqualified 'ptr' type. Do pointer cast if
163+
// it's the case.
164+
if (CGM.getContext().getLangOpts().OpenCL)
165+
Fmt = Builder.CreatePointerCast(Fmt, llvm::PointerType::getUnqual(Ctx));
166+
167+
llvm::SmallVector<llvm::Value *, 3> Vec = {Fmt, BufferPtr};
161168
if (WithSizeArg) {
162169
// Passing > 32bit of data as a local alloca doesn't work for nvptx or
163170
// amdgpu

clang/lib/Sema/SemaDecl.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7008,8 +7008,12 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) {
70087008
}
70097009

70107010
void Sema::deduceOpenCLAddressSpace(ValueDecl *Decl) {
7011-
if (Decl->getType().hasAddressSpace())
7012-
return;
7011+
// Address space is only meaningful for pointer type
7012+
if (Decl->getType()->isPointerType()) {
7013+
const PointerType *T = dyn_cast<PointerType>(Decl->getType().getTypePtr());
7014+
if (T->getPointeeType().hasAddressSpace())
7015+
return;
7016+
}
70137017
if (Decl->getType()->isDependentType())
70147018
return;
70157019
if (VarDecl *Var = dyn_cast<VarDecl>(Decl)) {

clang/test/CodeGenOpenCL/test-printf-nvptx.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2)))
66
// NV-LABEL: define dso_local spir_kernel void @test_printf(
77
// NV-SAME: ) #[[ATTR0:[0-9]+]] !kernel_arg_addr_space !4 !kernel_arg_access_qual !4 !kernel_arg_type !4 !kernel_arg_base_type !4 !kernel_arg_type_qual !4 {
88
// NV-NEXT: entry:
9-
// NV-NEXT: [[CALL:%.*]] = call i32 (ptr addrspace(4), ...) @printf(ptr addrspace(4) noundef @.str) #[[ATTR2:[0-9]+]]
9+
// NV-NEXT: [[TMP0:%.*]] = call i32 @vprintf(ptr addrspacecast (ptr addrspace(4) @.str to ptr), ptr null)
1010
// NV-NEXT: ret void
1111
//
1212
__kernel void test_printf() {

0 commit comments

Comments
 (0)