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]>
