Skip to content

Commit 24eb1ab

Browse files
[SYCL] Introduce non-variadic version of __spirv_ocl_printf (#4779)
Moved declaration of the built-in from compiler to header files, in order to add a switch (through macro) between two versions of the built-in: variadic and non-variadic one. The problem with variadic version is that it follows C++ argument promotion rules and replaces all floats with doubles, which doesn't look good on HW, which doesn't support doubles. Due to the fact, that we don't know the target HW in advance, we can't selectively disable argument promotion for only some targets and doing so will look like a hack anyway. Therefore, a non-variadic version is introduced, which allows to avoid argument promotion without any further changes to the compiler (and thus, not affecting other variadic functions). Encountering such `printf` call without argument promotion performed should not be a surprise for a backend which consumes SPIR-V, because SPIR-V instruction for `printf` is not variadic, all argument types are statically known and it is legal to have both floats and doubles as arguments at the same time. However, there is no certainty yet in proper support of that instruction in backends: they were mostly designed for OpenCL, where we either have argument promotion or don't have it, but not encountering a mixed case. Because of that, the new version is put under a macro for now, which allows to experiment with it without disrupting existing applications using `printf`.
1 parent 7187f7b commit 24eb1ab

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

clang/lib/Sema/SPIRVBuiltins.td

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -722,12 +722,6 @@ foreach VSize1 = [Vec2, Vec4, Vec8, Vec16] in {
722722

723723
// 2.8. Misc instructions
724724

725-
let IsVariadic = 1 in {
726-
foreach name = ["printf"] in {
727-
def : OCLSPVBuiltin<name, [Int, PointerType<ConstType<TrueChar>, ConstantAS>]>;
728-
}
729-
}
730-
731725
foreach name = ["prefetch"] in {
732726
def : OCLSPVBuiltin<name, [Void, PointerType<ConstType<AGenTypeN>, GlobalAS>, Size]>;
733727
}

sycl/include/CL/__spirv/spirv_ops.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,16 @@ extern SYCL_EXTERNAL float __spirv_ConvertBF16ToFINTEL(uint16_t) noexcept;
636636
__SYCL_CONVERGENT__ extern SYCL_EXTERNAL __SYCL_EXPORT __ocl_vec_t<uint32_t, 4>
637637
__spirv_GroupNonUniformBallot(uint32_t Execution, bool Predicate) noexcept;
638638

639+
#ifdef __SYCL_USE_NON_VARIADIC_SPIRV_OCL_PRINTF__
640+
template <typename... Args>
641+
extern SYCL_EXTERNAL int
642+
__spirv_ocl_printf(const __attribute__((opencl_constant)) char *Format,
643+
Args... args);
644+
#else
645+
extern SYCL_EXTERNAL int
646+
__spirv_ocl_printf(const __attribute__((opencl_constant)) char *Format, ...);
647+
#endif
648+
639649
#else // if !__SYCL_DEVICE_ONLY__
640650

641651
template <typename dataT>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// This test is intended to check that internal
2+
// __SYCL_USE_NON_VARIADIC_SPIRV_OCL_PRINTF__ works as expected, i.e. we can
3+
// see printf ExtInst regardless of the macro presence and that argument
4+
// promotion is disabled if the macro is present.
5+
//
6+
// RUN: %clangxx -fsycl -fsycl-device-only -fno-sycl-use-bitcode %s -o %t.spv
7+
// RUN: llvm-spirv -to-text %t.spv -o %t.spt
8+
// RUN: FileCheck %s --check-prefixes CHECK,CHECK-DOUBLE < %t.spt
9+
//
10+
// RUN: %clangxx -fsycl -fsycl-device-only -fno-sycl-use-bitcode -D__SYCL_USE_NON_VARIADIC_SPIRV_OCL_PRINTF__ %s -o %t.spv
11+
// RUN: llvm-spirv -to-text %t.spv -o %t.spt
12+
// RUN: FileCheck %s --check-prefixes CHECK,CHECK-FLOAT < %t.spt
13+
14+
// CHECK-FLOAT: TypeFloat [[#TYPE:]] 32
15+
// CHECK-DOUBLE: TypeFloat [[#TYPE:]] 64
16+
// CHECK: Constant [[#TYPE]] [[#CONST:]]
17+
// CHECK: ExtInst [[#]] [[#]] [[#]] printf [[#]] [[#CONST]]
18+
19+
#include <CL/sycl.hpp>
20+
21+
#ifdef __SYCL_DEVICE_ONLY__
22+
#define __SYCL_CONSTANT_AS __attribute__((opencl_constant))
23+
#else
24+
#define __SYCL_CONSTANT_AS
25+
#endif
26+
27+
const __SYCL_CONSTANT_AS char fmt[] = "Hello, World! %f\n";
28+
29+
int main() {
30+
sycl::queue q;
31+
32+
q.submit([&](sycl::handler &cgh) {
33+
cgh.single_task([=]() {
34+
float f = 3.14;
35+
sycl::ext::oneapi::experimental::printf(fmt, f);
36+
});
37+
});
38+
39+
return 0;
40+
}

0 commit comments

Comments
 (0)