------- 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