[clang] f8d5b49 - Fix missing error for use of 128-bit integer inside SPIR64 device code.

Jennifer Yu via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 7 10:52:58 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 cfe-commits mailing list