expr.c (expand_expr_real_2): Move COND_EXPR and VEC_COND_EXPR handling here, from ...
authorRichard Guenther <rguenther@suse.de>
Thu, 1 Sep 2011 11:46:08 +0000 (11:46 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 1 Sep 2011 11:46:08 +0000 (11:46 +0000)
2011-08-31  Richard Guenther  <rguenther@suse.de>

* expr.c (expand_expr_real_2): Move COND_EXPR and VEC_COND_EXPR
handling here, from ...
(expand_expr_real_1): ... here.
* gimple-pretty-print.c (dump_ternary_rhs): Handle COND_EXPR
and VEC_COND_EXPR.
* gimple.c (gimple_rhs_class_table): Make COND_EXPR and VEC_COND_EXPR
a GIMPLE_TERNARY_RHS.
* tree-cfg.c (verify_gimple_assign_ternary): Handle COND_EXPR
and VEC_COND_EXPR here ...
(verify_gimple_assign_single): ... not here.
* gimple-fold.c (fold_gimple_assign): Move COND_EXPR folding.
* tree-object-size.c (cond_expr_object_size): Adjust.
(collect_object_sizes_for): Likewise.
* tree-scalar-evolution.c (interpret_expr): Don't handle
ternary RHSs.
* tree-ssa-forwprop.c (forward_propagate_into_cond): Fix and
simplify.
(ssa_forward_propagate_and_combine): Adjust.
* tree-ssa-loop-im.c (move_computations_stmt): Build the COND_EXPR
as ternary.
* tree-ssa-threadedge.c (fold_assignment_stmt): Adjust.
* tree-vect-loop.c (vect_is_simple_reduction_1): Likewise.
* tree-vect-stmt.c (vectorizable_condition): Likewise.
* tree-vrp.c (extract_range_from_cond_expr): Likewise.
(extract_range_from_assignment): Likewise.

From-SVN: r178408

14 files changed:
gcc/ChangeLog
gcc/expr.c
gcc/gimple-fold.c
gcc/gimple-pretty-print.c
gcc/gimple.c
gcc/tree-cfg.c
gcc/tree-object-size.c
gcc/tree-scalar-evolution.c
gcc/tree-ssa-forwprop.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-threadedge.c
gcc/tree-vect-loop.c
gcc/tree-vect-stmts.c
gcc/tree-vrp.c

index 71155e2b5435e9836343adf8535ae347823a2ea8..ffd2855a31bd5296a3f5f01fedac81831ee8126b 100644 (file)
@@ -1,3 +1,31 @@
+2011-08-31  Richard Guenther  <rguenther@suse.de>
+
+       * expr.c (expand_expr_real_2): Move COND_EXPR and VEC_COND_EXPR
+       handling here, from ...
+       (expand_expr_real_1): ... here.
+       * gimple-pretty-print.c (dump_ternary_rhs): Handle COND_EXPR
+       and VEC_COND_EXPR.
+       * gimple.c (gimple_rhs_class_table): Make COND_EXPR and VEC_COND_EXPR
+       a GIMPLE_TERNARY_RHS.
+       * tree-cfg.c (verify_gimple_assign_ternary): Handle COND_EXPR
+       and VEC_COND_EXPR here ...
+       (verify_gimple_assign_single): ... not here.
+       * gimple-fold.c (fold_gimple_assign): Move COND_EXPR folding.
+       * tree-object-size.c (cond_expr_object_size): Adjust.
+       (collect_object_sizes_for): Likewise.
+       * tree-scalar-evolution.c (interpret_expr): Don't handle
+       ternary RHSs.
+       * tree-ssa-forwprop.c (forward_propagate_into_cond): Fix and
+       simplify.
+       (ssa_forward_propagate_and_combine): Adjust.
+       * tree-ssa-loop-im.c (move_computations_stmt): Build the COND_EXPR
+       as ternary.
+       * tree-ssa-threadedge.c (fold_assignment_stmt): Adjust.
+       * tree-vect-loop.c (vect_is_simple_reduction_1): Likewise.
+       * tree-vect-stmt.c (vectorizable_condition): Likewise.
+       * tree-vrp.c (extract_range_from_cond_expr): Likewise.
+       (extract_range_from_assignment): Likewise.
+
 2011-08-31  Richard Sandiford  <rdsandiford@googlemail.com>
 
        * config/i386/i386.md: Use (match_test ...) for attribute tests.
index e29f3f6f4f9fece7820c8a46658ea3cc25940c4f..6e35db2f2e015934c0e584abd81e4a7017e5c06d 100644 (file)
@@ -8636,6 +8636,64 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
         return temp;
       }
 
