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)
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

index 8bdbcd3..31c7db3 100644 (file)
@@ -1,6 +1,6 @@
 /* PR c++/78949 */
 /* { dg-do compile } */
-/* { dg-options "-Wunused" } */
+/* { dg-options "-Wunused -fdump-tree-optimized" } */
 /* { dg-additional-options "-fno-common" { target hppa*-*-hpux* } } */
 
 typedef unsigned char V __attribute__((vector_size(16)));
@@ -14,3 +14,5 @@ foo ()
   y &= ~x;
   v = y;
 }
+
+/* { dg-final { scan-tree-dump-not " ~0" "optimized" } } */
index 2e00b3e..0d7f041 100644 (file)
@@ -2162,9 +2162,10 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi,
       if (op >= FIRST_NORM_OPTAB && op <= LAST_NORM_OPTAB
          && optab_handler (op, TYPE_MODE (TREE_TYPE (type))) != CODE_FOR_nothing)
        {
-         tree slhs = make_ssa_name (TREE_TYPE (TREE_TYPE (lhs)));
-         gimple *repl = gimple_build_assign (slhs, code, srhs1, srhs2);
-         gsi_insert_before (gsi, repl, GSI_SAME_STMT);
+         tree stype = TREE_TYPE (TREE_TYPE (lhs));
+         tree slhs = (rhs2 != NULL_TREE)
+                     ? gimplify_build2 (gsi, code, stype, srhs1, srhs2)
+                     : gimplify_build1 (gsi, code, stype, srhs1);
          gimple_assign_set_rhs_from_tree (gsi,
                                           build_vector_from_val (type, slhs));
          update_stmt (stmt);