Hi Jeff, Hi Kazu,

  We have run across an H8300 RTL generation bug which I think might be
  generic, rather than specific to the H8300, although it may only
  trigger for small targets.

  Given the following source file:

    struct fields { unsigned long long u2 : 33; } flags;

    int main (void) { flags.u2 = 0x1FFFFFFFFULL; return 0; }

  Compile with an h8300-elf toolchain.  (I used -O2 but this is not
  necessary in order to reproduce the bug).  If you run this inside
  GDB and break on the return you will find that flags.u2 only 
  contains 0x1ffff!

  Looking at the RTL generated in the expand pass (105r.expand) shows
  that something very weird is going on.  (RTL trimmed slightly for
  this email):

  ;; flags.u2 = 1ffffffff
  (insn 11 (set (reg:HI 19)           (const:HI (plus:HI (symbol_ref:HI 
("flags")) (const_int 2))))
  (insn 12 (set (reg:HI 20)           (mem:HI (reg:HI 19)))
  (insn 13 (set (reg:HI 21)           (ior:HI (reg:HI 20) (const_int 0x7fff)))
  (insn 14 (set (mem:HI (reg:HI 19))  (reg:HI 21))

  (insn 15 (set (reg:HI 22)           (const:HI (plus:HI (symbol_ref:HI 
("flags")) (const_int 4))))
  (insn 16 (set (reg:QI 23)           (mem:QI (reg:HI 22)))
  (insn 17 (set (reg:QI 24)           (ior:QI (reg:QI 23) (const_int 0x80)))
  (insn 18 (set (mem:QI (reg:HI 22))  (reg:QI 24))

  (insn 19 (set (reg:HI 25)           (symbol_ref:HI ("flags")))
  (insn 20 (set (reg:HI 26)           (mem:HI (reg:HI 25)))
  (insn 21 (set (reg:HI 27)           (and:HI (reg:HI 26) (const_int 0x8000)))
  (insn 22 (set (mem:HI (reg:HI 25))  (reg:HI 27))

  (insn 23 (set (reg:HI 28)           (const:HI (plus:HI (symbol_ref:HI 
("flags")) (const_int 2))))
  (insn 24 (set (reg:QI 29)           (mem:QI (reg:HI 28)))
  (insn 25 (set (reg:QI 30)           (ior:QI (reg:QI 29) (const_int 0x80)))
  (insn 26 (set (mem:QI (reg:HI 28))  (reg:QI 30))

  (insn 27 (set (reg:HI 31)           (symbol_ref:HI ("flags")))
  (insn 28 (set (reg:QI 32)           (mem:QI (reg:HI 31)))
  (insn 29 (set (reg:QI 33)           (and:QI (reg:QI 32) (const_int 0x7f)))
  (insn 30 (set (mem:QI (reg:HI 31))  (reg:QI 33))

  Gcc appears to have a completely broken idea of how the u2 bitfield
  is laid out.  When I saw that this was happening in RTL generation
  I baulked and decided to call in the big guns - you guys :-)

  What do you think.  Is this a generic bitfield allocation problem in
  gcc ?

Cheers
  Nick

Reply via email to