This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix handling of call clobbering readonly-result
Richard Earnshaw wrote:
> The fundamental failure is coming from an incorrect cse'ing of the calls
> to test3.
Thanks for the feedback. Your analysis about cse doing something wrong
appears confirmed in the RTL dumps for my reduced case with
positive/negative functions (see below).
> Unfortunately, I don't know enough about CSE to begin to fix this :-(
Neither do I. I gave it a try and will keep searching, but Richard Kenner's
help would be welcome at this point.
Richard (Kenner), could you please give a hand here ? A description of the
problem follows. Thanks in advance.
For this testcase:
int negative (int x)
{
return (x < 0);
}
int positive (int x)
{
return (x > 0);
}
int main()
{
int x;
x = 80;
if (negative (x))
abort ();
if (! positive (x))
abort ();
x = 100;
if (negative (x))
abort ();
if (! positive (x))
abort ();
return 0;
}
An arm-elf cross compiler from the current sources generates wrong O2 code,
missing the second call to "positive".
The .cse2 dump excerpts below show the anomaly: the first call's return value
(pseudo 53) is reused as the result of the second call.
(call_insn/u 36 35 37 2 0x401d4738 (parallel [
(set (reg:SI 0 r0)
(call (mem:SI (symbol_ref:SI ("^positive")...
(const_int 0 [0x0])))
(use (const_int 0 [0x0]))
(clobber (reg:SI 14 lr))
]) 190 {*call_value_symbol} (nil)
(expr_list:REG_EH_REGION (const_int -1 [0xffffffff])
(nil))
(expr_list (use (reg:SI 0 r0 [ x ]))
(nil)))
(insn 37 36 40 2 0x401d4738 (set (reg:SI 53) <===
(reg:SI 0 r0)) 124 {*arm_movsi_insn} (nil) <===
(insn_list:REG_RETVAL 35
(expr_list:REG_EQUAL (expr_list (symbol_ref:SI ("^positive"))
(expr_list (reg/v:SI 49 [ x ])
(nil)))
(nil))))
[...]
(call_insn/u 74 73 75 6 0x401d4738 (parallel [
(set (reg:SI 0 r0)
(call (mem:SI (symbol_ref:SI ("^positive")...
(const_int 0 [0x0])))
(use (const_int 0 [0x0]))
(clobber (reg:SI 14 lr))
]) 190 {*call_value_symbol} (nil)
(expr_list:REG_EH_REGION (const_int -1 [0xffffffff])
(nil))
(expr_list (use (reg:SI 0 r0 [ x ]))
(nil)))
(insn 75 74 78 6 0x401d4738 (set (reg:SI 57)
(reg:SI 53)) 124 {*arm_movsi_insn} (nil) <===
(insn_list:REG_RETVAL 73
(expr_list:REG_EQUAL (expr_list (symbol_ref:SI ("^positive"))
(expr_list (reg/v:SI 49 [ x ])
(nil)))
(nil))))
(insn 78 75 91 6 0x401d4738 (set (reg:CC 24 cc)
(compare:CC (reg:SI 53) <===
(const_int 0 [0x0]))) 162 {*arm_cmpsi_insn} (nil)
(nil))