The ivopts pass fails to set the REG_POINTER attribute on a pseudo that is equal to two pseudos, one of which has teh REG_POINTER attribute and the other is just a n offset from it. This leads us to not sort the operands on an indexed load/store instruction causing performance problems on POWER6.
The test case used to recreate the problem is: linux> cat > bug.c <<EOF unsigned int *quadrant; unsigned int fullGtU (int i1, int n) { unsigned int s1 = 0; for (; n >= 0; n--) { s1 = quadrant[i1]; i1 += n; } return s1; } EOF linux> /path/to/gcc -O1 -S -da bug.c Resulting assembly: fullGtU: li 0,0 cmpwi 0,4,0 blt 0,.L3 lis 9,[EMAIL PROTECTED] lwz 11,[EMAIL PROTECTED](9) addi 0,4,1 mtctr 0 addi 0,4,-1 cmpwi 7,0,-1 bge+ 7,.L4 li 0,1 mtctr 0 .L4: slwi 9,3,2 lwzx 0,9,11 <- bad operand ordering add 3,3,4 addi 4,4,-1 bdnz .L4 .L3: mr 3,0 blr Bad RTL in bug.c.127r.expand: (insn 21 20 22 bug.c:8 (set (reg/f:SI 129) (plus:SI (reg:SI 128) (reg:SI 121 [ quadrant.0 ]))) -1 (nil)) (insn 22 21 0 bug.c:8 (set (reg/v:SI 120 [ s1 ]) (mem:SI (reg/f:SI 129) [0 S4 A32])) -1 (nil)) Eventually, pseudo 129 )which has the REG_POINTER attribute) gets exchanged with the (plus:SI (reg:SI 128) (reg:SI 121 [ quadrant.0 ])) and pseudo 121 doesn't have the attribute, so we end up failing to swap them. -- Summary: ivopts fails to set REG_POINTER attribute on pseudo Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bergner at gcc dot gnu dot org GCC build triplet: powerpc64-linux GCC host triplet: powerpc64-linux GCC target triplet: powerpc64-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32940