I see the following ICE since the mentioned revision: $ gcc /home/marxin/Programming/gcc/gcc/testsuite/c-c++-common/vector-scalar.c -m32 -march=athlon-4 during RTL pass: reload /home/marxin/Programming/gcc/gcc/testsuite/c-c++-common/vector-scalar.c: In function ‘f’: /home/marxin/Programming/gcc/gcc/testsuite/c-c++-common/vector-scalar.c:10:1: internal compiler error: maximum number of generated reload insns per insn achieved (90) 10 | } | ^ 0xc99204 lra_constraints(bool) /home/marxin/Programming/gcc/gcc/lra-constraints.c:4948 0xc86044 lra(_IO_FILE*) /home/marxin/Programming/gcc/gcc/lra.c:2437 0xc3dcc1 do_reload /home/marxin/Programming/gcc/gcc/ira.c:5523 0xc3dcc1 execute /home/marxin/Programming/gcc/gcc/ira.c:5709 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions.
Before my patch, the compiler generated this IR: #(insn 42 291 43 2 (set (strict_low_part (mem/c:HI (plus:SI (reg/f:SI 6 bp) # (const_int -40 [0xffffffffffffffd8])) [5 %sfp+-16 S2 A128])) # (reg:HI 1 dx [orig:91 _14 ] [91])) "vector-scalar.c":9:17 83 {*movstricthi_1} # (nil)) movw %dx, -40(%ebp) # 42 [c=4 l=4] *movstricthi_1/0 This is strict_low_part of a memory operand, which isn't valid according to docs: '(strict_low_part (subreg:M (reg:N R) 0))' This expression code is used in only one context: as the destination operand of a 'set' expression. In addition, the operand of this expression must be a non-paradoxical 'subreg' expression. The presence of 'strict_low_part' says that the part of the register which is meaningful in mode N, but is not part of mode M, is not to be altered. Normally, an assignment to such a subreg is allowed to have undefined effects on the rest of the register when M is smaller than 'REGMODE_NATURAL_SIZE (N)'. After the patch, we have: (insn 42 41 43 2 (set (strict_low_part (subreg:HI (reg:TI 135) 0)) (reg:HI 91 [ _14 ])) "vector-scalar.c":9:17 83 {*movstricthi_1} (nil)) but TImode is not valid for general regs. Probably we have to reject TImode in case of 32bit targets from the expander.
(In reply to Uroš Bizjak from comment #1) > Probably we have to reject TImode in case of 32bit targets from the expander. Like this: --cut here-- diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 6c57500ae8ec..8e29dffafa6e 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2778,7 +2778,7 @@ { gcc_assert (SUBREG_P (operands[0])); if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) - || GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT) + || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0])))) FAIL; }) --cut here--
The master branch has been updated by Uros Bizjak <uros@gcc.gnu.org>: https://gcc.gnu.org/g:b80cbe2d8d46c8518dca2d781c8ee4d02c5ba1ed commit r10-6979-gb80cbe2d8d46c8518dca2d781c8ee4d02c5ba1ed Author: Uros Bizjak <ubizjak@gmail.com> Date: Mon Mar 2 21:13:36 2020 +0100 i386: Allow only registers with VALID_INT_MODE_P modes in movstrict<mode> [PR93997] *movstrict<mode>_1 insn pattern allows only general registers, so we have to reject modes not suitable for general regs in corresponding movstrict<mode> expander. PR target/93997 * config/i386/i386.md (movstrict<mode>): Allow only registers with VALID_INT_MODE_P modes. testsuite/ChangeLog: PR target/93997 * gcc.target/i386/pr93997.c: New test.
Fixed.
.