------- Comment #1 from ubizjak at gmail dot com  2009-01-17 17:04 -------
The problem is in a thinko in alias.c, base_alias_check (). For our problematic
addresses, we enter base_alias_check with:

x = (reg:DI 18 $18 [ i ])

and 

y = (and:DI (reg/f:DI 16 $16 [orig:69 __result ] [69])
      (const_int -8 [0xfffffffffffffff8]))

We actually have the code that handles this situation, just after the comment: 

  /* The base addresses of the read and write are different expressions.
     If they are both symbols and they are not accessed via AND, there is
     no conflict.  We can bring knowledge of object alignment into play
     here.  For example, on alpha, "char a, b;" can alias one another,
     though "char a; long b;" cannot.  */

At the start of this code, we have:

base_x = (address (reg:DI 18 $18))

and

base_y = (address (reg:DI 16 $16))

These RTXes should trigger the code that analyses addresses involving AND
operation. So, actually we have to reverse the guarding condition!

Following patch fixes the failure:

--cut here--
Index: alias.c
===================================================================
--- alias.c     (revision 143461)
+++ alias.c     (working copy)
@@ -1527,7 +1527,7 @@ base_alias_check (rtx x, rtx y, enum mac
      no conflict.  We can bring knowledge of object alignment into play
      here.  For example, on alpha, "char a, b;" can alias one another,
      though "char a; long b;" cannot.  */
-  if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
+  if (GET_CODE (x_base) == ADDRESS || GET_CODE (y_base) == ADDRESS)
     {
       if (GET_CODE (x) == AND && GET_CODE (y) == AND)
        return 1;
--cut here--

Now, the scheduler creates correct schedule:

;;       12-->    17 $7=$17|$8                         :(ev4_ib0+ev4_ebox)
;;       13-->    21 $4=unspec[$7,0x40,$16] 2          :(ev4_ib0+ev4_ebox)
;;       14-->    22 $5=$7<<$16<<0x3                   :(ev4_ib0+ev4_ebox)
;;       15-->    25 $3=$6|$4                          :(ev4_ib0+ev4_ebox)
;;       15-->    27 [$16+0x7&0xfffffffffffffff8]=$3   :(ev4_ib1+ev4_abox)
;;       16-->    26 $0=$2|$5                          :(ev4_ib0+ev4_ebox)
;;       16-->    28 [$16&0xfffffffffffffff8]=$0       :(ev4_ib1+ev4_abox)
;;       17-->    30 [$18]=$1                          :(ev4_ib1+ev4_abox)
;;       18-->    45 return                        
:(ev4_ib1+ev4_bbox),ev4_bbox

And the asm is correct:

w_:
        .frame $30,0,$26,0
        ldah $29,0($27)         !gpdisp!1
        lda $29,0($29)          !gpdisp!1
$w_..ng:
        .prologue 1
        ldah $25,$LC0($29)              !gprelhigh
        cpys $f31,$f31,$f31
        lda $22,$LC0($25)               !gprellow
        ldq_u $21,7($16)
        and $22,7,$20
        ldq_u $24,$LC0($25)             !gprellow
        ldq_u $23,7($22)
        bis $31,$31,$31
        mskqh $21,$16,$6
        ldq_u $19,0($16)
        extql $24,$22,$17
        extqh $23,$22,$8
        mskql $19,$16,$2
        cmoveq $20,0,$8
        lda $1,8($31)
        bis $17,$8,$7
        insqh $7,$16,$4
        insql $7,$16,$5
        bis $6,$4,$3
        stq_u $3,7($16)
        bis $2,$5,$0
        stq_u $0,0($16)
        stl $1,0($18)
        ret $31,($26),1
        .end w_


-- 

ubizjak at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|unassigned at gcc dot gnu   |ubizjak at gmail dot com
                   |dot org                     |
             Status|UNCONFIRMED                 |ASSIGNED
     Ever Confirmed|0                           |1
   Last reconfirmed|0000-00-00 00:00:00         |2009-01-17 17:04:31
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38879

Reply via email to