public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Load hoisting bug
@ 2001-12-07 16:01 David Edelsohn
  2001-12-07 16:49 ` Richard Henderson
  2001-12-07 16:49 ` law
  0 siblings, 2 replies; 6+ messages in thread
From: David Edelsohn @ 2001-12-07 16:01 UTC (permalink / raw)
  To: gcc

	We have not had enough fun with loop optimizations lately, so I
found one...

	The divconst-3.c regression on AIX which appeared at the beginning
of November is due to GCC miscompiling itself.  The miscompilation is
caused by a loop optimization which was not safe.

Prior to loop optimization:

(note 47 177 53 NOTE_INSN_LOOP_BEG)

(insn 68 66 69 (set (reg:SI 4 r4)
        (subreg:SI (reg/v:DI 119) 4)) 289 {*movsi_internal1} (nil)
    (nil))

(insn 69 68 71 (parallel[ 
            (set (reg:DI 3 r3)
                (mult:DI (sign_extend:DI (reg:SI 3 r3))
                    (sign_extend:DI (reg:SI 4 r4))))
            (clobber (scratch:SI))
            (clobber (reg:SI 0 r0))
        ] ) 76 {mull_call} (nil)
    (nil))

After loop optimization:

Insn 68: regno 4 (life 1), savings 1  moved to 178

(insn 178 177 179 (set (reg:SI 4 r4)
        (subreg:SI (reg/v:DI 119) 4)) -1 (nil)
    (nil))

(note 47 205 202 NOTE_INSN_LOOP_BEG)

(insn 69 66 71 (parallel[ 
            (set (reg:DI 3 r3)
                (mult:DI (sign_extend:DI (reg:SI 3 r3))
                    (sign_extend:DI (reg:SI 4 r4))))
            (clobber (scratch:SI))
            (clobber (reg:SI 0 r0))
        ] ) -1 (nil)
    (nil))


scan_loop() decides that it can move the SET of r4 out of the loop,
placing it on the move_movables list.

	The register only is used within the loop (prior to register
allocation).  loop_invariant_p() returns true which seems incorrect to me.
The value is invariant, but the register is not invariant.

(set (reg:DI 3) ...) uses the register pair r3 and r4 on a 32-bit target!
The instruction clobbers r3, so it needs to be restored on each iteration
(as gcc-3.0 correctly performed), but the mainline now is hoisting the
load out of the loop although the register is modified in the loop.  The
loop information array has r4 listed as set_in_loop=1.

	Is GCC getting confused by the use of a hard register?  Is GCC
getting confused because of DImode?  The pattern could explicitly clobber
r4, but GCC should know that DImode requires a pair of GPRs.

	I still am trying to figure out the origin of the problem.  Any
guidance would be appreciated.

Thanks, David

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2001-12-13 21:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-07 16:01 Load hoisting bug David Edelsohn
2001-12-07 16:49 ` Richard Henderson
2001-12-07 16:49 ` law
2001-12-07 16:50   ` Richard Henderson
2001-12-13 10:42     ` David Edelsohn
2001-12-13 13:26       ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).