Fix ICE with enum vector division [PR123437]

Message ID 20260108131610.724543-1-peter0x44@disroot.org
State New
Headers
Series Fix ICE with enum vector division [PR123437] |

Commit Message

Peter Damianov Jan. 8, 2026, 1:16 p.m. UTC
  The C and C++ frontends were incorrectly generating RDIV_EXPR instead of
TRUNC_DIV_EXPR for division of vectors with enum element types.

The issue was that the division operator handling only checked for
INTEGER_TYPE (and BITINT_TYPE in the C frontend) when determining whether
to use integer division. However, ENUMERAL_TYPE is also represents an
integral type. When enum types were used in vectors, the frontend would
incorrectly fall through to RDIV_EXPR, causing an ICE during the
veclower2 pass because RDIV_EXPR is only valid for floating-point types.

The fix adds ENUMERAL_TYPE to the type checks. Note that scalar enum
operands are promoted to int before reaching this code, but enum
*vectors* are not promoted.

gcc/c/ChangeLog:

	PR c/123437
	* c-typeck.cc (build_binary_op): Include ENUMERAL_TYPE in
	integer division check for vectors.

gcc/cp/ChangeLog:

	PR c/123437
	* typeck.cc (cp_build_binary_op): Include ENUMERAL_TYPE in
	integer division check.

gcc/testsuite/ChangeLog:

	PR c/123437
	* c-c++-common/pr123437.c: New test.
---
 gcc/c/c-typeck.cc                     |  6 ++++--
 gcc/cp/typeck.cc                      |  3 ++-
 gcc/testsuite/c-c++-common/pr123437.c | 11 +++++++++++
 3 files changed, 17 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/pr123437.c
  

Comments

Jeffrey Law Jan. 15, 2026, 8:21 p.m. UTC | #1
On 1/8/2026 6:16 AM, Peter Damianov wrote:
> The C and C++ frontends were incorrectly generating RDIV_EXPR instead of
> TRUNC_DIV_EXPR for division of vectors with enum element types.
>
> The issue was that the division operator handling only checked for
> INTEGER_TYPE (and BITINT_TYPE in the C frontend) when determining whether
> to use integer division. However, ENUMERAL_TYPE is also represents an
> integral type. When enum types were used in vectors, the frontend would
> incorrectly fall through to RDIV_EXPR, causing an ICE during the
> veclower2 pass because RDIV_EXPR is only valid for floating-point types.
>
> The fix adds ENUMERAL_TYPE to the type checks. Note that scalar enum
> operands are promoted to int before reaching this code, but enum
> *vectors* are not promoted.
>
> gcc/c/ChangeLog:
>
> 	PR c/123437
> 	* c-typeck.cc (build_binary_op): Include ENUMERAL_TYPE in
> 	integer division check for vectors.
>
> gcc/cp/ChangeLog:
>
> 	PR c/123437
> 	* typeck.cc (cp_build_binary_op): Include ENUMERAL_TYPE in
> 	integer division check.
>
> gcc/testsuite/ChangeLog:
>
> 	PR c/123437
> 	* c-c++-common/pr123437.c: New test.
I think Jakub's comment probably points to a slightly better patch. In 
particular his patch/comment only allow the ENUMERAL_TYPE  for tcode 
when the code is a VECTOR_TYPE.  Seems safer at this point.

