aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r--gcc/expr.cc28
1 files changed, 25 insertions, 3 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 4a69910..7d84ad9 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -9802,6 +9802,29 @@ expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
}
+/* Return true if EXP has a range of values [0..1], false
+ otherwise. This works for constants and ssa names, calling back into the ranger. */
+static bool
+expr_has_boolean_range (tree exp, gimple *stmt)
+{
+ /* An integral type with a single bit of precision. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
+ && TYPE_UNSIGNED (TREE_TYPE (exp))
+ && TYPE_PRECISION (TREE_TYPE (exp)) == 1)
+ return true;
+
+ /* Signed 1 bit integers are not boolean ranges. */
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
+ || TYPE_PRECISION (TREE_TYPE (exp)) <= 1)
+ return false;
+
+ if (TREE_CODE (exp) == SSA_NAME)
+ return ssa_name_has_boolean_range (exp, stmt);
+ if (TREE_CODE (exp) == INTEGER_CST)
+ return wi::leu_p (wi::to_wide (exp), 1);
+ return false;
+}
+
rtx
expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode,
enum expand_modifier modifier)
@@ -10460,9 +10483,8 @@ expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode,
/* Expand X*Y as X&-Y when Y must be zero or one. */
if (SCALAR_INT_MODE_P (mode))
{
- bool gimple_zero_one_valued_p (tree, tree (*)(tree));
- bool bit0_p = gimple_zero_one_valued_p (treeop0, nullptr);
- bool bit1_p = gimple_zero_one_valued_p (treeop1, nullptr);
+ bool bit0_p = expr_has_boolean_range (treeop0, currently_expanding_gimple_stmt);
+ bool bit1_p = expr_has_boolean_range (treeop1, currently_expanding_gimple_stmt);
/* Expand X*Y as X&Y when both X and Y must be zero or one. */
if (bit0_p && bit1_p)