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