This fixes one issue with copyrename, that it "leaks" names backward
through a PHI node because it treats a PHI node

 _1 = PHI <_2, _3, _4>

as

 _1 = _2;
 _1 = _3;
 _1 = _4;

at the point of the PHI node which is certainly not what it is
(the assigns exist, one each, on the incoming edges only).

The following fixes that.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  The guality
test fails for -Os on x86_64 and for -O2 -flto -fuse-linker-plugin 
-fno-fat-lto-objects on i586, a single FAIL is much better than
another 7 XPASSes, so I left it as FAIL.  On x86_64 now also
gcc.target/i386/pad-10.c FAILs, because appearantly whatever is
responsible for not issueing padding nops is confused by the
no longer occuring coalescing at out-of-SSA time.  Thus clearly
a pre-existing bug and simply a weak testcase.

Applied.

Richard.

2012-08-13  Richard Guenther  <rguent...@suse.de>

        PR tree-optimization/54200
        * tree-ssa-copyrename.c (rename_ssa_copies): Do not add
        PHI results to another partition if not all PHI arguments
        have the same partition.

        * gcc.dg/guality/pr54200.c: New testcase.
        * gcc.dg/tree-ssa/slsr-8.c: Adjust.

Index: gcc/tree-ssa-copyrename.c
===================================================================
*** gcc/tree-ssa-copyrename.c.orig      2012-08-10 15:51:19.000000000 +0200
--- gcc/tree-ssa-copyrename.c   2012-08-10 15:51:29.000638547 +0200
*************** rename_ssa_copies (void)
*** 348,362 ****
          res = gimple_phi_result (phi);
  
          /* Do not process virtual SSA_NAMES.  */
!         if (!is_gimple_reg (res))
            continue;
  
!           for (i = 0; i < gimple_phi_num_args (phi); i++)
!             {
!               tree arg = gimple_phi_arg (phi, i)->def;
!               if (TREE_CODE (arg) == SSA_NAME)
!               updated |= copy_rename_partition_coalesce (map, res, arg, 
debug);
!             }
          }
      }
  
--- 348,400 ----
          res = gimple_phi_result (phi);
  
          /* Do not process virtual SSA_NAMES.  */
!         if (virtual_operand_p (res))
            continue;
  
!         /* Make sure to only use the same partition for an argument
!            as the result but never the other way around.  */
!         if (SSA_NAME_VAR (res)
!             && !DECL_IGNORED_P (SSA_NAME_VAR (res)))
!           for (i = 0; i < gimple_phi_num_args (phi); i++)
!             {
!               tree arg = PHI_ARG_DEF (phi, i);
!               if (TREE_CODE (arg) == SSA_NAME)
!                 updated |= copy_rename_partition_coalesce (map, res, arg,
!                                                            debug);
!             }
!         /* Else if all arguments are in the same partition try to merge
!            it with the result.  */
!         else
!           {
!             int all_p_same = -1;
!             int p = -1;
!             for (i = 0; i < gimple_phi_num_args (phi); i++)
!               {
!                 tree arg = PHI_ARG_DEF (phi, i);
!                 if (TREE_CODE (arg) != SSA_NAME)
!                   {
!                     all_p_same = 0;
!                     break;
!                   }
!                 else if (all_p_same == -1)
!                   {
!                     p = partition_find (map->var_partition,
!                                         SSA_NAME_VERSION (arg));
!                     all_p_same = 1;
!                   }
!                 else if (all_p_same == 1
!                          && p != partition_find (map->var_partition,
!                                                  SSA_NAME_VERSION (arg)))
!                   {
!                     all_p_same = 0;
!                     break;
!                   }
!               }
!             if (all_p_same == 1)
!               updated |= copy_rename_partition_coalesce (map, res,
!                                                          PHI_ARG_DEF (phi, 0),
!                                                          debug);
!           }
          }
      }
  
Index: gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c.orig 2012-08-10 15:51:19.000000000 
+0200
--- gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c      2012-08-10 15:51:29.000638547 
+0200
*************** f (int s, int *c)
*** 17,23 ****
    return x1 ? x2 : x3;
  }
  
! /* There are 2 ' * ' instances in the decls (since "int * x3;" is
!    optimized out), 1 parm, 2 in the code.  */
! /* { dg-final { scan-tree-dump-times " \\* " 5 "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */
--- 17,23 ----
    return x1 ? x2 : x3;
  }
  
! /* There are 4 ' * ' instances in the decls (since "int * iftmp.0;" is
!    added), 1 parm, 2 in the code.  */
! /* { dg-final { scan-tree-dump-times " \\* " 7 "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */
Index: gcc/testsuite/gcc.dg/guality/pr54200.c
===================================================================
*** /dev/null   1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/guality/pr54200.c      2012-08-10 16:12:48.006594252 
+0200
***************
*** 0 ****
--- 1,28 ----
+ /* PR tree-optimization/54200 */
+ /* { dg-do run } */
+ /* { dg-options "-g -fno-var-tracking-assignments" } */
+ 
+ int o __attribute__((used));
+ 
+ void bar (void) { o = 2; }
+ 
+ int __attribute__((noinline,noclone))
+ foo (int z, int x, int b)
+ {
+   if (x == 1)
+     {
+       bar ();
+       return z;
+     }
+   else
+     {
+       int a = (x + z) + b;
+       return a; /* { dg-final { gdb-test 20 "z" "3" } } */
+     }
+ }
+ 
+ int main ()
+ {
+   foo (3, 2, 1);
+   return 0;
+ }

Reply via email to