HI to SI mode miss conversion on MIPS.
Hiroyuki Machida
machida@sm.sony.co.jp
Tue Feb 15 20:57:00 GMT 2000
From: Jeffrey A Law <law@cygnus.com>
Subject: Re: HI to SI mode miss conversion on MIPS.
Date: Tue, 15 Feb 2000 13:59:01 -0700
:
:
> > Suppose that 108's nozero_bits is 0xffffffff and those X is set to
> > some SI register.
> >
> > (set (reg:SI 111) (and:SI (ashift:SI (reg:SI 108)
> > (const_int 8 [0x8]))
> > (const_int 65280 [0xff00]))
> >
> > (set (reg:SI 111) (subreg:HI (ashift:SI (reg:SI 108)
> > (const_int 8 [0x8])) 0)
> >
> > The nonzero_bits of 111 correspoding to the first X is 0x0000ff00,
> > but, the second is 0xffffff00.
> > I don't know force_mode() should preserve nonzero_bits or not.
> > But, I guess the problem is cause by ignoring nonzero_bits
> > information somewhere I can't point out.
> But the (subreg:HI) indicates that we don't actually care about the upper
> 16 bits. ie, they're never used/examined.
>
> So, even if nonzero_bits for reg111 in the second case is 0xffffff00 we do
> not care because we know that the upper 16bits are completely unimportant
> for the proper execution of the program.
>
I think so. That is why I think nonzero_bits was porpagated
incorrectly.
Finally I found the problem the order of calling
set_nonzero_bits_and_sign_copies() at try_combine().
Attached is the patch to really fix the problem, I think.
In the orginal combine.c, you can see
/* Update reg_nonzero_bits et al for any changes that may have been made
to this insn. */
note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
But the newi2pat can affect to nonzero_bits of the newpat.
(Of course, the newi2pat is appear earlier than the newpat.)
So I think this order must be inverted.
Actually, I ovserved the following situation using the test program
hisi.c;
The try_combine() tryed to combine arg i1:
(insn/i 76 75 78 (set (reg:SI 112)
(and:SI (reg:SI 108)
(const_int 255 [0xff]))) 135 {andsi3+1} (insn_list 69 (nil))
(nil))
and arg i2:
(insn/i 78 76 79 (set (reg:SI 114)
(ashift:SI (reg:SI 112)
(const_int 8 [0x8]))) 283 {ashlsi3_internal1} (insn_list 76 (nil))
(expr_list:REG_DEAD (reg:SI 112)
(nil)))
into arg i3:
(insn/i 86 85 89 (set (subreg:SI (reg:HI 111) 0)
(ior:SI (reg:SI 114)
(reg:SI 117))) 143 {iorsi3+1} (insn_list 78 (insn_list 81 (nil)))
(expr_list:REG_DEAD (reg:SI 114)
(expr_list:REG_DEAD (reg:SI 117)
(nil))))
The results are
newpat:
(set (reg:HI 111) (subreg:HI (ior:SI (reg:SI 114) (reg:SI 117)) 0))
newi2pat:
(set (reg:SI 114) (ashift:SI (reg:SI 108) (const_int 8 [0x8])))
At the orginal try_combine(), nonzero_bits of reg111 was computed
using old (appeared as i2) nonzero_bits of reg114( 0x0000ff00 ).
But, renonzero_bits of reg114 (appeared as newi2pat) is changed to
0xffffff00. This confusion makes "zero_extend" vanished.
---
Hiroyuki Machida
2000-02-16 Hiroyuki Machida <machida@sm.sony.co.jp>
* combine.c (try_combine): Update reg_nonzero_bits of
newi2pat before newpat. Because reg_nonzero_bits of
newi2pat can affect reg_nonzero_bits of newpat.
*** combine.c.ORG Tue Jan 25 05:10:01 2000
--- combine.c Wed Feb 16 12:57:24 2000
*************** try_combine (i3, i2, i1)
*** 2665,2675 ****
}
/* Update reg_nonzero_bits et al for any changes that may have been made
! to this insn. */
!
! note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
/* If I3 is now an unconditional jump, ensure that it has a
BARRIER following it since it may have initially been a
--- 2665,2675 ----
}
/* Update reg_nonzero_bits et al for any changes that may have been made
! to this insn. The order of set_nonzero_bits_and_sign_copies() is
! important. Because newi2pat can affect nonzero_bits of newpat */
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
+ note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
/* If I3 is now an unconditional jump, ensure that it has a
BARRIER following it since it may have initially been a
More information about the Gcc-bugs
mailing list