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.
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.
/* 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));
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* { 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);
+}