This backports a piece of

2012-09-24  Richard Guenther  <rguent...@suse.de>

       * tree-ssa-pre.c (bitmap_find_leader, create_expression_by_pieces,
       find_or_generate_expression): Remove dominating stmt argument.
       (find_leader_in_sets, phi_translate_1, bitmap_find_leader,
       create_component_ref_by_pieces_1, create_component_ref_by_pieces,
       do_regular_insertion, do_partial_partial_insertion): Adjust.
       (compute_avail): Do not set uids.

to the 4.7 branch.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to
the branch (and the testcase added to 4.8, 4.9 and trunk).

Richard.

2014-05-06  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/57864
        * tree-ssa-pre.c (phi_translate_1): Backport NAME case
        simplification from mainline.  Do not lookup the VN
        value-number here.

        * gcc.dg/torture/pr57864.c: New testcase.

Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c  (revision 210104)
--- gcc/tree-ssa-pre.c  (working copy)
*************** phi_translate_1 (pre_expr expr, bitmap_s
*** 1756,1794 ****
  
      case NAME:
        {
-       gimple phi = NULL;
-       edge e;
-       gimple def_stmt;
        tree name = PRE_EXPR_NAME (expr);
! 
!       def_stmt = SSA_NAME_DEF_STMT (name);
        if (gimple_code (def_stmt) == GIMPLE_PHI
            && gimple_bb (def_stmt) == phiblock)
-         phi = def_stmt;
-       else
-         return expr;
- 
-       e = find_edge (pred, gimple_bb (phi));
-       if (e)
          {
!           tree def = PHI_ARG_DEF (phi, e->dest_idx);
!           pre_expr newexpr;
! 
!           if (TREE_CODE (def) == SSA_NAME)
!             def = VN_INFO (def)->valnum;
  
            /* Handle constant. */
            if (is_gimple_min_invariant (def))
              return get_or_alloc_expr_for_constant (def);
  
!           if (TREE_CODE (def) == SSA_NAME && ssa_undefined_value_p (def))
!             return NULL;
! 
!           newexpr = get_or_alloc_expr_for_name (def);
!           return newexpr;
          }
        }
-       return expr;
  
      default:
        gcc_unreachable ();
--- 1756,1781 ----
  
      case NAME:
        {
        tree name = PRE_EXPR_NAME (expr);
!       gimple def_stmt = SSA_NAME_DEF_STMT (name);
!       /* If the SSA name is defined by a PHI node in this block,
!          translate it.  */
        if (gimple_code (def_stmt) == GIMPLE_PHI
            && gimple_bb (def_stmt) == phiblock)
          {
!           edge e = find_edge (pred, gimple_bb (def_stmt));
!           tree def = PHI_ARG_DEF (def_stmt, e->dest_idx);
  
            /* Handle constant. */
            if (is_gimple_min_invariant (def))
              return get_or_alloc_expr_for_constant (def);
  
!           return get_or_alloc_expr_for_name (def);
          }
+       /* Otherwise return it unchanged - it will get cleaned if its
+          value is not available in PREDs AVAIL_OUT set of expressions.  */
+       return expr;
        }
  
      default:
        gcc_unreachable ();
Index: gcc/testsuite/gcc.dg/torture/pr57864.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr57864.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr57864.c      (working copy)
***************
*** 0 ****
--- 1,37 ----
+ /* { dg-do compile } */
+ 
+ union U {
+     double val;
+     union U *ptr;
+ };
+ 
+ union U *d;
+ double a;
+ int b;
+ int c;
+ 
+ static void fn1(union U *p1, int p2, _Bool p3)
+ {
+     union U *e;
+ 
+     if (p2 == 0)
+       a = ((union U*)((unsigned long)p1 & ~1))->val;
+ 
+     if (b) {
+       e = p1;
+     } else if (c) {
+       e = ((union U*)((unsigned long)p1 & ~1))->ptr;
+       d = e;
+     } else {
+       e = 0;
+       d = ((union U*)0)->ptr;
+     }
+ 
+     fn1 (e, 0, 0);
+     fn1 (0, 0, p3);
+ }
+ 
+ void fn2 (void)
+ {
+   fn1 (0, 0, 0);
+ }

Reply via email to