* [PATCH], Enable _Float128 in VSX PowerPC system and enable #pragma GCC target "float128"
@ 2017-08-14 19:31 Michael Meissner
2017-08-16 22:56 ` Segher Boessenkool
0 siblings, 1 reply; 2+ messages in thread
From: Michael Meissner @ 2017-08-14 19:31 UTC (permalink / raw)
To: GCC Patches, Segher Boessenkool, David Edelsohn, Bill Schmidt
[-- Attachment #1: Type: text/plain, Size: 2618 bytes --]
This patch enables the _Float128 keyword for the C langauge all of the time for
PowerPC VSX systems. The __float128 keyword continues to be only enabled if
you use the -mfloat128 option.
A previous patch had separated the underlying support (-mfloat128-type) from
enabling the __float128 keyword (-mfloat128). In the prevous implementation,
the compiler used -mfloat128 to enable the _Float128 keyword. This patch uses
-mfloat128-keyword (which is typically on by default) to enable the _Float128
keyword.
In addition to enabling _Float128 keyword, this patch now allows the user to
enable or disable -mfloat128 via the target attribute or pragma.
In order to do this, I needed to change the keyword associated with the IEEE
128-bit type. Previously if the user used -mfloat128, the keyword added was
"__float128" and a #define mapping "__ieee128" to "__float128" was used.
Now, with this patch, the keyword that is created is "__ieee128". If the
__float128 keyword is enabled either through the -mfloat128 option or the
target pragma/attribute, the compiler will create a #define mapping
"__float128" to "__ieee128". This way, we can easily enable or disable
__float128, just by defining or undefining the macro.
I also fixed two of the original __float128 test cases to not use the
-static-libgcc option.
I've tested this patch on big endian power7 (both 32/64-bits) and little endian
power8 (just 64-bits). Can I commit this patch to the trunk?
[gcc]
2017-08-14 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/70589
* config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Make the
real keyword for IEEE 128-bit be __ieee128 for VSX runs, and define
__float128 to be __ieee128 if -mfloat128 is used or a float128
target attribute/pragma is used. Enable _Float128 all of the
time.
(rs6000_cpu_cpp_builtins): Likewise.
* config/rs6000/rs6000.c (rs6000_init_builtins): Likewise.
(rs6000_floatn_mode): Likewise.
(rs6000_opt_masks): Likewise.
[gcc/testsuite]
2017-08-14 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/70589
* gcc.target/powerpc/float128-1.c: Eliminate using the
-static-libgcc option. Use -mvsx instead of -mcpu=power7 to run
the tests.
* gcc.target/powerpc/float128-2.c: Likewise.
* gcc.target/powerpc/float128-3.c: Test enabling -mfloat128 via
#pragma target.
* gcc.target/powerpc/float128-4.c: New test, clone float128-1.c,
using the _Float128 keyword. Do not use the -mfloat128 option.
--
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797
[-- Attachment #2: ieee128-patch20b --]
[-- Type: text/plain, Size: 11280 bytes --]
Index: gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc/config/rs6000/rs6000-c.c (revision 251058)
+++ gcc/config/rs6000/rs6000-c.c (working copy)
@@ -575,6 +575,18 @@ rs6000_target_modify_macros (bool define
2. If TARGET_ALTIVEC is turned off. */
if ((flags & OPTION_MASK_CRYPTO) != 0)
rs6000_define_or_undefine_macro (define_p, "__CRYPTO__");
+ if ((flags & OPTION_MASK_FLOAT128_KEYWORD) != 0)
+ {
+ rs6000_define_or_undefine_macro (define_p, "__FLOAT128__");
+ if (define_p)
+ rs6000_define_or_undefine_macro (true, "__float128=__ieee128");
+ else
+ rs6000_define_or_undefine_macro (false, "__float128");
+ }
+ /* OPTION_MASK_FLOAT128_HARDWARE can be turned on if -mcpu=power9 is used or
+ via the target attribute/pragma. */
+ if ((flags & OPTION_MASK_FLOAT128_HW) != 0)
+ rs6000_define_or_undefine_macro (define_p, "__FLOAT128_HARDWARE__");
/* options from the builtin masks. */
/* Note that RS6000_BTM_PAIRED is enabled only if
@@ -602,24 +614,14 @@ rs6000_cpu_cpp_builtins (cpp_reader *pfi
builtin_define ("__RSQRTE__");
if (TARGET_FRSQRTES)
builtin_define ("__RSQRTEF__");
- if (TARGET_FLOAT128_KEYWORD)
- builtin_define ("__FLOAT128__");
if (TARGET_FLOAT128_TYPE)
builtin_define ("__FLOAT128_TYPE__");
- if (TARGET_FLOAT128_HW)
- builtin_define ("__FLOAT128_HARDWARE__");
if (TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (TFmode))
builtin_define ("__ibm128=long double");
#ifdef TARGET_LIBC_PROVIDES_HWCAP_IN_TCB
builtin_define ("__BUILTIN_CPU_SUPPORTS__");
#endif
- /* We needed to create a keyword if -mfloat128-type was used but not -mfloat,
- so we used __ieee128. If -mfloat128 was used, create a #define back to
- the real keyword in case somebody used it. */
- if (TARGET_FLOAT128_KEYWORD)
- builtin_define ("__ieee128=__float128");
-
if (TARGET_EXTRA_BUILTINS && cpp_get_options (pfile)->lang != CLK_ASM)
{
/* Define the AltiVec syntactic elements. */
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 251058)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -16868,16 +16868,17 @@ rs6000_init_builtins (void)
format that uses a pair of doubles, depending on the switches and
defaults.
- We do not enable the actual __float128 keyword unless the user explicitly
- asks for it, because the library support is not yet complete.
-
If we don't support for either 128-bit IBM double double or IEEE 128-bit
floating point, we need make sure the type is non-zero or else self-test
fails during bootstrap.
We don't register a built-in type for __ibm128 if the type is the same as
long double. Instead we add a #define for __ibm128 in
- rs6000_cpu_cpp_builtins to long double. */
+ rs6000_cpu_cpp_builtins to long double.
+
+ For IEEE 128-bit floating point, always create the type __ieee128. If the
+ user used -mfloat128, rs6000-c.c will create a define from __float128 to
+ __ieee128. */
if (TARGET_LONG_DOUBLE_128 && FLOAT128_IEEE_P (TFmode))
{
ibm128_float_type_node = make_node (REAL_TYPE);
@@ -16891,24 +16892,10 @@ rs6000_init_builtins (void)
else
ibm128_float_type_node = long_double_type_node;
- if (TARGET_FLOAT128_KEYWORD)
+ if (TARGET_FLOAT128_TYPE)
{
ieee128_float_type_node = float128_type_node;
lang_hooks.types.register_builtin_type (ieee128_float_type_node,
- "__float128");
- }
-
- else if (TARGET_FLOAT128_TYPE)
- {
- ieee128_float_type_node = make_node (REAL_TYPE);
- TYPE_PRECISION (ibm128_float_type_node) = 128;
- SET_TYPE_MODE (ieee128_float_type_node, KFmode);
- layout_type (ieee128_float_type_node);
-
- /* If we are not exporting the __float128/_Float128 keywords, we need a
- keyword to get the types created. Use __ieee128 as the dummy
- keyword. */
- lang_hooks.types.register_builtin_type (ieee128_float_type_node,
"__ieee128");
}
@@ -35987,7 +35974,7 @@ rs6000_floatn_mode (int n, bool extended
return DFmode;
case 64:
- if (TARGET_FLOAT128_KEYWORD)
+ if (TARGET_FLOAT128_TYPE)
return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode;
else
return VOIDmode;
@@ -36011,7 +35998,7 @@ rs6000_floatn_mode (int n, bool extended
return DFmode;
case 128:
- if (TARGET_FLOAT128_KEYWORD)
+ if (TARGET_FLOAT128_TYPE)
return (FLOAT128_IEEE_P (TFmode)) ? TFmode : KFmode;
else
return VOIDmode;
@@ -36101,9 +36088,9 @@ static struct rs6000_opt_mask const rs60
{ "dlmzb", OPTION_MASK_DLMZB, false, true },
{ "efficient-unaligned-vsx", OPTION_MASK_EFFICIENT_UNALIGNED_VSX,
false, true },
- { "float128", OPTION_MASK_FLOAT128_KEYWORD, false, false },
+ { "float128", OPTION_MASK_FLOAT128_KEYWORD, false, true },
{ "float128-type", OPTION_MASK_FLOAT128_TYPE, false, false },
- { "float128-hardware", OPTION_MASK_FLOAT128_HW, false, false },
+ { "float128-hardware", OPTION_MASK_FLOAT128_HW, false, true },
{ "fprnd", OPTION_MASK_FPRND, false, true },
{ "hard-dfp", OPTION_MASK_DFP, false, true },
{ "htm", OPTION_MASK_HTM, false, true },
Index: gcc/testsuite/gcc.target/powerpc/float128-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-1.c (revision 251058)
+++ gcc/testsuite/gcc.target/powerpc/float128-1.c (working copy)
@@ -1,6 +1,7 @@
/* { dg-do run { target { powerpc*-*-linux* } } } */
/* { dg-require-effective-target ppc_float128_sw } */
-/* { dg-options "-mcpu=power7 -O2 -mfloat128 -static-libgcc" } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O2 -mfloat128" } */
#ifdef DEBUG
#include <stdio.h>
Index: gcc/testsuite/gcc.target/powerpc/float128-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-2.c (revision 251058)
+++ gcc/testsuite/gcc.target/powerpc/float128-2.c (working copy)
@@ -1,6 +1,7 @@
/* { dg-do run { target { powerpc*-*-linux* } } } */
/* { dg-require-effective-target ppc_float128_sw } */
-/* { dg-options "-mcpu=power7 -O2 -mfloat128 -static-libgcc" } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O2 -mfloat128" } */
/*
* Test program to make sure we are getting more precision than the 53 bits we
Index: gcc/testsuite/gcc.target/powerpc/float128-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-3.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-3.c (working copy)
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target powerpc_float128_sw_ok } */
+/* { dg-options "-O2 -mvsx -mno-float128" } */
+
+/* Test that we can use #pragma GCC target to enable -mfloat128. */
+
+#ifdef __FLOAT128__
+#error "-mno-float128 should disable initially defining __FLOAT128__"
+#endif
+
+#pragma GCC target("float128")
+
+#ifndef __FLOAT128__
+#error "#pragma GCC target(\"float128\") should enable -mfloat128"
+#endif
+
+__float128
+qadd (__float128 a, __float128 b)
+{
+ return a+b;
+}
Index: gcc/testsuite/gcc.target/powerpc/float128-4.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/float128-4.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/float128-4.c (working copy)
@@ -0,0 +1,152 @@
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target ppc_float128_sw } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-mvsx -O2" } */
+
+/* This is the same as test float128-1.c, using the _Float128 keyword instead
+ of __float128, and not using -mfloat128. */
+
+#ifdef DEBUG
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <inttypes.h>
+#endif
+
+#if !defined(__FLOAT128__) || !defined(_ARCH_PPC)
+static _Float128
+pass_through (_Float128 x)
+{
+ return x;
+}
+
+_Float128 (*no_optimize) (_Float128) = pass_through;
+#endif
+
+#ifdef DEBUG
+__attribute__((__noinline__))
+static void
+print_f128 (_Float128 x)
+{
+ unsigned sign;
+ unsigned exponent;
+ uint64_t mantissa1;
+ uint64_t mantissa2;
+ uint64_t upper;
+ uint64_t lower;
+
+#if defined(_ARCH_PPC) && defined(__BIG_ENDIAN__)
+ struct ieee128 {
+ uint64_t upper;
+ uint64_t lower;
+ };
+
+#elif (defined(_ARCH_PPC) && defined(__LITTLE_ENDIAN__)) || defined(__x86_64__)
+ struct ieee128 {
+ uint64_t lower;
+ uint64_t upper;
+ };
+
+#else
+#error "Unknown system"
+#endif
+
+ union {
+ _Float128 f128;
+ struct ieee128 s128;
+ } u;
+
+ u.f128 = x;
+ upper = u.s128.upper;
+ lower = u.s128.lower;
+
+ sign = (unsigned)((upper >> 63) & 1);
+ exponent = (unsigned)((upper >> 48) & ((((uint64_t)1) << 16) - 1));
+ mantissa1 = (upper & ((((uint64_t)1) << 48) - 1));
+ mantissa2 = lower;
+
+ printf ("%c 0x%.4x 0x%.12" PRIx64 " 0x%.16" PRIx64,
+ sign ? '-' : '+',
+ exponent,
+ mantissa1,
+ mantissa2);
+}
+#endif
+
+__attribute__((__noinline__))
+static void
+do_test (_Float128 expected, _Float128 got, const char *name)
+{
+ int equal_p = (expected == got);
+
+#ifdef DEBUG
+ printf ("Test %s, expected: ", name);
+ print_f128 (expected);
+ printf (" %5g, got: ", (double) expected);
+ print_f128 (got);
+ printf (" %5g, result %s\n",
+ (double) got,
+ (equal_p) ? "equal" : "not equal");
+#endif
+
+ if (!equal_p)
+ __builtin_abort ();
+}
+
+
+int
+main (void)
+{
+ _Float128 one = 1.0f128;
+ _Float128 two = 2.0f128;
+ _Float128 three = 3.0f128;
+ _Float128 four = 4.0f128;
+ _Float128 five = 5.0f128;
+ _Float128 add_result = (1.0f128 + 2.0f128);
+ _Float128 mul_result = ((1.0f128 + 2.0f128) * 3.0f128);
+ _Float128 div_result = (((1.0f128 + 2.0f128) * 3.0f128) / 4.0f128);
+ _Float128 sub_result = ((((1.0f128 + 2.0f128) * 3.0f128) / 4.0f128)
+ - 5.0f128);
+ _Float128 neg_result = - sub_result;
+ _Float128 add_xresult;
+ _Float128 mul_xresult;
+ _Float128 div_xresult;
+ _Float128 sub_xresult;
+ _Float128 neg_xresult;
+
+#if defined(__FLOAT128__) && defined(_ARCH_PPC)
+ __asm__ (" #prevent constant folding, %x0" : "+wa" (one));
+ __asm__ (" #prevent constant folding, %x0" : "+wa" (two));
+ __asm__ (" #prevent constant folding, %x0" : "+wa" (three));
+ __asm__ (" #prevent constant folding, %x0" : "+wa" (four));
+ __asm__ (" #prevent constant folding, %x0" : "+wa" (five));
+
+#else
+ one = no_optimize (one);
+ two = no_optimize (two);
+ three = no_optimize (three);
+ four = no_optimize (four);
+ five = no_optimize (five);
+#endif
+
+ add_xresult = (one + two);
+ do_test (add_result, add_xresult, "add");
+
+ mul_xresult = add_xresult * three;
+ do_test (mul_result, mul_xresult, "mul");
+
+ div_xresult = mul_xresult / four;
+ do_test (div_result, div_xresult, "div");
+
+ sub_xresult = div_xresult - five;
+ do_test (sub_result, sub_xresult, "sub");
+
+ neg_xresult = - sub_xresult;
+ do_test (neg_result, neg_xresult, "neg");
+
+#ifdef DEBUG
+ printf ("Passed\n");
+#endif
+
+ return 0;
+}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH], Enable _Float128 in VSX PowerPC system and enable #pragma GCC target "float128"
2017-08-14 19:31 [PATCH], Enable _Float128 in VSX PowerPC system and enable #pragma GCC target "float128" Michael Meissner
@ 2017-08-16 22:56 ` Segher Boessenkool
0 siblings, 0 replies; 2+ messages in thread
From: Segher Boessenkool @ 2017-08-16 22:56 UTC (permalink / raw)
To: Michael Meissner, GCC Patches, David Edelsohn, Bill Schmidt
Hi Mike,
On Mon, Aug 14, 2017 at 03:21:42PM -0400, Michael Meissner wrote:
> This patch enables the _Float128 keyword for the C langauge all of the time for
> PowerPC VSX systems. The __float128 keyword continues to be only enabled if
> you use the -mfloat128 option.
Looks good, please commit. Thanks!
Segher
> PR target/70589
> * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Make the
> real keyword for IEEE 128-bit be __ieee128 for VSX runs, and define
> __float128 to be __ieee128 if -mfloat128 is used or a float128
> target attribute/pragma is used. Enable _Float128 all of the
> time.
> (rs6000_cpu_cpp_builtins): Likewise.
> * config/rs6000/rs6000.c (rs6000_init_builtins): Likewise.
> (rs6000_floatn_mode): Likewise.
> (rs6000_opt_masks): Likewise.
>
> [gcc/testsuite]
> 2017-08-14 Michael Meissner <meissner@linux.vnet.ibm.com>
>
> PR target/70589
> * gcc.target/powerpc/float128-1.c: Eliminate using the
> -static-libgcc option. Use -mvsx instead of -mcpu=power7 to run
> the tests.
> * gcc.target/powerpc/float128-2.c: Likewise.
> * gcc.target/powerpc/float128-3.c: Test enabling -mfloat128 via
> #pragma target.
> * gcc.target/powerpc/float128-4.c: New test, clone float128-1.c,
> using the _Float128 keyword. Do not use the -mfloat128 option.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2017-08-16 22:19 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-14 19:31 [PATCH], Enable _Float128 in VSX PowerPC system and enable #pragma GCC target "float128" Michael Meissner
2017-08-16 22:56 ` Segher Boessenkool
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).