[llvm-branch-commits] [clang] f8d5b49 - Fix missing error for use of 128-bit integer inside SPIR64 device code.
Jennifer Yu via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Dec 7 10:56:57 PST 2020
Author: Jennifer Yu
Date: 2020-12-07T10:42:32-08:00
New Revision: f8d5b49c786f5766aa89b59606bd4c4ae10b46f6
URL: https://github.com/llvm/llvm-project/commit/f8d5b49c786f5766aa89b59606bd4c4ae10b46f6
DIFF: https://github.com/llvm/llvm-project/commit/f8d5b49c786f5766aa89b59606bd4c4ae10b46f6.diff
LOG: Fix missing error for use of 128-bit integer inside SPIR64 device code.
Emit error for use of 128-bit integer inside device code had been
already implemented in https://reviews.llvm.org/D74387. However,
the error is not emitted for SPIR64, because for SPIR64, hasInt128Type
return true.
hasInt128Type: is also used to control generation of certain 128-bit
predefined macros, initializer predefined 128-bit integer types and
build 128-bit ArithmeticTypes. Except predefined macros, only the
device target is considered, since error only emit when 128-bit
integer is used inside device code, the host target (auxtarget) also
needs to be considered.
The change address:
1. (SPIR.h) Correct hasInt128Type() for SPIR targets.
2. Sema.cpp and SemaOverload.cpp: Add additional check to consider host
target(auxtarget) when call to hasInt128Type. So that __int128_t
and __int128() are allowed to avoid error when they used outside
device code.
3. SemaType.cpp: add check for SYCLIsDevice to delay the error message.
The error will be emitted if the use of 128-bit integer in the device
code.
Reviewed By: Johannes Doerfert and Aaron Ballman
Differential Revision: https://reviews.llvm.org/D92439
Added:
clang/test/SemaSYCL/int128.cpp
Modified:
clang/lib/Basic/Targets/SPIR.h
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaOverload.cpp
clang/lib/Sema/SemaType.cpp
clang/test/CodeGen/ext-int-cc.c
Removed:
################################################################################
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 6473138982c1..130ce1872dce 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -104,6 +104,8 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
}
bool hasExtIntType() const override { return true; }
+
+ bool hasInt128Type() const override { return false; }
};
class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
public:
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 3901c5e1fec8..b99dc33d8748 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -236,7 +236,9 @@ void Sema::Initialize() {
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");
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 02638beb6627..ff010fd6e4df 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -8187,12 +8187,16 @@ class BuiltinOperatorOverloadBuilder {
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();
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index a8ba0643d41d..0d80bce10ffd 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1515,6 +1515,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
}
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";
diff --git a/clang/test/CodeGen/ext-int-cc.c b/clang/test/CodeGen/ext-int-cc.c
index 02e2f3aef274..dd21845592a8 100644
--- a/clang/test/CodeGen/ext-int-cc.c
+++ b/clang/test/CodeGen/ext-int-cc.c
@@ -43,7 +43,7 @@ void ParamPassing(_ExtInt(129) a, _ExtInt(128) b, _ExtInt(64) c) {}
// 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 @@ void ParamPassing2(_ExtInt(129) a, _ExtInt(127) b, _ExtInt(63) c) {}
// 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 @@ _ExtInt(127) ReturnPassing3(){}
// 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 @@ _ExtInt(128) ReturnPassing4(){}
// 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
diff --git a/clang/test/SemaSYCL/int128.cpp b/clang/test/SemaSYCL/int128.cpp
new file mode 100644
index 000000000000..38271bc020d3
--- /dev/null
+++ b/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 T>
+class Z {
+public:
+ // expected-note at +1 {{'field' defined here}}
+ T field;
+ // expected-note at +1 2{{'field1' defined here}}
+ __int128 field1;
+ using BIGTYPE = __int128;
+ // expected-note at +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 at +1 3{{'A' defined here}}
+ __int128 A;
+ Z<__int128> C;
+ // expected-error at +2 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ // expected-error at +1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ C.field1 = A;
+ // expected-error at +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 at +1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ auto foo1 = [=]() {
+ __int128 AA;
+ // expected-note at +2 {{'BB' defined here}}
+ // expected-error at +1 {{'A' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ auto BB = A;
+ // expected-error at +1 {{'BB' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ BB += 1;
+ };
+
+ // expected-note at +1 {{called by 'usage'}}
+ foo1();
+}
+
+template <typename t>
+void foo2(){};
+
+// expected-note at +3 {{'P' defined here}}
+// expected-error at +2 {{'P' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+// expected-note at +1 2{{'foo' defined here}}
+__int128 foo(__int128 P) { return P; }
+
+void foobar() {
+ // expected-note at +1 {{'operator __int128' defined here}}
+ struct X { operator __int128() const; } x;
+ bool a = false;
+ // expected-error at +1 {{'operator __int128' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ a = x == __int128(0);
+}
+
+template <typename Name, typename Func>
+__attribute__((sycl_kernel)) void kernel(Func kernelFunc) {
+ // expected-note at +1 6{{called by 'kernel}}
+ kernelFunc();
+}
+
+int main() {
+ // expected-note at +1 {{'CapturedToDevice' defined here}}
+ __int128 CapturedToDevice = 1;
+ host_ok();
+ kernel<class variables>([=]() {
+ decltype(CapturedToDevice) D;
+ // expected-error at +1 {{'CapturedToDevice' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ auto C = CapturedToDevice;
+ Z<__int128> S;
+ // expected-error at +1 {{'field1' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ S.field1 += 1;
+ // expected-error at +1 {{'field' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ S.field = 1;
+ });
+
+ kernel<class functions>([=]() {
+ // expected-note at +1 2{{called by 'operator()'}}
+ usage();
+ // expected-note at +1 {{'BBBB' defined here}}
+ BIGTY BBBB;
+ // expected-error at +3 {{'BBBB' requires 128 bit size 'BIGTY' (aka 'unsigned __int128') type support, but device 'spir64' does not support it}}
+ // expected-error at +2 2{{'foo' requires 128 bit size '__int128' type support, but device 'spir64' does not support it}}
+ // expected-note at +1 1{{called by 'operator()'}}
+ auto A = foo(BBBB);
+ // expected-note at +1 {{called by 'operator()'}}
+ foobar();
+ });
+
+ kernel<class ok>([=]() {
+ 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);
+}
+
More information about the llvm-branch-commits
mailing list