On 11/20/2015 02:19 AM, Nick Clifton wrote:
Hi Jeff,
The code there would solve this problem, but the approach is is overly
cautious, since it disables the optimization for all extensions that
increase the number of hard registers used. Some of these will be
viable candidates, provided that the extra hard registers are no used.
(This is certainly true for the RL78, where the (patched) optimization
does improve code, even though the widening does use extra registers).
Nick -- can you pass along your testcode?
Sure - this is for the RL78 toolchain. In theory the problem is
generic, but I have not tested other toolchains.
Compile the gcc.c-torture/execute/pr42833.c or
gcc.c-torture/execute/strct-stdarg-1.c tests at -O1 or higher with -free
also specified on the command line. Without -free these tests pass.
With -free they fail.
So this looks like a pretty fundamental failing in ree.c and AFAICT has
been there since day 1. Thankfully, I don't think it's likely to
trigger all that often.
It's useful to ponder two cases. One where we're going to add a copy
and one where we don't. I added the copy case during the 4.9 cycle as
an extension of existing code. It only fires in easy to analyze
circumstances -- when the original set and the extension are in the same
basic block, but have different destination registers.
In the copy case. The code checks that the destination of the
*extension* is neither used nor set between the original set and the
extension. So in the case of multi-word hard reg, we'll verify that the
entire multi-word hard reg survives from the original insn to the
extension. That avoids this problem in cases where a copy is needed.
However, in the case where no copy is needed, no such checks are made.
In fact the checks could be fairly painful as the original set and the
extension can be in different blocks with arbitrary flow between them.
I would hazard a guess that the authors simply didn't consider the
multi-hard reg case. Essentially if the original set reached an
extension, then obviously the original set got there unharmed and the
extended destination should reach as well -- except that doesn't apply
to multi-word hard regs.
Given the expense in checking all the potential paths between the
original set and the extension, I think just disallowing this case ought
to be is the best way to go. Ideally we'll filter out that case before
we get to combine_set_extension. But if we can't, it's easy enough to
test there.
Jeff