Message ID | 02a901d79512$4ac874c0$e0595e40$@nextmovesoftware.com |
---|---|
State | New |
Headers | show |
Series | Fold more constants during veclower pass. | expand |
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 --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);