Fold more constants during veclower pass.
authorRoger Sayle <roger@nextmovesoftware.com>
Thu, 19 Aug 2021 23:24:23 +0000 (00:24 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Thu, 19 Aug 2021 23:28:47 +0000 (00:28 +0100)
commit976401aa4781fa5850e1f34142bc13d1cfe0b2bd
tree799b32089cf1082f197598a9ac10b6e475d7aee2
parentb0963c4379becafaebd8e52b0b42698ff151c293
Fold more constants during veclower pass.

An issue with a backend patch I've been investigating has revealed
a missed optimization opportunity during GCC's vector lowering pass.
An unrecognized insn for "(set (reg:SI) (not:SI (const_int 0))"
revealed that not only was my expander not expecting a NOT with
a constant operand, but also that veclower was producing the
dubious tree expression ~0.

The attached patch replaces a call to gimple_build_assign with a
call to either gimplify_build1 or gimplify_build2 depending upon
whether the operation takes one or two operands.  The net effect
is that where GCC previously produced the following optimized
gimple for testsuite/c-c++common/Wunused-var-16.c (notice the ~0
and the "& 0"):

void foo ()
{
  V x;
  V y;
  vector(16) unsigned char _1;
  unsigned char _7;
  unsigned char _8;

  y_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  x_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  _7 = ~0;
  _1 = {_7, _7, _7, _7, _7, _7, _7, _7, _7, _7, _7, _7, _7, _7, _7, _7};
  _8 = 0 & _7;
  y_4 = {_8, _8, _8, _8, _8, _8, _8, _8, _8, _8, _8, _8, _8, _8, _8, _8};
  v = y_4;
  return;
}

With this patch we now generate:

void foo ()
{
  V x;
  V y;
  vector(16) unsigned char _1;

  y_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  x_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  _1 = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 2
55, 255 };
  y_4 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  v = y_4;
  return;
}

2021-08-20  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
* tree-vect-generic.c (expand_vector_operations_1): Use either
gimplify_build1 or gimplify_build2 instead of gimple_build_assign
when constructing scalar splat expressions.

gcc/testsuite/ChangeLog
* c-c++-common/Wunused-var-16.c: Add an extra check that ~0
is optimized away.
gcc/testsuite/c-c++-common/Wunused-var-16.c
gcc/tree-vect-generic.c