aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2021-09-03 09:58:29 +0200
committerAldy Hernandez <aldyh@redhat.com>2021-09-03 15:30:56 +0200
commitbccf4b88e184e925ee2d7931e4cf09704f1c3932 (patch)
treef6d2a064075687dd01cca20343ecefd175296e47
parent4ce90454c2c81246be993d997cab12e21bc0be68 (diff)
downloadgcc-bccf4b88e184e925ee2d7931e4cf09704f1c3932.zip
gcc-bccf4b88e184e925ee2d7931e4cf09704f1c3932.tar.gz
gcc-bccf4b88e184e925ee2d7931e4cf09704f1c3932.tar.bz2
Improve support for IMAGPART_EXPR and REALPART_EXPR in ranger.
Currently we adjust statements containing an IMAGPART_EXPR if the defining statement was one of a few built-ins known to return boolean types. We can also adjust statements for both IMAGPART_EXPR and REALPART_EXPR where the defining statement is a constant. This patch adds such support, and cleans up the code a bit. Tested on x86-64 Linux. gcc/ChangeLog: * gimple-range-fold.cc (adjust_imagpart_expr): Move from gimple_range_adjustment. Add support for constants. (adjust_realpart_expr): New. (gimple_range_adjustment): Move IMAGPART_EXPR code to adjust_imagpart_expr. * range-op.cc (integral_table::integral_table): Add entry for REALPART_CST.
-rw-r--r--gcc/gimple-range-fold.cc110
-rw-r--r--gcc/range-op.cc1
2 files changed, 77 insertions, 34 deletions
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index 94dd042..8be6d47 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -369,14 +369,78 @@ adjust_pointer_diff_expr (irange &res, const gimple *diff_stmt)
}
}
+// Adjust the range for an IMAGPART_EXPR.
+
+static void
+adjust_imagpart_expr (irange &res, const gimple *stmt)
+{
+ tree name = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
+
+ if (TREE_CODE (name) != SSA_NAME || !SSA_NAME_DEF_STMT (name))
+ return;
+
+ gimple *def_stmt = SSA_NAME_DEF_STMT (name);
+ if (is_gimple_call (def_stmt) && gimple_call_internal_p (def_stmt))
+ {
+ switch (gimple_call_internal_fn (def_stmt))
+ {
+ case IFN_ADD_OVERFLOW:
+ case IFN_SUB_OVERFLOW:
+ case IFN_MUL_OVERFLOW:
+ case IFN_ATOMIC_COMPARE_EXCHANGE:
+ {
+ int_range<2> r;
+ r.set_varying (boolean_type_node);
+ tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+ range_cast (r, type);
+ res.intersect (r);
+ }
+ default:
+ break;
+ }
+ return;
+ }
+ if (is_gimple_assign (def_stmt))
+ {
+ tree cst = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (cst) == COMPLEX_CST)
+ {
+ tree imag = TREE_IMAGPART (cst);
+ int_range<2> tmp (imag, imag);
+ res.intersect (tmp);
+ }
+ }
+}
+
+// Adjust the range for a REALPART_EXPR.
+
+static void
+adjust_realpart_expr (irange &res, const gimple *stmt)
+{
+ tree name = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
+
+ if (TREE_CODE (name) != SSA_NAME)
+ return;
+
+ gimple *def_stmt = SSA_NAME_DEF_STMT (name);
+ if (!SSA_NAME_DEF_STMT (name))
+ return;
+
+ if (is_gimple_assign (def_stmt))
+ {
+ tree cst = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (cst) == COMPLEX_CST)
+ {
+ tree imag = TREE_REALPART (cst);
+ int_range<2> tmp (imag, imag);
+ res.intersect (tmp);
+ }
+ }
+}
+
// This function looks for situations when walking the use/def chains
// may provide additonal contextual range information not exposed on
-// this statement. Like knowing the IMAGPART return value from a
-// builtin function is a boolean result.
-
-// We should rework how we're called, as we have an op_unknown entry
-// for IMAGPART_EXPR and POINTER_DIFF_EXPR in range-ops just so this
-// function gets called.
+// this statement.
static void
gimple_range_adjustment (irange &res, const gimple *stmt)
@@ -388,34 +452,12 @@ gimple_range_adjustment (irange &res, const gimple *stmt)
return;
case IMAGPART_EXPR:
- {
- tree name = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
- if (TREE_CODE (name) == SSA_NAME)
- {
- gimple *def_stmt = SSA_NAME_DEF_STMT (name);
- if (def_stmt && is_gimple_call (def_stmt)
- && gimple_call_internal_p (def_stmt))
- {
- switch (gimple_call_internal_fn (def_stmt))
- {
- case IFN_ADD_OVERFLOW:
- case IFN_SUB_OVERFLOW:
- case IFN_MUL_OVERFLOW:
- case IFN_ATOMIC_COMPARE_EXCHANGE:
- {
- int_range<2> r;
- r.set_varying (boolean_type_node);
- tree type = TREE_TYPE (gimple_assign_lhs (stmt));
- range_cast (r, type);
- res.intersect (r);
- }
- default:
- break;
- }
- }
- }
- break;
- }
+ adjust_imagpart_expr (res, stmt);
+ return;
+
+ case REALPART_EXPR:
+ adjust_realpart_expr (res, stmt);
+ return;
default:
break;
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 56eccf4..fee0e83 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -4017,6 +4017,7 @@ integral_table::integral_table ()
set (PAREN_EXPR, op_identity);
set (OBJ_TYPE_REF, op_identity);
set (IMAGPART_EXPR, op_unknown);
+ set (REALPART_EXPR, op_unknown);
set (POINTER_DIFF_EXPR, op_unknown);
set (ABS_EXPR, op_abs);
set (ABSU_EXPR, op_absu);