This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/32698] [4.3 regression] inefficient pointer expression
- From: "rguenth at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 9 Jul 2007 15:00:51 -0000
- Subject: [Bug tree-optimization/32698] [4.3 regression] inefficient pointer expression
- References: <bug-32698-14001@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #5 from rguenth at gcc dot gnu dot org 2007-07-09 15:00 -------
Note that we don't hoist the i*4 or the addition to p to help addressing mode
selection which likes to see the "whole" address.
Of course it shouldn't matter in which form we see the addresses and the same
code should be generated for all, still canonicalization to the same form
makes a difference.
In fact, canonicalizing to
unsigned int D.1656;
<bb 2>:
D.1656 = i * 4;
return (*(p + (D.1656 + 8)) + *(p + (D.1656 + 4))) + *(p + (D.1656 + 12));
as you suggest creates worse assembly (look at the extra shift)
foo:
pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %ecx
movl 8(%ebp), %edx
popl %ebp
sall $2, %ecx
movl 8(%ecx,%edx), %eax
addl 4(%ecx,%edx), %eax
addl 12(%ecx,%edx), %eax
ret
in fact the above shows that the proper fix would be in the backend (if
there is anything to fix) and making sure we consistently canonicalize
is good enough. Consider the related testcase
int foo(int *p, short *q, char *r, unsigned int i)
{
return p[i + 1] + q[i + 1] + r[i + 1];
}
which in one case is canonicalized to
unsigned int D.1658;
<bb 2>:
D.1658 = i + 1;
return ((int) *(r + D.1658) + *(p + D.1658 * 4)) + (int) *(q + D.1658 * 2);
in the other to
return ((int) *(r + (i + 1)) + *(p + (i * 4 + 4))) + (int) *(q + (i * 2 +
2));
so there is no form that is clearly better to canonicalize to. But the
correct "form" depends on the context (whether it is profitable to either
CSE i * 4 or i + 1).
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32698