https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91131

            Bug ID: 91131
           Summary: Bad bitfield coalescing
           Product: gcc
           Version: 8.3.0
               URL: http://knaldgas.dk/~pdj/bitfields/
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pdj at knaldgas dot dk
  Target Milestone: ---

In both C and Ada, bitfield coalescing does not work right, or at least not
optimal. Since the issue manifests itself in the same way in both C and Ada
front-ends, and on ARM, AVR and X86_64 back-ends, I presume that that the issue
must lie somewhere in between. Please see past that C bitfields are defective
by definition; Ada's definition is pretty well-defined.
Seen on GCC version 4.9.3, 8.3.0 and reportedly also on 9.1.

The key point below is that all assignments have a data-width of less or equal
the machines data-width, and can be fully evaluated at compile time.

Pseudo-code:
type Rec_Type record
  A: 3 bits
  B: 1 bit
  C: 4 bits
end (packed, 8-bit wide)

volatile Rec_A : Rec_Type
volatile Rec_B : Rec_Type
volatile Rec_C : Rec_Type

Rec_A := (A => 0, B => 1, C => 0)
results in one pre-calculated constant byte being assigned directly. This is
the way all such assignments should be.

Rec_B := (A => 1, B => 1, C => 1)
results in one pre-calculated value being stored in a memory location, which is
then ĺoaded and assigned to Rec_B. Unnecessary memory consumption.

Rec_C := (A => 0, B => 0, C => 0)
results in Read, Modify, Write for each field (3 times). Horrible, and may
cause defective execution if Reg_C is a peripheral register! Reading a register
does not always give the last value written to it. Also Writing bits in
"random" order may cause malfunction of the device.

In Ada the Reg_C problem can be mitigated by using pragma Atomic instead, this
still causes a memory location to be used for the evaluated constant that could
just as well be loaded as an immediate.

I've uploaded sources, preprocessed file and Makefile/GPR to this location:
http://knaldgas.dk/~pdj/bitfields/ - The c-file is just compiled with gcc
-O<whatever> -c main.c

Pretty odd that three similar assignments can give three different kinds of
code generation...

Reply via email to