Wrong code generated for big-endian and -O1
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
GNU Arm Embedded Toolchain |
Fix Released
|
High
|
Thomas Preud'homme |
Bug Description
Version: 4.8-2014q2
Host: All
Target: Cortex-R4 big-endian (TMS570)
To reproduce, build this simple test program with -O0, -O1 and -O2:
test.c:
---------
#include <stdio.h>
unsigned short v = 0x5678;
int i;
int j = 0;
int *ptr = &j;
int func()
{
for (i = 0; i < 1; ++i)
{
*ptr = -1;
v = 0x1234;
}
return v;
}
int main (void)
{
int x = func();
printf("x = 0x%x, j = %d, v = 0x%x\n", x, j, v);
return 0;
}
This program outputs (depending on optimization level):
-O0: x = 0x1234, j = -1, v = 0x1234
-O1: x = 0x0, j = -1, v = 0x0
-O2: x = 0x1234, j = -1, v = 0x1234
build commands:
arm-none-eabi-gcc -c test.c -o test0be.o -O0 -march=armv7-r -mbig-endian
arm-none-eabi-gcc -c test.c -o test1be.o -O1 -march=armv7-r -mbig-endian
arm-none-eabi-gcc -c test.c -o test2be.o -O2 -march=armv7-r -mbig-endian
arm-none-
arm-none-
arm-none-
The function func() sets the global variable "unsigned short v" to value 0x1234. We get correct output of the program for -O0 and -O2. Optimization -O1 causes program miscompilation.
object dump (-O1 case only):
00000000 <func>:
0: e3003000 movw r3, #0
4: e3403000 movt r3, #0
8: e3a02000 mov r2, #0
c: e5832000 str r2, [r3]
10: e3001000 movw r1, #0
14: e3401000 movt r1, #0
18: e3e0c000 mvn ip, #0
1c: e1df03b0 ldrh r0, [pc, #48] ; 54 <func+0x54> <== here we load half-word from offset 0x54 where should be 0x1234
20: e1a02003 mov r2, r3
24: e5913000 ldr r3, [r1]
28: e583c000 str ip, [r3]
2c: e1c100b4 strh r0, [r1, #4] <== here we write to global variable v
30: e5923000 ldr r3, [r2]
34: e2833001 add r3, r3, #1
38: e5823000 str r3, [r2]
3c: e3530000 cmp r3, #0
40: dafffff7 ble 24 <func+0x24>
44: e3003000 movw r3, #0
48: e3403000 movt r3, #0
4c: e1d300b4 ldrh r0, [r3, #4]
50: e12fff1e bx lr
54: 00001234 .word 0x00001234 <== loading half-word from this offset results in reading 0x0000 (we're on big-endian)
Changed in gcc-arm-embedded: | |
status: | New → Confirmed |
importance: | Undecided → High |
assignee: | nobody → Thomas Preud'homme (thomas-preudhomme) |
Changed in gcc-arm-embedded: | |
status: | Confirmed → In Progress |
Changed in gcc-arm-embedded: | |
status: | In Progress → Fix Committed |
Changed in gcc-arm-embedded: | |
status: | Fix Committed → In Progress |
Changed in gcc-arm-embedded: | |
status: | In Progress → Fix Committed |
Changed in gcc-arm-embedded: | |
status: | Fix Committed → Fix Released |
milestone: | none → 4.9-2015-q2-update |
This affects latest release toolchain but seems to have been solved in trunk. Or maybe not but the code generated doesn't use a litteral anymore but an immediate instead. Maybe the bug is still latent though.