From: rguenth Date: Thu, 1 Sep 2011 11:46:08 +0000 (+0000) Subject: 2011-08-31 Richard Guenther X-Git-Tag: upstream/4.9.2~18016 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8a2caf10dc2cc415e4b494611dad5c8bffb7c9df;p=platform%2Fupstream%2Flinaro-gcc.git 2011-08-31 Richard Guenther * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@178408 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 71155e2..ffd2855 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2011-08-31 Richard Guenther + + * 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 * config/i386/i386.md: Use (match_test ...) for attribute tests. diff --git a/gcc/expr.c b/gcc/expr.c index e29f3f6..6e35db2 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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; diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 72dc42a..be5535b 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -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) { diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index eaf3e5f..1f6efc9 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -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 (); } diff --git a/gcc/gimple.c b/gcc/gimple.c index 561e41e..75885bb 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -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, diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index bcb8ba9..62e2da0 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -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; diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index b85c973..b176758 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -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); } diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c index 646b4f1c..6c32923 100644 --- a/gcc/tree-scalar-evolution.c +++ b/gcc/tree-scalar-evolution.c @@ -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); diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 7dd5e08..89d6239 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -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) { diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 7828c5b..cb52791 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -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; } diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index a485b21..707c8df 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -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); } diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 539bcaa..5c0b0a1 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -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) { diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 3b5fa01..2a13181 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -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 */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index df19cbb..56fc5a2 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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),