On Fri, Jan 23, 2026 at 01:18:18PM +0100, Richard Biener wrote:
> On Fri, 23 Jan 2026, Artemiy Volkov wrote:
>
> > On Thu, Jan 22, 2026 at 10:32:50AM +0100, Richard Biener wrote:
> > > On Thu, Jan 22, 2026 at 10:31 AM Richard Biener
> > > <[email protected]> wrote:
> > > >
> > > > On Wed, Jan 21, 2026 at 4:10 PM Artemiy Volkov <[email protected]>
> > > > wrote:
> > > > >
> > > > > Currently, simplify_vector_constructor () tries to rewrite a
> > > > > CONSTRUCTOR
> > > > > expression into a VEC_PERM_EXPR, as long as constructor elements all
> > > > > come
> > > > > from 1 or 2 source vectors. While doing so, it protects against
> > > > > creating
> > > > > VEC_PERM_EXPRs unsupported by the target by calling
> > > > > can_vec_perm_const_p
> > > > > () before enacting the transformation and bailing when that returns
> > > > > false.
> > > > >
> > > > > However, we can instead allow those VEC_PERM_EXPRs to be created if we
> > > > > know that a later vector lowering pass will legitimize them for us.
> > > > > IOW,
> > > > > only if the target doesn't support the resulting permute and the
> > > > > PROP_gimple_lvec property is already set, do we give up. This patch
> > > > > inserts the required checks.
> > > > >
> > > > > This also allows us to remove the unnecessary vect_int requirement
> > > > > (wrongly added in r16-5244-g5a2319b71e4d30) from forwprop-43.c.
> > > > >
> > > > > Regtested on aarch64 and x86_64, and on arm with
> > > > > RUNTESTFLAGS=--target_board=unix/-mfpu=vfpv3-d16/-march=armv7-a.
> > > >
> > > Is this a regression fix of some sorts? I'm a bit worried that the
> > > poor-mans
> > > lowering will create much worse code than what we produce from the
> > > original CTOR (and the fix should probably to vector lowering).
> >
> > There is no regression per se, but this is a proposed long-term fix for
> > PR122679 which has 16.0 set as "target milestone". I would be equally
> > happy if this was considered for GCC 17 instead.
>
> Target milestone is meaningless for non-regressions, I think the target
> milestone is because of some testsuite FAILs on sparc.
>
> > For some context, this patch was prompted by the discussion at
> > https://gcc.gnu.org/pipermail/gcc-patches/2025-November/700465.html and
> > specifically the "vect_int" requirement that I'd added to the test and now
> > want to remove. I think that the right invariant to establish is that
> > forwprop1 always creates the VEC_PERM_EXPRs, regardless of whether those
> > are supported by the target or not.
> >
> > My reasoning here is that since vector lowering has the final say on what
> > VPEs are and aren't legal for the target, it should be fine to create new
> > VPEs prior to (the first instance of) that pass. After vector lowering
> > though (i.e. during forwprop4), we need to check explicitly whether VPEs
> > we're about to create are supported (aka the current behavior). So for
> > vector-capable targets this patch will be a no-op (as just validated
> > on aarch64 and x86_64 across SPEC2017).
> >
> > For other targets (arm w/o vector FPU, some sparc targets mentioned in the
> > PR, etc.) the only problematic case I see is when lower_vec_perm (), when
> > doing piecewise lowering of VEC_PERM_EXPRs, gives back narrower
> > BIT_FIELD_REFs that those we had originally. (That is, the original CTOR
> > had subvectors as arguments, but now we have a BFR for each individual
> > element.) The RTL pipeline takes care of this situation though, and on
> > AdvSIMD-less arm codegen for superword accesses seems to be slightly
> > improved.
> >
> > It is quite possible that I'm missing some corner case here, if so please
> > let me know.
>
> I'm indeed thinking of vector lowering not caring about CONSTRUCTOR
> expansion (see below), and the VEC_PERM lowering is always element-wise.
> We for example do not try to turn an unsupported VEC_PERM into a
> sequence of two supported ones (we kind-of expect the target expander
> to be "complete" in this way, synthesizing these cases itself).
> The upper/lower vector half combination case is likely specifically
> problematic.
Yes, and I think this is part of the reason why this patch is a no-op at
least on aarch64 and x86_64.
>
> I think we should do this change during stage1 where I'd say we just
> do it and deal with the fallout that's eventually reported as bug. But
> we don't want to do this at this point.
That's very fair. I will come back with a (trivial) v2 after stage1 opens.
Thanks,
Artemiy
>
> > > Oh, and we also have to be careful to not trust can_vec_perm_const_p
> > > before
> > > IPA since we might face to be offloaded code. That's a pre-existing
> > > issue as
> > > well.
> >
> > I think this can be solved by swapping the operands of the new "&&"
> > operators, since that way can_vec_perm_const_p () will never be called at
> > all before veclower (also, the cheaper check is performed first). Do you
> > agree?
>
> I guess so. We nowhere validate CONSTRUCTORs given we can expand
> all of them, just some of them might be expanded very poorly compared
> to others.
>
> Richard.
>
> > Thanks,
> > Artemiy
> >
> > >
> > > Richard.
> > >
> > > > Thanks,
> > > > Richard.
> > > >
> > > > > PR tree-optimization/122679
> > > > >
> > > > > gcc/ChangeLog:
> > > > >
> > > > > * tree-ssa-forwprop.cc (simplify_vector_constructor): Check
> > > > > the
> > > > > PROP_gimple_lvec property before bailing.
> > > > >
> > > > > gcc/testsuite/ChangeLog:
> > > > >
> > > > > * gcc.dg/tree-ssa/forwprop-43.c: Remove the vect_int check.
> > > > > ---
> > > > > gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c | 1 -
> > > > > gcc/tree-ssa-forwprop.cc | 6 ++++--
> > > > > 2 files changed, 4 insertions(+), 3 deletions(-)
> > > > >
> > > > > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c
> > > > > b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c
> > > > > index bfda376e1f7..0e802ea5107 100644
> > > > > --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c
> > > > > +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-43.c
> > > > > @@ -1,7 +1,6 @@
> > > > > /* { dg-do compile } */
> > > > > /* { dg-options "-O2 -fdump-tree-forwprop1" } */
> > > > > /* { dg-require-effective-target stdint_types } */
> > > > > -/* { dg-require-effective-target vect_int } */
> > > > > /* { dg-additional-options "-fgimple" } */
> > > > >
> > > > > #include <stdint.h>
> > > > > diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> > > > > index bdc63a7a71b..6c847ee7ff3 100644
> > > > > --- a/gcc/tree-ssa-forwprop.cc
> > > > > +++ b/gcc/tree-ssa-forwprop.cc
> > > > > @@ -4173,7 +4173,8 @@ simplify_vector_constructor
> > > > > (gimple_stmt_iterator *gsi)
> > > > > ? 0 : refnelts) + i);
> > > > > vec_perm_indices indices (sel, orig[1] ? 2 : 1, refnelts);
> > > > > machine_mode vmode = TYPE_MODE (perm_type);
> > > > > - if (!can_vec_perm_const_p (vmode, vmode, indices))
> > > > > + if (!can_vec_perm_const_p (vmode, vmode, indices)
> > > > > + && (cfun->curr_properties & PROP_gimple_lvec))
> > > > > return false;
> > > > > mask_type = build_vector_type (ssizetype, refnelts);
> > > > > tree op2 = vec_perm_indices_to_tree (mask_type, indices);
> > > > > @@ -4238,7 +4239,8 @@ simplify_vector_constructor
> > > > > (gimple_stmt_iterator *gsi)
> > > > > ? elts[i].second + nelts : i);
> > > > > vec_perm_indices indices (sel, 2, nelts);
> > > > > machine_mode vmode = TYPE_MODE (type);
> > > > > - if (!can_vec_perm_const_p (vmode, vmode, indices))
> > > > > + if (!can_vec_perm_const_p (vmode, vmode, indices)
> > > > > + && (cfun->curr_properties & PROP_gimple_lvec))
> > > > > return false;
> > > > > mask_type = build_vector_type (ssizetype, nelts);
> > > > > blend_op2 = vec_perm_indices_to_tree (mask_type, indices);
> > > > > --
> > > > > 2.43.0
> > > > >
> >
>
> --
> Richard Biener <[email protected]>
> SUSE Software Solutions Germany GmbH,
> Frankenstrasse 146, 90461 Nuernberg, Germany;
> GF: Jochen Jaser, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)