[v6] LoongArch:Implement 128-bit floating point functions in gcc.
Checks
Commit Message
Brief version history of patch set:
v1 -> v2:
According to the GNU code specification, adjust the format of the
function implementation with "q" as the suffix function.
v2 - >v3:
1.On the LoongArch architecture, refer to the functionality of 64-bit
functions and modify the underlying implementation of __builtin_{nanq, nansq}
functions in libgcc.
2.Modify the function's instruction template to use some instructions such
as "bstrins.d" to implement the 128-bit __builtin_{fabsq, copysignq} function
instead of calling libgcc library support, so as to better play the machine's
performance.
v3 -> v4:
1.The above v1,v2, and v3 all implement 128-bit floating-point functions
with "q" as the suffix, but it is an older implementation. The v4 version
completely abandoned the old implementation by associating the 128-bit
floating-point function with the "q" suffix with the "f128" function that
already existed in GCC.
2.Modify the code so that both "__float128" and "_Float128" function types
can be supported in compiler gcc.
3.Associating a function with the suffix "q" to the "f128" function allows
two different forms of the function to produce the same effect, For example,
__builtin_{huge_{valq/valf128},{infq/inff128},{nanq/nanf128},{nansq/nansf128},
{fabsq/fabsf128}}.
4.For the _builtin_copysignq function, do not call the new "f128"
implementation, but use the "bstrins" and other instructions in the machine
description file to implement the function function, the result is that the
number of assembly instructions can be reduced and the function optimization
to achieve the optimal effect.
v4 -> v5:
Removed the v4 implementation of the __builtin_fabsf128() function added
to LoongArch.md.
v5 -> v6:
1.Modify the test cases in the math-float-128.c file.
2.Removed the v5 implementation of the __builtin_copysignf128() function
added to LoongArch.md.
During implementation, float128_type_node is bound with the type "__float128"
so that the compiler can correctly identify the type of the function. The
"q" suffix is associated with the "f128" function, which makes GCC more
flexible to support different user input cases, implementing functions such
as __builtin_{huge_valq, infq, fabsq, copysignq, nanq, nansq}.
gcc/ChangeLog:
* config/loongarch/loongarch-builtins.cc (loongarch_init_builtins):
Associate the __float128 type to float128_type_node so that it can
be recognized by the compiler.
* config/loongarch/loongarch-c.cc (loongarch_cpu_cpp_builtins):
Add the flag "FLOAT128_TYPE" to gcc and associate a function
with the suffix "q" to "f128".
* doc/extend.texi:Added support for 128-bit floating-point functions on
the LoongArch architecture.
gcc/testsuite/ChangeLog:
* gcc.target/loongarch/math-float-128.c: New test.
---
gcc/config/loongarch/loongarch-builtins.cc | 5 ++
gcc/config/loongarch/loongarch-c.cc | 11 +++
gcc/doc/extend.texi | 20 ++++-
.../gcc.target/loongarch/math-float-128.c | 81 +++++++++++++++++++
4 files changed, 114 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/loongarch/math-float-128.c
Comments
Hi,RuoYao:
I have merged the V6 patch into trunk(r14-3635). If the generic
optimization of copysignf128 cannot be solved,
we will mention the optimization code under the architecture again.
Thanks!
在 2023/9/1 上午11:22, chenxiaolong 写道:
> Brief version history of patch set:
>
> v1 -> v2:
> According to the GNU code specification, adjust the format of the
> function implementation with "q" as the suffix function.
>
> v2 - >v3:
>
> 1.On the LoongArch architecture, refer to the functionality of 64-bit
> functions and modify the underlying implementation of __builtin_{nanq, nansq}
> functions in libgcc.
>
> 2.Modify the function's instruction template to use some instructions such
> as "bstrins.d" to implement the 128-bit __builtin_{fabsq, copysignq} function
> instead of calling libgcc library support, so as to better play the machine's
> performance.
>
> v3 -> v4:
>
> 1.The above v1,v2, and v3 all implement 128-bit floating-point functions
> with "q" as the suffix, but it is an older implementation. The v4 version
> completely abandoned the old implementation by associating the 128-bit
> floating-point function with the "q" suffix with the "f128" function that
> already existed in GCC.
>
> 2.Modify the code so that both "__float128" and "_Float128" function types
> can be supported in compiler gcc.
>
> 3.Associating a function with the suffix "q" to the "f128" function allows
> two different forms of the function to produce the same effect, For example,
> __builtin_{huge_{valq/valf128},{infq/inff128},{nanq/nanf128},{nansq/nansf128},
> {fabsq/fabsf128}}.
>
> 4.For the _builtin_copysignq function, do not call the new "f128"
> implementation, but use the "bstrins" and other instructions in the machine
> description file to implement the function function, the result is that the
> number of assembly instructions can be reduced and the function optimization
> to achieve the optimal effect.
>
> v4 -> v5:
>
> Removed the v4 implementation of the __builtin_fabsf128() function added
> to LoongArch.md.
>
> v5 -> v6:
>
> 1.Modify the test cases in the math-float-128.c file.
>
> 2.Removed the v5 implementation of the __builtin_copysignf128() function
> added to LoongArch.md.
>
> During implementation, float128_type_node is bound with the type "__float128"
> so that the compiler can correctly identify the type of the function. The
> "q" suffix is associated with the "f128" function, which makes GCC more
> flexible to support different user input cases, implementing functions such
> as __builtin_{huge_valq, infq, fabsq, copysignq, nanq, nansq}.
>
> gcc/ChangeLog:
>
> * config/loongarch/loongarch-builtins.cc (loongarch_init_builtins):
> Associate the __float128 type to float128_type_node so that it can
> be recognized by the compiler.
> * config/loongarch/loongarch-c.cc (loongarch_cpu_cpp_builtins):
> Add the flag "FLOAT128_TYPE" to gcc and associate a function
> with the suffix "q" to "f128".
> * doc/extend.texi:Added support for 128-bit floating-point functions on
> the LoongArch architecture.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/loongarch/math-float-128.c: New test.
> ---
> gcc/config/loongarch/loongarch-builtins.cc | 5 ++
> gcc/config/loongarch/loongarch-c.cc | 11 +++
> gcc/doc/extend.texi | 20 ++++-
> .../gcc.target/loongarch/math-float-128.c | 81 +++++++++++++++++++
> 4 files changed, 114 insertions(+), 3 deletions(-)
> create mode 100644 gcc/testsuite/gcc.target/loongarch/math-float-128.c
>
> diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc
> index b929f224dfa..58b612bf445 100644
> --- a/gcc/config/loongarch/loongarch-builtins.cc
> +++ b/gcc/config/loongarch/loongarch-builtins.cc
> @@ -256,6 +256,11 @@ loongarch_init_builtins (void)
> unsigned int i;
> tree type;
>
> + /* Register the type float128_type_node as a built-in type and
> + give it an alias "__float128". */
> + (*lang_hooks.types.register_builtin_type) (float128_type_node,
> + "__float128");
> +
> /* Iterate through all of the bdesc arrays, initializing all of the
> builtin functions. */
> for (i = 0; i < ARRAY_SIZE (loongarch_builtins); i++)
> diff --git a/gcc/config/loongarch/loongarch-c.cc b/gcc/config/loongarch/loongarch-c.cc
> index 67911b78f28..6ffbf748316 100644
> --- a/gcc/config/loongarch/loongarch-c.cc
> +++ b/gcc/config/loongarch/loongarch-c.cc
> @@ -99,6 +99,17 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
> else
> builtin_define ("__loongarch_frlen=0");
>
> + /* Add support for FLOAT128_TYPE on the LoongArch architecture. */
> + builtin_define ("__FLOAT128_TYPE__");
> +
> + /* Map the old _Float128 'q' builtins into the new 'f128' builtins. */
> + builtin_define ("__builtin_fabsq=__builtin_fabsf128");
> + builtin_define ("__builtin_copysignq=__builtin_copysignf128");
> + builtin_define ("__builtin_nanq=__builtin_nanf128");
> + builtin_define ("__builtin_nansq=__builtin_nansf128");
> + builtin_define ("__builtin_infq=__builtin_inff128");
> + builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
> +
> /* Native Data Sizes. */
> builtin_define_with_int_value ("_LOONGARCH_SZINT", INT_TYPE_SIZE);
> builtin_define_with_int_value ("_LOONGARCH_SZLONG", LONG_TYPE_SIZE);
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 80dd2a84b0b..947c05babc9 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -1093,10 +1093,10 @@ types.
> As an extension, GNU C and GNU C++ support additional floating
> types, which are not supported by all targets.
> @itemize @bullet
> -@item @code{__float128} is available on i386, x86_64, IA-64, and
> -hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable
> +@item @code{__float128} is available on i386, x86_64, IA-64, LoongArch
> +and hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable
> the vector scalar (VSX) instruction set. @code{__float128} supports
> -the 128-bit floating type. On i386, x86_64, PowerPC, and IA-64
> +the 128-bit floating type. On i386, x86_64, PowerPC, LoongArch and IA-64,
> other than HP-UX, @code{__float128} is an alias for @code{_Float128}.
> On hppa and IA-64 HP-UX, @code{__float128} is an alias for @code{long
> double}.
> @@ -16657,6 +16657,20 @@ function you need to include @code{larchintrin.h}.
> void __break (imm0_32767)
> @end smallexample
>
> +Additional built-in functions are available for LoongArch family
> +processors to efficiently use 128-bit floating-point (__float128)
> +values.
> +
> +The following are the basic built-in functions supported.
> +@smallexample
> +__float128 __builtin_fabsq (__float128);
> +__float128 __builtin_copysignq (__float128, __float128);
> +__float128 __builtin_infq (void);
> +__float128 __builtin_huge_valq (void);
> +__float128 __builtin_nanq (void);
> +__float128 __builtin_nansq (void);
> +@end smallexample
> +
> @node MIPS DSP Built-in Functions
> @subsection MIPS DSP Built-in Functions
>
> diff --git a/gcc/testsuite/gcc.target/loongarch/math-float-128.c b/gcc/testsuite/gcc.target/loongarch/math-float-128.c
> new file mode 100644
> index 00000000000..387566a57c9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/loongarch/math-float-128.c
> @@ -0,0 +1,81 @@
> +/* { dg-do compile } */
> +/* { dg-options " -march=loongarch64 -O2 " } */
> +/* { dg-final { scan-assembler-not "my_fabsq2:.*\\bl\t%plt\\(__builtin_fabsq\\).*my_fabsq2" } } */
> +/* { dg-final { scan-assembler-not "my_copysignq2:.*\\bl\t%plt\\(__builtin_copysignq\\).*my_copysignq2" } } */
> +/* { dg-final { scan-assembler-not "my_infq2:.*\\bl\t%plt\\(__builtin_infq\\).*my_infq2" } } */
> +/* { dg-final { scan-assembler-not "my_huge_valq2:.*\\bl\t%plt\\(__builtin_huge_valq\\).*my_huge_valq2" } } */
> +/* { dg-final { scan-assembler-not "my_nanq2:.*\\bl\t%plt\\(__builtin_nanq\\).*my_nanq2" } } */
> +/* { dg-final { scan-assembler-not "my_nansq2:.*\\bl\t%plt\\(__builtin_nansq\\).*my_nansq2" } } */
> +
> +__float128
> +my_fabsq1 (__float128 a)
> +{
> + return __builtin_fabsq (a);
> +}
> +
> +_Float128
> +my_fabsq2 (_Float128 a)
> +{
> + return __builtin_fabsq (a);
> +}
> +
> +__float128
> +my_copysignq1 (__float128 a, __float128 b)
> +{
> + return __builtin_copysignq (a, b);
> +}
> +
> +_Float128
> +my_copysignq2 (_Float128 a, _Float128 b)
> +{
> + return __builtin_copysignq (a, b);
> +}
> +
> +__float128
> +my_infq1 (void)
> +{
> + return __builtin_infq ();
> +}
> +
> +_Float128
> +my_infq2 (void)
> +{
> + return __builtin_infq ();
> +}
> +
> +__float128
> +my_huge_valq1 (void)
> +{
> + return __builtin_huge_valq ();
> +}
> +
> +_Float128
> +my_huge_valq2 (void)
> +{
> + return __builtin_huge_valq ();
> +}
> +
> +__float128
> +my_nanq1 (void)
> +{
> + return __builtin_nanq ("");
> +}
> +
> +_Float128
> +my_nanq2 (void)
> +{
> + return __builtin_nanq ("");
> +}
> +
> +__float128
> +my_nansq1 (void)
> +{
> + return __builtin_nansq ("");
> +}
> +
> +_Float128
> +my_nansq2 (void)
> +{
> + return __builtin_nansq ("");
> +}
> +
@@ -256,6 +256,11 @@ loongarch_init_builtins (void)
unsigned int i;
tree type;
+ /* Register the type float128_type_node as a built-in type and
+ give it an alias "__float128". */
+ (*lang_hooks.types.register_builtin_type) (float128_type_node,
+ "__float128");
+
/* Iterate through all of the bdesc arrays, initializing all of the
builtin functions. */
for (i = 0; i < ARRAY_SIZE (loongarch_builtins); i++)
@@ -99,6 +99,17 @@ loongarch_cpu_cpp_builtins (cpp_reader *pfile)
else
builtin_define ("__loongarch_frlen=0");
+ /* Add support for FLOAT128_TYPE on the LoongArch architecture. */
+ builtin_define ("__FLOAT128_TYPE__");
+
+ /* Map the old _Float128 'q' builtins into the new 'f128' builtins. */
+ builtin_define ("__builtin_fabsq=__builtin_fabsf128");
+ builtin_define ("__builtin_copysignq=__builtin_copysignf128");
+ builtin_define ("__builtin_nanq=__builtin_nanf128");
+ builtin_define ("__builtin_nansq=__builtin_nansf128");
+ builtin_define ("__builtin_infq=__builtin_inff128");
+ builtin_define ("__builtin_huge_valq=__builtin_huge_valf128");
+
/* Native Data Sizes. */
builtin_define_with_int_value ("_LOONGARCH_SZINT", INT_TYPE_SIZE);
builtin_define_with_int_value ("_LOONGARCH_SZLONG", LONG_TYPE_SIZE);
@@ -1093,10 +1093,10 @@ types.
As an extension, GNU C and GNU C++ support additional floating
types, which are not supported by all targets.
@itemize @bullet
-@item @code{__float128} is available on i386, x86_64, IA-64, and
-hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable
+@item @code{__float128} is available on i386, x86_64, IA-64, LoongArch
+and hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable
the vector scalar (VSX) instruction set. @code{__float128} supports
-the 128-bit floating type. On i386, x86_64, PowerPC, and IA-64
+the 128-bit floating type. On i386, x86_64, PowerPC, LoongArch and IA-64,
other than HP-UX, @code{__float128} is an alias for @code{_Float128}.
On hppa and IA-64 HP-UX, @code{__float128} is an alias for @code{long
double}.
@@ -16657,6 +16657,20 @@ function you need to include @code{larchintrin.h}.
void __break (imm0_32767)
@end smallexample
+Additional built-in functions are available for LoongArch family
+processors to efficiently use 128-bit floating-point (__float128)
+values.
+
+The following are the basic built-in functions supported.
+@smallexample
+__float128 __builtin_fabsq (__float128);
+__float128 __builtin_copysignq (__float128, __float128);
+__float128 __builtin_infq (void);
+__float128 __builtin_huge_valq (void);
+__float128 __builtin_nanq (void);
+__float128 __builtin_nansq (void);
+@end smallexample
+
@node MIPS DSP Built-in Functions
@subsection MIPS DSP Built-in Functions
new file mode 100644
@@ -0,0 +1,81 @@
+/* { dg-do compile } */
+/* { dg-options " -march=loongarch64 -O2 " } */
+/* { dg-final { scan-assembler-not "my_fabsq2:.*\\bl\t%plt\\(__builtin_fabsq\\).*my_fabsq2" } } */
+/* { dg-final { scan-assembler-not "my_copysignq2:.*\\bl\t%plt\\(__builtin_copysignq\\).*my_copysignq2" } } */
+/* { dg-final { scan-assembler-not "my_infq2:.*\\bl\t%plt\\(__builtin_infq\\).*my_infq2" } } */
+/* { dg-final { scan-assembler-not "my_huge_valq2:.*\\bl\t%plt\\(__builtin_huge_valq\\).*my_huge_valq2" } } */
+/* { dg-final { scan-assembler-not "my_nanq2:.*\\bl\t%plt\\(__builtin_nanq\\).*my_nanq2" } } */
+/* { dg-final { scan-assembler-not "my_nansq2:.*\\bl\t%plt\\(__builtin_nansq\\).*my_nansq2" } } */
+
+__float128
+my_fabsq1 (__float128 a)
+{
+ return __builtin_fabsq (a);
+}
+
+_Float128
+my_fabsq2 (_Float128 a)
+{
+ return __builtin_fabsq (a);
+}
+
+__float128
+my_copysignq1 (__float128 a, __float128 b)
+{
+ return __builtin_copysignq (a, b);
+}
+
+_Float128
+my_copysignq2 (_Float128 a, _Float128 b)
+{
+ return __builtin_copysignq (a, b);
+}
+
+__float128
+my_infq1 (void)
+{
+ return __builtin_infq ();
+}
+
+_Float128
+my_infq2 (void)
+{
+ return __builtin_infq ();
+}
+
+__float128
+my_huge_valq1 (void)
+{
+ return __builtin_huge_valq ();
+}
+
+_Float128
+my_huge_valq2 (void)
+{
+ return __builtin_huge_valq ();
+}
+
+__float128
+my_nanq1 (void)
+{
+ return __builtin_nanq ("");
+}
+
+_Float128
+my_nanq2 (void)
+{
+ return __builtin_nanq ("");
+}
+
+__float128
+my_nansq1 (void)
+{
+ return __builtin_nansq ("");
+}
+
+_Float128
+my_nansq2 (void)
+{
+ return __builtin_nansq ("");
+}
+