------- 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