avr-gcc-list
[Top][All Lists]
Advanced

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

Re: [avr-gcc-list] Re: C aliasing rules


From: Wouter van Gulik
Subject: Re: [avr-gcc-list] Re: C aliasing rules
Date: Wed, 19 May 2010 21:05:00 +0200
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100423 Thunderbird/3.0.4

Hi all,

This might be due to bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39635
or the still open http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39386.
It is about an error on shifting/inline/return values, it might be this that is code triggers the same bug
Although I thought it was fixed it was not fixed in 4.4 the comments says.

HTH,

Wouter

On 19/05/10 14:10, Lars Noschinski wrote:
Hello!

* David Brown<address@hidden>  [10-05-18 21:01]:

Thanks for your answer, David.

Lars Noschinski wrote:
I'm trying to debug a strange problem, which depends on whether a
function is inlined (then it's broken) or not (then it's ok). Can
someone tell me if the following code snippet violates the C aliasing
rules for b1 (declared as uint8_t*, written as uint32_t* by
xteaDecrypt)?
[...]
It's not impossible that this is a bug when inlining such complex
code (and 32-bit code like this is complex on an 8-bit micro).  It's
difficult to tell without a compilable code snippet, and some
indication of the expected results.  If you can, you should look at
the generated assembly to see if you can figure out what is going
wrong.  Also try to simplify or remove parts of the code until you
have a minimal example of the problem.

While it would be useful to find out about the problem (especially
if it is a bug that is not already known), code like this does not
benefit much from being inlined.  It's too complex, and requires too
many registers - the function call overhead is therefore minimal.
You could improve the results somewhat by manual restructuring
(perhaps eliminating the memcpy calls), but unless XTEA_ROUNDS is
very small, the loop there will dominate everything.
XTEA_ROUNDS is 32 and this code is far from being performance critical,
but code breaking with optimization always makes me nervous ;)

Reading more about strict aliasing issues, especially

     
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
     http://davmac.wordpress.com/2010/02/26/c99-revisited/

I'm fairly sure, that accessing a uint8_t[] via a uint32_t* constitutes
undefined behaviour; the same holds for converting the pointer by use of an
union { uint32_t[2]; uint8_t[8] }; by the gcc (4.3.4) documentation for
-fstrict-aliasing:

|     Similarly, access by taking the address, casting the resulting
|     pointer and dereferencing the result has undefined behavior, even
|     if the cast uses a union type, e.g.:
|          int f() {
|            double d = 3.0;
|            return ((union a_union *)&d)->i;
|          }

So it seems the only correct way is either changing the declaration of
xteaDecryptCbc (i.e. use uint32_t from the beginning) or using memcpy.
Or maybe some playing around with __attribute__((may_alias)).

OTOH, this problem also occurs with -fno-strict-aliasing, so maybe there
is some real bug down there in the compiler. I'll try analyising it
later.

If I read http://mail-index.netbsd.org/tech-kern/2003/08/11/0001.html
correctly, it should violate the rules?

// ---------------------------------------------------------------------------
void xteaDecrypt(uint32_t v[2], uint32_t const k[4]) {
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*XTEA_ROUNDS;
    for (uint8_t i=0; i<  XTEA_ROUNDS; i++) {
        v1 -= (((v0<<  4) ^ (v0>>  5)) + v0) ^ (sum + k[(sum>>11)&  3]);
        sum -= delta;
        v0 -= (((v1<<  4) ^ (v1>>  5)) + v1) ^ (sum + k[sum&  3]);
    }
    v[0]=v0; v[1]=v1;
}

void xteaDecryptCbc(uint8_t v[8], uint8_t cb[8], uint8_t const k[16]) {
    static uint8_t tmpbuf[8];
    memcpy(tmpbuf, v, 8);
    xteaDecrypt((uint32_t*)v, (uint32_t*)k);
    for (uint8_t i=0; i<  8; i++)
        v[i] ^= cb[i];
    memcpy(cb, tmpbuf, 8);
}

int main(void) {
    uint8_t b1[8], b2[8], b3[16];
    xteaDecryptCbc(b1, b2 b3);
}
// ---------------------------------------------------------------------------
   -- Lars

_______________________________________________
AVR-GCC-list mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list




reply via email to

[Prev in Thread] Current Thread [Next in Thread]