Index: clang/lib/Basic/Targets/SPIR.h =================================================================== --- clang/lib/Basic/Targets/SPIR.h +++ clang/lib/Basic/Targets/SPIR.h @@ -104,6 +104,8 @@ } bool hasExtIntType() const override { return true; } + + bool hasInt128Type() const override { return false; } }; class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { public: Index: clang/lib/Sema/Sema.cpp =================================================================== --- clang/lib/Sema/Sema.cpp +++ clang/lib/Sema/Sema.cpp @@ -236,7 +236,9 @@ return; // Initialize predefined 128-bit integer types, if needed. - if (Context.getTargetInfo().hasInt128Type()) { + if (Context.getTargetInfo().hasInt128Type() || + (Context.getAuxTargetInfo() && + Context.getAuxTargetInfo()->hasInt128Type())) { // If either of the 128-bit integer types are unavailable to name lookup, // define them now. DeclarationName Int128 = &Context.Idents.get("__int128_t"); Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -8199,12 +8199,16 @@ ArithmeticTypes.push_back(S.Context.IntTy); ArithmeticTypes.push_back(S.Context.LongTy); ArithmeticTypes.push_back(S.Context.LongLongTy); - if (S.Context.getTargetInfo().hasInt128Type()) + if (S.Context.getTargetInfo().hasInt128Type() || + (S.Context.getAuxTargetInfo() && + S.Context.getAuxTargetInfo()->hasInt128Type())) ArithmeticTypes.push_back(S.Context.Int128Ty); ArithmeticTypes.push_back(S.Context.UnsignedIntTy); ArithmeticTypes.push_back(S.Context.UnsignedLongTy); ArithmeticTypes.push_back(S.Context.UnsignedLongLongTy); - if (S.Context.getTargetInfo().hasInt128Type()) + if (S.Context.getTargetInfo().hasInt128Type() || + (S.Context.getAuxTargetInfo() && + S.Context.getAuxTargetInfo()->hasInt128Type())) ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty); LastPromotedIntegralType = ArithmeticTypes.size(); LastPromotedArithmeticType = ArithmeticTypes.size(); Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -1515,6 +1515,7 @@ } case DeclSpec::TST_int128: if (!S.Context.getTargetInfo().hasInt128Type() && + !S.getLangOpts().SYCLIsDevice && !(S.getLangOpts().OpenMP && S.getLangOpts().OpenMPIsDevice)) S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) << "__int128"; Index: clang/test/CodeGen/ext-int-cc.c =================================================================== --- clang/test/CodeGen/ext-int-cc.c +++ clang/test/CodeGen/ext-int-cc.c @@ -43,7 +43,7 @@ // SPARC: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}}) // MIPS64: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 signext %{{.+}}, i64 signext %{{.+}}) // MIPS: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 signext %{{.+}}) -// SPIR64: define spir_func void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128 %{{.+}}, i64 %{{.+}}) +// SPIR64: define spir_func void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}}) // SPIR: define spir_func void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}}) // HEX: define void @ParamPassing(i129* byval(i129) align 8 %{{.+}}, i128* byval(i128) align 8 %{{.+}}, i64 %{{.+}}) // LANAI: define void @ParamPassing(i129* byval(i129) align 4 %{{.+}}, i128* byval(i128) align 4 %{{.+}}, i64 %{{.+}}) @@ -72,7 +72,7 @@ // SPARC: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}}) // MIPS64: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 signext %{{.+}}, i63 signext %{{.+}}) // MIPS: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 signext %{{.+}}) -// SPIR64: define spir_func void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127 %{{.+}}, i63 %{{.+}}) +// SPIR64: define spir_func void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}}) // SPIR: define spir_func void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}}) // HEX: define void @ParamPassing2(i129* byval(i129) align 8 %{{.+}}, i127* byval(i127) align 8 %{{.+}}, i63 %{{.+}}) // LANAI: define void @ParamPassing2(i129* byval(i129) align 4 %{{.+}}, i127* byval(i127) align 4 %{{.+}}, i63 %{{.+}}) @@ -191,7 +191,7 @@ // SPARC: define void @ReturnPassing3(i127* noalias sret // MIPS64: define i127 @ReturnPassing3( // MIPS: define void @ReturnPassing3(i127* noalias sret -// SPIR64: define spir_func i127 @ReturnPassing3( +// SPIR64: define spir_func void @ReturnPassing3(i127* noalias sret // SPIR: define spir_func void @ReturnPassing3(i127* noalias sret // HEX: define void @ReturnPassing3(i127* noalias sret // LANAI: define void @ReturnPassing3(i127* noalias sret @@ -220,7 +220,7 @@ // SPARC: define void @ReturnPassing4(i128* noalias sret // MIPS64: define i128 @ReturnPassing4( // MIPS: define void @ReturnPassing4(i128* noalias sret -// SPIR64: define spir_func i128 @ReturnPassing4( +// SPIR64: define spir_func void @ReturnPassing4(i128* noalias sret // SPIR: define spir_func void @ReturnPassing4(i128* noalias sret // HEX: define void @ReturnPassing4(i128* noalias sret // LANAI: define void @ReturnPassing4(i128* noalias sret Index: clang/test/SemaSYCL/int128.cpp =================================================================== --- /dev/null +++ clang/test/SemaSYCL/int128.cpp @@ -0,0 +1,118 @@ +// RUN: %clang_cc1 -triple spir64 -aux-triple x86_64-unknown-linux-gnu \ +// RUN: -fsycl -fsycl-is-device -verify -fsyntax-only %s + +typedef __uint128_t BIGTY; + +template +class Z { +public: + // expected-note@+1 {{'field' defined here}} + T field; + // expected-note@+1 2{{'field1' defined here}} + __int128 field1; + using BIGTYPE = __int128; + // expected-note@+1 {{'bigfield' defined here}} + BIGTYPE bigfield; +}; + +void host_ok(void) { + __int128 A; + int B = sizeof(__int128); + Z<__int128> C; + C.field1 = A; +} + +void usage() { + // expected-note@+1 3{{'A' defined here}} + __int128 A; + Z<__int128> C; + // expected-error@+2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + C.field1 = A; + // expected-error@+1 {{'bigfield' requires 128 bit size 'Z::BIGTYPE' (aka '__int128') type support, but device 'spir64' does not support it}} + C.bigfield += 1.0; + + // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + auto foo1 = [=]() { + __int128 AA; + // expected-note@+2 {{'BB' defined here}} + // expected-error@+1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + auto BB = A; + // expected-error@+1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + BB += 1; + }; + + // expected-note@+1 {{called by 'usage'}} + foo1(); +} + +template +void foo2(){}; + +// expected-note@+3 {{'P' defined here}} +// expected-error@+2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} +// expected-note@+1 2{{'foo' defined here}} +__int128 foo(__int128 P) { return P; } + +void foobar() { + // expected-note@+1 {{'operator __int128' defined here}} + struct X { operator __int128() const; } x; + bool a = false; + // expected-error@+1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + a = x == __int128(0); +} + +template +__attribute__((sycl_kernel)) void kernel(Func kernelFunc) { + // expected-note@+1 6{{called by 'kernel}} + kernelFunc(); +} + +int main() { + // expected-note@+1 {{'CapturedToDevice' defined here}} + __int128 CapturedToDevice = 1; + host_ok(); + kernel([=]() { + decltype(CapturedToDevice) D; + // expected-error@+1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + auto C = CapturedToDevice; + Z<__int128> S; + // expected-error@+1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + S.field1 += 1; + // expected-error@+1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + S.field = 1; + }); + + kernel([=]() { + // expected-note@+1 2{{called by 'operator()'}} + usage(); + // expected-note@+1 {{'BBBB' defined here}} + BIGTY BBBB; + // expected-error@+3 {{'BBBB' requires 128 bit size 'BIGTY' (aka 'unsigned __int128') type support, but device 'spir64' does not support it}} + // expected-error@+2 2{{'foo' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}} + // expected-note@+1 1{{called by 'operator()'}} + auto A = foo(BBBB); + // expected-note@+1 {{called by 'operator()'}} + foobar(); + }); + + kernel([=]() { + Z<__int128> S; + foo2<__int128>(); + auto A = sizeof(CapturedToDevice); + }); + + return 0; +} + +// no error expected +BIGTY zoo(BIGTY h) { + h = 1; + return h; +} + +namespace PR12964 { + struct X { operator __int128() const; } x; + bool a = x == __int128(0); +} +