aboutsummaryrefslogtreecommitdiff
path: root/gcc/vr-values.c
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2021-10-25 18:04:06 -0400
committerAndrew MacLeod <amacleod@redhat.com>2021-10-25 19:39:50 -0400
commitf5bacd9c5be5e129688d9c91eeed05e7b968117e (patch)
treeb4ff3281056503053939cfbc7ad8ef91ba7315ea /gcc/vr-values.c
parentcb153222404e2e149aa65a4b3139b09477551203 (diff)
downloadgcc-f5bacd9c5be5e129688d9c91eeed05e7b968117e.zip
gcc-f5bacd9c5be5e129688d9c91eeed05e7b968117e.tar.gz
gcc-f5bacd9c5be5e129688d9c91eeed05e7b968117e.tar.bz2
Move vrp_simplify_cond_using_ranges into the simplifier.
This static VRP routine does a simplification with casted conditions. Add it to the general simplfier, and continue to invoke if from the VRP folder. * tree-vrp.c (vrp_simplify_cond_using_ranges): Add return type and move to vr-values.c. (simplify_casted_conds): Move to vrp_folder class. (execute_vrp): Call via vrp_folder now. * vr-values.c (simplify_cond_using_ranges_1): Call simplify_casted_cond. (simplify_using_ranges::simplify_casted_cond): Relocate from tree-vrp.c. * vr-values.h (simplify_casted_cond): Add prototype.
Diffstat (limited to 'gcc/vr-values.c')
-rw-r--r--gcc/vr-values.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index d0f7cb4..00246c9 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -3630,6 +3630,75 @@ simplify_using_ranges::simplify_cond_using_ranges_1 (gcond *stmt)
}
}
}
+ // Try to simplify casted conditions.
+ return simplify_casted_cond (stmt);
+}
+
+/* STMT is a conditional at the end of a basic block.
+
+ If the conditional is of the form SSA_NAME op constant and the SSA_NAME
+ was set via a type conversion, try to replace the SSA_NAME with the RHS
+ of the type conversion. Doing so makes the conversion dead which helps
+ subsequent passes. */
+
+bool
+simplify_using_ranges::simplify_casted_cond (gcond *stmt)
+{
+ tree op0 = gimple_cond_lhs (stmt);
+ tree op1 = gimple_cond_rhs (stmt);
+
+ /* If we have a comparison of an SSA_NAME (OP0) against a constant,
+ see if OP0 was set by a type conversion where the source of
+ the conversion is another SSA_NAME with a range that fits
+ into the range of OP0's type.
+
+ If so, the conversion is redundant as the earlier SSA_NAME can be
+ used for the comparison directly if we just massage the constant in the
+ comparison. */
+ if (TREE_CODE (op0) == SSA_NAME
+ && TREE_CODE (op1) == INTEGER_CST)
+ {
+ gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
+ tree innerop;
+
+ if (!is_gimple_assign (def_stmt))
+ return false;
+
+ switch (gimple_assign_rhs_code (def_stmt))
+ {
+ CASE_CONVERT:
+ innerop = gimple_assign_rhs1 (def_stmt);
+ break;
+ case VIEW_CONVERT_EXPR:
+ innerop = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
+ return false;
+ break;
+ default:
+ return false;
+ }
+
+ if (TREE_CODE (innerop) == SSA_NAME
+ && !POINTER_TYPE_P (TREE_TYPE (innerop))
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
+ && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
+ {
+ const value_range *vr = query->get_value_range (innerop);
+
+ if (range_int_cst_p (vr)
+ && range_fits_type_p (vr,
+ TYPE_PRECISION (TREE_TYPE (op0)),
+ TYPE_SIGN (TREE_TYPE (op0)))
+ && int_fits_type_p (op1, TREE_TYPE (innerop)))
+ {
+ tree newconst = fold_convert (TREE_TYPE (innerop), op1);
+ gimple_cond_set_lhs (stmt, innerop);
+ gimple_cond_set_rhs (stmt, newconst);
+ update_stmt (stmt);
+ return true;
+ }
+ }
+ }
return false;
}