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