On Fri, Jun 17, 2022 at 10:37:45AM +0200, Richard Biener wrote:
> > --- gcc/varasm.cc.jj    2022-06-06 12:18:12.792812888 +0200
> > +++ gcc/varasm.cc    2022-06-17 09:49:21.918029072 +0200
> > @@ -4716,7 +4716,8 @@ narrowing_initializer_constant_valid_p (
> >     {
> >       tree inner = TREE_OPERAND (op0, 0);
> >       if (inner == error_mark_node
> > -      || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner)))
> > +      || VECTOR_TYPE_P (TREE_TYPE (inner))
> 
> Do we really want to allow all integer modes here regardless of a
> composite type (record type for example)?  I’d say !INTEGRAL_TYPE_P would
> match the rest better.  OTOH if we want to allow integer modes I fail to
> see why to exclude vector types (but not complex, etc)

I've excluded VECTOR_TYPE_P because those are the only types for which
TYPE_MODE can be different from the raw type mode (so, SCALAR_INT_MODE_P
was true but SCALAR_INT_TYPE_MODE still ICEd).

Checking for INTEGRAL_TYPE_P seems reasonable to me though,
and I'd say we also want to check the outer type too because nothing
really checks it (at least for the first iteration, 2nd and further
get it from checking of inner in the previous iteration).

So like this if it passes bootstrap/regtest?

2022-06-17  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/105998
        * varasm.cc (narrowing_initializer_constant_valid_p): Check
        SCALAR_INT_MODE_P instead of INTEGRAL_MODE_P, also break on
        ! INTEGRAL_TYPE_P and do the same check also on op{0,1}'s type.

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

--- gcc/varasm.cc.jj    2022-06-17 11:07:57.883679019 +0200
+++ gcc/varasm.cc       2022-06-17 11:10:09.190932417 +0200
@@ -4716,7 +4716,10 @@ narrowing_initializer_constant_valid_p (
     {
       tree inner = TREE_OPERAND (op0, 0);
       if (inner == error_mark_node
-         || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner)))
+         || ! INTEGRAL_TYPE_P (TREE_TYPE (op0))
+         || ! SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (op0)))
+         || ! INTEGRAL_TYPE_P (TREE_TYPE (inner))
+         || ! SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (inner)))
          || (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (op0)))
              > GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (inner)))))
        break;
@@ -4728,7 +4731,10 @@ narrowing_initializer_constant_valid_p (
     {
       tree inner = TREE_OPERAND (op1, 0);
       if (inner == error_mark_node
-         || ! INTEGRAL_MODE_P (TYPE_MODE (TREE_TYPE (inner)))
+         || ! INTEGRAL_TYPE_P (TREE_TYPE (op1))
+         || ! SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (op1)))
+         || ! INTEGRAL_TYPE_P (TREE_TYPE (inner))
+         || ! SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (inner)))
          || (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (op1)))
              > GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (inner)))))
        break;
--- gcc/testsuite/c-c++-common/pr105998.c.jj    2022-06-17 11:09:11.196703834 
+0200
+++ gcc/testsuite/c-c++-common/pr105998.c       2022-06-17 11:09:11.196703834 
+0200
@@ -0,0 +1,12 @@
+/* PR middle-end/105998 */
+
+typedef int __attribute__((__vector_size__ (sizeof (long long)))) V;
+
+V v;
+
+long long
+foo (void)
+{
+  long long l = (long long) ((0 | v) - ((V) { } == 0));
+  return l;
+}


        Jakub

Reply via email to