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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
     Ever confirmed|0                           |1
             Status|RESOLVED                    |REOPENED
         Resolution|DUPLICATE                   |---
                 CC|                            |jakub at gcc dot gnu.org
   Last reconfirmed|                            |2020-12-08

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
I don't see UB there, UB would be if you copy a value other than 0 or 1 to the
_Bool variable, but that is not happening here.

Consider even:
static int __attribute__((noipa))
foo (const char *p, const char *q, const int len)
{
  for (int i = 0; i < len; p++, q++, i++)
    {
      int equal;
      _Bool x, y;
      __builtin_memcpy ((char *) &x, p, sizeof x);
      __builtin_memcpy ((char *) &y, q, sizeof y);
      equal = (x == y);
      if (equal <= 0)
        return equal;
    }
  return 1;
}

int
main ()
{
  const _Bool buf[4] = { 1, 0, 0, 0 };
  register long x4 asm ("x4") = 0xdeadbeefULL;
  register long x5 asm ("x5") = 0xdeadbeefULL;
  asm volatile (""::"r" (x4), "r" (x5));
  if (foo ((char *) &buf[0], (char *) &buf[0], 1) != 1)
    __builtin_abort ();
  return 0;
}

Copying through char * from _Bool to _Bool really must work, that is what
happens e.g. in structure assignments etc. if it has _Bool fields.

The reason this is miscompiled is that the aarch64 backend decides that the x
and y variables should be promoted from QImode to SImode and the expansion of
the memcpy folded into assignment sets a MEM_REF with QImode (i.e. low parts of
the promoted DECL_RTL), but nothing sign or zero extends it.

Reply via email to