https://gcc.gnu.org/g:ddacdb8b37ce268cac26e594e8f84b530b4f85b4
commit r17-1416-gddacdb8b37ce268cac26e594e8f84b530b4f85b4 Author: Richard Sandiford <[email protected]> Date: Mon Jun 8 08:31:18 2026 +0100 Simplify vec_duplicates of vec_duplicates r17-899-g52d5a8870d2108 added a pattern with a nested vec_duplicate, but I think those should be folded down to a single vec_duplicate. The later: if (VECTOR_MODE_P (mode) && vec_duplicate_p (op, &elt) && code != VEC_DUPLICATE) handles only scalar elements, but this rule applies to vec_duplicates of vectors as well. A bit of scripting suggests that this was the only use of nested vec_duplicates in the md files. This is tested by gcc.target/aarch64/sve/vec_init_5.c. gcc/ * simplify-rtx.cc (simplify_context::simplify_unary_operation_1): Simplify vec_duplicates of vec_duplicates. * config/aarch64/aarch64-sve.md (*aarch64_vec_duplicate_subvector<vconsv><vconq><mode>): Remove nested vec_duplicate. Diff: --- gcc/config/aarch64/aarch64-sve.md | 3 +-- gcc/simplify-rtx.cc | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md index 585a587d8cf4..723b8d6e6ecf 100644 --- a/gcc/config/aarch64/aarch64-sve.md +++ b/gcc/config/aarch64/aarch64-sve.md @@ -2895,8 +2895,7 @@ (define_insn "*aarch64_vec_duplicate_subvector<vconsv><vconq><mode>" [(set (match_operand:<VCONSV> 0 "register_operand") (vec_duplicate:<VCONSV> - (vec_duplicate:<VCONQ> - (match_operand:VQDUP 1 "register_operand"))))] + (match_operand:VQDUP 1 "register_operand")))] "TARGET_SVE" {@ [ cons: =0 , 1 ] [ w , r ] mov\t%0.<single_type>, %<single_wx>1 diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index c2d89641dfc6..872ae0328691 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -1900,6 +1900,12 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode, #endif break; + case VEC_DUPLICATE: + if (GET_CODE (op) == VEC_DUPLICATE) + return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0), + GET_MODE (XEXP (op, 0))); + break; + default: break; }
