]> git.ipfire.org Git - thirdparty/gcc.git/commit
arm: Fix ICE due to infinite splitting [PR109800]
authorAlex Coplan <alex.coplan@arm.com>
Thu, 25 May 2023 12:34:46 +0000 (13:34 +0100)
committerAlex Coplan <alex.coplan@arm.com>
Thu, 25 May 2023 12:34:46 +0000 (13:34 +0100)
commitf5298d9969b4fa34ff3aecd54b9630e22b2984a5
treec30d07103845dfa1c391e5f1d892e9a956b63207
parentf97572c2aeddc71b01686993b978895e55890ab6
arm: Fix ICE due to infinite splitting [PR109800]

In r11-966-g9a182ef9ee011935d827ab5c6c9a7cd8e22257d8 we introduce a
simplification to emit_move_insn that attempts to simplify moves of the form:

(set (subreg:M1 (reg:M2 ...)) (constant C))

where M1 and M2 are of equal mode size. That is problematic for the splitter
vfp.md:no_literal_pool_df_immediate in the arm backend, which tries to pun an
lvalue DFmode pseudo into DImode and assign a constant to it with
emit_move_insn, as the new transformation simply undoes this, and we end up
splitting indefinitely.

This patch changes things around in the arm backend so that we use a
DImode temporary (instead of DFmode) and first load the DImode constant
into the pseudo, and then pun the pseudo into DFmode as an rvalue in a
reg -> reg move. I believe this should be semantically equivalent but
avoids the pathalogical behaviour seen in the PR.

gcc/ChangeLog:

PR target/109800
* config/arm/arm.md (movdf): Generate temporary pseudo in DImode
instead of DFmode.
* config/arm/vfp.md (no_literal_pool_df_immediate): Rather than punning an
lvalue DFmode pseudo into DImode, use a DImode pseudo and pun it into
DFmode as an rvalue.

gcc/testsuite/ChangeLog:

PR target/109800
* gcc.target/arm/pure-code/pr109800.c: New test.
gcc/config/arm/arm.md
gcc/config/arm/vfp.md
gcc/testsuite/gcc.target/arm/pure-code/pr109800.c [new file with mode: 0644]