On Fri, Nov 8, 2013 at 10:28 AM, Konstantin Vladimirov <konstantin.vladimirov@xxxxxxxxx> wrote: > 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? IIRC there is some code hoisting in RTL GCSE but not very strong. code-hoisting in GIMPLE via PRE is still in-progress (see PR23286). Richard. > --- > With best regards, Konstantin