<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1">
<title></title>
</head>
<body text="#000000" bgcolor="#ffffff">
Till Straumann wrote:<br>
<blockquote type="cite" cite="mid4732BBF0.6020703@slac.stanford.edu">Today,
I was again hit by the alias rule when a driver
<br>
stopped working.
</blockquote>
I really do not see this as an evil b/c I have seen the worst. <span
class="moz-smiley-s1"><span> :-) </span></span><br>
I think most people are using -fno-strict-aliasing except<br>
it is forgotten to be updated in the release,<br>
where all the makefile are for the BSP (e.g. make/custom).<br>
The make/custom is not where each BSP is. Thus it is easy<br>
to be ignored. However, the compiling warning message<br>
without the -fno-strict-aliasing option could be so ugly that<br>
one could simply update the makefile for the system<br>
without thinking.<br>
<br>
I had a look at the mvme5500.cfg and found out that <br>
I have been using the -fno-strict-aliasing option. However,<br>
it was not updated in the CVS. I will submit a PR <br>
for the mvme5500.cfg. However, this does not imply<br>
that -fno-strict-aliasing will solve all alias problems.<br>
<br>
Kate<br>
<br>
<blockquote type="cite" cite="mid4732BBF0.6020703@slac.stanford.edu"><br>
<br>
I have a driver which uses
<br>
<br>
#include <libcpu/byteorder.h>
<br>
<br>
/* Driver defines helper inline function for swapping to LE */
<br>
<br>
static inline uint32_t
<br>
swp32(uint32_t v)
<br>
{
<br>
unsigned rval;
<br>
st_le32(&rval,v);
<br>
return rval;
<br>
}
<br>
<br>
and the driver then does things, simplified:
<br>
<br>
void test(uint32_t *buf)
<br>
{
<br>
buf[0] = swp32(0xdeadbeef);
<br>
buf[1] = swp32(0xcafecafe);
<br>
}
<br>
<br>
<br>
However, recently Ralf changed byteorder.h so that st_le32 is no
<br>
longer
<br>
<br>
static inline void st_le32( volatile unsigned *a, unsigned v);
<br>
<br>
but it is now
<br>
<br>
static inline void st_le32( volatile uint32_t *a, unsigned v);
<br>
<br>
which introduces a violation of the alias rule into 'swp32'.
<br>
The compiler now may assume that st_le32 does not modify
<br>
'rval' above because according to the alias rule
<br>
the pointer argument to st_le32 must not alias 'rval'
<br>
since rval is unsigned and the pointer
<br>
is a pointer to uint32_t which are incompatible.
<br>
<br>
Indeed, gcc-4.2.2 does use that assumption (it warns about
<br>
incompatible pointer types but gives no type-punnning warning).
<br>
<br>
Just another example for how a small change (in this case:
<br>
to the byteorder.h header) can have big effects that are
<br>
hard to track down.
<br>
<br>
How many more of these incidents do we need to convince
<br>
you to use -fno-strict-aliasing (linux uses it) ?
<br>
<br>
More detailed description attached...
<br>
<br>
-- Till
<br>
<pre wrap="">
<hr width="90%" size="4">
#include <stdint.h>
/* This is from <libcpu/byteorder.h>; type was changed
* recently changed (vers. 1.6 -> 1.7)
*
* from
* volatile unsigned *
* to
* volatile uint32_t *
*
*/
static inline void st_le32(volatile uint32_t *a, unsigned v)
{
__asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*a) : "r" (v), "r" (a));
}
/* Some Driver defines inline function for swapping to LE */
static inline uint32_t
swp32(uint32_t v)
{
unsigned rval __attribute__((may_alias));
/* Change of types in byteorder.h introduces
* violation of alias rule here; compiler assumes
* unsigned cannot alias uint32_t
*/
st_le32((volatile uint32_t*)&rval,v);
return rval;
}
void test(uint32_t *buf)
{
buf[0] = swp32(0);
/* Gcc assumes pointer passed to st_le32() cannot't alias
* 'rval' above and therefore it stores a cached value
* in buf[1].
*/
buf[1] = swp32(1);
/*
00000000 <test>:
0: 94 21 ff e8 stwu r1,-24(r1)
4: 38 00 00 00 li r0,0
8: 39 21 00 08 addi r9,r1,8
c: 7c 00 4d 2c stwbrx r0,0,r9
10: 81 61 00 08 lwz r11,8(r1)
14: 38 00 00 01 li r0,1
18: 91 63 00 00 stw r11,0(r3)
1c: 7c 00 4d 2c stwbrx r0,0,r9
20: 38 21 00 18 addi r1,r1,24
24: 91 63 00 04 stw r11,4(r3)
28: 4e 80 00 20 blr
which corresponds to
rval = bytereverse(0)
buf[0] = rval;
buf[1] = rval;
rval = bytereverse(1)
*/
}
</pre>
<pre wrap="">
<hr width="90%" size="4">
_______________________________________________
rtems-users mailing list
<a class="moz-txt-link-abbreviated" href="mailto:rtems-users@rtems.com">rtems-users@rtems.com</a>
<a class="moz-txt-link-freetext" href="http://rtems.rtems.org/mailman/listinfo/rtems-users">http://rtems.rtems.org/mailman/listinfo/rtems-users</a>
</pre>
</blockquote>
<br>
</body>
</html>