Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYCL] [NATIVECPU] Implement missing math builtins for scalar data types #11321

Merged
merged 12 commits into from
Oct 24, 2023
6 changes: 4 additions & 2 deletions clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,9 +517,11 @@ void TargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
if (Opts.FakeAddressSpaceMap)
AddrSpaceMap = &FakeAddrSpaceMap;

if (Opts.SYCLIsDevice && Opts.SYCLIsNativeCPU) {
if ((Opts.SYCLIsDevice || Opts.OpenCL) && Opts.SYCLIsNativeCPU) {
elizabethandrews marked this conversation as resolved.
Show resolved Hide resolved
// For SYCL Native CPU we use the NVPTXAddrSpaceMap because
// we need builtins to be mangled with AS information
// we need builtins to be mangled with AS information.
// This is also enabled in OpenCL mode so that mangling
// matches when building libclc.

static const unsigned SYCLNativeCPUASMap[] = {
0, // Default
Expand Down
36 changes: 36 additions & 0 deletions clang/test/CodeGenSYCL/native_cpu_as.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// This test is temporarily disabled for SYCL Native CPU on Windows
// UNSUPPORTED: system-windows
// Checks that name mangling matches between SYCL Native CPU and OpenCL when -fsycl-is-native-cpu is set
// RUN: %clang_cc1 -DCPP -fsycl-is-device -S -emit-llvm -internal-isystem %S/Inputs -fsycl-is-native-cpu -o %t_sycl.ll %s
// RUN: FileCheck -input-file=%t_sycl.ll %s

// RUN: %clang_cc1 -x cl -DOCL -S -emit-llvm -internal-isystem %S/Inputs -fsycl-is-native-cpu -o %t_ocl.ll %s
// RUN: FileCheck -input-file=%t_ocl.ll %s

#ifdef CPP
#define AS_LOCAL __attribute((address_space(3)))
#define AS_GLOBAL __attribute((address_space(1)))
#define AS_PRIVATE __attribute((address_space(0)))
#define ATTRS [[intel::device_indirectly_callable]]
#define ATTRS2 SYCL_EXTERNAL
#else
#ifdef OCL
#define AS_LOCAL __local
#define AS_GLOBAL __global
#define AS_PRIVATE __private
#define ATTRS __attribute((overloadable))
#define ATTRS2 __attribute((overloadable))
#endif
#endif


ATTRS2 void use_private(int *p);
ATTRS void func(AS_LOCAL int *p1, AS_GLOBAL int *p2, AS_PRIVATE int *p3){
int private_var;
use_private(&private_var);
}
// CHECK: define dso_local void @_Z4funcPU3AS3iPU3AS1iPi(
// CHECK: call void @_Z11use_privatePi(



3 changes: 2 additions & 1 deletion libclc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,9 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
# clang builtins need to be accessible
set( flags "SHELL:-mcpu=gfx940")
elseif( ${ARCH} STREQUAL x86_64)
# TODO: This is used by native cpu, we should define an option to set this flags
# TODO: This is used by SYCL Native Cpu, we should define an option to set this flags
set( flags "SHELL:-Xclang -target-feature -Xclang +avx"
"SHELL:-Xclang -fsycl-is-native-cpu"
"SHELL:-Xclang -target-feature -Xclang +avx512f")
else()
set ( flags )
Expand Down
1 change: 1 addition & 0 deletions libclc/x86_64-unknown-linux/libspirv/SOURCES
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ math/native_sqrt.cl
math/rint.cl
math/round.cl
math/trunc.cl
shared/helpers.ll
9 changes: 9 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/integer/helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "func.h"

#define GEN_UNARY_BUILTIN_T(NAME, TYPE) \
_CLC_OVERLOAD TYPE __##NAME##_helper(TYPE); \
_CLC_OVERLOAD TYPE __spirv_ocl_##NAME(TYPE n) { return __##NAME##_helper(n); }

#define GEN_UNARY_BUILTIN(NAME) \
GEN_UNARY_BUILTIN_T(NAME, int) \
GEN_UNARY_BUILTIN_T(NAME, signed char)
3 changes: 3 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/integer/popcount.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "helpers.h"

GEN_UNARY_BUILTIN(popcount)
3 changes: 3 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/ceil.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "helpers.h"

GEN_UNARY_BUILTIN(ceil)
4 changes: 4 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/fabs.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define IS_FABS
#include "helpers.h"

GEN_UNARY_BUILTIN(fabs)
3 changes: 3 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/floor.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "helpers.h"

GEN_UNARY_BUILTIN(floor)
4 changes: 4 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/fma.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "helpers.h"

GEN_TERNARY_BUILTIN(fma);

82 changes: 82 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/helpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include "func.h"
#include "types.h"

#ifdef NO_CLANG_BUILTINS

#define GEN_UNARY_BUILTIN_T(NAME, TYPE) \
_CLC_OVERLOAD TYPE __##NAME##_helper(TYPE); \
_CLC_OVERLOAD TYPE __spirv_ocl_##NAME(TYPE n) { return __##NAME##_helper(n); }

#define GEN_TERNARY_BUILTIN_T(NAME, TYPE) \
_CLC_OVERLOAD TYPE __##NAME##_helper(TYPE, TYPE, TYPE); \
_CLC_OVERLOAD TYPE __spirv_ocl_##NAME(TYPE a, TYPE b, TYPE c) { \
return __##NAME##_helper(a, b, c); \
}
#define GEN_UNARY_BUILTIN(NAME) \
GEN_UNARY_BUILTIN_T(NAME, float) \
GEN_UNARY_BUILTIN_T(NAME, double)

#define GEN_TERNARY_BUILTIN(NAME) \
GEN_TERNARY_BUILTIN_T(NAME, float) \
GEN_TERNARY_BUILTIN_T(NAME, double)

#else

#ifndef IS_NATIVE
#define GETNAME(ID) __spirv_ocl_##ID
#else
#define GETNAME(ID) __spirv_ocl_native_##ID
#endif

// Todo: fabs is the only builtin whose vector version is not named
// __builtin_elementwise_##NAME
#ifndef IS_FABS
#define GEN_UNARY_VECTOR_BUILTIN(NAME, TYPE, NUM) \
_CLC_OVERLOAD TYPE##NUM GETNAME(NAME)(TYPE##NUM n) { \
return __builtin_elementwise_##NAME(n); \
}
#else
#define GEN_UNARY_VECTOR_BUILTIN(NAME, TYPE, NUM) \
_CLC_OVERLOAD TYPE##NUM GETNAME(NAME)(TYPE##NUM n) { \
return __builtin_elementwise_abs(n); \
}
#endif

