https://gcc.gnu.org/g:6fea108d4725f1aa79ce3acd9b6933da003d11a4
commit r17-4176-g6fea108d4725f1aa79ce3acd9b6933da003d11a4 Author: Robin Dapp <[email protected]> Date: Fri Sep 11 16:59:27 2026 +0200 expmed: Use store_bit_field for unsplittable target. [PR127323] In extract_integral_bit_field we can get an unsplittable target like (reg:V2DF) and we try to store word-sized parts into it. After the regmode-natural-size changes, this will ICE. This patch goes through store_bit_field if we cannot use a subreg. For riscv, this will currently cause one spill per iteration but that can be mitigated later. gcc/ChangeLog: PR middle-end/127323 * expmed.cc (extract_integral_bit_field): Use store_bit_field if operand_subword fails. gcc/testsuite/ChangeLog: * g++.target/riscv/rvv/autovec/pr127323.C: New test. Diff: --- gcc/expmed.cc | 6 ++-- .../g++.target/riscv/rvv/autovec/pr127323.C | 39 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/gcc/expmed.cc b/gcc/expmed.cc index 13803c6bbd04..c6494484251f 100644 --- a/gcc/expmed.cc +++ b/gcc/expmed.cc @@ -2022,14 +2022,16 @@ extract_integral_bit_field (rtx op0, opt_scalar_int_mode op0_mode, (unsignedp ? 1 : -1), target_part, mode, word_mode, reverse, fallback_p, NULL); - gcc_assert (target_part); if (!result_part) { delete_insns_since (last); return NULL; } - if (result_part != target_part) + if (!target_part) + store_bit_field (target, BITS_PER_WORD, i * BITS_PER_WORD, + 0, 0, word_mode, result_part, false, i == 0); + else if (result_part != target_part) emit_move_insn (target_part, result_part); } diff --git a/gcc/testsuite/g++.target/riscv/rvv/autovec/pr127323.C b/gcc/testsuite/g++.target/riscv/rvv/autovec/pr127323.C new file mode 100644 index 000000000000..86141b749368 --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/rvv/autovec/pr127323.C @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -mrvv-max-lmul=conv-dynamic -march=rv64gcv -mabi=lp64d -mtune=generic-ooo" } */ + +typedef double VECTOR[3]; +enum { X, Y, Z }; +struct Bicubic_Patch_Struct { + VECTOR Control_Points[4][4]; + VECTOR Bounding_Sphere_Center; + double Bounding_Sphere_Radius; +}; +void Assign_Vector(VECTOR d, VECTOR s) { + d[X] = s[X]; + d[Y] = s[Y]; + d[Z] = s[Z]; +} +typedef struct Bicubic_Patch_Struct BICUBIC_PATCH; +namespace std { +void find_average(int vector_count, VECTOR *vectors, VECTOR, double *radius) { + int i; + double r0, r1, yc, zc, y0; + for (i = 0; i < vector_count; i++) { + yc += vectors[i][Y]; + zc += vectors[i][Z]; + } + y0 = yc - zc; + r1 = y0; + if (r1) + *radius = r0; +} +void Precompute_Patch_Values(BICUBIC_PATCH *Shape) { + int i, j; + VECTOR Control_Points[6]; + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + Assign_Vector(Control_Points[4 * i + j], Shape->Control_Points[i][j]); + find_average(6, Control_Points, Shape->Bounding_Sphere_Center, + &Shape->Bounding_Sphere_Radius); +} +}
