diff mbox series

Fold more constants during veclower pass.

Message ID 02a901d79512$4ac874c0$e0595e40$@nextmovesoftware.com
State New
Headers show
Series Fold more constants during veclower pass. | expand

Commit Message

Roger Sayle Aug. 19, 2021, 3:53 p.m. UTC
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, 255, 255 };
  y_4 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  v = y_4;
  return;
}

This patch has been tested on x86_64-pc-linux-gnu with "make bootstrap"
and "make -k check".

Ok for mainline?


2021-08-18  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/Wununsed-var-16.c: Add extra check for that ~0
	is optimized away.

Roger
--

Comments

Jeff Law Aug. 19, 2021, 6:03 p.m. UTC | #1
On 8/19/2021 9:53 AM, Roger Sayle wrote:
> 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, 255, 255 };
>    y_4 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
>    v = y_4;
>    return;
> }
>
> This patch has been tested on x86_64-pc-linux-gnu with "make bootstrap"
> and "make -k check".
>
> Ok for mainline?
>
>
> 2021-08-18  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/Wununsed-var-16.c: Add extra check for that ~0
> 	is optimized away.
OK
jeff
diff mbox series

Patch

diff --git a/gcc/testsuite/c-c++-common/Wunused-var-16.c b/gcc/testsuite/c-c++-common/Wunused-var-16.c
index 8bdbcd3..31c7db3 100644
--- a/gcc/testsuite/c-c++-common/Wunused-var-16.c
+++ b/gcc/testsuite/c-c++-common/Wunused-var-16.c
@@ -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" } } */
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 2e00b3e..0d7f041 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -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);