When compiling (-O2) the following code (file attached: bug.c):
#include <inttypes.h>
typedef struct Bar { uint8_t value; } Bar;
void make_bar( Bar* bar, uint32_t code ) { bar->value = (code >> 12) & 0x7f; }
uint32_t
foo( uint32_t code )
{
if ((code & 0xfe000001) == 0x70000001)
{
Bar bar;
make_bar(&bar, code);
return bar.value;
}
return 0;
}
The generated assembly for foo is:
00000008 <foo>:
8: 74 67 07 cd e_rlwinm r7,r3,0,31,6
c: 74 69 a6 6f e_rlwinm r9,r3,20,25,23
10: 71 40 00 00 e_li r10,0
14: 70 6e e0 00 e_lis r3,28672
18: 65 f3 se_bseti r3,31
1a: 0c 37 se_cmp r7,r3
1c: 7c 69 50 9e iseleq r3,r9,r10
20: 00 04 se_blr
The "e_rlwinm r9,r3,20,25,23" is obviously faulty; should be "e_rlwinm r9,r3,20,25,31".
Thus when given 0x70004001, foo returns 0x00170004 whereas it should return 4.
Original Attachment has been moved to: bug.c.zip