[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gcc compiler bug (sparc, ppc)



Ralf Corsepius wrote:
> On Wed, 2007-05-23 at 06:30 -0500, Joel Sherrill wrote:
>   
>> Sergei Organov wrote:
>>     
>>> Till Straumann <strauman at slac.stanford.edu> writes:
>>>   
>>>       
>>>> I found that gcc produces bad code for the
>>>> following example:
>>>>
>>>> struct node {
>>>>      struct node *next, *prev;
>>>> };
>>>>
>>>> void xtract(struct node *x)
>>>> {
>>>> struct node *n, *p;
>>>>     n = x->n;
>>>>     p = x->p;
>>>>     n->prev = p;
>>>>     p->next = n;
>>>> }
>>>>     
>>>>         
>>> This doesn't compile:
>>>
>>> np.c: In function ?xtract?:
>>> np.c:8: error: ?struct node? has no member named ?n?
>>> np.c:9: error: ?struct node? has no member named ?p?
>>>
>>> I think you mean:
>>>
>>> void xtract(struct node *x)
>>> {
>>>     struct node *n, *p;
>>>     n = x->next;
>>>     p = x->prev;
>>>     n->prev = p;
>>>     p->next = n;
>>> }
>>>
>>> right?
>>>
>>>   
>>>       
>> Changing the structure definition to make the pointers volatile appears
>> to result in correct code.
>>     
> IMO, this is bad advice, these ain't no volatiles.
>   
Not in the general sense but this looks remarkably like the RTEMS chain code
and the intent there was very simple.  The code was originally in assembly
language and we really meant each memory load or store to occur. 

I would go so far as to assert that most of the RTEMS SuperCore and
APIs are written with this intent.  It was written as C that is just 
marginally
above assembly language.  RTEMS generally has very simple C statements.
> Till, please ask on gcc@
>
>   
>>>> powerpc-rtems-gcc -O -fschedule-insns -fno-strict-aliasing
>>>> (version 4.1.1) produces:
>>>>     
>>>>         
>>> [...]
>>>   
>>>       
>>>> The order of the last two assignments was swapped
>>>> which makes a difference in the special case where &p->next and
>>>> &n->prev are addressing the same location but n != p.
>>>>     
>>>>         
>>> You mean when *n and *p overlap like this?:
>>>
>>>   n ->  |next|prev|
>>>   p ->       |next|prev|
>>>
>>>   
>>>       
>>>> The bug is apparently triggered by -fschedule-insns; if I turn
>>>> on all other optimizations (including -fstrict-aliasing) correct
>>>> code is generated.
>>>>     
>>>>         
>>> -fstrict-aliasing should have no effect here, I think, as all the
>>> pointers involved have the same type and are therefore allowed to alias
>>> each other anyway.
>>>
>>> PPC GCC 2.95.2 seems to produce correct code using
>>>
>>> powerpc-rtems-gcc -O -fschedule-insns -fno-strict-aliasing:
>>>
>>> xtract:
>>> 	lwz %r11,0(%r3) # r11 = n = x->next
>>> 	lwz %r9,4(%r3)  # r9  = p = x->prev
>>> 	stw %r9,4(%r11) # n->prev = p
>>> 	stw %r11,0(%r9) # p->next = n
>>> 	blr
>>>
>>>
>>> Overall, it looks like gcc bug indeed. Did you file bug-report?
>>>
>>> -- Sergei.
>>> _______________________________________________
>>> rtems-users mailing list
>>> rtems-users at rtems.com
>>> http://rtems.rtems.org/mailman/listinfo/rtems-users
>>>   
>>>       
>> _______________________________________________
>> rtems-users mailing list
>> rtems-users at rtems.com
>> http://rtems.rtems.org/mailman/listinfo/rtems-users
>>     
>
>