https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127976
Bug ID: 127976
Summary: [14/15/16 Regression] ICE in
simplify_binary_operation_1 (VEC_CONCAT) during
combine on aarch64 since 8968e92cc65e
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: zeno490 at gmail dot com
Target Milestone: ---
Created attachment 65882
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=65882&action=edit
repro file
[Note that this was generated by Claude]
GCC 14.1 to 16.2 crash on aarch64 at -O1 and -O2 with the testcase below.
GCC 12.5, GCC 13.4, and trunk (17.0.0 20261005) compile it. Clang 22 also
compiles it.
The failing assert is the operand size check of the VEC_CONCAT case in
simplify_binary_operation_1:
gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
+ GET_MODE_SIZE (op1_mode),
GET_MODE_SIZE (mode)));
(simplify-rtx.cc:5378 in 16.2.0, :5108 in 15.2.0, :4821 in 14.3.0, :4793 in
14.1.0)
The cause appears to be the VEC_CONCAT fold that 8968e92cc65e
("simplify-rtx: Simplify VEC_CONCAT of SUBREG and VEC_CONCAT from same vector")
added:
/* (vec_concat:
(subreg_lowpart:N OP)
(vec_select:N OP P)) --> OP when P selects the high half
of the OP. */
...
return XEXP (trueop1, 0);
The fold does not check that the mode of OP is the result mode. In the failing
combine
attempt, insn 24 is:
(vec_concat:V2SF (subreg:SF (reg:V4SF 101) 0)
(vec_select:SF (reg:V4SF 101) (parallel [(const_int 1)])))
The fold returns (reg:V4SF 101), a 16-byte value, for the V2SF result. The
outer
vec_concat:V4SF from vcombine_f32 (insn 28) then gets a 16-byte operand and an
8-byte operand, and the assert fails.
On trunk, b085ae4b49b4 (PR target/48609, 2026-08-25) replaced this fold with a
fold
that checks known_eq (GET_MODE_SIZE (GET_MODE (base0)), GET_MODE_SIZE (mode)).
That commit is an x86 optimization, so it is not on the release branches.
A smaller fix for the branches can be to add GET_MODE (XEXP (trueop1, 0)) ==
mode
to the condition of the old fold. (Not tested.)
Testcase (gcc_ice.c):
#include <arm_neon.h>
int run(float threshold)
{
const float32x4_t values[] = {
{ 0.0F, 0.0F, 0.0F, 1.0F },
{ -0.701057315F, 0.0922959521F, -0.430459321F, 0.560985446F },
{ -0.597238779F, -0.565758348F, -0.0560427159F, 0.565758348F },
};
int all_ok = 1;
for (int i = 0; i < 3; ++i)
{
const float32x2_t lo = vset_lane_f32(vgetq_lane_f32(values[i],
1), vmov_n_f32(vgetq_lane_f32(values[i], 0)), 1);
const float32x2_t hi = vset_lane_f32(vgetq_lane_f32(values[i],
2), vdup_n_f32(0.0F), 0);
const uint32x4_t mask = vcleq_f32(vabsq_f32(vcombine_f32(lo,
hi)), vdupq_n_f32(threshold));
all_ok &= vminvq_u32(mask) != 0;
}
return all_ok;
}
Command line:
gcc -O2 -c gcc_ice.c
Output:
during RTL pass: combine
gcc_ice.c: In function 'run':
gcc_ice.c:21:1: internal compiler error: in simplify_binary_operation_1, at
simplify-rtx.cc:5378
21 | }
| ^
0x1e1564f diagnostics::context::diagnostic_impl(rich_location*,
diagnostics::metadata const*, diagnostics::option_id, char const*,
std::__va_list*, diagnostics::kind)
???:0
0x1e0e833 internal_error(char const*, ...)
???:0
0x80e5d3 fancy_abort(char const*, int, char const*)
???:0
0xe745ff simplify_context::simplify_binary_operation_1(rtx_code, machine_mode,
rtx_def*, rtx_def*, rtx_def*, rtx_def*)
???:0
0xe74893 simplify_context::simplify_binary_operation(rtx_code, machine_mode,
rtx_def*, rtx_def*)
???:0
The last combine attempt in -fdump-rtl-combine-details:
Trying 22, 24 -> 28:
22: r131:SF=vec_select(r101:V4SF,parallel)
24: r132:V2SF=vec_concat(r101:V4SF#0,r131:SF)
REG_DEAD r131:SF
28: r128:V4SF=vec_concat(r132:V2SF,r134:V2SF)
REG_DEAD r134:V2SF
REG_DEAD r132:V2SF
gcc -v:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/aarch64-linux-gnu/16.2.0/lto-wrapper
Target: aarch64-linux-gnu
Configured with: /usr/src/gcc/configure --build=aarch64-linux-gnu
--disable-multilib --enable-languages=c,c++,fortran,go
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 16.2.0 (GCC)
(The official gcc:16 Docker image. The other versions: the Ubuntu 26.04 arm64
packages
for 14.3.0 and 15.2.0, and Compiler Explorer for 12.x, 13.x, 14.1.0, 15.1.0,
16.1.0, and trunk.)
Found in: the unit tests of the Realtime Math library
(https://github.com/nfrechette/rtm).