+    case COND_EXPR:
+      /* A COND_EXPR with its type being VOID_TYPE represents a
+        conditional jump and is handled in
+        expand_gimple_cond_expr.  */
+      gcc_assert (!VOID_TYPE_P (type));
+
+      /* Note that COND_EXPRs whose type is a structure or union
+        are required to be constructed to contain assignments of
+        a temporary variable, so that we can evaluate them here
+        for side effect only.  If type is void, we must do likewise.  */
+
+      gcc_assert (!TREE_ADDRESSABLE (type)
+                 && !ignore
+                 && TREE_TYPE (treeop1) != void_type_node
+                 && TREE_TYPE (treeop2) != void_type_node);
+
+      /* If we are not to produce a result, we have no target.  Otherwise,
+        if a target was specified use it; it will not be used as an
+        intermediate target unless it is safe.  If no target, use a
+        temporary.  */
+
+      if (modifier != EXPAND_STACK_PARM
+         && original_target
+         && safe_from_p (original_target, treeop0, 1)
+         && GET_MODE (original_target) == mode
+#ifdef HAVE_conditional_move
+         && (! can_conditionally_move_p (mode)
+             || REG_P (original_target))
+#endif
+         && !MEM_P (original_target))
+       temp = original_target;
+      else
+       temp = assign_temp (type, 0, 0, 1);
+
+      do_pending_stack_adjust ();
+      NO_DEFER_POP;
+      op0 = gen_label_rtx ();
+      op1 = gen_label_rtx ();
+      jumpifnot (treeop0, op0, -1);
+      store_expr (treeop1, temp,
+                 modifier == EXPAND_STACK_PARM,
+                 false);
+
+      emit_jump_insn (gen_jump (op1));
+      emit_barrier ();
+      emit_label (op0);
+      store_expr (treeop2, temp,
+                 modifier == EXPAND_STACK_PARM,
+                 false);
+
+      emit_label (op1);
+      OK_DEFER_POP;
+      return temp;
+
+    case VEC_COND_EXPR:
+      target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target);
+      return target;
+
     default:
       gcc_unreachable ();
     }
@@ -9878,64 +9936,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
 
       return op0;
 
