builtins: Handle BITINT_TYPE in __builtin_iseqsig folding [PR117802]

Message ID Z0gt8K3F5aV4B3Ne@tucnak
State New
Headers
Series builtins: Handle BITINT_TYPE in __builtin_iseqsig folding [PR117802] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_check--master-arm fail Patch failed to apply

Commit Message

Jakub Jelinek Nov. 28, 2024, 8:46 a.m. UTC
  Hi!

In check_builtin_function_arguments in the _BitInt patchset I've changed
INTEGER_TYPE tests to INTEGER_TYPE or BITINT_TYPE, but haven't done the
same in fold_builtin_iseqsig, which now ICEs because of that.

The following patch fixes that.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

BTW, that TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) test
for REAL_TYPE vs. REAL_TYPE looks pretty random and dangerous, I think
it would be useful to handle this builtin also in the C and C++ FEs,
if both arguments have REAL_TYPE, use the FE specific routine to decide
which types to use and error if a comparison between types would be
erroneous (e.g. complain about _Decimal* vs. float/double/long
double/_Float*, pick up the preferred type, complain about
__ibm128 vs. _Float128 in C++, etc.).
But the FEs can just promote one argument to the other in that case
and keep fold_builtin_iseqsig as is for say Fortran and other FEs.

2024-11-28  Jakub Jelinek  <jakub@redhat.com>

	PR c/117802
	* builtins.cc (fold_builtin_iseqsig): Handle BITINT_TYPE like
	INTEGER_TYPE.

	* gcc.dg/builtin-iseqsig-1.c: New test.
	* gcc.dg/bitint-118.c: New test.


	Jakub
  

Comments

Richard Biener Nov. 28, 2024, 9:01 a.m. UTC | #1
On Thu, 28 Nov 2024, Jakub Jelinek wrote:

> Hi!
> 
> In check_builtin_function_arguments in the _BitInt patchset I've changed
> INTEGER_TYPE tests to INTEGER_TYPE or BITINT_TYPE, but haven't done the
> same in fold_builtin_iseqsig, which now ICEs because of that.
> 
> The following patch fixes that.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> BTW, that TYPE_PRECISION (type0) >= TYPE_PRECISION (type1) test
> for REAL_TYPE vs. REAL_TYPE looks pretty random and dangerous, I think
> it would be useful to handle this builtin also in the C and C++ FEs,
> if both arguments have REAL_TYPE, use the FE specific routine to decide
> which types to use and error if a comparison between types would be
> erroneous (e.g. complain about _Decimal* vs. float/double/long
> double/_Float*, pick up the preferred type, complain about
> __ibm128 vs. _Float128 in C++, etc.).
> But the FEs can just promote one argument to the other in that case
> and keep fold_builtin_iseqsig as is for say Fortran and other FEs.
> 
> 2024-11-28  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c/117802
> 	* builtins.cc (fold_builtin_iseqsig): Handle BITINT_TYPE like
> 	INTEGER_TYPE.
> 
> 	* gcc.dg/builtin-iseqsig-1.c: New test.
> 	* gcc.dg/bitint-118.c: New test.
> 
> --- gcc/builtins.cc.jj	2024-11-27 14:33:07.522815405 +0100
> +++ gcc/builtins.cc	2024-11-27 16:36:41.111547052 +0100
> @@ -9946,9 +9946,11 @@ fold_builtin_iseqsig (location_t loc, tr
>      /* Choose the wider of two real types.  */
>      cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
>        ? type0 : type1;
> -  else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
> +  else if (code0 == REAL_TYPE
> +	   && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
>      cmp_type = type0;
> -  else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
> +  else if ((code0 == INTEGER_TYPE || code0 == BITINT_TYPE)
> +	   && code1 == REAL_TYPE)
>      cmp_type = type1;
>  
>    arg0 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg0));
> --- gcc/testsuite/gcc.dg/builtin-iseqsig-1.c.jj	2024-11-27 16:45:00.951518847 +0100
> +++ gcc/testsuite/gcc.dg/builtin-iseqsig-1.c	2024-11-27 17:03:48.029664444 +0100
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +int
> +foo (float x, int y)
> +{
> +  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
> +}
> +
> +int
> +bar (double x, unsigned long y)
> +{
> +  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
> +}
> +
> +int
> +baz (long double x, long long y)
> +{
> +  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
> +}
> --- gcc/testsuite/gcc.dg/bitint-118.c.jj	2024-11-27 16:45:21.457230486 +0100
> +++ gcc/testsuite/gcc.dg/bitint-118.c	2024-11-27 17:01:55.968241400 +0100
> @@ -0,0 +1,21 @@
> +/* PR c/117802 */
> +/* { dg-do compile { target bitint575 } } */
> +/* { dg-options "-std=c23" } */
> +
> +int
> +foo (float x, _BitInt(8) y)
> +{
> +  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
> +}
> +
> +int
> +bar (double x, unsigned _BitInt(162) y)
> +{
> +  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
> +}
> +
> +int
> +baz (long double x, _BitInt(574) y)
> +{
> +  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
> +}
> 
> 	Jakub
> 
>
  

Patch

--- gcc/builtins.cc.jj	2024-11-27 14:33:07.522815405 +0100
+++ gcc/builtins.cc	2024-11-27 16:36:41.111547052 +0100
@@ -9946,9 +9946,11 @@  fold_builtin_iseqsig (location_t loc, tr
     /* Choose the wider of two real types.  */
     cmp_type = TYPE_PRECISION (type0) >= TYPE_PRECISION (type1)
       ? type0 : type1;
-  else if (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
+  else if (code0 == REAL_TYPE
+	   && (code1 == INTEGER_TYPE || code1 == BITINT_TYPE))
     cmp_type = type0;
-  else if (code0 == INTEGER_TYPE && code1 == REAL_TYPE)
+  else if ((code0 == INTEGER_TYPE || code0 == BITINT_TYPE)
+	   && code1 == REAL_TYPE)
     cmp_type = type1;
 
   arg0 = builtin_save_expr (fold_convert_loc (loc, cmp_type, arg0));
--- gcc/testsuite/gcc.dg/builtin-iseqsig-1.c.jj	2024-11-27 16:45:00.951518847 +0100
+++ gcc/testsuite/gcc.dg/builtin-iseqsig-1.c	2024-11-27 17:03:48.029664444 +0100
@@ -0,0 +1,20 @@ 
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+int
+foo (float x, int y)
+{
+  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
+}
+
+int
+bar (double x, unsigned long y)
+{
+  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
+}
+
+int
+baz (long double x, long long y)
+{
+  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
+}
--- gcc/testsuite/gcc.dg/bitint-118.c.jj	2024-11-27 16:45:21.457230486 +0100
+++ gcc/testsuite/gcc.dg/bitint-118.c	2024-11-27 17:01:55.968241400 +0100
@@ -0,0 +1,21 @@ 
+/* PR c/117802 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-std=c23" } */
+
+int
+foo (float x, _BitInt(8) y)
+{
+  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
+}
+
+int
+bar (double x, unsigned _BitInt(162) y)
+{
+  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
+}
+
+int
+baz (long double x, _BitInt(574) y)
+{
+  return __builtin_iseqsig (x, y) * 2 + __builtin_iseqsig (y, x);
+}