This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, rtl-optimization]: Fix PR rtl-optimization/33638
- From: "Uros Bizjak" <ubizjak at gmail dot com>
- To: "GCC Patches" <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 8 Oct 2007 14:14:42 +0200
- Subject: [PATCH, rtl-optimization]: Fix PR rtl-optimization/33638
Hello!
This patch fixes the problem with -fforce-addr, where we blindly move
calculation of a function argument stack slot address into the
temporary, but we fail to update REG_DEP_TRUE of a function call,
breaking the dependancy chain.
The failure silently propagates up to dse1 pass, where "unused" stack
slot is removed.
The problem starts at expand, where we generate:
;; bscale = __builtin_powf (2.0e+0, (real4) D.1062)
(insn 1310 1309 1311 t.f:61 (set (reg:SF 646)
(float:SF (reg:SI 182 [ D.1062 ]))) -1 (nil))
(insn 1311 1310 1312 t.f:61 (parallel [
(set (reg/f:SI 647)
(plus:SI (reg/f:SI 56 virtual-outgoing-args)
(const_int 4 [0x4])))
(clobber (reg:CC 17 flags))
]) -1 (nil))
(insn 1312 1311 1313 t.f:61 (set (mem:SF (reg/f:SI 647) [0 S4 A32])
(reg:SF 646)) -1 (nil))
(insn 1313 1312 1314 t.f:61 (set (reg:SF 648)
(mem/u/c/i:SF (symbol_ref/u:SI ("*.LC4") [flags 0x2]) [9 S4
A32])) -1 (nil))
(insn 1314 1313 1315 t.f:61 (set (mem:SF (reg/f:SI 56
virtual-outgoing-args) [0 S4 A32])
(reg:SF 648)) -1 (nil))
(call_insn/u 1315 1314 1316 t.f:61 (set (reg:SF 8 st)
(call (mem:QI (symbol_ref:SI ("powf") [flags 0x41]
<function_decl 0xb7c3a200 __builtin_powf>) [0 S1 A8])
(const_int 8 [0x8]))) -1 (nil)
(expr_list:REG_DEP_TRUE (use (mem/i:SF (reg/f:SI 56
virtual-outgoing-args) [0 S4 A32]))
(expr_list:REG_DEP_TRUE (use (mem/i:SF (plus:SI (reg/f:SI 56
virtual-outgoing-args)
(const_int 4 [0x4])) [0 S4 A32]))
(nil))))
Note, that (call_insn 1315) still refers to "mem (v-o-a + 4)", where
the argument's address is in fact "mem (reg 647)", generated in (insn
1311).
There are two solutions to this problem:
a) update call_insn dependencies with temporary pointer or
b) prevent v-o-a and stack_reg referred addresses to be pushed to a temporary.
Attached patch implements b). Patch was bootstrapped and regression
tested on i686-pc-linux-gnu. OK for mainline?
Unfortunatelly, I was not able to construct short test case, but at
the end of the day, the problem looks kind of obvious.
2007-10-08 Uros Bizjak <ubizjak@gmail.com>
PR rtl-optimization/33638
* explow.c (memory_address): When -fforce-addr is in effect,
do not force addresses using virtual_outgoing_args_rtx or
stack_pointer_rtx to a temporary register.
Uros.
Index: explow.c
===================================================================
--- explow.c (revision 129120)
+++ explow.c (working copy)
@@ -488,7 +488,13 @@ memory_address (enum machine_mode mode,
win2:
x = oldx;
win:
- if (flag_force_addr && ! cse_not_expected && !REG_P (x))
+ if (flag_force_addr && ! cse_not_expected && !REG_P (x)
+ /* Do not force address using v_o_a and SP to a temporary.
+ The code below does not update function call's argument
+ dependencies, so dependency chain is broken when
+ function arguments are passed on the stack. */
+ && ! reg_mentioned_p (virtual_outgoing_args_rtx, x)
+ && ! reg_mentioned_p (stack_pointer_rtx, x))
{
x = force_operand (x, NULL_RTX);
x = force_reg (Pmode, x);