-    case COND_EXPR:
-      /* A COND_EXPR with its type being VOID_TYPE represents a
-        conditional jump and is handled in
-        expand_gimple_cond_expr.  */
-      gcc_assert (!VOID_TYPE_P (type));
-
-        /* Note that COND_EXPRs whose type is a structure or union
-        are required to be constructed to contain assignments of
-        a temporary variable, so that we can evaluate them here
-        for side effect only.  If type is void, we must do likewise.  */
-
-        gcc_assert (!TREE_ADDRESSABLE (type)
-                   && !ignore
-                   && TREE_TYPE (treeop1) != void_type_node
-                   && TREE_TYPE (treeop2) != void_type_node);
-
-       /* If we are not to produce a result, we have no target.  Otherwise,
-        if a target was specified use it; it will not be used as an
-        intermediate target unless it is safe.  If no target, use a
-        temporary.  */
-
-       if (modifier != EXPAND_STACK_PARM
-         && original_target
-         && safe_from_p (original_target, treeop0, 1)
-         && GET_MODE (original_target) == mode
-#ifdef HAVE_conditional_move
-         && (! can_conditionally_move_p (mode)
-             || REG_P (original_target))
-#endif
-         && !MEM_P (original_target))
-       temp = original_target;
-       else
-       temp = assign_temp (type, 0, 0, 1);
-
-       do_pending_stack_adjust ();
-       NO_DEFER_POP;
-       op0 = gen_label_rtx ();
-       op1 = gen_label_rtx ();
-       jumpifnot (treeop0, op0, -1);
-       store_expr (treeop1, temp,
-                 modifier == EXPAND_STACK_PARM,
-                 false);
-
-       emit_jump_insn (gen_jump (op1));
-       emit_barrier ();
-       emit_label (op0);
-       store_expr (treeop2, temp,
-                 modifier == EXPAND_STACK_PARM,
-                 false);
-
-       emit_label (op1);
-       OK_DEFER_POP;
-       return temp;
-
-    case VEC_COND_EXPR:
-      target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target);
-      return target;
-
     case MODIFY_EXPR:
       {
        tree lhs = treeop0;
index 72dc42a5bdc9f410e033f3c5fb06753d458a1038..be5535bf113ead3f75c2934250777ee4f5fb1ac9 100644 (file)
@@ -294,42 +294,7 @@ fold_gimple_assign (gimple_stmt_iterator *si)
       {
         tree rhs = gimple_assign_rhs1 (stmt);
 
-        /* Try to fold a conditional expression.  */
-        if (TREE_CODE (rhs) == COND_EXPR)
-          {
-           tree op0 = COND_EXPR_COND (rhs);
-           tree tem;
-           bool set = false;
-           location_t cond_loc = EXPR_LOCATION (rhs);
-
-           if (COMPARISON_CLASS_P (op0))
-             {
-               fold_defer_overflow_warnings ();
-               tem = fold_binary_loc (cond_loc,
-                                  TREE_CODE (op0), TREE_TYPE (op0),
-                                  TREE_OPERAND (op0, 0),
-                                  TREE_OPERAND (op0, 1));
-               /* This is actually a conditional expression, not a GIMPLE
-                  conditional statement, however, the valid_gimple_rhs_p
-                  test still applies.  */
-               set = (tem && is_gimple_condexpr (tem)
-                      && valid_gimple_rhs_p (tem));
-               fold_undefer_overflow_warnings (set, stmt, 0);
-             }
-           else if (is_gimple_min_invariant (op0))
-             {
-               tem = op0;
-               set = true;
-             }
-           else
-             return NULL_TREE;
-
-           if (set)
-             result = fold_build3_loc (cond_loc, COND_EXPR, TREE_TYPE (rhs), tem,
-                                   COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
-          }
-
-       else if (REFERENCE_CLASS_P (rhs))
+       if (REFERENCE_CLASS_P (rhs))
          return maybe_fold_reference (rhs, false);
 
        else if (TREE_CODE (rhs) == ADDR_EXPR)
@@ -469,11 +434,49 @@ fold_gimple_assign (gimple_stmt_iterator *si)
       break;
 
     case GIMPLE_TERNARY_RHS:
-      result = fold_ternary_loc (loc, subcode,
-                                TREE_TYPE (gimple_assign_lhs (stmt)),
-                                gimple_assign_rhs1 (stmt),
-                                gimple_assign_rhs2 (stmt),
-                                gimple_assign_rhs3 (stmt));
+      /* Try to fold a conditional expression.  */
+      if (gimple_assign_rhs_code (stmt) == COND_EXPR)
+       {
+         tree op0 = gimple_assign_rhs1 (stmt);
+         tree tem;
+         bool set = false;
+         location_t cond_loc = gimple_location (stmt);
+
+         if (COMPARISON_CLASS_P (op0))
+           {
+             fold_defer_overflow_warnings ();
+             tem = fold_binary_loc (cond_loc,
+                                    TREE_CODE (op0), TREE_TYPE (op0),
+                                    TREE_OPERAND (op0, 0),
+                                    TREE_OPERAND (op0, 1));
+             /* This is actually a conditional expression, not a GIMPLE
+                conditional statement, however, the valid_gimple_rhs_p
+                test still applies.  */
+             set = (tem && is_gimple_condexpr (tem)
+                    && valid_gimple_rhs_p (tem));
+             fold_undefer_overflow_warnings (set, stmt, 0);
+           }
+         else if (is_gimple_min_invariant (op0))
+           {
+             tem = op0;
+             set = true;
+           }
+         else
+           return NULL_TREE;
+
+         if (set)
+           result = fold_build3_loc (cond_loc, COND_EXPR,
+                                     TREE_TYPE (gimple_assign_lhs (stmt)), tem,
+                                     gimple_assign_rhs2 (stmt),
+                                     gimple_assign_rhs3 (stmt));
+       }
+
+      if (!result)
+       result = fold_ternary_loc (loc, subcode,
+                                  TREE_TYPE (gimple_assign_lhs (stmt)),
+                                  gimple_assign_rhs1 (stmt),
+                                  gimple_assign_rhs2 (stmt),
+                                  gimple_assign_rhs3 (stmt));
 
       if (result)
         {
index eaf3e5fa995fcd045c77025a6adefaa63ad18710..1f6efc993f2d7c5f702059ea3e0c53887bf88ac7 100644 (file)
@@ -428,6 +428,24 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
       pp_string (buffer, ">");
       break;
 
+    case COND_EXPR:
+      dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+      pp_string (buffer, " ? ");
+      dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+      pp_string (buffer, " : ");
+      dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
+      break;
+
+    case VEC_COND_EXPR:
+      pp_string (buffer, "VEC_COND_EXPR <");
+      dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+      pp_string (buffer, ", ");
+      dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
+      pp_string (buffer, ">");
+      break;
+
     default:
       gcc_unreachable ();
     }
index 561e41e45826d351992b9c74f0dd2afdc15d8f3c..75885bbb20e6e4ea9bf4d2c9f6d42dd3938b554d 100644 (file)
@@ -2611,19 +2611,19 @@ get_gimple_rhs_num_ops (enum tree_code code)
       || (SYM) == TRUTH_OR_EXPR                                                    \
       || (SYM) == TRUTH_XOR_EXPR) ? GIMPLE_BINARY_RHS                      \
    : (SYM) == TRUTH_NOT_EXPR ? GIMPLE_UNARY_RHS                                    \
-   : ((SYM) == WIDEN_MULT_PLUS_EXPR                                        \
+   : ((SYM) == COND_EXPR                                                   \
+      || (SYM) == WIDEN_MULT_PLUS_EXPR                                     \
       || (SYM) == WIDEN_MULT_MINUS_EXPR                                            \
       || (SYM) == DOT_PROD_EXPR                                                    \
       || (SYM) == REALIGN_LOAD_EXPR                                        \
+      || (SYM) == VEC_COND_EXPR                                                    \
       || (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS                           \
-   : ((SYM) == COND_EXPR                                                   \
-      || (SYM) == CONSTRUCTOR                                              \
+   : ((SYM) == CONSTRUCTOR                                                 \
       || (SYM) == OBJ_TYPE_REF                                             \
       || (SYM) == ASSERT_EXPR                                              \
       || (SYM) == ADDR_EXPR                                                \
       || (SYM) == WITH_SIZE_EXPR                                           \
-      || (SYM) == SSA_NAME                                                 \
-      || (SYM) == VEC_COND_EXPR) ? GIMPLE_SINGLE_RHS                       \
+      || (SYM) == SSA_NAME) ? GIMPLE_SINGLE_RHS                                    \
    : GIMPLE_INVALID_RHS),
 #define END_OF_BASE_TREE_CODES (unsigned char) GIMPLE_INVALID_RHS,
 
index bcb8ba9b742a3a31da4df33914f3335d0aebfe2d..62e2da0c12f5004afe035dbee50de31b1dc2a91b 100644 (file)
@@ -3668,7 +3668,8 @@ verify_gimple_assign_ternary (gimple stmt)
       return true;
     }
 
-  if (!is_gimple_val (rhs1)
+  if (((rhs_code == VEC_COND_EXPR || rhs_code == COND_EXPR)
+       ? !is_gimple_condexpr (rhs1) : !is_gimple_val (rhs1))
       || !is_gimple_val (rhs2)
       || !is_gimple_val (rhs3))
     {
@@ -3711,6 +3712,19 @@ verify_gimple_assign_ternary (gimple stmt)
        }
       break;
 
+    case COND_EXPR:
+    case VEC_COND_EXPR:
+      if (!useless_type_conversion_p (lhs_type, rhs2_type)
+         || !useless_type_conversion_p (lhs_type, rhs3_type))
+       {
+         error ("type mismatch in conditional expression");
+         debug_generic_expr (lhs_type);
+         debug_generic_expr (rhs2_type);
+         debug_generic_expr (rhs3_type);
+         return true;
+       }
+      break;
+
     case DOT_PROD_EXPR:
     case REALIGN_LOAD_EXPR:
       /* FIXME.  */
@@ -3827,26 +3841,10 @@ verify_gimple_assign_single (gimple stmt)
        }
       return res;
 
-    case COND_EXPR:
-      if (!is_gimple_reg (lhs)
-         || (!is_gimple_reg (TREE_OPERAND (rhs1, 0))
-             && !COMPARISON_CLASS_P (TREE_OPERAND (rhs1, 0)))
-         || (!is_gimple_reg (TREE_OPERAND (rhs1, 1))
-             && !is_gimple_min_invariant (TREE_OPERAND (rhs1, 1)))
-         || (!is_gimple_reg (TREE_OPERAND (rhs1, 2))
-             && !is_gimple_min_invariant (TREE_OPERAND (rhs1, 2))))
-       {
-         error ("invalid COND_EXPR in gimple assignment");
-         debug_generic_stmt (rhs1);
-         return true;
-       }
-      return res;
-
     case CONSTRUCTOR:
     case OBJ_TYPE_REF:
     case ASSERT_EXPR:
     case WITH_SIZE_EXPR:
-    case VEC_COND_EXPR:
       /* FIXME.  */
       return res;
 
index b85c9730f1d96c73f49de51908e577274050b810..b1767584da8a3aefa3e6fe0ef3a2c84b4b5abeeb 100644 (file)
@@ -53,7 +53,7 @@ static void expr_object_size (struct object_size_info *, tree, tree);
 static bool merge_object_sizes (struct object_size_info *, tree, tree,
                                unsigned HOST_WIDE_INT);
 static bool plus_stmt_object_size (struct object_size_info *, tree, gimple);
-static bool cond_expr_object_size (struct object_size_info *, tree, tree);
+static bool cond_expr_object_size (struct object_size_info *, tree, gimple);
 static unsigned int compute_object_sizes (void);
 static void init_offset_limit (void);
 static void check_for_plus_in_loops (struct object_size_info *, tree);
@@ -827,25 +827,25 @@ plus_stmt_object_size (struct object_size_info *osi, tree var, gimple stmt)
 }
 
 
-/* Compute object_sizes for VAR, defined to VALUE, which is
+/* Compute object_sizes for VAR, defined at STMT, which is
    a COND_EXPR.  Return true if the object size might need reexamination
    later.  */
 
 static bool
-cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
+cond_expr_object_size (struct object_size_info *osi, tree var, gimple stmt)
 {
   tree then_, else_;
   int object_size_type = osi->object_size_type;
   unsigned int varno = SSA_NAME_VERSION (var);
   bool reexamine = false;
 
-  gcc_assert (TREE_CODE (value) == COND_EXPR);
+  gcc_assert (gimple_assign_rhs_code (stmt) == COND_EXPR);
 
   if (object_sizes[object_size_type][varno] == unknown[object_size_type])
     return false;
 
-  then_ = COND_EXPR_THEN (value);
-  else_ = COND_EXPR_ELSE (value);
+  then_ = gimple_assign_rhs2 (stmt);
+  else_ = gimple_assign_rhs3 (stmt);
 
   if (TREE_CODE (then_) == SSA_NAME)
     reexamine |= merge_object_sizes (osi, var, then_, 0);
@@ -932,14 +932,14 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
            || (gimple_assign_rhs_code (stmt) == ADDR_EXPR
                && TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF))
           reexamine = plus_stmt_object_size (osi, var, stmt);
+       else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
+         reexamine = cond_expr_object_size (osi, var, stmt);
         else if (gimple_assign_single_p (stmt)
                  || gimple_assign_unary_nop_p (stmt))
           {
             if (TREE_CODE (rhs) == SSA_NAME
                 && POINTER_TYPE_P (TREE_TYPE (rhs)))
               reexamine = merge_object_sizes (osi, var, rhs, 0);
-            else if (TREE_CODE (rhs) == COND_EXPR)
-              reexamine = cond_expr_object_size (osi, var, rhs);
             else
               expr_object_size (osi, var, rhs);
           }
@@ -956,8 +956,6 @@ collect_object_sizes_for (struct object_size_info *osi, tree var)
             if (TREE_CODE (arg) == SSA_NAME
                 && POINTER_TYPE_P (TREE_TYPE (arg)))
               reexamine = merge_object_sizes (osi, var, arg, 0);
-            else if (TREE_CODE (arg) == COND_EXPR)
-              reexamine = cond_expr_object_size (osi, var, arg);
             else
               expr_object_size (osi, var, arg);
           }
index 646b4f1c5683602a5ec906044951c24ac88f4274..6c32923852e8df84888b33eca2b4bcff27634e83 100644 (file)
@@ -1796,7 +1796,8 @@ interpret_expr (struct loop *loop, gimple at_stmt, tree expr)
   if (automatically_generated_chrec_p (expr))
     return expr;
 
-  if (TREE_CODE (expr) == POLYNOMIAL_CHREC)
+  if (TREE_CODE (expr) == POLYNOMIAL_CHREC
+      || get_gimple_rhs_class (TREE_CODE (expr)) == GIMPLE_TERNARY_RHS)
     return chrec_dont_know;
 
   extract_ops_from_tree (expr, &code, &op0, &op1);
index 7dd5e08ac6d14e77f168c7ac9671caaa4584f77c..89d6239836bb754617dd1209960f8ed0b4a18379 100644 (file)
@@ -540,12 +540,9 @@ forward_propagate_into_gimple_cond (gimple stmt)
 
 /* Propagate from the ssa name definition statements of COND_EXPR
    in the rhs of statement STMT into the conditional if that simplifies it.
-   Returns zero if no statement was changed, one if there were
-   changes and two if cfg_cleanup needs to run.
-
-   This must be kept in sync with forward_propagate_into_gimple_cond.  */
+   Returns true zero if the stmt was changed.  */
 
-static int
+static bool
 forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
 {
   gimple stmt = gsi_stmt (*gsi_p);
@@ -560,15 +557,17 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
                                               TREE_OPERAND (cond, 1));
   else if (TREE_CODE (cond) == SSA_NAME)
     {
-      tree name = cond, rhs0;
+      tree name = cond;
       gimple def_stmt = get_prop_source_stmt (name, true, NULL);
       if (!def_stmt || !can_propagate_from (def_stmt))
        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);
+      if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison)
+       tmp = fold_build2_loc (gimple_location (def_stmt),
+                              gimple_assign_rhs_code (def_stmt),
+                              boolean_type_node,
+                              gimple_assign_rhs1 (def_stmt),
+                              gimple_assign_rhs2 (def_stmt));
     }
 
   if (tmp)
