On Mon, 27 Oct 2025, Artemiy Volkov wrote:
> 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).
Yes, this should work. I hope there are no weird cases with respect
to the original type of @1, if that's not a register type, that is.
> Please let me know whether you're happy with either of these, and I'll
> respin the patch.
Please.
Thanks,
Richard.
> 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)
>
--
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)