[Bug rtl-optimization/33638] [4.3 regression]: wrong code with -fforce-addr
ubizjak at gmail dot com
gcc-bugzilla@gcc.gnu.org
Fri Oct 5 10:47:00 GMT 2007
------- Comment #9 from ubizjak at gmail dot com 2007-10-05 10:47 -------
> Hope this helps.
Sure, I've got the problem. The problem is actually in RTL optimization, where
dse1 pass removes wrong insn.
Suprisingly, the problem is in line 61 of comunpack.f:
--> bscale = 2.0**real(idrstmpl(2))
dscale = 10.0**real(-idrstmpl(3))
This expands into:
=====8<=====
;; bscale = __builtin_powf (2.0e+0, (real4) D.1062)
(insn 1310 1309 1311 pr33638.f:61 (set (reg:SF 646)
(float:SF (reg:SI 182 [ D.1062 ]))) -1 (nil))
(insn 1311 1310 1312 pr33638.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 pr33638.f:61 (set (mem:SF (reg/f:SI 647) [0 S4 A32])
(reg:SF 646)) -1 (nil))
(insn 1313 1312 1314 pr33638.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 pr33638.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 pr33638.f:61 (set (reg:SF 8 st)
(call (mem:QI (symbol_ref:SI ("powf") [flags 0x41] <function_decl
0xb7c1c200 __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))))
=====>8=====
and in the second powf call, we have similar sequence with (insn 1321) and
(insn 1322):
=====8<=====
(insn 1321 1320 1322 pr33638.f:62 (parallel [
(set (reg/f:SI 653)
(plus:SI (reg/f:SI 56 virtual-outgoing-args)
(const_int 4 [0x4])))
(clobber (reg:CC 17 flags))
]) -1 (nil))
(insn 1322 1321 1323 pr33638.f:62 (set (mem:SF (reg/f:SI 653) [0 S4 A32])
(reg:SF 652)) -1 (nil))
=====>8=====
Important instructions are (insn 1311) - calculation of ebp+4, (insn 1312) -
store to calculated address and equivalent (insn 1321) and (insn 1322). First,
gcse1 pass correctly eliminates (insn 1311) and (insn 1321), so we got:
=====8<=====
(insn 1310 1309 1312 150 pr33638.f:61 (set (reg:SF 646)
(float:SF (reg:SI 182 [ D.1062 ]))) 148 {*floatsisf2_i387}
(expr_list:REG_DEAD (reg:SI 182 [ D.1062 ])
(nil)))
(insn 1312 1310 1313 150 pr33638.f:61 (set (mem:SF (reg/f:SI 755) [0 S4 A32])
(reg:SF 646)) 66 {*movsf_1} (expr_list:REG_DEAD (reg:SF 646)
(nil)))
(insn 1313 1312 1314 150 pr33638.f:61 (set (reg:SF 648)
(mem/u/c/i:SF (symbol_ref/u:SI ("*.LC4") [flags 0x2]) [9 S4 A32])) 66
{*movsf_1} (expr_list:REG_EQUAL (const_double:SF -2147483648 [0x80000000]
2.0e+0 [0x0.8p+2])
(nil)))
(insn 1314 1313 1315 150 pr33638.f:61 (set (mem:SF (reg/f:SI 7 sp) [0 S4 A32])
(reg:SF 648)) 66 {*movsf_1} (expr_list:REG_DEAD (reg:SF 648)
(nil)))
(call_insn/u 1315 1314 1316 150 pr33638.f:61 (set (reg:SF 8 st)
(call (mem:QI (symbol_ref:SI ("powf") [flags 0x41] <function_decl
0xb7c1c200 __builtin_powf>) [0 S1 A8])
(const_int 8 [0x8]))) 611 {*call_value_0} (nil)
(expr_list:REG_DEP_TRUE (use (mem/i:SF (reg/f:SI 7 sp) [0 S4 A32]))
(expr_list:REG_DEP_TRUE (use (mem/i:SF (plus:SI (reg/f:SI 7 sp)
(const_int 4 [0x4])) [0 S4 A32]))
(nil))))
...
(insn 1322 1320 1323 150 pr33638.f:62 (set (mem:SF (reg/f:SI 755) [0 S4 A32])
(reg:SF 652)) 66 {*movsf_1} (expr_list:REG_DEAD (reg/f:SI 755)
(expr_list:REG_DEAD (reg:SF 652)
(nil))))
=====>8=====
where (reg 755) in (insn 1312) is correctly marked as live-in register:
;; live in 6 [bp] 7 [sp] 16 [argp] 20 [frame] 137 138 139 140 142 181 182
188 189 749 755
;; live gen 8 [st] 17 [flags] 646 648 649 651 652 654 655
;; live kill 17 [flags]
We proceed to dse1 pass where (insn 1312):
**scanning insn=1312
mem: (reg/f:SI 755)
expanding: r755 into: NULL
after cselib_expand address: (reg/f:SI 755)
after canon_rtx address: (reg/f:SI 755)
varying cselib base=2 offset = 0
processing cselib store [0..4)
mems_found = 1, cannot_delete = false
and (insn 1322):
**scanning insn=1322
mem: (reg/f:SI 755)
expanding: r755 into: NULL
after cselib_expand address: (reg/f:SI 755)
after canon_rtx address: (reg/f:SI 755)
varying cselib base=2 offset = 0
processing cselib store [0..4)
trying store in insn=1312 gid=-1[0..4)
Locally deleting insn 1312
deferring deletion of insn with uid = 1312.
mems_found = 1, cannot_delete = false
This is wrong. dse1 pass should _not_ remove (insn 1312). (insn 1322) is
storing to the same address as (insn 1312), but we have a call to powf in
between, so new store insn doesn't kill previous store.
Confirmed as a regression on i686-pc-linux-gnu on comunpack.f using '-O2
-march=pentium4 -fforce-addr'
--
ubizjak at gmail dot com changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Component|middle-end |rtl-optimization
Ever Confirmed|0 |1
GCC target triplet| |i686-pc-linux-gnu
Last reconfirmed|0000-00-00 00:00:00 |2007-10-05 10:47:20
date| |
Summary|optimization bug: wrong code|[4.3 regression]: wrong code
|with -fforce-addr |with -fforce-addr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33638
More information about the Gcc-bugs
mailing list