From bb1ea2d6139a72340b426e114510c46d938645a6 Mon Sep 17 00:00:00 2001 From: Nemanja Ivanovic Date: Mon, 9 May 2016 08:52:33 +0000 Subject: Enable support for __float128 in Clang and enable it on pertinent platforms This patch corresponds to reviews: http://reviews.llvm.org/D15120 http://reviews.llvm.org/D19125 It adds support for the __float128 keyword, literals and target feature to enable it. Based on the latter of the two aforementioned reviews, this feature is enabled on Linux on i386/X86 as well as SystemZ. This is also the second attempt in commiting this feature. The first attempt did not enable it on required platforms which caused failures when compiling type_traits with -std=gnu++11. If you see failures with compiling this header on your platform after this commit, it is likely that your platform needs to have this feature enabled. llvm-svn: 268898 --- clang/test/CodeGenCXX/float128-declarations.cpp | 138 +++++++++++++++++++++ clang/test/Preprocessor/init.c | 3 + clang/test/Sema/128bitfloat.cpp | 27 ++-- clang/test/Sema/attr-mode.c | 2 +- clang/test/Sema/float128-ld-incompatibility.cpp | 36 ++++++ clang/test/SemaCXX/deleted-operator.cpp | 2 +- .../test/SemaCXX/overloaded-builtin-operators.cpp | 2 +- 7 files changed, 199 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGenCXX/float128-declarations.cpp create mode 100644 clang/test/Sema/float128-ld-incompatibility.cpp (limited to 'clang/test') diff --git a/clang/test/CodeGenCXX/float128-declarations.cpp b/clang/test/CodeGenCXX/float128-declarations.cpp new file mode 100644 index 00000000000..e1604a61cac --- /dev/null +++ b/clang/test/CodeGenCXX/float128-declarations.cpp @@ -0,0 +1,138 @@ +// RUN: %clang_cc1 -emit-llvm -triple powerpc64-unknown-unknown \ +// RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown \ +// RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -triple i386-unknown-linux-gnu -std=c++11 \ +// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86 +// RUN: %clang_cc1 -emit-llvm -triple x86_64-unknown-linux-gnu -std=c++11 \ +// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-X86 +// RUN: %clang_cc1 -emit-llvm -triple systemz-unknown-linux-gnu -std=c++11 \ +// RUN: %s -o - | FileCheck %s -check-prefix=CHECK-SYSZ +// +/* Various contexts where type __float128 can appear. The different check + prefixes are due to different mangling on X86 and different calling + convention on SystemZ. */ + +/* Namespace */ +namespace { + __float128 f1n; + __float128 f2n = 33.q; + __float128 arr1n[10]; + __float128 arr2n[] = { 1.2q, 3.0q, 3.e11q }; + const volatile __float128 func1n(const __float128 &arg) { + return arg + f2n + arr1n[4] - arr2n[1]; + } +} + +/* File */ +__float128 f1f; +__float128 f2f = 32.4q; +static __float128 f3f = f2f; +__float128 arr1f[10]; +__float128 arr2f[] = { -1.2q, -3.0q, -3.e11q }; +__float128 func1f(__float128 arg); + +/* Class */ +class C1 { + __float128 f1c; + static const __float128 f2c; + volatile __float128 f3c; +public: + C1(__float128 arg) : f1c(arg), f3c(arg) { } + __float128 func1c(__float128 arg ) { + return f1c + arg; + } + static __float128 func2c(__float128 arg) { + return arg * C1::f2c; + } +}; + +/* Template */ +template C func1t(C arg) { return arg * 2.q; } +template struct S1 { + C mem1; +}; +template <> struct S1<__float128> { + __float128 mem2; +}; + +/* Local */ +int main(void) { + __float128 f1l = 123e220q; + __float128 f2l = -0.q; + __float128 f3l = 1.189731495357231765085759326628007e4932q; + C1 c1(f1l); + S1<__float128> s1 = { 132.q }; + __float128 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) + + func1t(f1l) + s1.mem2 - f1n + f2n; +#if (__cplusplus >= 201103L) + auto f5l = -1.q, *f6l = &f2l, f7l = func1t(f3l); +#endif + __float128 f8l = f4l++; + __float128 arr1l[] = { -1.q, -0.q, -11.q }; +} +// CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000 +// CHECK-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000 +// CHECK-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128] +// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000] +// CHECK-DAG: define internal fp128 @_ZN12_GLOBAL__N_16func1nERKU10__float128(fp128* +// CHECK-DAG: @f1f = global fp128 0xL00000000000000000000000000000000 +// CHECK-DAG: @f2f = global fp128 0xL33333333333333334004033333333333 +// CHECK-DAG: @arr1f = global [10 x fp128] +// CHECK-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000] +// CHECK-DAG: declare fp128 @_Z6func1fU10__float128(fp128) +// CHECK-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128 %arg) +// CHECK-DAG: define linkonce_odr fp128 @_ZN2C16func2cEU10__float128(fp128 %arg) +// CHECK-DAG: define linkonce_odr fp128 @_Z6func1tIU10__float128ET_S0_(fp128 %arg) +// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 } +// CHECK-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16 +// CHECK-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16 +// CHECK-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16 +// CHECK-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16 +// CHECK-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l +// CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000 +// CHECK-DAG: store fp128 [[INC]], fp128* %f4l + +// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000 +// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000 +// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128] +// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000] +// CHECK-X86-DAG: define internal fp128 @_ZN12_GLOBAL__N_16func1nERKg(fp128* +// CHECK-X86-DAG: @f1f = global fp128 0xL00000000000000000000000000000000 +// CHECK-X86-DAG: @f2f = global fp128 0xL33333333333333334004033333333333 +// CHECK-X86-DAG: @arr1f = global [10 x fp128] +// CHECK-X86-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000] +// CHECK-X86-DAG: declare fp128 @_Z6func1fg(fp128) +// CHECK-X86-DAG: define linkonce_odr void @_ZN2C1C2Eg(%class.C1* %this, fp128 %arg) +// CHECK-X86-DAG: define linkonce_odr fp128 @_ZN2C16func2cEg(fp128 %arg) +// CHECK-X86-DAG: define linkonce_odr fp128 @_Z6func1tIgET_S0_(fp128 %arg) +// CHECK-X86-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 } +// CHECK-X86-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16 +// CHECK-X86-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16 +// CHECK-X86-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16 +// CHECK-X86-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16 +// CHECK-X86-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l +// CHECK-X86-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000 +// CHECK-X86-DAG: store fp128 [[INC]], fp128* %f4l + +// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000 +// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000 +// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128] +// CHECK-SYSZ-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000] +// CHECK-SYSZ-DAG: define internal void @_ZN12_GLOBAL__N_16func1nERKU10__float128(fp128* +// CHECK-SYSZ-DAG: @f1f = global fp128 0xL00000000000000000000000000000000 +// CHECK-SYSZ-DAG: @f2f = global fp128 0xL33333333333333334004033333333333 +// CHECK-SYSZ-DAG: @arr1f = global [10 x fp128] +// CHECK-SYSZ-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000] +// CHECK-SYSZ-DAG: declare void @_Z6func1fU10__float128(fp128* +// CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128* +// CHECK-SYSZ-DAG: define linkonce_odr void @_ZN2C16func2cEU10__float128(fp128* +// CHECK-SYSZ-DAG: define linkonce_odr void @_Z6func1tIU10__float128ET_S0_(fp128* +// CHECK-SYSZ-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 } +// CHECK-SYSZ-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16 +// CHECK-SYSZ-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16 +// CHECK-SYSZ-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16 +// CHECK-SYSZ-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16 +// CHECK-SYSZ-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l +// CHECK-SYSZ-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000 +// CHECK-SYSZ-DAG: store fp128 [[INC]], fp128* %f4l diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c index 98be2ac03d1..41f50109c10 100644 --- a/clang/test/Preprocessor/init.c +++ b/clang/test/Preprocessor/init.c @@ -5827,6 +5827,9 @@ // PPCPOWER8:#define _ARCH_PWR7 1 // PPCPOWER8:#define _ARCH_PWR8 1 // +// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s +// PPC-FLOAT128:#define __FLOAT128__ 1 +// // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-LINUX %s // // PPC64-LINUX:#define _ARCH_PPC 1 diff --git a/clang/test/Sema/128bitfloat.cpp b/clang/test/Sema/128bitfloat.cpp index cb76dac9600..2449cb6b659 100644 --- a/clang/test/Sema/128bitfloat.cpp +++ b/clang/test/Sema/128bitfloat.cpp @@ -1,24 +1,35 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++11 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +#ifdef __FLOAT128__ +__float128 f; +template struct __is_floating_point_helper {}; +template<> struct __is_floating_point_helper<__float128> {}; +int g(int x, __float128 *y) { + return x + *y; +} + +// expected-no-diagnostics +#else #if !defined(__STRICT_ANSI__) -__float128 f; // expected-error {{support for type '__float128' is not yet implemented}} +__float128 f; // expected-error {{__float128 is not supported on this target}} // But this should work: template struct __is_floating_point_helper {}; -template<> struct __is_floating_point_helper<__float128> {}; +template<> struct __is_floating_point_helper<__float128> {}; // expected-error {{__float128 is not supported on this target}} // FIXME: This could have a better diag. -void g(int x, __float128 *y) { - x + *y; // expected-error {{invalid operands to binary expression ('int' and '__float128')}} +int g(int x, __float128 *y) { // expected-error {{__float128 is not supported on this target}} + return x + *y; } #else -__float128 f; // expected-error {{unknown type name '__float128'}} +__float128 f; // expected-error {{__float128 is not supported on this target}} template struct __is_floating_point_helper {}; -template<> struct __is_floating_point_helper<__float128> {}; // expected-error {{use of undeclared identifier '__float128'}} +template<> struct __is_floating_point_helper<__float128> {}; // expected-error {{__float128 is not supported on this target}} -void g(int x, __float128 *y) { // expected-error {{unknown type name '__float128'}} - x + *y; +int g(int x, __float128 *y) { // expected-error {{__float128 is not supported on this target}} + return x + *y; } #endif +#endif diff --git a/clang/test/Sema/attr-mode.c b/clang/test/Sema/attr-mode.c index e0115495380..e160d8d4846 100644 --- a/clang/test/Sema/attr-mode.c +++ b/clang/test/Sema/attr-mode.c @@ -76,7 +76,7 @@ void test_long_to_ui64(unsigned long long* y) { f_ui64_arg(y); } void test_long_to_i64(long* y) { f_i64_arg(y); } void test_long_to_ui64(unsigned long* y) { f_ui64_arg(y); } #endif -typedef float f128ibm __attribute__ ((mode (TF))); // expected-error{{unsupported machine mode 'TF'}} +typedef float f128ibm __attribute__ ((mode (TF))); #elif TEST_64BIT_PPC64 typedef float f128ibm __attribute__ ((mode (TF))); typedef _Complex float c128ibm __attribute__ ((mode (TC))); diff --git a/clang/test/Sema/float128-ld-incompatibility.cpp b/clang/test/Sema/float128-ld-incompatibility.cpp new file mode 100644 index 00000000000..d993ed7b081 --- /dev/null +++ b/clang/test/Sema/float128-ld-incompatibility.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 \ +// RUN: -triple powerpc64le-unknown-linux-gnu -target-cpu pwr8 \ +// RUN: -target-feature +float128 %s + +__float128 qf(); +long double ldf(); + +// FIXME: once operations between long double and __float128 are implemented for +// targets where the types are different, these next two will change +long double ld{qf()}; // expected-error {{cannot initialize a variable of type 'long double' with an rvalue of type '__float128'}} +__float128 q{ldf()}; // expected-error {{cannot initialize a variable of type '__float128' with an rvalue of type 'long double'}} + +auto test1(__float128 q, long double ld) -> decltype(q + ld) { // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}} + return q + ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}} +} + +auto test2(long double a, __float128 b) -> decltype(a + b) { // expected-error {{invalid operands to binary expression ('long double' and '__float128')}} + return a + b; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}} +} + +void test3(bool b) { + long double ld; + __float128 q; + + ld + q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}} + q + ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}} + ld - q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}} + q - ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}} + ld * q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}} + q * ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}} + ld / q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}} + q / ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}} + ld = q; // expected-error {{assigning to 'long double' from incompatible type '__float128'}} + q = ld; // expected-error {{assigning to '__float128' from incompatible type 'long double'}} + q + b ? q : ld; // expected-error {{incompatible operand types ('__float128' and 'long double')}} +} diff --git a/clang/test/SemaCXX/deleted-operator.cpp b/clang/test/SemaCXX/deleted-operator.cpp index df67978a36d..f71e83aa258 100644 --- a/clang/test/SemaCXX/deleted-operator.cpp +++ b/clang/test/SemaCXX/deleted-operator.cpp @@ -9,7 +9,7 @@ int PR10757f() { PR10757 a1; // FIXME: We get a ridiculous number of "built-in candidate" notes here... if(~a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 8 {{built-in candidate}} - if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 121 {{built-in candidate}} + if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 144 {{built-in candidate}} } struct DelOpDel { diff --git a/clang/test/SemaCXX/overloaded-builtin-operators.cpp b/clang/test/SemaCXX/overloaded-builtin-operators.cpp index 4c2953b0b3f..7a99a898e20 100644 --- a/clang/test/SemaCXX/overloaded-builtin-operators.cpp +++ b/clang/test/SemaCXX/overloaded-builtin-operators.cpp @@ -183,7 +183,7 @@ void test_dr425(A a) { // FIXME: lots of candidates here! (void)(1.0f * a); // expected-error{{ambiguous}} \ // expected-note 4{{candidate}} \ - // expected-note {{remaining 117 candidates omitted; pass -fshow-overloads=all to show them}} + // expected-note {{remaining 140 candidates omitted; pass -fshow-overloads=all to show them}} } // pr5432 -- cgit v1.2.3