bitfields miscompiled for big-endian and optimization

Bug #1330388 reported by Petr Cvachouček
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
Fix Released
Medium
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 and with -O1:

test.c:
---------
union U
{
    const int a;
    unsigned b : 20;
};

static union U u = { 0x12345678 };

int main(int argc, char * argv[])
{
    return u.b;
}

The above program, when build without optimization returns value 0x12345 (20 bits starting MSB).
When build with optimization returns value 0x45678 (20 bits starting LSB).

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-objdump -d test0be.o >>test.dump
arm-none-eabi-objdump -d test1be.o >>test.dump

object dump:
test0be.o: file format elf32-bigarm
Disassembly of section .text:

00000000 <main>:
   0: e52db004 push {fp} ; (str fp, [sp, #-4]!)
   4: e28db000 add fp, sp, #0
   8: e24dd00c sub sp, sp, #12
   c: e50b0008 str r0, [fp, #-8]
  10: e50b100c str r1, [fp, #-12]
  14: e3003000 movw r3, #0
  18: e3403000 movt r3, #0
  1c: e5933000 ldr r3, [r3]
  20: e7f33653 ubfx r3, r3, #12, #20 <== bitfield taken from 20 MSB bits
  24: e1a00003 mov r0, r3
  28: e24bd000 sub sp, fp, #0
  2c: e49db004 pop {fp} ; (ldr fp, [sp], #4)
  30: e12fff1e bx lr

test1be.o: file format elf32-bigarm
Disassembly of section .text:

00000000 <main>:
   0: e3050678 movw r0, #22136 ; 0x5678
   4: e3400004 movt r0, #4 <== value 0x45678 pre-calculated
   8: e12fff1e bx lr

Revision history for this message
Petr Cvachouček (cvachoucek) wrote :
Changed in gcc-arm-embedded:
status: New → Confirmed
assignee: nobody → Thomas Preud'homme (thomas-preudhomme)
importance: Undecided → High
Revision history for this message
Thomas Preud'homme (thomas-preudhomme) wrote :

Although I agree the -O1 case is wrong, this code can't expect any specific value when reading b. Indeed, the initialization is made through a which is an integer but read back as a bitfield. Since the way a bitfield is stored is undefined, a given value can be stored in whatever way in a bitfield. The bit endianness could be same or different from the byte endianness for instance.

Changed in gcc-arm-embedded:
importance: High → Medium
Changed in gcc-arm-embedded:
status: Confirmed → Fix Committed
Changed in gcc-arm-embedded:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.