Skip to content

[SYCL] Restore missing 'signed char' SPIR-V builtins #18807

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

Closed
wants to merge 5 commits into from
Closed
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
36 changes: 20 additions & 16 deletions clang/lib/Sema/SPIRVBuiltins.td
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,8 @@ class ConstOCLSPVBuiltin<string _Name, list<Type> _Signature> :

// OpenCL v1.0/1.2/2.0 s6.1.1: Built-in Scalar Data Types.
def Bool : IntType<"bool", QualType<"Context.BoolTy">, 1>;
def TrueChar : IntType<"_char", QualType<"Context.CharTy", 0, 1>, 8>;
def Char : IntType<"char", QualTypeFromFunction<"GetCharType", 0, 1>, 8>;
def Char : IntType<"char", QualType<"Context.CharTy", 0, 1>, 8>;
def SChar : IntType<"schar", QualType<"Context.SignedCharTy", 0, 1>, 8>;
def UChar : UIntType<"uchar", QualType<"Context.UnsignedCharTy">, 8>;
def Short : IntType<"short", QualType<"Context.ShortTy", 0, 1>, 16>;
def UShort : UIntType<"ushort", QualType<"Context.UnsignedShortTy">, 16>;
Expand Down Expand Up @@ -355,19 +355,20 @@ def Vec16 : IntList<"Vec16", [16]>;
def Vec1234 : IntList<"Vec1234", [1, 2, 3, 4]>;

