The following fixes a missed optimization in PRE which was over-cautionous
with rejecting simplifications to SSA names during phi-translation.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2016-08-12  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/57326
        * tree-ssa-pre.c (fully_constant_expression): Handle simplification
        returning an SSA name.
        (phi_translate_1): When fully_constant_expression returns a NAME
        make sure we have a leader for it.

        * gcc.dg/tree-ssa/ssa-pre-32.c: New testcase.

Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c  (revision 239361)
--- gcc/tree-ssa-pre.c  (working copy)
*************** get_or_alloc_expr_for (tree t)
*** 1201,1207 ****
  }
  
  /* Return the folded version of T if T, when folded, is a gimple
!    min_invariant.  Otherwise, return T.  */
  
  static pre_expr
  fully_constant_expression (pre_expr e)
--- 1201,1207 ----
  }
  
  /* Return the folded version of T if T, when folded, is a gimple
!    min_invariant or an SSA name.  Otherwise, return T.  */
  
  static pre_expr
  fully_constant_expression (pre_expr e)
*************** fully_constant_expression (pre_expr e)
*** 1218,1227 ****
          return e;
        if (is_gimple_min_invariant (res))
          return get_or_alloc_expr_for_constant (res);
!       /* We might have simplified the expression to a
!          SSA_NAME for example from x_1 * 1.  But we cannot
!          insert a PHI for x_1 unconditionally as x_1 might
!          not be available readily.  */
        return e;
        }
      case REFERENCE:
--- 1218,1225 ----
          return e;
        if (is_gimple_min_invariant (res))
          return get_or_alloc_expr_for_constant (res);
!       if (TREE_CODE (res) == SSA_NAME)
!         return get_or_alloc_expr_for_name (res);
        return e;
        }
      case REFERENCE:
*************** phi_translate_1 (pre_expr expr, bitmap_s
*** 1464,1470 ****
            constant = fully_constant_expression (expr);
            PRE_EXPR_NARY (expr) = nary;
            if (constant != expr)
!             return constant;
  
            tree result = vn_nary_op_lookup_pieces (newnary->length,
                                                    newnary->opcode,
--- 1462,1481 ----
            constant = fully_constant_expression (expr);
            PRE_EXPR_NARY (expr) = nary;
            if (constant != expr)
!             {
!               /* For non-CONSTANTs we have to make sure we can eventually
!                  insert the expression.  Which means we need to have a
!                  leader for it.  */
!               if (constant->kind != CONSTANT)
!                 {
!                   unsigned value_id = get_expr_value_id (constant);
!                   constant = find_leader_in_sets (value_id, set1, set2);
!                   if (constant)
!                     return constant;
!                 }
!               else
!                 return constant;
!             }
  
            tree result = vn_nary_op_lookup_pieces (newnary->length,
                                                    newnary->opcode,
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c  (revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c  (working copy)
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fdump-tree-pre" } */
+ 
+ unsigned f(unsigned x, unsigned y, _Bool b)
+ {
+ #define m (b?-1:0)
+   return (x&m)|(y&~m);
+ #undef m
+ }
+ 
+ /* { dg-final { scan-tree-dump "# prephitmp_\[0-9\]+ = PHI 
<\[xy\]_\[0-9\]+\\(D\\)\[^,\]*, \[xy\]_\[0-9\]+\\(D\\)" "pre" } } */

Reply via email to