This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/61839] More optimize opportunity for VRP
- From: "kugan at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 12 Apr 2016 23:57:06 +0000
- Subject: [Bug tree-optimization/61839] More optimize opportunity for VRP
- Auto-submitted: auto-generated
- References: <bug-61839-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61839
kugan at gcc dot gnu.org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |kugan at gcc dot gnu.org
Known to fail|4.10.0 |5.0
--- Comment #2 from kugan at gcc dot gnu.org ---
> - c = b != 0 ? 486097858 : 972195717;
> + c = a + 972195718 >> (b != 0);
...
> until the very end, not transforming c_6. Note that VRP could do the
> missing transform as it knows that _5 is [0, 1] (it has to jump through
> the shift - the value-range for the shift itself is too broad).
>
> If written this kind of transform should be applied more generally, not
> just for shifts. It basically wants to ask whether a conditional test
> can be carried out against another SSA name (and another constant) if
> an intermediate compute can be omitted in that case.
Do you mean something like,
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index bbdf9ce..dfce619 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -9902,6 +9902,47 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
{
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+ tree var;
+
+ /* Convert:
+ COND_RES = X COMPARE Y
+ TMP = (CAST) COND_RES
+ LHS = CST BINOP TMP
+
+ To:
+ LHS = COND_RES ? (CST BINOP 1) : (CST BINOP 0) */
+
+ if (TREE_CODE_CLASS (rhs_code) == tcc_binary
+ && TREE_CODE (rhs1) == INTEGER_CST
+ && TREE_CODE (rhs2) == SSA_NAME
+ && is_gimple_assign (SSA_NAME_DEF_STMT (rhs2))
+ && gimple_assign_rhs_code (SSA_NAME_DEF_STMT (rhs2)) == NOP_EXPR
+ && (var = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs2)))
+ && TREE_CODE (var) == SSA_NAME
+ && is_gimple_assign (SSA_NAME_DEF_STMT (var))
+ && TREE_CODE_CLASS (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (var)))
+ == tcc_comparison)
+
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ value_range *vr = get_value_range (var);
+ if (range_int_cst_p (vr)
+ && integer_zerop (vr->min)
+ && integer_onep (vr->max))
+ {
+
+ tree lhs = gimple_assign_lhs (stmt);
+ tree new_rhs1 = int_const_binop (rhs_code, rhs1, vr->min);
+ tree new_rhs2 = int_const_binop (rhs_code, rhs1, vr->max);
+
+ gimple *s = gimple_build_assign (lhs, COND_EXPR, var,
+ new_rhs1,
+ new_rhs2 PASS_MEM_STAT);
+ gsi_replace (&gsi, s, false);
+ return true;
+ }
+ }
switch (rhs_code)
{