<HTML>
<HEAD>
<TITLE>Re: gcc  4.3.2 vectorizes access to volatile array</TITLE>
</HEAD>
<BODY>
<FONT FACE="Verdana, Helvetica, Arial"><SPAN STYLE='font-size:12.0px'>Seems like a bug, and see this paper for some scary research on compiler volatile handling in general:<BR>
<BR>
<FONT COLOR="#0000FF"><U><a href="http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf">http://www.cs.utah.edu/~regehr/papers/emsoft08-preprint.pdf</a><BR>
</U></FONT><BR>
Ken<BR>
<BR>
> ABSTRACT<BR>
> C’s volatile qualifier is intended to provide a reliable link between<BR>
> operations at the source-code level and operations at the memorysystem<BR>
> level. We tested thirteen production-quality C compilers<BR>
> and, for each, found situations in which the compiler generated<BR>
> incorrect code for accessing volatile variables. This result is disturbing<BR>
> because it implies that embedded software and operating<BR>
> systems - both typically coded in C, both being bases for many<BR>
> mission-critical and safety-critical applications, and both relying<BR>
> on the correct translation of volatiles - may be being miscompiled.<BR>
<BR>
<BR>
<BR>
<BR>
<BR>
On 6/22/09 7:47 AM, "Till Straumann" <strauman@slac.stanford.edu> wrote:<BR>
<BR>
</SPAN></FONT><BLOCKQUOTE><FONT FACE="Verdana, Helvetica, Arial"><SPAN STYLE='font-size:12.0px'>gcc-4.3.2 seems to produce bad code when<BR>
accessing an array of small 'volatile'<BR>
objects -- it may try to access multiple<BR>
such objects in a 'parallel' fashion.<BR>
E.g., instead of reading two consecutive<BR>
'volatile short's sequentially it reads<BR>
a single 32-bit longword. This may crash<BR>
e.g., when accessing a memory-mapped device<BR>
which allows only 16-bit accesses.<BR>
<BR>
If I compile this code fragment<BR>
<BR>
void volarrcpy(short *d, volatile short *s, int n)<BR>
{<BR>
int i;<BR>
  for (i=0; i<n; i++)<BR>
    d[i] = s[i];<BR>
}<BR>
<BR>
<BR>
with '-O3' (the critical option seems to be '-ftree-vectorize')<BR>
then gcc-4.3.2 produces quite complicated code<BR>
but the essential section is (powerpc)<BR>
<BR>
.L7:<BR>
    lhz 0,0(11)<BR>
    addi 11,11,2<BR>
    lwzx 0,4,9<BR>
    stwx 0,3,9<BR>
    addi 9,9,4<BR>
    bdnz .L7<BR>
<BR>
or i386<BR>
<BR>
.L7:<BR>
    movw    (%ecx), %ax<BR>
    movl    (%esi,%edx,4), %eax<BR>
    movl    %eax, (%ebx,%edx,4)<BR>
    incl    %edx<BR>
    addl    $2, %ecx<BR>
    cmpl    %edx, -20(%ebp)<BR>
    ja  .L7<BR>
<BR>
<BR>
Disassembled back into C-code, this reads<BR>
<BR>
uint32_t *dst_l = (uint32_t*)d;<BR>
uint32_t *src_l = (uint32_t*)s;<BR>
<BR>
for (i=0; i<n/2; i++) {<BR>
    d[i]     = s[i];<BR>
    dst_l[i] = src_l[i];<BR>
}<BR>
<BR>
This code seems neither optimal nor correct.<BR>
Besides reading half of the locations twice<BR>
which violates the semantics of volatile<BR>
objects accessing such objects in a 'vectorized'<BR>
way (in this case: instead of reading<BR>
two adjacent short addresses gcc emits<BR>
a single 32-bit read) seems illegal to me.<BR>
<BR>
Similar behavior seems to be present in 4.3.3.<BR>
<BR>
Does anybody have some insight? Should I file<BR>
a bug report?<BR>
<BR>
Regards<BR>
-- Till<BR>
<BR>
PS: I'm not subscribed to the gcc mailing list;<BR>
please CC me on any replies, thanks.<BR>
_______________________________________________<BR>
rtems-users mailing list<BR>
rtems-users@rtems.org<BR>
<a href="http://www.rtems.org/mailman/listinfo/rtems-users">http://www.rtems.org/mailman/listinfo/rtems-users</a><BR>
<BR>
</SPAN></FONT></BLOCKQUOTE><FONT FACE="Verdana, Helvetica, Arial"><SPAN STYLE='font-size:12.0px'><BR>
</SPAN></FONT>
</BODY>
</HTML>