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.

Attachment: t3.c
Description: Binary data

Reply via email to