https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125746
--- Comment #8 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Dimitar Dimitrov <[email protected]>: https://gcc.gnu.org/g:20a4465989b7de0e44491d59f10b29812f2bb88c commit r17-3651-g20a4465989b7de0e44491d59f10b29812f2bb88c Author: Dimitar Dimitrov <[email protected]> Date: Mon Jun 15 23:02:12 2026 +0300 i386: Reject 16-bit modes for SSE1 registers [PR125746] 16-bit modes are not supported by SSE registers without SSE2. When asm register variable is declared with such mode, register allocation fails with an ICE: pr104974.c:5:1: internal compiler error: in gen_rtx_SUBREG, at emit-rtl.cc:1047 ... 0xe4aad9 emit_spill_move /home/mjires/git/GCC/master/gcc/lra-constraints.cc:1373 Here LRA attempts to create a paradoxical subreg for a spill move: (subreg:SI (reg/v:HI 21 xmm1)) Before the tightened checks in r16-718-geb2ea476db2182, this paradoxical subreg was valid. But when the checks were tightened, REG_CAN_CHANGE_MODE_P started being called to ensure the hardware register can change from the inner subreg mode to the outer subreg mode. In this case - HI and SI modes, which is rejected by ix86_can_change_mode_class. Thus the subreg generated by LRA was declared invalid, resulting in ICE. Fix by modifying ix86_hard_regno_mode_ok to start rejecting 16-bit modes as invalid for SSE hardware registers when SSE2 is not available. There are no functional changes if SSE2 is enabled. This change is mostly not affecting code generation. I built ffmpeg with and without this patch, with "-msse -mno-sse2" options for GCC, and in some rare occasions LRA resulted in different register allocations. This seems to be caused by targetm.modes_tieable_p, which calls the function patched with this fix: ix86_hard_regno_mode_ok. I'm not sufficiently familiar with x86 to judge whether the difference in code generation is a performance regression. Boostrapped and regtested x86_64-pc-linux-gnu for C and C++. I ran coremark with "-msse -mno-sse2 -O3", and I did not detect performance regression. PR target/125746 gcc/ChangeLog: * config/i386/i386.cc (ix86_hard_regno_mode_ok): For SSEv1, reject 16-bit modes. gcc/testsuite/ChangeLog: * gcc.target/i386/pr125746.c: New test. Signed-off-by: Dimitar Dimitrov <[email protected]>
