On Thu, 8 Dec 2016, Jakub Jelinek wrote:

> Hi!
> 
> The following testcases show two bugs in zero_one_operation (used during
> undistribute optimization) and functions it calls.
> The first one (wrong-code) is fixed by the
> +  tree orig_def = *def;
> and
> -  if (stmts_to_fix.length () > 0)
> +  if (stmts_to_fix.length () > 0 || *def == orig_def)
> changes in zero_one_operation - e.g. in the testcase we have before reassoc
>   _6 = _5 * a_11;
>   _7 = _5 * _6;
> and call zero_one_operation for _7 with op a_11.  The last stmt isn't pushed
> into stmts_to_fix, the *def stmt is handled specially in
> make_new_ssa_for_all_defs.  And the previous one, while it is pushed, it is
> popped from there again, because the stmt is removed and instead _6 use
> is replaced with _5.  That changes what value _7 holds, so we want to use
> a new SSA_NAME for it (or deal with debug stmts and reset flow sensitive
> info etc.).
> 
> The second one is wrong-debug, make_new_ssa_for_def replaces the uses of old
> lhs with the new lhs (which is fine in the code uses, but for debug info
> because we zeroed out a_11 we want to say that previous uses of _7 are now
> the _7's replacement * a_11.  Which is what the rest of the patch does
> and there is a guality testcase that verifies it (previously it would fail).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2016-12-08  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/78726
>       * tree-ssa-reassoc.c (make_new_ssa_for_def): Add OPCODE and OP
>       argument.  For lhs uses in debug stmts, don't replace lhs with
>       new_lhs, but with a debug temp set to new_lhs opcode op.
>       (make_new_ssa_for_all_defs): Add OPCODE argument, pass OPCODE and
>       OP down to make_new_ssa_for_def.
>       (zero_one_operation): Call make_new_ssa_for_all_defs even when
>       stmts_to_fix is empty, if *def has not changed yet.  Pass
>       OPCODE to make_new_ssa_for_all_defs.
> 
>       * gcc.c-torture/execute/pr78726.c: New test.
>       * gcc.dg/guality/pr78726.c: New test.
> 
> --- gcc/tree-ssa-reassoc.c.jj 2016-11-09 16:34:58.000000000 +0100
> +++ gcc/tree-ssa-reassoc.c    2016-12-08 15:53:13.768894146 +0100
> @@ -1153,12 +1153,12 @@ decrement_power (gimple *stmt)
>     SSA.  Also return the new SSA.  */
>  
>  static tree
> -make_new_ssa_for_def (gimple *stmt)
> +make_new_ssa_for_def (gimple *stmt, enum tree_code opcode, tree op)
>  {
>    gimple *use_stmt;
>    use_operand_p use;
>    imm_use_iterator iter;
> -  tree new_lhs;
> +  tree new_lhs, new_debug_lhs = NULL_TREE;
>    tree lhs = gimple_get_lhs (stmt);
>  
>    new_lhs = make_ssa_name (TREE_TYPE (lhs));
> @@ -1167,8 +1167,28 @@ make_new_ssa_for_def (gimple *stmt)
>    /* Also need to update GIMPLE_DEBUGs.  */
>    FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
>      {
> +      tree repl = new_lhs;
> +      if (is_gimple_debug (use_stmt))
> +     {
> +       if (new_debug_lhs == NULL_TREE)
> +         {
> +           new_debug_lhs = make_node (DEBUG_EXPR_DECL);
> +           gdebug *def_temp
> +             = gimple_build_debug_bind (new_debug_lhs,
> +                                        build2 (opcode, TREE_TYPE (lhs),
> +                                                new_lhs, op),
> +                                        stmt);
> +           DECL_ARTIFICIAL (new_debug_lhs) = 1;
> +           TREE_TYPE (new_debug_lhs) = TREE_TYPE (lhs);
> +           SET_DECL_MODE (new_debug_lhs, TYPE_MODE (TREE_TYPE (lhs)));
> +           gimple_set_uid (def_temp, gimple_uid (stmt));
> +           gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
> +           gsi_insert_after (&gsi, def_temp, GSI_SAME_STMT);
> +         }
> +       repl = new_debug_lhs;
> +     }
>        FOR_EACH_IMM_USE_ON_STMT (use, iter)
> -     SET_USE (use, new_lhs);
> +     SET_USE (use, repl);
>        update_stmt (use_stmt);
>      }
>    return new_lhs;
> @@ -1179,7 +1199,7 @@ make_new_ssa_for_def (gimple *stmt)
>     if *DEF is not OP.  */
>  
>  static void
> -make_new_ssa_for_all_defs (tree *def, tree op,
> +make_new_ssa_for_all_defs (tree *def, enum tree_code opcode, tree op,
>                          vec<gimple *> &stmts_to_fix)
>  {
>    unsigned i;
> @@ -1189,10 +1209,10 @@ make_new_ssa_for_all_defs (tree *def, tr
>        && TREE_CODE (*def) == SSA_NAME
>        && (stmt = SSA_NAME_DEF_STMT (*def))
>        && gimple_code (stmt) != GIMPLE_NOP)
> -    *def = make_new_ssa_for_def (stmt);
> +    *def = make_new_ssa_for_def (stmt, opcode, op);
>  
>    FOR_EACH_VEC_ELT (stmts_to_fix, i, stmt)
> -    make_new_ssa_for_def (stmt);
> +    make_new_ssa_for_def (stmt, opcode, op);
>  }
>  
>  /* Find the single immediate use of STMT's LHS, and replace it
> @@ -1232,6 +1252,7 @@ propagate_op_to_single_use (tree op, gim
>  static void
>  zero_one_operation (tree *def, enum tree_code opcode, tree op)
>  {
> +  tree orig_def = *def;
>    gimple *stmt = SSA_NAME_DEF_STMT (*def);
>    /* PR72835 - Record the stmt chain that has to be updated such that
>       we dont use the same LHS when the values computed are different.  */
> @@ -1335,8 +1356,8 @@ zero_one_operation (tree *def, enum tree
>      }
>    while (1);
>  
> -  if (stmts_to_fix.length () > 0)
> -    make_new_ssa_for_all_defs (def, op, stmts_to_fix);
> +  if (stmts_to_fix.length () > 0 || *def == orig_def)
> +    make_new_ssa_for_all_defs (def, opcode, op, stmts_to_fix);
>  }
>  
>  /* Returns true if statement S1 dominates statement S2.  Like
> --- gcc/testsuite/gcc.c-torture/execute/pr78726.c.jj  2016-12-08 
> 15:55:08.847434702 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/pr78726.c     2016-12-08 
> 15:54:46.000000000 +0100
> @@ -0,0 +1,23 @@
> +/* PR tree-optimization/78726 */
> +
> +unsigned char b = 36, c = 173;
> +unsigned int d;
> +
> +__attribute__((noinline, noclone)) void
> +foo (void)
> +{
> +  unsigned a = ~b;
> +  d = a * c * c + 1023094746U * a;
> +}
> +
> +int
> +main ()
> +{
> +  if (__SIZEOF_INT__ != 4 || __CHAR_BIT__ != 8)
> +    return 0;
> +  asm volatile ("" : : "g" (&b), "g" (&c) : "memory");
> +  foo ();
> +  if (d != 799092689U)
> +    __builtin_abort ();
> +  return 0;
> +}
> --- gcc/testsuite/gcc.dg/guality/pr78726.c.jj 2016-12-08 15:57:07.779926381 
> +0100
> +++ gcc/testsuite/gcc.dg/guality/pr78726.c    2016-12-08 16:02:57.216494771 
> +0100
> @@ -0,0 +1,30 @@
> +/* PR tree-optimization/78726 */
> +/* { dg-do run } */
> +/* { dg-options "-g" } */
> +
> +#include "../nop.h"
> +
> +unsigned char b = 36, c = 173;
> +unsigned int d;
> +
> +__attribute__((noinline, noclone)) void
> +foo (void)
> +{
> +  unsigned a = ~b;
> +  unsigned d1 = a * c;               /* { dg-final { gdb-test 21 "d1" "~36U 
> * 173" } } */
> +  unsigned d2 = d1 * c;              /* { dg-final { gdb-test 21 "d2" "~36U 
> * 173 * 173" } } */
> +  unsigned d3 = 1023094746 * a;      /* { dg-final { gdb-test 21 "d3" "~36U 
> * 1023094746" } } */
> +  d = d2 + d3;
> +  unsigned d4 = d1 * 2;      /* { dg-final { gdb-test 21 "d4" "~36U * 173 * 
> 2" } } */
> +  unsigned d5 = d2 * 2;              /* { dg-final { gdb-test 21 "d5" "~36U 
> * 173 * 173 * 2" } } */
> +  unsigned d6 = d3 * 2;              /* { dg-final { gdb-test 21 "d6" "~36U 
> * 1023094746 * 2" } } */
> +  asm (NOP : : : "memory");
> +}
> +
> +int
> +main ()
> +{
> +  asm volatile ("" : : "g" (&b), "g" (&c) : "memory");
> +  foo ();
> +  return 0;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to