On Thu, Oct 23, 2025 at 01:50:07PM +0200, Richard Biener wrote:
> On Thu, 23 Oct 2025, Artemiy Volkov wrote:
>
> > +/* Squash view_converts of BFRs if no precision is lost. */
> > +(simplify
> > + (view_convert (BIT_FIELD_REF@0 @1 @2 @3))
> > + (if (!INTEGRAL_TYPE_P (type)
> > + || !INTEGRAL_TYPE_P (TREE_TYPE (@0))
> > + || TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (@0)))
> > + (BIT_FIELD_REF:type @1 @2 @3)))
>
> I think you want to ensure that you do not fold in size changes.
> See tree-cfg.cc:verify_types_in_gimple_reference. The view_convert
> could convert to a variably-sized type.
Thank you for the pointers. Reading the code for
verify_types_in_gimple_reference (), it looks like is_gimple_reg_type ()
is definitely necessary, but since that restricts `type' to scalar types,
and taking into account tree.def:476-477: "It is undefined if the type of
the input and of the expression have different sizes", we should just be
able to assume the fact that view_convert retains the size of its
argument, right? If that is so, then we needn't explicitly check that the
size is preserved, only that there is no loss of precision for integral
types.
>
> I'm concerned there are many corner cases you can't think of. So
> instead of a negative list (aka !INTEGRAL_TYPE_P) I'm looking for
> a positive-list we are sure will work. I'd suggest to use
> is_gimple_reg_type. Also require type_has_mode_precision_p
> on integral types.
So for a full list, at the risk of being overly verbose, I would go with
something like:
(if (is_gimple_reg_type (type))
(with
{
poly_uint64 size = tree_to_poly_uint64 (@2);
}
(if ((INTEGRAL_TYPE_P (type)
&& known_eq (TYPE_PRECISION (type), size))
|| (!INTEGRAL_TYPE_P (type)
&& (TYPE_MODE (type) == BLKmode
|| known_eq (GET_MODE_BITSIZE (TYPE_MODE (type)),
size))))
(BIT_FIELD_REF:type @1 @2 @3)))))
However, this is a bit too contrived, and in view of the UB on size
mismatch, it seems to me that this could be simplified to:
if (is_gimple_reg_type (type)
&& (!INTEGRAL_TYPE_P (type)
|| type_has_mode_precision_p (type))
(The `type_has_mode_precision_p (type)' check seems equivalent to the
TYPE_PRECISION equality check I had in the original patch. I think either
one looks OK but this one matches nicely with the pattern on lines
9830-9834, and there's no need to capture @0).
Please let me know whether you're happy with either of these, and I'll
respin the patch.
Thanks,
Artemiy
>
> Richard.
>
>
> > +
> > /* For integral conversions with the same precision or pointer
> > conversions use a NOP_EXPR instead. */
> > (simplify
> > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-42.c
> > b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-42.c
> > new file mode 100644
> > index 00000000000..5785e51c089
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-42.c
> > @@ -0,0 +1,12 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -fdump-tree-forwprop1" } */
> > +
> > +typedef unsigned int vec2 __attribute__ ((vector_size (2 * sizeof
> > (unsigned int))));
> > +typedef unsigned int vec1 __attribute__ ((vector_size (sizeof (unsigned
> > int))));
> > +
> > +vec1 foo (vec2 x)
> > +{
> > + return (vec1) x[1];
> > +}
> > +
> > +/* { dg-final { scan-tree-dump-not "VIEW_CONVERT_EXPR" "forwprop1" } } */
> >
>
> --
> Richard Biener <[email protected]>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)