#define GEN_UNARY_VECTOR_BUILTIN_T(NAME, TYPE) \
GEN_UNARY_VECTOR_BUILTIN(NAME, TYPE, 2) \
GEN_UNARY_VECTOR_BUILTIN(NAME, TYPE, 3) \
GEN_UNARY_VECTOR_BUILTIN(NAME, TYPE, 4) \
GEN_UNARY_VECTOR_BUILTIN(NAME, TYPE, 8) \
GEN_UNARY_VECTOR_BUILTIN(NAME, TYPE, 16)

#define GEN_UNARY_BUILTIN(NAME) \
_CLC_OVERLOAD float GETNAME(NAME)(float n) { \
return __builtin_##NAME##f(n); \
} \
_CLC_OVERLOAD double GETNAME(NAME)(double n) { return __builtin_##NAME(n); } \
GEN_UNARY_VECTOR_BUILTIN_T(NAME, float) \
GEN_UNARY_VECTOR_BUILTIN_T(NAME, double)

#define GEN_TERNARY_VECTOR_BUILTIN(NAME, TYPE, NUM) \
_CLC_OVERLOAD TYPE##NUM GETNAME(NAME)(TYPE##NUM n1, TYPE##NUM n2, \
TYPE##NUM n3) { \
return __builtin_elementwise_##NAME(n1, n2, n3); \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these __builtin* specific to nativecpu?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are part of clang see here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I was thinking. It seems a bit strange to me to be calling generic clang builtins in a target specific libclc backend. Is there a good reason to do it like this?

Maybe these clang builtins better than the ones in the libclc/generic backend? Such generic impls that would be called if you don't add a target specific impl. Or could the clang builtins used here just be added to the libclc/generic impls?

Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The clang builtins should lead to the same LLVM intrinsics used in libclc/generic, but the way the SPIRV builtins are implemented in generic doesn't play well with the x86 ABI on Linux (see #10970). I think you are right and it's worth considering changing the implementation in generic, but I'm not 100% sure about the implications of doing so.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I see, makes sense, thanks for the clarification.

}

