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

            Bug ID: 126489
           Summary: [14/15/16/17 Regression] Wrong code/ICE on
                    VIEW_CONVERT
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ktkachov at gcc dot gnu.org
  Target Milestone: ---

typedef unsigned char v8u __attribute__((vector_size (8)));
typedef unsigned char v4u __attribute__((vector_size (4)));

/* cmp_bits_i == 4: rshift 3, mask 0x11, multiplier 15.  */
__attribute__((noipa)) v8u
f4 (v8u x)
{
  v8u m = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
  v8u n = { 15, 15, 15, 15, 15, 15, 15, 15 };
  return ((x >> 3) & m) * n;
}

/* cmp_bits_i == 2: rshift 1, mask 0x55, multiplier 3.  */
__attribute__((noipa)) v4u
f2 (v4u x)
{
  v4u m = { 0x55, 0x55, 0x55, 0x55 };
  v4u n = { 3, 3, 3, 3 };
  return ((x >> 1) & m) * n;
}

/* Reference: one operation at a time through volatile scalars.  */
__attribute__((noipa)) unsigned char
ref4 (unsigned char b)
{
  volatile unsigned char v = b;
  volatile unsigned char s = (unsigned char) (v >> 3);
  volatile unsigned char a = (unsigned char) (s & 0x11);
  volatile unsigned int p = (unsigned int) a * 15u;
  return (unsigned char) p;
}

__attribute__((noipa)) unsigned char
ref2 (unsigned char b)
{
  volatile unsigned char v = b;
  volatile unsigned char s = (unsigned char) (v >> 1);
  volatile unsigned char a = (unsigned char) (s & 0x55);
  volatile unsigned int p = (unsigned int) a * 3u;
  return (unsigned char) p;
}

static volatile unsigned char seed[16]
  = { 0x00, 0x01, 0x08, 0x11, 0x80, 0x88, 0x89, 0xff,
      0x7f, 0x0f, 0xf0, 0x55, 0xaa, 0x18, 0x81, 0x99 };

int
main (void)
{
  for (unsigned k = 0; k < 16; k++)
    {
      unsigned char buf[8];
      unsigned char got[8];
      v8u x8;
      v4u x4;
      unsigned i;

      for (i = 0; i < 8; i++)
        buf[i] = seed[(k + i) % 16];

      __builtin_memcpy (&x8, buf, 8);
      {
        v8u r = f4 (x8);
        __builtin_memcpy (got, &r, 8);
        for (i = 0; i < 8; i++)
          if (got[i] != ref4 (buf[i]))
            __builtin_abort ();
      }

      __builtin_memcpy (&x4, buf, 4);
      {
        v4u r = f2 (x4);
        __builtin_memcpy (got, &r, 4);
        for (i = 0; i < 4; i++)
          if (got[i] != ref2 (buf[i]))
            __builtin_abort ();
      }
    }
  return 0;
}

on aarch64 at -O2 ICEs on trunk:
In function 'f4':
<source>:80:1: error: conversion of register to a different size in
'view_convert_expr'
   80 | }
      | ^
VIEW_CONVERT_EXPR<vector(16) <unnamed-signed:4>>(x_5(D));

_8 = VIEW_CONVERT_EXPR<vector(16) <unnamed-signed:4>>(x_5(D));
<source>:80:1: error: conversion of register to a different size in
'view_convert_expr'
VIEW_CONVERT_EXPR<v8u>(_10);

_6 = VIEW_CONVERT_EXPR<v8u>(_10);
during GIMPLE pass: ccp
<source>:80:1: internal compiler error: verify_gimple failed

but on GCC 14-16 it aborts. GCC 13 and Clang runs fine

Reply via email to