[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