OK with that change (which I think makes it idential to Jakub's patch in 
c#5 in the bugzilla case.

Jeff
  
Andrew Pinski Jan. 15, 2026, 8:25 p.m. UTC | #2
On Thu, Jan 15, 2026 at 12:23 PM Jeffrey Law
<jeffrey.law@oss.qualcomm.com> wrote:
>
>
>
> On 1/8/2026 6:16 AM, Peter Damianov wrote:
> > The C and C++ frontends were incorrectly generating RDIV_EXPR instead of
> > TRUNC_DIV_EXPR for division of vectors with enum element types.
> >
> > The issue was that the division operator handling only checked for
> > INTEGER_TYPE (and BITINT_TYPE in the C frontend) when determining whether
> > to use integer division. However, ENUMERAL_TYPE is also represents an
> > integral type. When enum types were used in vectors, the frontend would
> > incorrectly fall through to RDIV_EXPR, causing an ICE during the
> > veclower2 pass because RDIV_EXPR is only valid for floating-point types.
> >
> > The fix adds ENUMERAL_TYPE to the type checks. Note that scalar enum
> > operands are promoted to int before reaching this code, but enum
> > *vectors* are not promoted.
> >
> > gcc/c/ChangeLog:
> >
> >       PR c/123437
> >       * c-typeck.cc (build_binary_op): Include ENUMERAL_TYPE in
> >       integer division check for vectors.
> >
> > gcc/cp/ChangeLog:
> >
> >       PR c/123437
> >       * typeck.cc (cp_build_binary_op): Include ENUMERAL_TYPE in
> >       integer division check.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       PR c/123437
> >       * c-c++-common/pr123437.c: New test.
> I think Jakub's comment probably points to a slightly better patch. In
> particular his patch/comment only allow the ENUMERAL_TYPE  for tcode
> when the code is a VECTOR_TYPE.  Seems safer at this point.
>
> OK with that change (which I think makes it idential to Jakub's patch in
> c#5 in the bugzilla case.

Jakub posted his patch here already:
https://gcc.gnu.org/pipermail/gcc-patches/2026-January/705874.html

Thanks,
Andrew

>
> Jeff
  
Jakub Jelinek Jan. 15, 2026, 10:40 p.m. UTC | #3
On Thu, Jan 15, 2026 at 12:25:07PM -0800, Andrew Pinski wrote:
> > > gcc/c/ChangeLog:
> > >
> > >       PR c/123437
> > >       * c-typeck.cc (build_binary_op): Include ENUMERAL_TYPE in
> > >       integer division check for vectors.
> > >
> > > gcc/cp/ChangeLog:
> > >
> > >       PR c/123437
> > >       * typeck.cc (cp_build_binary_op): Include ENUMERAL_TYPE in
> > >       integer division check.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >       PR c/123437
> > >       * c-c++-common/pr123437.c: New test.
> > I think Jakub's comment probably points to a slightly better patch. In
> > particular his patch/comment only allow the ENUMERAL_TYPE  for tcode
> > when the code is a VECTOR_TYPE.  Seems safer at this point.
> >
> > OK with that change (which I think makes it idential to Jakub's patch in
> > c#5 in the bugzilla case.
> 
> Jakub posted his patch here already:
> https://gcc.gnu.org/pipermail/gcc-patches/2026-January/705874.html

I'm sorry I have missed Peter's patch being posted to gcc-patches,
the "WDYT the solution should be?" in bugzilla made me think it is not.

Anyway, the testcase posted by Peter will suffer from -Wpsabi warnings
e.g. on i686-linux, so I think it is better to avoid vector arguments/return
values when we can (and we can in this case).

If we want to go with my version, I can add Peter as Co-Authored-By
on the commit.

	Jakub
  
Jeffrey Law Jan. 15, 2026, 10:44 p.m. UTC | #4
On 1/15/2026 3:40 PM, Jakub Jelinek wrote:
> On Thu, Jan 15, 2026 at 12:25:07PM -0800, Andrew Pinski wrote:
>>>> gcc/c/ChangeLog:
>>>>
>>>>        PR c/123437
>>>>        * c-typeck.cc (build_binary_op): Include ENUMERAL_TYPE in
>>>>        integer division check for vectors.
>>>>
>>>> gcc/cp/ChangeLog:
>>>>
>>>>        PR c/123437
>>>>        * typeck.cc (cp_build_binary_op): Include ENUMERAL_TYPE in
>>>>        integer division check.
>>>>
>>>> gcc/testsuite/ChangeLog:
>>>>
>>>>        PR c/123437
>>>>        * c-c++-common/pr123437.c: New test.
>>> I think Jakub's comment probably points to a slightly better patch. In
>>> particular his patch/comment only allow the ENUMERAL_TYPE  for tcode
>>> when the code is a VECTOR_TYPE.  Seems safer at this point.
>>>
>>> OK with that change (which I think makes it idential to Jakub's patch in
>>> c#5 in the bugzilla case.
>> Jakub posted his patch here already:
>> https://gcc.gnu.org/pipermail/gcc-patches/2026-January/705874.html
> I'm sorry I have missed Peter's patch being posted to gcc-patches,
> the "WDYT the solution should be?" in bugzilla made me think it is not.
>
> Anyway, the testcase posted by Peter will suffer from -Wpsabi warnings
> e.g. on i686-linux, so I think it is better to avoid vector arguments/return
> values when we can (and we can in this case).
>
> If we want to go with my version, I can add Peter as Co-Authored-By
> on the commit.
Yes, I think we want to go with your patch version.  The testcase might 
need minor adjustment, but the core patch, yours looks best to me.

jeff
  

Patch

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 1903285b626..f08e051ad4e 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -14478,8 +14478,10 @@  build_binary_op (location_t location, enum tree_code code,
 	  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)
+		 && (tcode1 == INTEGER_TYPE || tcode1 == BITINT_TYPE
+		     || tcode1 == ENUMERAL_TYPE))
 		|| (tcode0 == FIXED_POINT_TYPE && tcode1 == FIXED_POINT_TYPE)))
 	    resultcode = RDIV_EXPR;
 	  else
diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index f6f71a03003..347ce7de1e0 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -5856,7 +5856,8 @@  cp_build_binary_op (const op_location_t &location,
 	  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)
+		&& (tcode1 == INTEGER_TYPE || tcode1 == ENUMERAL_TYPE)))
 	    resultcode = RDIV_EXPR;
 	  else
 	    {
diff --git a/gcc/testsuite/c-c++-common/pr123437.c b/gcc/testsuite/c-c++-common/pr123437.c
new file mode 100644
index 00000000000..78e48a28700
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr123437.c
@@ -0,0 +1,11 @@ 
+/* PR c/123437 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+enum foo { F };
+typedef enum foo vec_foo __attribute__((vector_size(16)));
+
+vec_foo div(vec_foo x, vec_foo y)
+{
+  return x / y;
+}