diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index edf292cfbe9..b908d329f1e 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "builtins.h" #include "opts.h" +#include "gimple-range.h" /* Some systems use __main in a way incompatible with its use in gcc, in these cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to @@ -3981,7 +3982,7 @@ expand_gimple_stmt_1 (gimple *stmt) don't directly expand to target. */ temp = nontemporal || promoted ? NULL_RTX : target; temp = expand_expr_real_2 (&ops, temp, GET_MODE (target), - EXPAND_NORMAL); + EXPAND_NORMAL, stmt); if (temp == target) ; @@ -6606,6 +6607,9 @@ pass_expand::execute (function *fun) rtx_insn *var_seq, *var_ret_seq; unsigned i; + if (optimize >= 2) + enable_ranger (cfun, false); + timevar_push (TV_OUT_OF_SSA); rewrite_out_of_ssa (&SA); timevar_pop (TV_OUT_OF_SSA); @@ -7054,6 +7058,9 @@ pass_expand::execute (function *fun) timevar_pop (TV_POST_EXPAND); + if (optimize >= 2) + disable_ranger (cfun); + return 0; } diff --git a/gcc/expr.cc b/gcc/expr.cc index 9a37bff1fdd..934fcbb9f63 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see #include "rtx-vector-builder.h" #include "tree-pretty-print.h" #include "flags.h" +#include "value-query.h" /* If this is nonzero, we do not bother generating VOLATILE @@ -9207,7 +9208,7 @@ expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0, rtx expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, - enum expand_modifier modifier) + enum expand_modifier modifier, gimple *stmt) { rtx op0, op1, op2, temp; rtx_code_label *lab; @@ -9958,6 +9959,27 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, expand_operands (treeop0, treeop1, target, &op0, &op1, EXPAND_NORMAL); + /* For MIN if a has a range with a lower bound of 0, + just expand as a != 0 if we can. */ + if (INTEGRAL_TYPE_P (type) + && op1 == const1_rtx + && code == MIN_EXPR) + { + value_range vr; + get_range_query (cfun)->range_of_expr (vr, treeop0, stmt); + if (vr.undefined_p ()) + vr.set_varying (type); + if (vr.lower_bound() == 0) + { + rtx tmp = emit_store_flag_force (target, NE, + op0, const0_rtx, + mode, unsignedp, + 1); + if (tmp) + return tmp; + } + } + /* First try to do it with a special MIN or MAX instruction. If that does not win, use a conditional jump to select the proper value. */ diff --git a/gcc/expr.h b/gcc/expr.h index 11bff531862..8aec76e4f31 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -298,7 +298,7 @@ extern rtx expand_expr_real (tree, rtx, machine_mode, extern rtx expand_expr_real_1 (tree, rtx, machine_mode, enum expand_modifier, rtx *, bool); extern rtx expand_expr_real_2 (sepops, rtx, machine_mode, - enum expand_modifier); + enum expand_modifier, gimple * = nullptr); /* Generate code for computing expression EXP. An rtx for the computed value is returned. The value is never null.