@@ -582,11 +581,16 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
          fprintf (dump_file, "'\n");
        }
 
-      gimple_assign_set_rhs_from_tree (gsi_p, unshare_expr (tmp));
+      if (integer_onep (tmp))
+       gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs2 (stmt));
+      else if (integer_zerop (tmp))
+       gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
+      else
+       gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
       stmt = gsi_stmt (*gsi_p);
       update_stmt (stmt);
 
-      return is_gimple_min_invariant (tmp) ? 2 : 1;
+      return true;
     }
 
   return 0;
@@ -2436,12 +2440,8 @@ ssa_forward_propagate_and_combine (void)
                else if (code == COND_EXPR)
                  {
                    /* In this case the entire COND_EXPR is in rhs1. */
-                   int did_something;
-                   did_something = forward_propagate_into_cond (&gsi);
+                   changed |= forward_propagate_into_cond (&gsi);
                    stmt = gsi_stmt (gsi);
-                   if (did_something == 2)
-                     cfg_changed = true;
-                   changed = did_something != 0;
                  }
                else if (TREE_CODE_CLASS (code) == tcc_comparison)
                  {
index 7828c5b343b091233d4776cceae4f4ad1214d257..cb527913d4f1b4d0df4001289ea2c114e4753552 100644 (file)
@@ -1251,11 +1251,9 @@ move_computations_stmt (struct dom_walk_data *dw_data,
          gcc_assert (arg0 && arg1);
          t = build2 (gimple_cond_code (cond), boolean_type_node,
                      gimple_cond_lhs (cond), gimple_cond_rhs (cond));
-         t = build3 (COND_EXPR, TREE_TYPE (gimple_phi_result (stmt)),
-                     t, arg0, arg1);
-         new_stmt = gimple_build_assign_with_ops (COND_EXPR,
-                                                  gimple_phi_result (stmt),
-                                                  t, NULL_TREE);
+         new_stmt = gimple_build_assign_with_ops3 (COND_EXPR,
+                                                   gimple_phi_result (stmt),
+                                                   t, arg0, arg1);
          SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt;
          *((unsigned int *)(dw_data->global_data)) |= TODO_cleanup_cfg;
        }
index a485b211e59286972639cbc659be125cdf260715..707c8df3ec59baf0a235749971f374b68788b211 100644 (file)
@@ -225,24 +225,7 @@ fold_assignment_stmt (gimple stmt)
   switch (get_gimple_rhs_class (subcode))
     {
     case GIMPLE_SINGLE_RHS:
-      {
-        tree rhs = gimple_assign_rhs1 (stmt);
-
-        if (TREE_CODE (rhs) == COND_EXPR)
-          {
-            /* Sadly, we have to handle conditional assignments specially
-               here, because fold expects all the operands of an expression
-               to be folded before the expression itself is folded, but we
-               can't just substitute the folded condition here.  */
-            tree cond = fold (COND_EXPR_COND (rhs));
-            if (cond == boolean_true_node)
-              rhs = COND_EXPR_THEN (rhs);
-            else if (cond == boolean_false_node)
-              rhs = COND_EXPR_ELSE (rhs);
-          }
-
-        return fold (rhs);
-      }
+      return fold (gimple_assign_rhs1 (stmt));
 
     case GIMPLE_UNARY_RHS:
       {
@@ -265,6 +248,14 @@ fold_assignment_stmt (gimple stmt)
         tree op0 = gimple_assign_rhs1 (stmt);
         tree op1 = gimple_assign_rhs2 (stmt);
         tree op2 = gimple_assign_rhs3 (stmt);
+
+       /* Sadly, we have to handle conditional assignments specially
+          here, because fold expects all the operands of an expression
+          to be folded before the expression itself is folded, but we
+          can't just substitute the folded condition here.  */
+        if (gimple_assign_rhs_code (stmt) == COND_EXPR)
+         op0 = fold (op0);
+
         return fold_ternary (subcode, TREE_TYPE (lhs), op0, op1, op2);
       }
 
index 539bcaabd9709f58012b07c497bfd36d8dfcff36..5c0b0a1c753f7533e73bb6a950f67294fa1d2f01 100644 (file)
@@ -2126,15 +2126,15 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
           return NULL;
         }
 
-      op3 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
+      op3 = gimple_assign_rhs1 (def_stmt);
       if (COMPARISON_CLASS_P (op3))
         {
           op4 = TREE_OPERAND (op3, 1);
           op3 = TREE_OPERAND (op3, 0);
         }
 
-      op1 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 1);
-      op2 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 2);
+      op1 = gimple_assign_rhs2 (def_stmt);
+      op2 = gimple_assign_rhs3 (def_stmt);
 
       if (TREE_CODE (op1) != SSA_NAME && TREE_CODE (op2) != SSA_NAME)
         {
index 3b5fa01f8fbd700144d63fe161e81f7b8bc40a5f..2a1318195e5b719e314e5052fbb6087186b0652d 100644 (file)
@@ -4740,7 +4740,6 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
 {
   tree scalar_dest = NULL_TREE;
   tree vec_dest = NULL_TREE;
-  tree op = NULL_TREE;
   tree cond_expr, then_clause, else_clause;
   stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
   tree vectype = STMT_VINFO_VECTYPE (stmt_info);
@@ -4794,11 +4793,9 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
   if (code != COND_EXPR)
     return false;
 
-  gcc_assert (gimple_assign_single_p (stmt));
-  op = gimple_assign_rhs1 (stmt);
-  cond_expr = TREE_OPERAND (op, 0);
-  then_clause = TREE_OPERAND (op, 1);
-  else_clause = TREE_OPERAND (op, 2);
+  cond_expr = gimple_assign_rhs1 (stmt);
+  then_clause = gimple_assign_rhs2 (stmt);
+  else_clause = gimple_assign_rhs3 (stmt);
 
   if (!vect_is_simple_cond (cond_expr, loop_vinfo))
     return false;
@@ -4839,7 +4836,8 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
   if (!vec_stmt)
     {
       STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
-      return expand_vec_cond_expr_p (TREE_TYPE (op), vec_mode);
+      return expand_vec_cond_expr_p (TREE_TYPE (gimple_assign_lhs (stmt)),
+                                    vec_mode);
     }
 
   /* Transform */
index df19cbbfdd1133d9a17d343cd13d2d02f7f03cd3..56fc5a20b2b4a65f0773e566e4f2d9918587a7d7 100644 (file)
@@ -3190,11 +3190,11 @@ extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
 }
 
 
-/* Extract range information from a conditional expression EXPR based on
+/* Extract range information from a conditional expression STMT based on
    the ranges of each of its operands and the expression code.  */
 
 static void
-extract_range_from_cond_expr (value_range_t *vr, tree expr)
+extract_range_from_cond_expr (value_range_t *vr, gimple stmt)
 {
   tree op0, op1;
   value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
@@ -3202,7 +3202,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr)
 
   /* Get value ranges for each operand.  For constant operands, create
      a new value range with the operand to simplify processing.  */
-  op0 = COND_EXPR_THEN (expr);
+  op0 = gimple_assign_rhs2 (stmt);
   if (TREE_CODE (op0) == SSA_NAME)
     vr0 = *(get_value_range (op0));
   else if (is_gimple_min_invariant (op0))
@@ -3210,7 +3210,7 @@ extract_range_from_cond_expr (value_range_t *vr, tree expr)
   else
     set_value_range_to_varying (&vr0);
 
-  op1 = COND_EXPR_ELSE (expr);
+  op1 = gimple_assign_rhs3 (stmt);
   if (TREE_CODE (op1) == SSA_NAME)
     vr1 = *(get_value_range (op1));
   else if (is_gimple_min_invariant (op1))
@@ -3302,7 +3302,7 @@ extract_range_from_assignment (value_range_t *vr, gimple stmt)
                                   gimple_expr_type (stmt),
                                   gimple_assign_rhs1 (stmt));
   else if (code == COND_EXPR)
-    extract_range_from_cond_expr (vr, gimple_assign_rhs1 (stmt));
+    extract_range_from_cond_expr (vr, stmt);
   else if (TREE_CODE_CLASS (code) == tcc_comparison)
     extract_range_from_comparison (vr, gimple_assign_rhs_code (stmt),
                                   gimple_expr_type (stmt),