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

            Bug ID: 97775
           Summary: Wrong code with bitfield
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: hubicka at gcc dot gnu.org
  Target Milestone: ---

The follwing testcase reduced from ssd/t2.c 

#include <stdio.h>

void dump (void *p, unsigned int len)
{
  const char digits[17] = "0123456789abcdef";
  unsigned char *a = (unsigned char *)p;
  int i;

  for (i = 0; i < len; i++)
    {
      putchar (' ');
      putchar (digits[a[i] / 16]);
      putchar (digits[a[i] % 16]);
    }
}

void put (const char s[])
{
  int i;
  for (i = 0; s[i]; i++)
    putchar (s[i]);
}

void new_line (void)
{
  putchar ('\n');
}
struct __attribute__((scalar_storage_order("little-endian"), packed)) R1
{
  unsigned S1 : 2;
  unsigned I  : 32;
  unsigned S2 : 2;
  unsigned A1 : 9;
  unsigned A2 : 9;
  unsigned A3 : 9;
  unsigned B  : 1;
};

struct R1 My_R1 = { 2, 0x12345678, 1, 0xAB, 0xCD, 0xEF, 1 };

int main (void)
{
  struct R1 Local_R1;


  Local_R1.B  = 1;

#ifdef BAD
  new_line ();
#endif
  /* { dg-output "Local_R1 : e2 59 d1 48 b4 aa d9 bb.*\n" } */

  Local_R1.S1 = 0;
  Local_R1.I  = 0;
  Local_R1.S2 = 0;
  Local_R1.A1 = 0;
  Local_R1.A2 = 0;
  Local_R1.A3 = 0;
  Local_R1.B  = !Local_R1.B;

  put ("Local_R1 :");
  dump (&Local_R1, sizeof (struct R1));
  new_line ();
  /* { dg-output "Local_R1 : e5 59 d1 48 b0 a0 c1 03.*\n" } */

  new_line ();
  return 0;
}

Defining BAD canges output 
< Local_R1 : 00 00 00 00 00 00 00 00
---
> Local_R1 : 00 00 00 00 00 00 00 80

Difference is already in fre1:
-Value numbering store Local_R1.B to _3
+Value numbering store Local_R1.B to 1
....
-RPO tracked 17 values available at 3 locations and 17 lattice elements
+RPO tracked 17 values available at 0 locations and 17 lattice elements
+Replaced BIT_FIELD_REF <Local_R1, 8, 56> with 0 in all uses of _1 =
BIT_FIELD_REF <Local_R1, 8, 56>;
+Replaced (signed char) _1 with 0 in all uses of _2 = (signed char) _1;
+Replaced _2 >= 0 with 1 in all uses of _3 = _2 >= 0;
+Deleted redundant store Local_R1.B = _3;
+Removing dead stmt Local_R1.B = _3;
+Removing dead stmt _3 = _2 >= 0;
+Removing dead stmt _2 = (signed char) _1;
+Removing dead stmt _1 = BIT_FIELD_REF <Local_R1, 8, 56>;
 main ()
 {
   struct R1 Local_R1;
-  unsigned char _1;
-  signed char _2;
-  _Bool _3;

   <bb 2> :
   Local_R1.B = 1;
@@ -533,10 +540,6 @@
   Local_R1.A1 = 0;
   Local_R1.A2 = 0;
   Local_R1.A3 = 0;
-  _1 = BIT_FIELD_REF <Local_R1, 8, 56>;
-  _2 = (signed char) _1;
-  _3 = _2 >= 0;
-  Local_R1.B = _3;
   put ("Local_R1 :");
   dump (&Local_R1, 8);
   new_line ();

Clearly B should be 0 and not 1.

Reply via email to