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