public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Edelsohn <dje@watson.ibm.com>
To: gcc@gcc.gnu.org
Subject: Load hoisting bug
Date: Fri, 07 Dec 2001 16:01:00 -0000	[thread overview]
Message-ID: <200112080000.TAA22812@makai.watson.ibm.com> (raw)

	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

             reply	other threads:[~2001-12-08  0:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-12-07 16:01 David Edelsohn [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200112080000.TAA22812@makai.watson.ibm.com \
    --to=dje@watson.ibm.com \
    --cc=gcc@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).