This fixes PR50082 by completely defering to fold what kind of
overflow warning to emit from tree-ssa-forwprop.c.  It also moves
overflow handling to the single place that decides whether and
what we optimize.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Ian, does this look ok?

Thanks,
Richard.

2011-08-16  Richard GUenther  <rguent...@suse.de>

        PR tree-optimization/50082
        * tree-ssa-forwprop.c (combine_cond_expr_cond): Handle overflow
        warnings here, instead of ...
        (ssa_forward_propagate_and_combine): ... here.
        (forward_propagate_into_comparison_1): Adjust.
        (forward_propagate_into_comparison): Likewise.
        (forward_propagate_into_gimple_cond): Likewise.
        (forward_propagate_into_cond): Likewise.

Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c     (revision 177781)
--- gcc/tree-ssa-forwprop.c     (working copy)
*************** rhs_to_tree (tree type, gimple stmt)
*** 369,384 ****
     considered simplified.  */
  
  static tree
! combine_cond_expr_cond (location_t loc, enum tree_code code, tree type,
                        tree op0, tree op1, bool invariant_only)
  {
    tree t;
  
    gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
  
!   t = fold_binary_loc (loc, code, type, op0, op1);
    if (!t)
!     return NULL_TREE;
  
    /* Require that we got a boolean type out if we put one in.  */
    gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
--- 369,388 ----
     considered simplified.  */
  
  static tree
! combine_cond_expr_cond (gimple stmt, enum tree_code code, tree type,
                        tree op0, tree op1, bool invariant_only)
  {
    tree t;
  
    gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
  
!   fold_defer_overflow_warnings ();
!   t = fold_binary_loc (gimple_location (stmt), code, type, op0, op1);
    if (!t)
!     {
!       fold_undefer_overflow_warnings (false, NULL, 0);
!       return NULL_TREE;
!     }
  
    /* Require that we got a boolean type out if we put one in.  */
    gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
*************** combine_cond_expr_cond (location_t loc,
*** 388,394 ****
  
    /* Bail out if we required an invariant but didn't get one.  */
    if (!t || (invariant_only && !is_gimple_min_invariant (t)))
!     return NULL_TREE;
  
    return t;
  }
--- 392,403 ----
  
    /* Bail out if we required an invariant but didn't get one.  */
    if (!t || (invariant_only && !is_gimple_min_invariant (t)))
!     {
!       fold_undefer_overflow_warnings (false, NULL, 0);
!       return NULL_TREE;
!     }
! 
!   fold_undefer_overflow_warnings (!gimple_no_warning_p (stmt), stmt, 0);
  
    return t;
  }
*************** combine_cond_expr_cond (location_t loc,
*** 398,404 ****
     were no simplifying combines.  */
  
  static tree
! forward_propagate_into_comparison_1 (location_t loc,
                                     enum tree_code code, tree type,
                                     tree op0, tree op1)
  {
--- 407,413 ----
     were no simplifying combines.  */
  
  static tree
! forward_propagate_into_comparison_1 (gimple stmt,
                                     enum tree_code code, tree type,
                                     tree op0, tree op1)
  {
*************** forward_propagate_into_comparison_1 (loc
*** 414,420 ****
        if (def_stmt && can_propagate_from (def_stmt))
        {
          rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
!         tmp = combine_cond_expr_cond (loc, code, type,
                                        rhs0, op1, !single_use0_p);
          if (tmp)
            return tmp;
--- 423,429 ----
        if (def_stmt && can_propagate_from (def_stmt))
        {
          rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
!         tmp = combine_cond_expr_cond (stmt, code, type,
                                        rhs0, op1, !single_use0_p);
          if (tmp)
            return tmp;
*************** forward_propagate_into_comparison_1 (loc
*** 428,434 ****
        if (def_stmt && can_propagate_from (def_stmt))
        {
          rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
!         tmp = combine_cond_expr_cond (loc, code, type,
                                        op0, rhs1, !single_use1_p);
          if (tmp)
            return tmp;
--- 437,443 ----
        if (def_stmt && can_propagate_from (def_stmt))
        {
          rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
!         tmp = combine_cond_expr_cond (stmt, code, type,
                                        op0, rhs1, !single_use1_p);
          if (tmp)
            return tmp;
*************** forward_propagate_into_comparison_1 (loc
*** 438,444 ****
    /* If that wasn't successful either, try both operands.  */
    if (rhs0 != NULL_TREE
        && rhs1 != NULL_TREE)
!     tmp = combine_cond_expr_cond (loc, code, type,
                                  rhs0, rhs1,
                                  !(single_use0_p && single_use1_p));
  
--- 447,453 ----
    /* If that wasn't successful either, try both operands.  */
    if (rhs0 != NULL_TREE
        && rhs1 != NULL_TREE)
!     tmp = combine_cond_expr_cond (stmt, code, type,
                                  rhs0, rhs1,
                                  !(single_use0_p && single_use1_p));
  
*************** forward_propagate_into_comparison (gimpl
*** 460,466 ****
    tree rhs2 = gimple_assign_rhs2 (stmt);
  
    /* Combine the comparison with defining statements.  */
!   tmp = forward_propagate_into_comparison_1 (gimple_location (stmt),
                                             gimple_assign_rhs_code (stmt),
                                             TREE_TYPE
                                               (gimple_assign_lhs (stmt)),
--- 469,475 ----
    tree rhs2 = gimple_assign_rhs2 (stmt);
  
    /* Combine the comparison with defining statements.  */
!   tmp = forward_propagate_into_comparison_1 (stmt,
                                             gimple_assign_rhs_code (stmt),
                                             TREE_TYPE
                                               (gimple_assign_lhs (stmt)),
*************** forward_propagate_into_comparison (gimpl
*** 491,497 ****
  static int
  forward_propagate_into_gimple_cond (gimple stmt)
  {
-   location_t loc = gimple_location (stmt);
    tree tmp;
    enum tree_code code = gimple_cond_code (stmt);
    bool cfg_changed = false;
--- 500,505 ----
*************** forward_propagate_into_gimple_cond (gimp
*** 502,508 ****
    if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
      return 0;
  
!   tmp = forward_propagate_into_comparison_1 (loc, code,
                                             boolean_type_node,
                                             rhs1, rhs2);
    if (tmp)
--- 510,516 ----
    if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
      return 0;
  
!   tmp = forward_propagate_into_comparison_1 (stmt, code,
                                             boolean_type_node,
                                             rhs1, rhs2);
    if (tmp)
*************** static int
*** 541,553 ****
  forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
  {
    gimple stmt = gsi_stmt (*gsi_p);
-   location_t loc = gimple_location (stmt);
    tree tmp = NULL_TREE;
    tree cond = gimple_assign_rhs1 (stmt);
  
    /* We can do tree combining on SSA_NAME and comparison expressions.  */
    if (COMPARISON_CLASS_P (cond))
!     tmp = forward_propagate_into_comparison_1 (loc, TREE_CODE (cond),
                                               boolean_type_node,
                                               TREE_OPERAND (cond, 0),
                                               TREE_OPERAND (cond, 1));
--- 549,560 ----
  forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
  {
    gimple stmt = gsi_stmt (*gsi_p);
    tree tmp = NULL_TREE;
    tree cond = gimple_assign_rhs1 (stmt);
  
    /* We can do tree combining on SSA_NAME and comparison expressions.  */
    if (COMPARISON_CLASS_P (cond))
!     tmp = forward_propagate_into_comparison_1 (stmt, TREE_CODE (cond),
                                               boolean_type_node,
                                               TREE_OPERAND (cond, 0),
                                               TREE_OPERAND (cond, 1));
*************** forward_propagate_into_cond (gimple_stmt
*** 559,565 ****
        return 0;
  
        rhs0 = gimple_assign_rhs1 (def_stmt);
!       tmp = combine_cond_expr_cond (loc, NE_EXPR, boolean_type_node, rhs0,
                                    build_int_cst (TREE_TYPE (rhs0), 0),
                                    false);
      }
--- 566,572 ----
        return 0;
  
        rhs0 = gimple_assign_rhs1 (def_stmt);
!       tmp = combine_cond_expr_cond (stmt, NE_EXPR, boolean_type_node, rhs0,
                                    build_int_cst (TREE_TYPE (rhs0), 0),
                                    false);
      }
*************** ssa_forward_propagate_and_combine (void)
*** 2440,2466 ****
                  {
                    /* In this case the entire COND_EXPR is in rhs1. */
                    int did_something;
-                   fold_defer_overflow_warnings ();
                    did_something = forward_propagate_into_cond (&gsi);
                    stmt = gsi_stmt (gsi);
                    if (did_something == 2)
                      cfg_changed = true;
-                   fold_undefer_overflow_warnings
-                     (!TREE_NO_WARNING (rhs1) && did_something, stmt,
-                      WARN_STRICT_OVERFLOW_CONDITIONAL);
                    changed = did_something != 0;
                  }
                else if (TREE_CODE_CLASS (code) == tcc_comparison)
                  {
-                   bool no_warning = gimple_no_warning_p (stmt);
                    int did_something;
-                   fold_defer_overflow_warnings ();
                    did_something = forward_propagate_into_comparison (&gsi);
                    if (did_something == 2)
                      cfg_changed = true;
-                   fold_undefer_overflow_warnings
-                       (!no_warning && changed,
-                        stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
                    changed = did_something != 0;
                  }
                else if (code == BIT_AND_EXPR
--- 2447,2464 ----
*************** ssa_forward_propagate_and_combine (void)
*** 2489,2500 ****
            case GIMPLE_COND:
              {
                int did_something;
-               fold_defer_overflow_warnings ();
                did_something = forward_propagate_into_gimple_cond (stmt);
                if (did_something == 2)
                  cfg_changed = true;
-               fold_undefer_overflow_warnings
-                 (did_something, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
                changed = did_something != 0;
                break;
              }
--- 2487,2495 ----

Reply via email to