https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127862

--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Igor Shevlyakov
<[email protected]>:

https://gcc.gnu.org/g:bb6efe4d690515e49c5da9167d9ca4836d1ab546

commit r17-5345-gbb6efe4d690515e49c5da9167d9ca4836d1ab546
Author: Igor Shevlyakov <[email protected]>
Date:   Wed Oct 14 10:44:39 2026 -0700

    middle-end: Fix VEC_PERM_EXPR merges of different-length vectors [PR127862]

    Since GCC 14 a VEC_PERM_EXPR with a constant selector may have inputs
    with a different number of elements than its result.  The match.pd
    patterns that merge a VEC_PERM_EXPR into a VEC_PERM_EXPR using it, and
    forwprop's identity check for two consecutive permutes, still assume
    that every permute and input involved has the same number of elements.

    On aarch64 this happens for plain SVE intrinsics: svld1rq folds to a
    permute from a 128-bit vector to the SVE vector, and with
    -msve-vector-bits=256 a following svrev, svzip1, svuzp1 or svtrn2 of it
    is merged into an invalid permute.  That fails GIMPLE verification, and
    without checking it is miscompiled or ICEs in expand_vec_perm_const.

    - Merging c = <a, b> into d = <c, c> builds the new selector with d's
      element count as the number of elements per input, and emits the new
      permute with a's type but d's selector length.  That is invalid
      GIMPLE: the verifier rejects it, and without checking it is
      miscompiled or ICEs during expansion.
    - Merging c = <a, b> into d = <x, c> or <c, x> builds the new selector
      with d's element count as the number of elements per input too, so
      when d is narrower than c, lanes of c are taken from x: silent wrong
      code.  When c and a differ in length, the new permute mixes inputs x
      and a of different widths.
    - is_combined_permutation_identity folds the outer mask through the
      inner one with the inner mask's type and reduces the result by its
      length, so mixed widths ICE in fold_vec_perm or wrongly look like an
      identity (a V2HI permute of a V2HI permute of two V4HI vectors gets
      replaced by one of the V4HI inputs).

    Build each selector with the element count of its own inputs.  In the
    <c, c> merge, emit the new permute as a vector of a's element type with
    d's length, which is d's type unless c is view-converted to a different
    element type, and query it with that type's mode.  In the <x, c> and
    <c, x> merges, require a and b to have x's type and query the inner
    permute with its own result mode.  In forwprop, leave permutes of
    different widths to match.pd.

    Assisted-by: Claude Opus 5.5

            PR middle-end/127862

    gcc/ChangeLog:

            * match.pd (vec_perm (vec_perm) merges): Handle inputs and results
            with different numbers of elements.
            * tree-ssa-forwprop.cc (simplify_permutation): Don't check for an
            identity when the permutes have different widths.

    gcc/testsuite/ChangeLog:

            * gcc.dg/torture/vec-perm-merge-wide-input-1.c: New test.
            * gcc.dg/torture/vec-perm-merge-wide-input-2.c: New test.
            * gcc.dg/torture/vec-perm-merge-wide-input-3.c: New test.
            * gcc.target/aarch64/sve/pr127862.c: New test.
            * gcc.target/aarch64/sve/pr127862_run.c: New test.

    Signed-off-by: Igor Shevlyakov <[email protected]>

Reply via email to