// Type lists.
def TLAll : TypeList<[Char, UChar, Short, UShort, Int, UInt, Long, ULong, Float, Double, Half]>;
def TLAllUnsigned : TypeList<[UChar, UChar, UShort, UShort, UInt, UInt, ULong, ULong, UInt, ULong, UShort]>;
def TLAllWithBool : TypeList<[Bool, Char, UChar, Short, UShort, Int, UInt, Long,
def TLAll : TypeList<[Char, SChar, UChar, Short, UShort, Int, UInt, Long, ULong, Float, Double, Half]>;
def TLAllUnsigned : TypeList<[UChar, UChar, UChar, UShort, UShort, UInt, UInt, ULong, ULong, UInt, ULong, UShort]>;
def TLAllWithBool : TypeList<[Bool, Char, SChar, UChar, Short, UShort, Int, UInt, Long,
ULong, Float, Double, Half]>;
def TLFloat : TypeList<[Float, Double, Half]>;
// FIXME: handle properly char (signed or unsigned depending on host)
def TLSignedInts : TypeList<[Char, Short, Int, Long]>;
def TLUnsignedInts : TypeList<[UChar, UShort, UInt, ULong]>;
def TLSignedInts : TypeList<[Char, SChar, Short, Int, Long]>;
def TLUIToSIInts : TypeList<[UChar, UChar, UShort, UInt, ULong]>;
def TLUnsignedInts : TypeList<[UChar, UShort, UInt, ULong]>;

// Signed to Unsigned conversion
// FIXME: handle properly char (signed or unsigned depending on host)
def TLSToUSignedInts : TypeList<[Char, Short, Int, Long]>;
def TLSToUUnsignedInts : TypeList<[UChar, UShort, UInt, ULong]>;
def TLSToUSignedInts : TypeList<[Char, SChar, Short, Int, Long]>;
def TLSToUUnsignedInts : TypeList<[UChar, UChar, UShort, UInt, ULong]>;

def TLIntLongFloats : TypeList<[Int, UInt, Long, ULong, Float, Double, Half]>;

Expand All @@ -376,7 +377,7 @@ def TLIntLongFloats : TypeList<[Int, UInt, Long, ULong, Float, Double, Half]>;
// uchar abs(uchar).
def TLAllUIntsTwice : TypeList<[UChar, UChar, UChar, UShort, UShort, UInt, UInt, ULong, ULong]>;

def TLAllInts : TypeList<[Char, UChar, Short, UShort, Int, UInt, Long, ULong]>;
def TLAllInts : TypeList<[Char, SChar, UChar, Short, UShort, Int, UInt, Long, ULong]>;

// GenType definitions for multiple base types (e.g. all floating point types,
// or all integer types).
Expand All @@ -393,6 +394,8 @@ def AIGenType1 : GenericType<"AIGenType1", TLAllInts, Vec1>;
def AIGenTypeN : GenericType<"AIGenTypeN", TLAllInts, VecAndScalar>;
def AUIGenTypeN : GenericType<"AUIGenTypeN", TLUnsignedInts, VecAndScalar>;
def ASIGenTypeN : GenericType<"ASIGenTypeN", TLSignedInts, VecAndScalar>;
// unsigned integers matching 1:1 with signed ints
def AUIToSIGenTypeN : GenericType<"AUIToSIGenTypeN", TLUIToSIInts, VecAndScalar>;
def AIGenTypeNNoScalar : GenericType<"AIGenTypeNNoScalar", TLAllInts, VecNoScalar>;
// All integer to unsigned
def AI2UGenTypeN : GenericType<"AI2UGenTypeN", TLAllUIntsTwice, VecAndScalar>;
Expand All @@ -402,6 +405,7 @@ def SGenTypeN : GenericType<"SGenTypeN", TLSignedInts, VecAndScalar
// Unsigned integer
def UGenType1 : GenericType<"UGenType1", TLUnsignedInts, Vec1>;
def UGenTypeN : GenericType<"UGenTypeN", TLUnsignedInts, VecAndScalar>;
def UToSGenTypeN : GenericType<"UToSGenTypeN", TLUIToSIInts, VecAndScalar>;
def UInt4 : GenericType<"UInt4", TypeList<[UInt]>, Vec4>;
// Float
def FGenType1 : GenericType<"FGenType1", TLFloat, Vec1>;
Expand All @@ -411,7 +415,7 @@ def IntLongFloatGenType1 : GenericType<"IntLongFloatGenType1", TLIntLongFloats

// GenType definitions for every single base type (e.g. fp32 only).
// Names are like: GenTypeFloatVecAndScalar.
foreach Type = [Char, UChar, Short, UShort,
foreach Type = [Char, SChar, UChar, Short, UShort,
Int, UInt, Long, ULong,
Float, Double, Half] in {
foreach VecSizes = [VecAndScalar, VecNoScalar] in {
Expand Down Expand Up @@ -549,9 +553,9 @@ foreach name = ["clz", "ctz", "popcount"] in {

def : ConstOCLSPVBuiltin<"rotate", [AIGenTypeN, AIGenTypeN, AIGenTypeN]>;

def : ConstOCLSPVBuiltin<"s_abs", [AUIGenTypeN, ASIGenTypeN]>;
def : ConstOCLSPVBuiltin<"s_abs", [AUIToSIGenTypeN, ASIGenTypeN]>;

def : ConstOCLSPVBuiltin<"s_abs_diff", [AUIGenTypeN, ASIGenTypeN, ASIGenTypeN]>;
def : ConstOCLSPVBuiltin<"s_abs_diff", [AUIToSIGenTypeN, ASIGenTypeN, ASIGenTypeN]>;

foreach name = ["s_add_sat",
"s_hadd", "s_rhadd",
Expand Down Expand Up @@ -651,9 +655,9 @@ def : ConstOCLSPVBuiltin<"bitselect", [AGenTypeN, AGenTypeN, AGenTypeN, AGenType

foreach name = ["select"] in {
def : ConstOCLSPVBuiltin<name, [SGenTypeN, SGenTypeN, SGenTypeN, SGenTypeN]>;
def : ConstOCLSPVBuiltin<name, [SGenTypeN, SGenTypeN, SGenTypeN, UGenTypeN]>;
def : ConstOCLSPVBuiltin<name, [SGenTypeN, SGenTypeN, SGenTypeN, UToSGenTypeN]>;
def : ConstOCLSPVBuiltin<name, [UGenTypeN, UGenTypeN, UGenTypeN, UGenTypeN]>;
def : ConstOCLSPVBuiltin<name, [UGenTypeN, UGenTypeN, UGenTypeN, SGenTypeN]>;
def : ConstOCLSPVBuiltin<name, [UToSGenTypeN, UToSGenTypeN, UToSGenTypeN, SGenTypeN]>;
def : ConstOCLSPVBuiltin<name, [GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeFloatVecAndScalar, GenTypeUIntVecAndScalar]>;
def : ConstOCLSPVBuiltin<name, [GenTypeDoubleVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeDoubleVecAndScalar, GenTypeULongVecAndScalar]>;
def : ConstOCLSPVBuiltin<name, [GenTypeHalfVecAndScalar, GenTypeHalfVecAndScalar, GenTypeHalfVecAndScalar, GenTypeUShortVecAndScalar]>;
Expand Down Expand Up @@ -988,7 +992,7 @@ foreach name = ["GroupLogicalAndKHR", "GroupLogicalOrKHR"] in {

def SubgroupShuffleINTELVecType
: GenericType<"SubgroupShuffleINTELVecType",
TypeList<[Char, UChar, Short, UShort, Int, UInt, Float]>,
TypeList<[Char, SChar, UChar, Short, UShort, Int, UInt, Float]>,
VecNoScalar>;

foreach name = ["SubgroupShuffleINTEL", "SubgroupShuffleXorINTEL"] in {
Expand Down
5 changes: 0 additions & 5 deletions clang/lib/Sema/SemaLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
#include <utility>
#include <vector>

static inline clang::QualType GetCharType(clang::ASTContext &Context);
static inline clang::QualType GetFloat16Type(clang::ASTContext &Context);

#include "OpenCLBuiltins.inc"
Expand Down Expand Up @@ -702,10 +701,6 @@ LLVM_DUMP_METHOD void LookupResult::dump() {
D->dump();
}

static inline QualType GetCharType(clang::ASTContext &Context) {
return Context.getLangOpts().OpenCL ? Context.CharTy : Context.SignedCharTy;
}

static inline QualType GetFloat16Type(clang::ASTContext &Context) {
return Context.getLangOpts().OpenCL ? Context.HalfTy : Context.Float16Ty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ template <class T> void test_logical() {
void test() {
test_with_bool<bool>();
test_with_bool<char>();
test_with_bool<signed char>();
test_with_bool<unsigned char>();
test_with_bool<short>();
test_with_bool<unsigned short>();
Expand All @@ -199,13 +200,15 @@ void test() {
test_with_bool<double>();

test_integer<char>();
test_integer<signed char>();
test_integer<unsigned char>();
test_integer<short>();
test_integer<unsigned short>();
test_integer<int>();
test_integer<unsigned int>();

test_signed<char>();
test_signed<signed char>();
test_signed<short>();
test_signed<int>();

Expand All @@ -232,13 +235,20 @@ void test() {
// CHECK: call noundef zeroext i1 @_Z33__spirv_GroupNonUniformShuffleXoribj
// CHECK: call noundef zeroext i1 @_Z32__spirv_GroupNonUniformShuffleUpibj
// CHECK: call noundef zeroext i1 @_Z34__spirv_GroupNonUniformShuffleDownibj
// CHECK: call noundef zeroext i1 @_Z31__spirv_GroupNonUniformAllEqualii
// CHECK: call noundef i32 @_Z32__spirv_GroupNonUniformBroadcastiij
// CHECK: call noundef i32 @_Z37__spirv_GroupNonUniformBroadcastFirstii
// CHECK: call noundef i32 @_Z30__spirv_GroupNonUniformShuffleiij
// CHECK: call noundef i32 @_Z33__spirv_GroupNonUniformShuffleXoriij
// CHECK: call noundef i32 @_Z32__spirv_GroupNonUniformShuffleUpiij
// CHECK: call noundef i32 @_Z34__spirv_GroupNonUniformShuffleDowniij
// CHECK: call noundef zeroext i1 @_Z31__spirv_GroupNonUniformAllEqualic
// CHECK: call noundef signext i8 @_Z32__spirv_GroupNonUniformBroadcasticj
// CHECK: call noundef signext i8 @_Z37__spirv_GroupNonUniformBroadcastFirstic
// CHECK: call noundef signext i8 @_Z30__spirv_GroupNonUniformShuffleicj
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformShuffleXoricj
// CHECK: call noundef signext i8 @_Z32__spirv_GroupNonUniformShuffleUpicj
// CHECK: call noundef signext i8 @_Z34__spirv_GroupNonUniformShuffleDownicj
// CHECK: call noundef zeroext i1 @_Z31__spirv_GroupNonUniformAllEqualia
// CHECK: call noundef signext i8 @_Z32__spirv_GroupNonUniformBroadcastiaj
// CHECK: call noundef signext i8 @_Z37__spirv_GroupNonUniformBroadcastFirstia
// CHECK: call noundef signext i8 @_Z30__spirv_GroupNonUniformShuffleiaj
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformShuffleXoriaj
// CHECK: call noundef signext i8 @_Z32__spirv_GroupNonUniformShuffleUpiaj
// CHECK: call noundef signext i8 @_Z34__spirv_GroupNonUniformShuffleDowniaj
// CHECK: call noundef zeroext i1 @_Z31__spirv_GroupNonUniformAllEqualih
// CHECK: call noundef zeroext i8 @_Z32__spirv_GroupNonUniformBroadcastihj
// CHECK: call noundef zeroext i8 @_Z37__spirv_GroupNonUniformBroadcastFirstih
Expand Down Expand Up @@ -295,16 +305,26 @@ void test() {
// CHECK: call noundef double @_Z33__spirv_GroupNonUniformShuffleXoridj
// CHECK: call noundef double @_Z32__spirv_GroupNonUniformShuffleUpidj
// CHECK: call noundef double @_Z34__spirv_GroupNonUniformShuffleDownidj
// CHECK: call noundef i32 @_Z27__spirv_GroupNonUniformIAddiii
// CHECK: call noundef i32 @_Z27__spirv_GroupNonUniformIAddiiij
// CHECK: call noundef i32 @_Z27__spirv_GroupNonUniformIMuliii
// CHECK: call noundef i32 @_Z27__spirv_GroupNonUniformIMuliiij
// CHECK: call noundef i32 @_Z33__spirv_GroupNonUniformBitwiseAndiii
// CHECK: call noundef i32 @_Z33__spirv_GroupNonUniformBitwiseAndiiij
// CHECK: call noundef i32 @_Z32__spirv_GroupNonUniformBitwiseOriii
// CHECK: call noundef i32 @_Z32__spirv_GroupNonUniformBitwiseOriiij
// CHECK: call noundef i32 @_Z33__spirv_GroupNonUniformBitwiseXoriii
// CHECK: call noundef i32 @_Z33__spirv_GroupNonUniformBitwiseXoriiij
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformIAddiic
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformIAddiicj
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformIMuliic
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformIMuliicj
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformBitwiseAndiic
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformBitwiseAndiicj
// CHECK: call noundef signext i8 @_Z32__spirv_GroupNonUniformBitwiseOriic
// CHECK: call noundef signext i8 @_Z32__spirv_GroupNonUniformBitwiseOriicj
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformBitwiseXoriic
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformBitwiseXoriicj
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformIAddiia
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformIAddiiaj
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformIMuliia
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformIMuliiaj
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformBitwiseAndiia
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformBitwiseAndiiaj
// CHECK: call noundef signext i8 @_Z32__spirv_GroupNonUniformBitwiseOriia
// CHECK: call noundef signext i8 @_Z32__spirv_GroupNonUniformBitwiseOriiaj
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformBitwiseXoriia
// CHECK: call noundef signext i8 @_Z33__spirv_GroupNonUniformBitwiseXoriiaj
// CHECK: call noundef zeroext i8 @_Z27__spirv_GroupNonUniformIAddiih
// CHECK: call noundef zeroext i8 @_Z27__spirv_GroupNonUniformIAddiihj
// CHECK: call noundef zeroext i8 @_Z27__spirv_GroupNonUniformIMuliih
Expand Down Expand Up @@ -355,10 +375,14 @@ void test() {
// CHECK: call noundef i32 @_Z32__spirv_GroupNonUniformBitwiseOriijj
// CHECK: call noundef i32 @_Z33__spirv_GroupNonUniformBitwiseXoriij
// CHECK: call noundef i32 @_Z33__spirv_GroupNonUniformBitwiseXoriijj
// CHECK: call noundef i32 @_Z27__spirv_GroupNonUniformSMiniii
// CHECK: call noundef i32 @_Z27__spirv_GroupNonUniformSMiniiij
// CHECK: call noundef i32 @_Z27__spirv_GroupNonUniformSMaxiii
// CHECK: call noundef i32 @_Z27__spirv_GroupNonUniformSMaxiiij
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformSMiniic
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformSMiniicj
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformSMaxiic
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformSMaxiicj
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformSMiniia
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformSMiniiaj
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformSMaxiia
// CHECK: call noundef signext i8 @_Z27__spirv_GroupNonUniformSMaxiiaj
// CHECK: call noundef signext i16 @_Z27__spirv_GroupNonUniformSMiniis
// CHECK: call noundef signext i16 @_Z27__spirv_GroupNonUniformSMiniisj
// CHECK: call noundef signext i16 @_Z27__spirv_GroupNonUniformSMaxiis
Expand Down
36 changes: 35 additions & 1 deletion libclc/libspirv/lib/generic/gen_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@
#pragma OPENCL EXTENSION cles_khr_int64 : enable
#endif

// Typedef some signed char types that SPIR-V requires as the destination of
// certain conversion builtins.
typedef signed char schar;
typedef __attribute__((ext_vector_type(2))) signed char schar2;
typedef __attribute__((ext_vector_type(3))) signed char schar3;
typedef __attribute__((ext_vector_type(4))) signed char schar4;
typedef __attribute__((ext_vector_type(8))) signed char schar8;
typedef __attribute__((ext_vector_type(16))) signed char schar16;

"""
)

Expand Down Expand Up @@ -151,11 +160,22 @@ def is_signed_unsigned_conversion(src, dst):
def generate_spirv_fn_impl(src, dst, size="", mode="", sat="", force_decoration=False):
close_conditional = conditional_guard(src, dst)

# If the destination is an schar type, we will be converting using the
# equivalent char type which in OpenCL C is signed. For vector types, we
# cannot rely on implicit casts back to the schar type so insert an
# explicit cast.
if dst.startswith("schar") and size:
cast = "__builtin_convertvector("
cast_end = f", {dst}{size})"
else:
cast = ""
cast_end = ""

print(
"""_CLC_DEF _CLC_OVERLOAD _CLC_CONSTFN
{DST}{N} {FN}({SRC}{N} x)
{{
return {CORE_FN}(x);
return {CAST}{CORE_FN}(x){CAST_END};
}}
""".format(
FN=spirv_fn_name(
Expand All @@ -166,6 +186,8 @@ def generate_spirv_fn_impl(src, dst, size="", mode="", sat="", force_decoration=
mode=mode,
force_sat_decoration=force_decoration,
),
CAST=cast,
CAST_END=cast_end,
CORE_FN=clc_core_fn_name(dst, size=size, sat=sat, mode=mode),
SRC=src,
DST=dst,
Expand Down Expand Up @@ -203,6 +225,10 @@ def generate_spirv_fn(src, dst, size="", mode="", sat=""):

# __spirv_ConvertUToF / __spirv_ConvertSToF + mode
for src in int_types:
# We're not interested in schar as source types; remangling will do that
# for us.
if src == "schar":
continue
for dst in float_types:
for size in vector_sizes:
for mode in rounding_modes:
Expand All @@ -217,13 +243,21 @@ def generate_spirv_fn(src, dst, size="", mode="", sat=""):

# __spirv_UConvert + sat
for src in int_types:
# We're not interested in schar as source types; remangling will do that
# for us.
if src == "schar":
continue
for dst in unsigned_types:
for size in vector_sizes:
for sat in saturation:
generate_spirv_fn(src, dst, size, sat=sat)

# __spirv_SConvert + sat
for src in int_types:
# We're not interested in schar as source types; remangling will do that
# for us.
if src == "schar":
continue
for dst in signed_types:
for size in vector_sizes:
for sat in saturation:
Expand Down
11 changes: 9 additions & 2 deletions libclc/libspirv/lib/generic/gen_convert_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

types = [
"char",
"schar",
"uchar",
"short",
"ushort",
Expand All @@ -16,6 +17,7 @@
]
int_types = [
"char",
"schar",
"uchar",
"short",
"ushort",
Expand All @@ -25,7 +27,7 @@
"ulong",
]
unsigned_types = ["uchar", "ushort", "uint", "ulong"]
signed_types = ["char", "short", "int", "long"]
signed_types = ["char", "schar", "short", "int", "long"]
float_types = ["half", "float", "double"]
int64_types = ["long", "ulong"]
float64_types = ["double"]
Expand All @@ -40,6 +42,7 @@

bool_type = {
"char": "char",
"schar": "char",
"uchar": "char",
"short": "short",
"ushort": "short",
Expand All @@ -54,6 +57,7 @@

unsigned_type = {
"char": "uchar",
"schar": "uchar",
"uchar": "uchar",
"short": "ushort",
"ushort": "ushort",
Expand All @@ -65,6 +69,7 @@

sizeof_type = {
"char": 1,
"schar": 1,
"uchar": 1,
"short": 2,
"ushort": 2,
Expand All @@ -79,6 +84,7 @@

limit_max = {
"char": "CHAR_MAX",
"schar": "SCHAR_MAX",
"uchar": "UCHAR_MAX",
"short": "SHRT_MAX",
"ushort": "USHRT_MAX",
Expand All @@ -91,6 +97,7 @@

limit_min = {
"char": "CHAR_MIN",
"schar": "SCHAR_MIN",
"uchar": "0",
"short": "SHRT_MIN",
"ushort": "0",
Expand Down Expand Up @@ -145,5 +152,5 @@ def clc_core_fn_name(dst, size="", mode="", sat=""):
and saturation arguments.
"""
return "__clc_convert_{DST}{N}{SAT}{MODE}".format(
DST=dst, N=size, SAT=sat, MODE=mode
DST="char" if dst == "schar" else dst, N=size, SAT=sat, MODE=mode
)
Loading
Loading