#define GEN_TERNARY_VECTOR_BUILTIN_T(NAME, TYPE) \
GEN_TERNARY_VECTOR_BUILTIN(NAME, TYPE, 2) \
GEN_TERNARY_VECTOR_BUILTIN(NAME, TYPE, 3) \
GEN_TERNARY_VECTOR_BUILTIN(NAME, TYPE, 4) \
GEN_TERNARY_VECTOR_BUILTIN(NAME, TYPE, 8) \
GEN_TERNARY_VECTOR_BUILTIN(NAME, TYPE, 16)

#define GEN_TERNARY_BUILTIN(NAME) \
_CLC_OVERLOAD float GETNAME(NAME)(float n1, float n2, float n3) { \
return __builtin_##NAME##f(n1, n2, n3); \
} \
_CLC_OVERLOAD double GETNAME(NAME)(double n1, double n2, double n3) { \
return __builtin_##NAME(n1, n2, n3); \
} \
GEN_TERNARY_VECTOR_BUILTIN_T(NAME, float) \
GEN_TERNARY_VECTOR_BUILTIN_T(NAME, double)
#endif
4 changes: 4 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/native_cos.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define IS_NATIVE
#include "helpers.h"

GEN_UNARY_BUILTIN(cos)
4 changes: 4 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/native_exp.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define IS_NATIVE
#include "helpers.h"

GEN_UNARY_BUILTIN(exp)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think IS_NATIVE could be staying defined when you don't want it to?

Suggested change
GEN_UNARY_BUILTIN(exp)
GEN_UNARY_BUILTIN(exp)
#undef IS_NATIVE

etc

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, that's done, thank you

4 changes: 4 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/native_exp2.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define IS_NATIVE
#include "helpers.h"

GEN_UNARY_BUILTIN(exp2)
4 changes: 4 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/native_log.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define IS_NATIVE
#include "helpers.h"

GEN_UNARY_BUILTIN(log)
5 changes: 5 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/native_log10.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#define IS_NATIVE
#include "helpers.h"

GEN_UNARY_BUILTIN(log10)

5 changes: 5 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/native_log2.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#define IS_NATIVE
#include "helpers.h"

GEN_UNARY_BUILTIN(log2)

5 changes: 5 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/native_sin.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#define IS_NATIVE
#include "helpers.h"

GEN_UNARY_BUILTIN(sin)

4 changes: 4 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/native_sqrt.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define IS_NATIVE
#include "helpers.h"

GEN_UNARY_BUILTIN(sqrt)
3 changes: 3 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/rint.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "helpers.h"

GEN_UNARY_BUILTIN(rint)
3 changes: 3 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/round.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "helpers.h"

GEN_UNARY_BUILTIN(round)
3 changes: 3 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/sqrt.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "helpers.h"

GEN_UNARY_BUILTIN(sqrt)
3 changes: 3 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/math/trunc.cl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "helpers.h"

GEN_UNARY_BUILTIN(trunc)
17 changes: 17 additions & 0 deletions libclc/x86_64-unknown-linux/libspirv/shared/helpers.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
declare i32 @llvm.ctpop.i32(i32 %n)
declare i8 @llvm.ctpop.i8(i8 %n)
npmiller marked this conversation as resolved.
Show resolved Hide resolved


define dso_local i32 @_Z17__popcount_helperi(i32 %x) {
entry:
%call = call i32 @llvm.ctpop.i32(i32 %x)
ret i32 %call
}


define dso_local i8 @_Z17__popcount_helpera(i8 %x) {
entry:
%call = call i8 @llvm.ctpop.i8(i8 %x)
ret i8 %call
}