Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions llvm/lib/SYCLLowerIR/MutatePrintfAddrspace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ static constexpr unsigned ConstantAddrspaceID = 2;
// of the non-variadic (variadic template) calls.
using FunctionVecTy = SmallVector<Function *, 8>;

Function *getCASPrintfFunction(Module &M, PointerType *CASLiteralType);
Function *getCASPrintfFunction(Module &M, PointerType *CASLiteralType,
CallingConv::ID CC);
size_t setFuncCallsOntoCASPrintf(Function *F, Function *CASPrintfFunc,
FunctionVecTy &FunctionsToDrop);
} // namespace
Expand All @@ -70,7 +71,7 @@ ModulePass *llvm::createSYCLMutatePrintfAddrspaceLegacyPass() {
PreservedAnalyses
SYCLMutatePrintfAddrspacePass::run(Module &M, ModuleAnalysisManager &MAM) {
auto *CASLiteralType = PointerType::get(M.getContext(), ConstantAddrspaceID);
Function *CASPrintfFunc = getCASPrintfFunction(M, CASLiteralType);
Function *CASPrintfFunc = nullptr;

FunctionVecTy FunctionsToDrop;
bool ModuleChanged = false;
Expand All @@ -82,13 +83,21 @@ SYCLMutatePrintfAddrspacePass::run(Module &M, ModuleAnalysisManager &MAM) {
if (F.getArg(0)->getType() == CASLiteralType)
// No need to replace the literal type and its printf users
continue;
if (F.use_empty()) {
FunctionsToDrop.emplace_back(&F);
ModuleChanged = true;
continue;
}
if (!CASPrintfFunc)
CASPrintfFunc =
getCASPrintfFunction(M, CASLiteralType, F.getCallingConv());
ModuleChanged |=
setFuncCallsOntoCASPrintf(&F, CASPrintfFunc, FunctionsToDrop);
}
for (Function *F : FunctionsToDrop)
F->eraseFromParent();

return ModuleChanged ? PreservedAnalyses::all() : PreservedAnalyses::none();
return ModuleChanged ? PreservedAnalyses::none() : PreservedAnalyses::all();
}

/// Helper implementations
Expand All @@ -97,7 +106,8 @@ namespace {
/// Get the constant addrspace version of the __spirv_ocl_printf declaration,
/// or generate it if the IR module doesn't have it yet. Also make it
/// variadic so that it could replace all non-variadic generic AS versions.
Function *getCASPrintfFunction(Module &M, PointerType *CASLiteralType) {
Function *getCASPrintfFunction(Module &M, PointerType *CASLiteralType,
CallingConv::ID CC) {
Type *Int32Type = Type::getInt32Ty(M.getContext());
auto *CASPrintfFuncTy = FunctionType::get(Int32Type, CASLiteralType,
/*isVarArg=*/true);
Expand All @@ -106,7 +116,7 @@ Function *getCASPrintfFunction(Module &M, PointerType *CASLiteralType) {
FunctionCallee CASPrintfFuncCallee =
M.getOrInsertFunction("_Z18__spirv_ocl_printfPU3AS2Kcz", CASPrintfFuncTy);
auto *CASPrintfFunc = cast<Function>(CASPrintfFuncCallee.getCallee());
CASPrintfFunc->setCallingConv(CallingConv::SPIR_FUNC);
CASPrintfFunc->setCallingConv(CC);
CASPrintfFunc->setDSOLocal(true);
return CASPrintfFunc;
}
Expand Down
14 changes: 14 additions & 0 deletions llvm/test/SYCLLowerIR/printf_addrspace/no_printf_no_decl.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
;; Verify that the pass does NOT insert a printf declaration when the module
;; has no printf functions that need transformation.

; RUN: opt < %s -passes=SYCLMutatePrintfAddrspace -S | FileCheck %s

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
target triple = "spir64-unknown-unknown"

define spir_kernel void @no_printf_kernel() {
entry:
ret void
}

; CHECK-NOT: @_Z18__spirv_ocl_printfPU3AS2Kcz
21 changes: 21 additions & 0 deletions llvm/test/SYCLLowerIR/printf_addrspace/non_spir_target.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
;; Verify that the pass does NOT set spir_func calling convention on the
;; printf declaration when the target triple is not SPIR/SPIR-V.

; RUN: opt < %s -passes=SYCLMutatePrintfAddrspace -S | FileCheck %s

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1

define void @test_printf() {
entry:
%call = call i32 @_Z18__spirv_ocl_printfIJEEiPKcDpT_(ptr @.str)
ret void
}

; CHECK: call i32 (ptr addrspace(2), ...) @_Z18__spirv_ocl_printfPU3AS2Kcz(ptr addrspace(2)
; The declaration should NOT have spir_func CC for non-SPIR targets.
; CHECK: declare dso_local i32 @_Z18__spirv_ocl_printfPU3AS2Kcz(ptr addrspace(2), ...)

declare i32 @_Z18__spirv_ocl_printfIJEEiPKcDpT_(ptr)
21 changes: 21 additions & 0 deletions llvm/test/SYCLLowerIR/printf_addrspace/unused_printf_decl.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
;; Verify that the pass does NOT insert an AS2 printf declaration when
;; the module has a matching printf declaration with no call users, and
;; that the unused declaration itself is removed from the module.

; RUN: opt < %s -passes=SYCLMutatePrintfAddrspace -S | FileCheck %s

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
target triple = "spir64-unknown-unknown"

define spir_kernel void @kernel() {
entry:
ret void
}

; This declaration matches the printf name prefix but has no users.
declare dso_local spir_func i32 @_Z18__spirv_ocl_printfIJfEEiPKcDpT_(ptr addrspace(4), float)

; No AS2 printf declaration should be created.
; CHECK-NOT: @_Z18__spirv_ocl_printfPU3AS2Kcz
; The unused generic-AS printf declaration should be removed.
; CHECK-NOT: @_Z18__spirv_ocl_printfIJfEEiPKcDpT_
Loading