[PATCH, middle-end]: Fix PR 38969

Uros Bizjak ubizjak@gmail.com
Mon Jan 26 20:32:00 GMT 2009


As shown in the PR [1], there is a long-standing problem with complex 
arguments for targets that split complex arguments. The problem is, when 
sibcalls are enabled, and the failure path goes this way:

- argument information is initialized in 
initialize_argument_information, where complex argument gets wrapped 
inside SAVE_EXPR before splitting into parts.

- a loop inside expand_call is entered, trying to expand the call as a 
sibling call first. Argumets are expanded through 
precompute_register_parameters, and since SAVE_EXPR expression is 
expanded, its arg gets replaced by a temporary, correctly initialized 
from original argument.

- sibling call fails for some reason, so the sequence is discarded and 
the loop is re-entered for normal call expansion.

- complex arguments are expanded again into a new sequence, but since 
they are wrapped into SAVE_EXPR, they are initialized from a temporary. 
But the initialization of a temporary is gone, it was discarded together 
with the rest of sibcall sequence of a failed sibcall.

- we are left with an uninitialized temporary, In 4.2, it _happens_ by 
pure luck that this temporary gets allocated to correct argument passing 
registers. In 4.3+, dataflow takes care of uninitialized regs by 
initializing them to zero.

Actually, I don't see the reason for wrapping expression into SAVE_EXPR. 
By splitting complex mode into its inner mode parts, it is _guaranteed_, 
that every _part_ of the expression is not evaluated more than once 
(i.e. SCmode value by SFmode access to both parts). So, even if the 
argument is in memory, each part of the location is not accessed more 
than once. FWIW, the same applies to register arguments as well. And 
since these are function arguments, passing either through memory or 
through registers, I'm not sure _what_  would SAVE_EXPR protect...

Attached one-liner fixes this problem by simply removing SAVE_EXPR wrapping.

2009-01-26  Uros Bizjak  <ubizjak@gmail.com>

    PR middle-end/38969
    * calls.c (initialize_argument_information): Do not wrap complex
    arguments in SAVE_EXPR.


2009-01-26  Uros Bizjak  <ubizjak@gmail.com>

    PR middle-end/38969
    * gcc.c-torture/execute/pr38969.c: New test.

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu 
{,-m32} and alphaev56-unknown-linux-gnu.

(The regression test on alpha is still running, but all interesting 
cases already passed.)

OK for 4.4 and 4.3 ?

[1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38969


-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: p.diff.txt
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20090126/c720f202/attachment.txt>

More information about the Gcc-patches mailing list