Hi,
Consider simple code:
typedef struct
{
unsigned prev;
unsigned next;
} foo_t;
void
foo( unsigned x, unsigned y)
{
foo_t *ptr = (foo_t *)((void *)x);
if (y != 0)
{
ptr->prev = y;
ptr->next = x;
}
else
{
ptr->prev = 0; /* or explicitly ptr->prev = y; no difference */
ptr->next = 0;
}
}
GCC 4.7.2 and 4.8.1 both on O2 and Os creates code like:
testl %esi, %esi
movl %edi, %eax
jne .L5
movl $0, (%edi)
movl $0, 4(%rax)
ret
.L5:
movl %esi, (%edi)
movl %edi, 4(%rax)
ret
Which can be obviously changed to:
testl %esi, %esi
movl %edi, %eax
movl %esi, (%edi)
jne .L5
movl $0, 4(%rax)
ret
.L5:
movl %edi, 4(%rax)
ret
May be there are some options to make it behave so? This is question
for gcc-help group.
Question for gcc group is trickier:
May be in x86 it is not a big deal, but I am working on my private
backend, that have predicated instructions and second form is really
much more prefferable. May be I can somehow tune my backend to achieve
this effect? I can see that 210r.csa pass (try_optimize_cfg before it,
not pass itself) can move code upper in some cases, but only with
very simple memory addressing and rather unstable, say changing
ptr->prev = y;
ptr->next = x;
to
ptr->prev = x;
ptr->next = y;
may break everything just because next is second member and addressed
like M[%r+4].
Any ideas?
---
With best regards, Konstantin