Hi, I was trying to use the ranger from inside of cfgexpand but since at this point we have a mix of RTL and gimple basic blocks, things fall over very fast.
First does it make sense to use the ranger from expand or should we change the gimple IR in isel instead if we have a better way of doing an expansion. In this case we have MIN_EXPR<a, 1> where a has a range of [0,INF] and I want to expand it as (a != 0) to get better code. Attached is the current patch which I did and a testcase which ICEs at -O2. The backtrace of the ICE is: 0x88c885 gsi_last_bb(basic_block_def*) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-iterator.h:165 0x88c885 gsi_last_nondebug_bb(basic_block_def*) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-iterator.h:325 0x88c885 gimple_outgoing_range_stmt_p(basic_block_def*) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range-edge.cc:42 0xe05739 gimple_outgoing_range::edge_range_p(irange&, edge_def*) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range-edge.cc:194 0xe12afa gori_compute::outgoing_edge_range_p(vrange&, edge_def*, tree_node*, range_query&) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range-gori.cc:1404 0xe00dde ranger_cache::edge_range(vrange&, edge_def*, tree_node*, ranger_cache::rfd_mode) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range-cache.cc:1185 0xe01e48 ranger_cache::propagate_cache(tree_node*) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range-cache.cc:1305 0xe0306f ranger_cache::fill_block_cache(tree_node*, basic_block_def*, basic_block_def*) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range-cache.cc:1592 0xe039b1 ranger_cache::block_range(vrange&, basic_block_def*, tree_node*, bool) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range-cache.cc:1260 0xdf9776 gimple_ranger::range_on_entry(vrange&, basic_block_def*, tree_node*) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range.cc:164 0xdfcc29 gimple_ranger::range_of_expr(vrange&, tree_node*, gimple*) /home/apinski/src/upstream-gcc-git/gcc/gcc/gimple-range.cc:138 0xd1a334 expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier, gimple*) /home/apinski/src/upstream-gcc-git/gcc/gcc/expr.cc:9969 Thanks, Andrew Pinski
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<a, 1> 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.
t3.c
Description: Binary data