Hi!

To my surprise we accept generic vectors with enumeral element
types (unlike e.g. _Complex) and we don't actually try to
perform "integral" promotions for those either (which for scalars
promotes ENUMERAL_TYPE operands to their underlying type or
promoted underlying type).  I'm afraid it is inappropriate
to change the promotions at this point in stage4, that would
be a significant user visible change (though sure for a feature
that hopefully nobody actually uses).  Anyway, in GCC 16
development some assertions that RDIV_EXPR is only used for floating
(scalar/vector/complex) operands were added and those now trigger
on trying to divide vectors where both operands are enum vectors.
THis is due to the FEs using RDIV_EXPR instead of TRUNC_DIV_EXPR
when the operands (after promotions) don't have INTEGER_TYPE (or for C
BITINT_TYPE) operands.

This patch just adds vector enum to that.

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

2026-01-15  Jakub Jelinek  <[email protected]>

        PR c/123437
        * c-typeck.cc (build_binary_op): Don't use RDIV_EXPR
        resultcode if both types are integral, _BitInt or
        newly VECTOR_TYPE of ENUMERAL_TYPE.

        * typeck.cc (cp_build_binary_op): Don't use RDIV_EXPR
        resultcode if both types are integral, _BitInt or
        newly VECTOR_TYPE of ENUMERAL_TYPE.

        * c-c++-common/pr123437.c: New test.

--- gcc/c/c-typeck.cc.jj        2026-01-14 13:21:06.130656198 +0100
+++ gcc/c/c-typeck.cc   2026-01-14 14:11:59.252325187 +0100
@@ -14452,8 +14452,10 @@ build_binary_op (location_t location, en
          if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
            tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
 
-         if (!(((tcode0 == INTEGER_TYPE || tcode0 == BITINT_TYPE)
-                && (tcode1 == INTEGER_TYPE || tcode1 == BITINT_TYPE))
+         if (!(((tcode0 == INTEGER_TYPE || tcode0 == BITINT_TYPE
+                 || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE))
+                && (tcode1 == INTEGER_TYPE || tcode1 == BITINT_TYPE
+                    || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE)))
                || (tcode0 == FIXED_POINT_TYPE && tcode1 == FIXED_POINT_TYPE)))
            resultcode = RDIV_EXPR;
          else
--- gcc/cp/typeck.cc.jj 2026-01-02 09:56:10.116337377 +0100
+++ gcc/cp/typeck.cc    2026-01-14 14:11:59.253325170 +0100
@@ -5790,7 +5790,10 @@ cp_build_binary_op (const op_location_t
          if (tcode1 == COMPLEX_TYPE || tcode1 == VECTOR_TYPE)
            tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
 
-         if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE))
+         if (!((tcode0 == INTEGER_TYPE
+                || (tcode0 == ENUMERAL_TYPE && code0 == VECTOR_TYPE))
+               && (tcode1 == INTEGER_TYPE
+                   || (tcode1 == ENUMERAL_TYPE && code1 == VECTOR_TYPE))))
            resultcode = RDIV_EXPR;
          else
            {
--- gcc/testsuite/c-c++-common/pr123437.c.jj    2026-01-14 14:13:36.461696363 
+0100
+++ gcc/testsuite/c-c++-common/pr123437.c       2026-01-14 14:13:29.349815522 
+0100
@@ -0,0 +1,12 @@
+/* PR c/123437 */
+/* { dg-do compile } */
+
+enum E { F };
+typedef enum E V __attribute__ ((vector_size (16)));
+V x, y, z;
+
+void
+foo ()
+{
+  z = x / y;
+}

        Jakub

Reply via email to