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

luoxhu at gcc dot gnu.org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |luoxhu at gcc dot gnu.org

--- Comment #30 from luoxhu at gcc dot gnu.org ---
Hi Jakub, thanks for your information, seems this test case from Linux kernel
could be added to your future fix patch.

struct page
{
  union
  {
    unsigned counters;
    struct
    {
      union
      {
        struct
        {
          unsigned inuse : 16;
          unsigned objects : 15;
          unsigned frozen : 1;
        };
      };
    };
  };
};

void
foo1 (struct page *page, unsigned long counters_new)
{
        struct page tmp;
        tmp.counters = counters_new;
        page->inuse   = tmp.inuse;
        page->objects = tmp.objects;
        page->frozen  = tmp.frozen;
}

 Tried gcc(r10-6717) with -O3 on powerpcle, the asm is:
Disassembly of section .text:

0000000000000000 <foo1>:
   0:   3e 84 89 54     rlwinm  r9,r4,16,16,31
   4:   00 00 83 b0     sth     r4,0(r3)
   8:   02 00 23 b1     sth     r9,2(r3)
   c:   20 00 80 4e     blr
        ...
  1c:   00 00 42 60     ori     r2,r2,0

It is expected to emit only one store stw instruction(Also two half store
instructions emitted for x86 platforms!).
I am not sure whether the fre pass could check consecutive store and do the
merge similar to store-merging pass as the input parameter counters_new is not
a constant. :)

Reply via email to