https://gcc.gnu.org/g:486c6296ed318d0df27a053d2288b6f4fa47517d
commit r17-4989-g486c6296ed318d0df27a053d2288b6f4fa47517d Author: Kyrylo Tkachov <[email protected]> Date: Wed Oct 7 17:29:35 2026 +0200 simplify-rtx: Fix ICE in the VEC_CONCAT halves fold [PR127483] simplify_binary_operation_1 simplifies the concatenation of the two halves of an object to gen_lowpart of the object. get_ref_base_and_offset can return any rtx as the object, such as an UNSPEC, but gen_lowpart asserts for an UNSPEC in another mode. For example, on AArch64 fwprop1 tries to propagate the result of an LD2 into the operands of an ADDP for: uint8x8x2_t v = vld2_u8 (p); return vpadd_u8 (v.val[0], v.val[1]); The ADDP operands then contain: (vec_concat:V16QI (subreg:V8QI (unspec:V2x8QI [(mem:V2x8QI (reg:DI p))] UNSPEC_LD2_DREG) 0) (subreg:V8QI (unspec:V2x8QI [(mem:V2x8QI (reg:DI p))] UNSPEC_LD2_DREG) 8)) and gen_lowpart (V16QImode, (unspec:V2x8QI ...)) fails the assert. The x86_64 testcase in the PR reaches the fold through debug insns. Use rtl_hooks.gen_lowpart_no_emit, like the other simplifications in this file, and do not fold if it fails. Unlike gen_lowpart, the hook also never emits instructions. Bootstrapped and tested on x86_64-pc-linux-gnu. gcc/ChangeLog: PR rtl-optimization/127483 * simplify-rtx.cc (simplify_context::simplify_binary_operation_1) <case VEC_CONCAT>: Use rtl_hooks.gen_lowpart_no_emit rather than gen_lowpart, and do not fold if it fails. gcc/testsuite/ChangeLog: PR rtl-optimization/127483 * gcc.dg/pr127483.c: New test. * gcc.target/aarch64/pr127483.c: Likewise. * gcc.target/aarch64/pr127483-be.c: Likewise. Signed-off-by: Kyrylo Tkachov <[email protected]> Diff: --- gcc/simplify-rtx.cc | 6 +++++- gcc/testsuite/gcc.dg/pr127483.c | 15 ++++++++++++++ gcc/testsuite/gcc.target/aarch64/pr127483-be.c | 7 +++++++ gcc/testsuite/gcc.target/aarch64/pr127483.c | 28 ++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index 42838cf0cdb5..68c65afb326f 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -5681,7 +5681,11 @@ simplify_ashift: && known_eq (offset, GET_MODE_SIZE (op0_mode)) && !side_effects_p (trueop0) && !side_effects_p (trueop1)) - return gen_lowpart (mode, base0); + { + tem = rtl_hooks.gen_lowpart_no_emit (mode, base0); + if (tem) + return tem; + } } } } diff --git a/gcc/testsuite/gcc.dg/pr127483.c b/gcc/testsuite/gcc.dg/pr127483.c new file mode 100644 index 000000000000..b81683785fa2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr127483.c @@ -0,0 +1,15 @@ +/* PR rtl-optimization/127483 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-Og -g" } */ + +typedef __attribute__((__vector_size__(16))) __int128 W; + +long c; +W g; + +void +foo() +{ + W w = g << c; + (struct {W m;}){w}; +} diff --git a/gcc/testsuite/gcc.target/aarch64/pr127483-be.c b/gcc/testsuite/gcc.target/aarch64/pr127483-be.c new file mode 100644 index 000000000000..ff7f9678c66d --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr127483-be.c @@ -0,0 +1,7 @@ +/* PR rtl-optimization/127483 */ +/* { dg-do compile } */ +/* { dg-require-effective-target aarch64_mbig_endian } */ +/* Avoid a dependence on big-endian C library headers. */ +/* { dg-options "-O2 -mbig-endian -ffreestanding" } */ + +#include "pr127483.c" diff --git a/gcc/testsuite/gcc.target/aarch64/pr127483.c b/gcc/testsuite/gcc.target/aarch64/pr127483.c new file mode 100644 index 000000000000..7f8fd1d4d540 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr127483.c @@ -0,0 +1,28 @@ +/* PR rtl-optimization/127483 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include <arm_neon.h> + +/* Pairwise additions of the two registers of a structure load. */ + +uint8x8_t +addp_u8 (const uint8_t *p) +{ + uint8x8x2_t v = vld2_u8 (p); + return vpadd_u8 (v.val[0], v.val[1]); +} + +uint8x8_t +addp_u8_rev (const uint8_t *p) +{ + uint8x8x2_t v = vld2_u8 (p); + return vpadd_u8 (v.val[1], v.val[0]); +} + +int32x2_t +addp_s32 (const int32_t *p) +{ + int32x2x2_t v = vld2_s32 (p); + return vpadd_s32 (v.val[0], v.val[1]); +}
