diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-10-09 11:26:33 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-10-20 18:21:23 +0200 |
commit | 16e4f1ad44e3c00b8b73c9e4ade3d236ea7044a8 (patch) | |
tree | 8d9782b4176bc6c40aac2f84355ffca712d75b73 /gcc/gimple-range.cc | |
parent | 5d53ec27015b916640171e891870adf2c6fdfd4c (diff) | |
download | gcc-16e4f1ad44e3c00b8b73c9e4ade3d236ea7044a8.zip gcc-16e4f1ad44e3c00b8b73c9e4ade3d236ea7044a8.tar.gz gcc-16e4f1ad44e3c00b8b73c9e4ade3d236ea7044a8.tar.bz2 |
Refactor range handling of builtins in vr_values and ranger.
This sets things up so we can share range handling of builtins between
vr_values and ranger. It is meant to refactor the code so that we can
verify that both implementations yield the same results.
First, we abstract out gimple_ranger::range_of_builtin_call into an externally
visible counterpart that can be called from vr_values. It will take a
range_query since both ranger and vr_values inherit from this base class.
Then we abstract out all the builtin handling in vr_values into a separate
method that is easier to compare against.
Finally, we call the ranger version from vr_values and compare it with the
vr_values version. Since this proves both versions return the same,
we can remove vr_values::extract_range_builtin in a follow-up patch.
The vr_values::range_of_expr change brings the vr_values version up to par
with the ranger version. It should've handled non-SSA's. This was
a small oversight that went unnoticed because the vr_value version isn't
stressed nearly as much as the ranger version. The change is needed because
the ranger code handling builtins calls, may call it for integer arguments
in range_of_builtin_ubsan_call.
There should be no change in functionality.
gcc/ChangeLog:
* gimple-range.cc (gimple_ranger::range_of_builtin_ubsan_call):
Make externally visble...
(range_of_builtin_ubsan_call): ...here. Add range_query argument.
(gimple_ranger::range_of_builtin_call): Make externally visible...
(range_of_builtin_call): ...here. Add range_query argument.
* gimple-range.h (range_of_builtin_call): Move out from class and
make externally visible.
* vr-values.c (vr_values::extract_range_basic): Abstract out
builtin handling to...
(vr_values::range_of_expr): Handle non SSAs.
(vr_values::extract_range_builtin): ...here.
* vr-values.h (class vr_values): Add extract_range_builtin.
(range_of_expr): Rename NAME to EXPR.
Diffstat (limited to 'gcc/gimple-range.cc')
-rw-r--r-- | gcc/gimple-range.cc | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index ed9609b..b790d62 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -552,10 +552,13 @@ gimple_ranger::range_of_call (irange &r, gcall *call) return true; } +// Return the range of a __builtin_ubsan* in CALL and set it in R. +// CODE is the type of ubsan call (PLUS_EXPR, MINUS_EXPR or +// MULT_EXPR). -void -gimple_ranger::range_of_builtin_ubsan_call (irange &r, gcall *call, - tree_code code) +static void +range_of_builtin_ubsan_call (range_query &query, irange &r, gcall *call, + tree_code code) { gcc_checking_assert (code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR); @@ -565,8 +568,8 @@ gimple_ranger::range_of_builtin_ubsan_call (irange &r, gcall *call, int_range_max ir0, ir1; tree arg0 = gimple_call_arg (call, 0); tree arg1 = gimple_call_arg (call, 1); - gcc_assert (range_of_expr (ir0, arg0, call)); - gcc_assert (range_of_expr (ir1, arg1, call)); + gcc_assert (query.range_of_expr (ir0, arg0, call)); + gcc_assert (query.range_of_expr (ir1, arg1, call)); bool saved_flag_wrapv = flag_wrapv; // Pretend the arithmetic is wrapping. If there is any overflow, @@ -582,9 +585,11 @@ gimple_ranger::range_of_builtin_ubsan_call (irange &r, gcall *call, r.set_varying (type); } +// For a builtin in CALL, return a range in R if known and return +// TRUE. Otherwise return FALSE. bool -gimple_ranger::range_of_builtin_call (irange &r, gcall *call) +range_of_builtin_call (range_query &query, irange &r, gcall *call) { combined_fn func = gimple_call_combined_fn (call); if (func == CFN_LAST) @@ -605,7 +610,7 @@ gimple_ranger::range_of_builtin_call (irange &r, gcall *call) return true; } arg = gimple_call_arg (call, 0); - if (range_of_expr (r, arg, call) && r.singleton_p ()) + if (query.range_of_expr (r, arg, call) && r.singleton_p ()) { r.set (build_one_cst (type), build_one_cst (type)); return true; @@ -619,7 +624,7 @@ gimple_ranger::range_of_builtin_call (irange &r, gcall *call) prec = TYPE_PRECISION (TREE_TYPE (arg)); mini = 0; maxi = prec; - gcc_assert (range_of_expr (r, arg, call)); + gcc_assert (query.range_of_expr (r, arg, call)); // If arg is non-zero, then ffs or popcount are non-zero. if (!range_includes_zero_p (&r)) mini = 1; @@ -663,7 +668,7 @@ gimple_ranger::range_of_builtin_call (irange &r, gcall *call) } } - gcc_assert (range_of_expr (r, arg, call)); + gcc_assert (query.range_of_expr (r, arg, call)); // From clz of minimum we can compute result maximum. if (r.constant_p ()) { @@ -728,7 +733,7 @@ gimple_ranger::range_of_builtin_call (irange &r, gcall *call) mini = -2; } } - gcc_assert (range_of_expr (r, arg, call)); + gcc_assert (query.range_of_expr (r, arg, call)); if (!r.undefined_p ()) { if (r.lower_bound () != 0) @@ -766,13 +771,13 @@ gimple_ranger::range_of_builtin_call (irange &r, gcall *call) r.set (build_int_cst (type, 0), build_int_cst (type, prec - 1)); return true; case CFN_UBSAN_CHECK_ADD: - range_of_builtin_ubsan_call (r, call, PLUS_EXPR); + range_of_builtin_ubsan_call (query, r, call, PLUS_EXPR); return true; case CFN_UBSAN_CHECK_SUB: - range_of_builtin_ubsan_call (r, call, MINUS_EXPR); + range_of_builtin_ubsan_call (query, r, call, MINUS_EXPR); return true; case CFN_UBSAN_CHECK_MUL: - range_of_builtin_ubsan_call (r, call, MULT_EXPR); + range_of_builtin_ubsan_call (query, r, call, MULT_EXPR); return true; case CFN_GOACC_DIM_SIZE: @@ -822,6 +827,11 @@ gimple_ranger::range_of_builtin_call (irange &r, gcall *call) } +bool +gimple_ranger::range_of_builtin_call (irange &r, gcall *call) +{ + return ::range_of_builtin_call (*this, r, call); +} // Calculate a range for COND_EXPR statement S and return it in R. // If a range cannot be calculated, return false. |