]> git.ipfire.org Git - thirdparty/gcc.git/commit
mmix: fix gcc.dg/loop-9.c by more accurate move insns
authorHans-Peter Nilsson <hp@bitrange.com>
Thu, 6 Aug 2020 23:57:15 +0000 (01:57 +0200)
committerHans-Peter Nilsson <hp@bitrange.com>
Thu, 6 Aug 2020 23:57:15 +0000 (01:57 +0200)
commit11b8ffa493039e8da3a7bc7d3c14354735d41e46
treee2f8979088dce10c72b810e4d9bf9b6d507a902d
parent140cf935cd118f7208b7c3826a8b9d50936242f0
mmix: fix gcc.dg/loop-9.c by more accurate move insns

It looks like gcc.dg/loop-9.c kind-of works as sentinel for sane
move-instruction generation for a port.

Looking at the
FAIL: gcc.dg/loop-9.c scan-rtl-dump loop2_invariant "Decided"
FAIL: gcc.dg/loop-9.c scan-rtl-dump loop2_invariant "without introducing a new temporary register"
it seems the problem is that in the loop:

  for (i = 0; i < 100; i++)
    a[i] = 18.4242;

the move insn corresponding to "a[i] = 18.4242" happens to be
generated as a move of a constant to a memory address, using no
registers except for the address (edited):

(insn 9 8 10 3 (set (mem:DF (reg:DI 269 [ ivtmp::9 ]))
        (const_double:DF 1.84241999e+1)) "x/loop-9.c":9:10 6 {movdf})

To wit, at the loop2 pass there's no register-initialization to move
out of the loop!  The insn above isn't accurate and has to be fixed up
at register allocation time to make constraints match.  While there
are insns to set memory to constant in MMIX, that's limited to 64-bit
moves corresponding to the integer bit-patterns for 0..255, and
18.4242 isn't one of them.  (Only 0.0 matches; the bit-patterns for
0..255 would IIUC be interpreted as denormal floating-point numbers
a.k.a. subnormal numbers and don't seem worthwhile to handle.)

The fault is with the port, for not requiring a register for an
operand that actually requires an intermediate register, in order to
enable pre-register-allocation passes to do their job.  The movdf
pattern (actually, all MMIX movM), only required the destination to be
a non-immediate operand and the source to be a general_operand,
i.e. anything-to-anything.

Better force the source to be a register, when asked to generate such
a move insn.  Also, make operands stay sane by using the matching insn
condition to require one of the operands to be a register
pre-register-allocation (for sake of combine-like passes that cook up
"simplified" insns, possibly losing the use of a register).  Looking
no deeper than at the results of test-runs with different variants, I
see that the latter "safety latch" has no effect on the test-results
(at 919c9d4bd3db7da0), but it just feels like the right thing to do.
Similarly, there's no effect on test-suite results, to do the same not
just for movdf but for all moves.

gcc:
* config/mmix/mmix.md (MM): New mode_iterator.
("mov<mode>"): New expander to expand for all MM-modes.
("*movqi_expanded", "*movhi_expanded", "*movsi_expanded")
("*movsf_expanded", "*movdf_expanded"): Rename from the
corresponding mov<M> named pattern.  Add to the condition that
either operand must be a register_operand.
("*movdi_expanded"): Similar, but also allow STCO in the condition.
gcc/config/mmix/mmix.md