aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-range-fold.cc
AgeCommit message (Collapse)AuthorFilesLines
2022-10-26Check if varying may also be non-negative.Andrew MacLeod1-0/+8
When using strict enums, we can sometimes turn varying into a better range. * gimple-range-fold.cc (fold_using_range::fold_stmt): Check if stmt is non-negative and adjust the range.
2022-10-17Add relation_trio class for range-ops.Andrew MacLeod1-2/+3
There are 3 possible relations range-ops might care about, but only the one most likely to be needed is supplied. This patch provides a new class relation_trio which allows 3 relations to be passed in a single word. fold_range (), op1_range (), and op2_range () are adjusted to take a relation_trio class instead of a relation_kind, then the routine can extract which relation it wants to work with. * gimple-range-fold.cc (fold_using_range::range_of_range_op): Provide relation_trio class. * gimple-range-gori.cc (gori_compute::refine_using_relation): Provide relation_trio class. (gori_compute::refine_using_relation): Ditto. (gori_compute::compute_operand1_range): Provide lhs_op2 and op1_op2 relations via relation_trio class. (gori_compute::compute_operand2_range): Ditto. * gimple-range-op.cc (gimple_range_op_handler::calc_op1): Use relation_trio instead of relation_kind. (gimple_range_op_handler::calc_op2): Ditto. (*::fold_range): Ditto. * gimple-range-op.h (gimple_range_op::calc_op1): Adjust prototypes. (gimple_range_op::calc_op2): Adjust prototypes. * range-op-float.cc (*::fold_range): Use relation_trio instead of relation_kind. (*::op1_range): Ditto. (*::op2_range): Ditto. * range-op.cc (*::fold_range): Use relation_trio instead of relation_kind. (*::op1_range): Ditto. (*::op2_range): Ditto. * range-op.h (class range_operator): Adjust prototypes. (class range_operator_float): Ditto. (class range_op_handler): Adjust prototypes. (relop_early_resolve): Pickup op1_op2 relation from relation_trio. * value-relation.cc (VREL_LAST): Adjust use to be one past the end of the enum. (relation_oracle::validate_relation): Use relation_trio in call to fold_range. * value-relation.h (enum relation_kind_t): Add VREL_LAST as final element. (class relation_trio): New. (TRIO_VARYING, TRIO_SHIFT, TRIO_MASK): New.
2022-09-22Convert CFN_BUILT_IN_PARITY to range-ops.Andrew MacLeod1-48/+12
Also, as the last builtin remaining, also remove the builtin infrastrucure routines from fold_using_range. * gimple-range-fold.cc (range_of_range_op): Handle no operands. (range_of_call): Do not check for builtins. (fold_using_range::range_of_builtin_call): Delete. (fold_using_range::range_of_builtin_int_call): Delete. * gimple-range-fold.h: Adjust prototypes. * gimple-range-op.cc (class cfn_parity): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_BUILT_IN_GOACC_DIM_* to range-ops.Andrew MacLeod1-19/+0
* gimple-range-fold.cc (range_of_builtin_int_call): Remove case for CFN_GOACC_DIM_*. * gimple-range-op.cc (class cfn_goacc_dim): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_BUILT_IN_STRLEN to range-ops.Andrew MacLeod1-21/+0
* gimple-range-fold.cc (range_of_builtin_int_call): Remove case for CFN_BUILT_IN_STRLEN. * gimple-range-op.cc (class cfn_strlen): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_BUILT_IN_UBSAN_CHECK_* to range-ops.Andrew MacLeod1-46/+1
* gimple-range-fold.cc (range_of_builtin_ubsan_call): Delete. (range_of_builtin_int_call): Remove cases for CFN_BUILT_IN_UBSAN_CHECK. * gimple-range-op.cc (class cfn_ubsan): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_BUILT_IN_CLRSB to range-ops.Andrew MacLeod1-7/+0
* gimple-range-fold.cc (range_of_builtin_int_call): Remove case for CFN_BUILT_IN_CLRSB. * gimple-range-op.cc (class cfn_clrsb): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_CTZ builtins to range-ops.Andrew MacLeod1-60/+1
* gimple-range-fold.cc (range_of_builtin_int_call): Remove case for CFN_CTZ. * gimple-range-op.cc (class cfn_ctz): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_CLZ builtins to range-ops.Andrew MacLeod1-61/+0
* gimple-range-fold.cc (range_of_builtin_int_call): Remove case for CFN_CLZ. * gimple-range-op.cc (class cfn_clz): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_BUILT_FFS and CFN_POPCOUNT to range-ops.Andrew MacLeod1-22/+0
* gimple-range-fold.cc (range_of_builtin_int_call): Remove case for CFN_FFS and CFN_POPCOUNT. * gimple-range-op.cc (class cfn_pocount): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_BUILT_IN_TOUPPER and TOLOWER to range-ops.Andrew MacLeod1-66/+0
* gimple-range-fold.cc (get_letter_range): Move to new class. (range_of_builtin_int_call): Remove case for CFN_BUILT_IN_TOUPPER and CFN_BUILT_IN_TOLOWER. * gimple-range-op.cc (class cfn_toupper_tolower): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Convert CFN_BUILT_IN_SIGNBIT to range-ops.Andrew MacLeod1-20/+0
* gimple-range-fold.cc (range_of_builtin_int_call): Remove case for CFN_BUILT_IN_SIGNBIT. * gimple-range-op.cc (class cfn_signbit): New. (gimple_range_op_handler::maybe_builtin_call): Set arguments.
2022-09-22Add range-ops support for builtin functions.Andrew MacLeod1-17/+0
Convert CFN_BUILT_IN_CONSTANT_P as first POC. * gimple-range-fold.cc (fold_using_range::range_of_builtin_int_call): Remove case for CFN_BUILT_IN_CONSTANT_P. * gimple-range-op.cc (gimple_range_op_handler::supported_p): Check if a call also creates a range-op object. (gimple_range_op_handler): Also check builtin calls. (class cfn_constant_float_p): New. Float CFN_BUILT_IN_CONSTANT_P. (class cfn_constant_p): New. Integral CFN_BUILT_IN_CONSTANT_P. (gimple_range_op_handler::maybe_builtin_call): Set arguments and handler for supported built-in calls. * gimple-range-op.h (maybe_builtin_call): New prototype.
2022-09-22Always check the return value of fold_range.Andrew MacLeod1-2/+4
The fold_range routine in range-ops returns FALSE if the operation fails. There are a few places which assume the operation was successful. Fix those. * gimple-range-fold.cc (range_of_range_op): Set result to VARYING if the call to fold_range fails. * tree-data-ref.cc (compute_distributive_range): Ditto. * tree-vrp.cc (range_fold_binary_expr): Ditto. (range_fold_unary_expr): Ditto. * value-query.cc (range_query::get_tree_range): Ditto.
2022-09-22Create gimple_range_op_handler in a new source file.Andrew MacLeod1-125/+28
Range-ops is meant to be IL independent. Some gimple processing has be placed in range-ops, and some is located in gori. Split it all into a file and isolate it in a new class gimple_range_op_handler. * Makefile.in (OBJS): Add gimple-range-op.o. * gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Use gimple_range_op_handler. * gimple-range-fold.cc (gimple_range_base_of_assignment): Move to a method in gimple_range_op_handler. (gimple_range_operand1): Ditto. (gimple_range_operand2): Ditto. (fold_using_range::fold_stmt): Use gimple_range_op_handler. (fold_using_range::range_of_range_op): Ditto. (fold_using_range::relation_fold_and_or): Ditto. (fur_source::register_outgoing_edges): Ditto. (gimple_range_ssa_names): Relocate to gimple-range-op.cc. * gimple-range-fold.h: Adjust prototypes. * gimple-range-gori.cc (gimple_range_calc_op1): Move to a method in gimple_range_op_handler. (gimple_range_calc_op2): Ditto. (gori_compute::compute_operand_range): Use gimple_range_op_handler. (gori_compute::compute_logical_operands): Ditto. (compute_operand1_range): Ditto. (gori_compute::compute_operand2_range): Ditto. (gori_compute::compute_operand1_and_operand2_range): Ditto. * gimple-range-gori.h: Adjust protoypes. * gimple-range-op.cc: New. Supply gimple_range_op_handler methods. * gimple-range-op.h: New. Supply gimple_range_op_handler class. * gimple-range.cc (gimple_ranger::prefill_name): Use gimple_range_op_handler. (gimple_ranger::prefill_stmt_dependencies): Ditto. * gimple-range.h: Include gimple-range-op.h. * range-op.cc (range_op_handler::range_op_handler): Adjust and remove gimple * parameter option. * range-op.h: Adjust prototypes.
2022-09-18Rewrite NAN and sign handling in frangeAldy Hernandez1-1/+1
The attatched patch rewrites the NAN and sign handling, dropping both tristates in favor of a pair of boolean flags for NANs, and nothing at all for signs. The signs are tracked in the range itself, so now it's possible to describe things like [-0.0, +0.0] +NAN, [+0, +0], [-5, +0], [+0, 3] -NAN, etc. Here is an example of the various ranges and how they are displayed: [frange] float VARYING NAN ;; Varying includes NAN [frange] UNDEFINED ;; Empty set as always [frange] float [] +-NAN ;; Unknown sign NAN [frange] float [] -NAN ;; -NAN [frange] float [] +NAN ;; +NAN [frange] float [-0.0, 0.0] ;; All zeros. [frange] float [-0.0, -0.0] +-NAN ;; -0 or NAN. [frange] float [-5.0e+0, -1.0e+0] +NAN ;; [-5, -1] or +NAN [frange] float [-5.0e+0, -0.0] +-NAN ;; [-5, -0] or NAN [frange] float [-5.0e+0, -0.0] ;; [-5, -0] [frange] float [5.0e+0, 1.0e+1] ;; [5, 10] Notice the NAN signs are decoupled from the range, so we can represent a negative range with a positive NAN. For this range, frange::signbit_p() would return false, as only when the signs of the NANs and range agree can we be certain. There is no longer any pessimization of ranges for intersects involving NANs. Also, union and intersect work with signed zeros: // [-0, x] U [+0, x] => [-0, x] // [ x, -0] U [ x, +0] => [ x, +0] // [-0, x] ^ [+0, x] => [+0, x] // [ x, -0] ^ [ x, +0] => [ x, -0] The special casing for signed zeros in the singleton code is gone in favor of just making sure the signs in the range agree, that is [-0, -0] for example. I have removed the idea that a known NAN is a "range", so a NAN is no longer in the endpoints itself. Requesting the bound of a known NAN is a hard fail. For that matter, we don't store the actual NAN in the range. The only information we have are the set of boolean flags. This way we make sure nothing seeps into the frange. This also means it's explicit that we don't track anything but the sign in NANs. We can revisit this if we desire to track signalling or whatever concoction y'all can imagine. Regstrapped with mpfr tests on x86-64 and ppc64le Linux. Selftests were also run with -ffinite-math-only on x86-64. At Jakub's suggestion, I built lapack with associated tests. They pass on x86-64 and ppc64le Linux with no regressions from mainline. As a sanity check, I also ran them for -ffinite-math-only on x86 which (as expected) returned: NaN arithmetic did not perform per the ieee spec Otherwise, all tests pass for -ffinite-math-only. gcc/ChangeLog: * range-op-float.cc (frange_add_zeros): Replace set_signbit with union of zero. * value-query.cc (range_query::get_tree_range): Remove set_signbit use. * value-range-pretty-print.cc (vrange_printer::print_frange_prop): Remove. (vrange_printer::print_frange_nan): New. * value-range-pretty-print.h (print_frange_prop): Remove. (print_frange_nan): New. * value-range-storage.cc (frange_storage_slot::set_frange): Set kind and NAN fields. (frange_storage_slot::get_frange): Restore kind and NAN fields. * value-range-storage.h (class frange_storage_slot): Add kind and NAN fields. * value-range.cc (frange::update_nan): Remove. (frange::set_signbit): Remove. (frange::set): Adjust for NAN fields. (frange::normalize_kind): Remove m_props. (frange::combine_zeros): New. (frange::union_nans): New. (frange::union_): Handle new NAN fields. (frange::intersect_nans): New. (frange::intersect): Handle new NAN fields. (frange::operator=): Same. (frange::operator==): Same. (frange::contains_p): Same. (frange::singleton_p): Remove special case for signed zeros. (frange::verify_range): Adjust for new NAN fields. (frange::set_zero): Handle signed zeros. (frange::set_nonnegative): Same. (range_tests_nan): Adjust tests. (range_tests_signed_zeros): Same. (range_tests_signbit): Same. (range_tests_floats): Same. * value-range.h (class fp_prop): Remove. (FP_PROP_ACCESSOR): Remove. (class frange_props): Remove (frange::lower_bound): NANs don't have endpoints. (frange::upper_bound): Same. (frange_props::operator==): Remove. (frange_props::union_): Remove. (frange_props::intersect): Remove. (frange::update_nan): New. (frange::clear_nan): New. (frange::undefined_p): New. (frange::set_nan): New. (frange::known_finite): Adjust for new NAN representation. (frange::maybe_isnan): Same. (frange::known_isnan): Same. (frange::signbit_p): Same. * gimple-range-fold.cc (range_of_builtin_int_call): Rename known_signbit_p into signbit_p.
2022-09-08Implement known/maybe fpclassify like API for frange.Aldy Hernandez1-9/+10
gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_builtin_int_call): Use fpclassify like API. * range-op-float.cc (finite_operand_p): Same. (finite_operands_p): Same. (foperator_lt::fold_range): Same. (foperator_le::fold_range): Same. (foperator_gt::fold_range): Same. (foperator_ge::fold_range): Same. (foperator_unordered::fold_range): Same. (foperator_unordered::op1_range): Same. (foperator_ordered::fold_range): Same. * value-range.cc (frange::set_nan): Same. (frange::set_signbit): Same. (frange::union_): Same. (frange::intersect): Same. (frange::operator==): Same. (frange::singleton_p): Same. (frange::verify_range): Same. (range_tests_nan): Same. (range_tests_floats): Same. * value-range.h(frange::known_finite): New. (frange::maybe_inf): New. (frange::known_inf): New. (frange::maybe_nan): New. (frange::known_nan): New. (frange::known_signbit): New.
2022-09-05Do not fold __builtin_signbit if NAN is a possibility.Aldy Hernandez1-1/+3
I had some queued up work to try harder to keep the sign bit up to date in the presence of NANs, but after the discussion with Richi regarding the representation of NAN and signs in the frange, I've decided to put it aside until after Cauldron, since it'll probably get rewritten anyhow. So for now, the sign property in the frange is not applicable to NANs. Right now the only user of the sign bit that affects generated code (apart from signed zeros) is __builtin_sign, so I'm just checking for NAN there. Signed zeros continue working as before. Regstrapped and mpfr checked on x86-64 Linux. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_builtin_int_call): Ignore sign bit when there's the possibility of a NAN.
2022-09-05Fold __builtin_signbit to nonzero instead of 1.Aldy Hernandez1-4/+1
After Joseph's comment wrt __builtin_signbit, I have been unable to convince myself that arbitrarily folding __builtin_signbit () of a negative number to 1 is correct. For example, on the true side of x < -5.0 we know the sign bit is set, but on the false side, we know nothing because X may be a NAN. I don't want to put ourselves in a position where the same call to __builtin_signbit can return two different things (1 or negative whatever), so I'm going to return nonzero which is correct across the board until someone can convince me otherwise. Setting the range to nonzero still allows us to fold conditionals checking __fold_builtin, while not actually propagating a 1. Zero propagation still works. That being said, I still think we should be folding __builtin_signbit's of negative numbers to whatever the hardware returns, instead of 1/0 like what the front ends do. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_builtin_int_call): Fold a set signbit in __builtin_signbit to nonzero. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/vrp-float-signbit-2.c: New test.
2022-09-01Implement ranger folder for __builtin_signbit.Aldy Hernandez1-0/+20
Now that we keep track of the signbit, we can use it to fold __builtin_signbit. I am assuming I don't have try too hard to get the actual signbit number and 1 will do. Especially, since we're inconsistent in trunk whether we fold the builtin or whether we calculate it at runtime. abulafia:~$ cat a.c float nzero = -0.0; main(){ printf("0x%x\n", __builtin_signbit(-0.0)); printf("0x%x\n", __builtin_signbit(nzero)); } abulafia:~$ gcc a.c -w && ./a.out 0x1 0x80000000 It is amazing that we've been failing to fold something as simple as this: if (x > 5.0) num = __builtin_signbit (x); It does the right thing now :-P. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_builtin_int_call): Add case for CFN_BUILT_IN_SIGNBIT. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/vrp-float-signbit-1.c: New test.
2022-08-16Abstract interesting ssa-names from GORI.Andrew MacLeod1-0/+33
Provide a routine to pick out the ssa-names from interesting statements. * gimple-range-fold.cc (gimple_range_ssa_names): New. * gimple-range-fold.h (gimple_range_ssa_names): New prototype. * gimple-range-gori.cc (range_def_chain::get_def_chain): Move code to new routine.
2022-08-02Do not register edges for statements not understood.Andrew MacLeod1-2/+4
Previously, all gimple_cond types were undserstoof, with float values, this is no longer true. We should gracefully do nothing if the gcond type is not supported. PR tree-optimization/106510 gcc/ * gimple-range-fold.cc (fur_source::register_outgoing_edges): Check for unsupported statements early. gcc/testsuite * gcc.dg/pr106510.c: New.
2022-08-02Make range_of_ssa_name_with_loop_info type agnostic.Aldy Hernandez1-11/+35
gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_phi): Remove irange check. (tree_lower_bound): New. (tree_upper_bound): New. (fold_using_range::range_of_ssa_name_with_loop_info): Convert to vrange. * gimple-range-fold.h (range_of_ssa_name_with_loop_info): Change argument to vrange.
2022-08-01Make irange dependency explicit for range_of_ssa_name_with_loop_info.Aldy Hernandez1-5/+5
Even though ranger is type agnostic, SCEV seems to only work with integers. This patch removes some FIXME notes making it explicit that bounds_of_var_in_loop only works with iranges. Tested on x86-64 Linux. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_phi): Only query SCEV for integers. (fold_using_range::range_of_ssa_name_with_loop_info): Remove irange check.
2022-07-04Misc conversions to vrange.Aldy Hernandez1-14/+18
The following converts a handful of places that were irange centric. Tested on x86-64 Linux. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_ssa_name_with_loop_info): Restrict the call to SCEV for irange supported types. (fold_using_range::range_of_builtin_int_call): Convert to vrange. * gimple-range.cc (gimple_ranger::prefill_stmt_dependencies): Same. * tree-ssa-dom.cc (cprop_operand): Same.
2022-06-29Don't use gori dependencies to optimize.Andrew MacLeod1-13/+17
The routine fold_using_range::relation_fold_and_or needs to veriyf that both operands of 2 stmts are the same, and uses GORIs dependency cache for this. This cache cannot be counted on to reflect the current contents of a stmt, expecially in the presence of an IL changing pass. Instead, look at the statement operands. PR tree-optimization/106114 gcc/ * gimple-range-fold.cc (fold_using_range::relation_fold_and_or): Check statement operands instead of GORI cache. gcc/testsuite/ * gcc.dg/pr106114.c: New.
2022-06-03Implement vrange::supports_type_p.Aldy Hernandez1-3/+2
[I have conservatively assumed that both the loop-ch and loop-unswitch passes, which also use the ranger, only support integers and pointers. If the goal is to handle other types as well, irange::supports_p() should be Value_Range::supports_type_p(), and any uses of int_range_max should be converted to Value_Range. I can help in the conversion if you'd like.] As discussed, this patch disambiguates the use of supports_type_p throughout, as what ranger supports is a totally different question than what a given range variant (irange, frange, etc) supports. Unfortunately we need both a static method and a virtual method, and they can't be named the same. The uses are documented in the vrange class: +// To query what types ranger and the entire ecosystem can support, +// use Value_Range::supports_type_p(tree type). This is a static +// method available independently of any vrange object. +// +// To query what a given vrange variant can support, use: +// irange::supports_p () +// frange::supports_p () +// etc +// +// To query what a range object can support, use: +// void foo (vrange &v, irange &i, frange &f) +// { +// if (v.supports_type_p (type)) ... +// if (i.supports_type_p (type)) ... +// if (f.supports_type_p (type)) ... +// } The value_range_equiv::supports_p() method can be use to determine what legacy VRP supports, as irange::supports_p() will no longer be applicable in the evrp analyzer code base once irange and prange are split. Tested on x86-64 Linux. gcc/ChangeLog: * gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Adjust for an object level supports_type_p for irange and a static Value_Range::supports_type_p. * gimple-range-fold.cc (fold_using_range::range_of_range_op): Same. (fold_using_range::range_of_address): Same. (fold_using_range::range_of_builtin_call): Same. * gimple-range-fold.h (gimple_range_type): Same. (gimple_range_ssa_p): Same. * gimple-range-path.cc (path_range_query::internal_range_of_expr): Same. (path_range_query::range_of_stmt): Same. (path_range_query::add_to_imports): Same. * gimple-range.cc (gimple_ranger::range_on_edge): Same. (gimple_ranger::export_global_ranges): Same. * gimple-ssa-evrp-analyze.cc (evrp_range_analyzer::record_ranges_from_phis): Same. * range-op.cc (range_operator::wi_fold): Same. (range_operator::fold_range): Same. * tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Same. * tree-ssa-loop-unswitch.cc (struct unswitch_predicate): Same. (evaluate_control_stmt_using_entry_checks): Same. * tree-ssa-threadedge.cc (hybrid_jt_simplifier::compute_ranges_from_state): Same. * tree-vrp.cc (supported_types_p): Same. * value-query.cc (range_query::value_of_expr): Same. (range_query::value_on_edge): Same. (range_query::value_of_stmt): Same. (range_query::get_tree_range): Same. (get_range_global): Same. (global_range_query::range_of_expr): Same. * value-range-equiv.h (class value_range_equiv): Same. * value-range.cc (irange::supports_type_p): Same. (unsupported_range::supports_type_p): Same. * value-range.h (enum value_range_discriminator): Same. (Value_Range::init): Same. (Value_Range::supports_type_p): Same. (irange::supports_type_p): Same. (irange::supports_p): Same. (vrange::supports_type_p): Same. (vrange_allocator::alloc_vrange): Same.
2022-06-01Convert ranger and clients to vrange.Aldy Hernandez1-59/+82
Finally, the meat of the work. Convert ranger and associated clients to vrange. Everything's relatively mechanical given the previous patches. I did include a minor cleanup in the edge code. There's no need to check that the type of the switch is an integer as non-integer switches are invalid. I verified this with an appropriately coded assert. Tested on x86-64 & ppc64le Linux. gcc/ChangeLog: * gimple-range-cache.cc (ssa_block_ranges::dump): Convert to vrange. (sbr_vector::sbr_vector): Same. (sbr_vector::grow): Same. (sbr_vector::set_bb_range): Same. (sbr_vector::get_bb_range): Same. (sbr_sparse_bitmap::sbr_sparse_bitmap): Same. (sbr_sparse_bitmap::set_bb_range): Same. (sbr_sparse_bitmap::get_bb_range): Same. (block_range_cache::set_bb_range): Same. (block_range_cache::get_bb_range): Same. (block_range_cache::dump): Same. (ssa_global_cache::get_global_range): Same. (ssa_global_cache::set_global_range): Same. (ssa_global_cache::clear): Same. (ssa_global_cache::dump): Same. (ranger_cache::get_global_range): Same. (ranger_cache::set_global_range): Same. (ranger_cache::range_of_def): Same. (ranger_cache::entry_range): Same. (ranger_cache::exit_range): Same. (ranger_cache::edge_range): Same. (ranger_cache::range_of_expr): Same. (ranger_cache::range_on_edge): Same. (ranger_cache::block_range): Same. (ranger_cache::propagate_cache): Same. (ranger_cache::fill_block_cache): Same. (ranger_cache::range_from_dom): Same. * gimple-range-cache.h: Same. * gimple-range-edge.cc (gimple_outgoing_range::get_edge_range): Same. (gimple_outgoing_range::switch_edge_range): Same. (gimple_outgoing_range::edge_range_p): Same. * gimple-range-edge.h: Same. * gimple-range-fold.cc (fur_source::get_operand): Same. (fur_source::get_phi_operand): Same. (fur_edge::get_operand): Same. (fur_edge::get_phi_operand): Same. (fur_stmt::get_operand): Same. (fur_stmt::get_phi_operand): Same. (fur_list::fur_list): Same. (fur_list::get_operand): Same. (fur_list::get_phi_operand): Same. (fold_range): Same. (adjust_imagpart_expr): Same. (adjust_realpart_expr): Same. (gimple_range_adjustment): Same. (fold_using_range::fold_stmt): Same. (fold_using_range::range_of_range_op): Same. (fold_using_range::range_of_address): Same. (fold_using_range::range_of_phi): Same. (fold_using_range::range_of_call): Same. (fold_using_range::range_of_builtin_call): Same. (fold_using_range::range_of_builtin_int_call): Same. (fold_using_range::range_of_cond_expr): Same. (fur_source::register_outgoing_edges): Same. * gimple-range-fold.h (fold_range): Same. (gimple_range_type): Same. (gimple_range_ssa_p): Same. * gimple-range-gori.cc (gimple_range_calc_op1): Same. (gimple_range_calc_op2): Same. (gori_compute::compute_operand_range_switch): Same. (gori_compute::compute_operand_range): Same. (gori_compute::logical_combine): Same. (gori_compute::compute_logical_operands): Same. (gori_compute::compute_operand1_range): Same. (gori_compute::compute_operand2_range): Same. (gori_compute::compute_operand1_and_operand2_range): Same. (gori_compute::outgoing_edge_range_p): Same. (gori_compute::condexpr_adjust): Same. * gimple-range-gori.h (gimple_range_calc_op1): Same. (gimple_range_calc_op2): Same. * gimple-range-path.cc (path_range_query::get_cache): Same. (path_range_query::set_cache): Same. (path_range_query::range_on_path_entry): Same. (path_range_query::internal_range_of_expr): Same. (path_range_query::range_of_expr): Same. (path_range_query::ssa_range_in_phi): Same. (path_range_query::range_defined_in_block): Same. (path_range_query::compute_ranges_in_phis): Same. (path_range_query::compute_ranges_in_block): Same. (path_range_query::add_to_imports): Same. (path_range_query::range_of_stmt): Same. * gimple-range-path.h: Same. * gimple-range-infer.cc (gimple_infer_range::add_range): Same. (gimple_infer_range::~side_effect_manager): Same. (gimple_infer_range::get_nonzero): Same. (gimple_infer_range::maybe_adjust_range): Same. (gimple_infer_range::add_range): Same. * gimple-range-infer.h: Same. * gimple-range-tests.cc: Same. * gimple-range-trace.cc (range_tracer::trailer): Same. (debug_seed_ranger): Same. * gimple-range-trace.h: Same. * gimple-range.cc (gimple_ranger::range_of_expr): Same. (gimple_ranger::range_on_entry): Same. (gimple_ranger::range_on_exit): Same. (gimple_ranger::range_on_edge): Same. (gimple_ranger::fold_range_internal): Same. (gimple_ranger::range_of_stmt): Same. (gimple_ranger::prefill_name): Same. (gimple_ranger::prefill_stmt_dependencies): Same. (gimple_ranger::export_global_ranges): Same. (gimple_ranger::dump_bb): Same. * gimple-range.h: Same. * gimple-ssa-warn-access.cc (check_nul_terminated_array): Same. (memmodel_to_uhwi): Same. * tree-ssa-loop-niter.cc (refine_value_range_using_guard): Same. (determine_value_range): Same. (record_nonwrapping_iv): Same. (infer_loop_bounds_from_signedness): Same. (scev_var_range_cant_overflow): Same. * tree-ssa-threadedge.cc (hybrid_jt_simplifier::simplify): Same. * value-query.cc (range_query::range_on_edge): Same. (range_query::range_of_stmt): Same. (range_query::value_of_expr): Same. (range_query::value_on_edge): Same. (range_query::value_of_stmt): Same. (range_query::get_tree_range): Same. (update_global_range): Same. (get_range_global): Same. (gimple_range_global): Same. (global_range_query::range_of_expr): Same. (range_query::query_relation): Same. * value-query.h (gimple_range_global): Same. (update_global_range): Same. * vr-values.cc (vr_values::range_of_expr): Same. (bounds_of_var_in_loop): Same. (simplify_using_ranges::vrp_visit_cond_stmt): Same. * vr-values.h (class vr_values): Same. * tree-ssa-loop-unswitch.cc (unswitch_predicate): Same.
2022-06-01Convert range-op.* to vrange.Aldy Hernandez1-22/+21
This patch provides the infrastructure to make range-ops type agnostic. First, the range_op_handler function has been replaced with an object of the same name. It's coded in such a way to minimize changes to the code base, and to encapsulate the dispatch code. Instead of: range_operator *op = range_op_handler (code, type); if (op) op->fold_range (...); We now do: range_op_handler op (code, type); if (op) op->fold_range (...); I've folded gimple_range_handler into the range_op_handler class, since it's also a query into the range operators. Instead of: range_operator *handler = gimple_range_handler (stmt); We now do: range_op_handler handler (stmt); This all has the added benefit of moving all the dispatch code into an independent class and avoid polluting range_operator (which we'll further split later when frange and prange come live). There's this annoying "using" keyword that's been added to each operator due to hiding rules in C++. The issue is that we will have different virtual versions of fold_range() for each combination of operands. For example: // Traditional binary op on irange's. fold_range (irange &lhs, const irange &op1, const irange &op2); // For POINTER_DIFF_EXPR: fold_range (irange &lhs, const prange &op1, const prange &op2); // Cast from irange to prange. fold_range (prange &lhs, const irange &op1, const irange &op2); Overloading virtuals when there are multiple same named methods causes hidden virtuals warnings from -Woverloaded-virtual, thus the using keyword. An alternative would be to have different names: fold_range_III, fold_range_IPP, fold_range_PII, but that's uglier still. Tested on x86-64 & ppc64le Linux. gcc/ChangeLog: * gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Adjust for vrange and convert range_op_handler function calls to use the identically named object. * gimple-range-fold.cc (gimple_range_operand1): Same. (gimple_range_operand2): Same. (fold_using_range::fold_stmt): Same. (fold_using_range::range_of_range_op): Same. (fold_using_range::range_of_builtin_ubsan_call): Same. (fold_using_range::relation_fold_and_or): Same. (fur_source::register_outgoing_edges): Same. * gimple-range-fold.h (gimple_range_handler): Remove. * gimple-range-gori.cc (gimple_range_calc_op1): Adjust for vrange. (gimple_range_calc_op2): Same. (range_def_chain::get_def_chain): Same. (gori_compute::compute_operand_range): Same. (gori_compute::condexpr_adjust): Same. * gimple-range.cc (gimple_ranger::prefill_name): Same. (gimple_ranger::prefill_stmt_dependencies): Same. * range-op.cc (get_bool_state): Same. (class operator_equal): Add using clause. (class operator_not_equal): Same. (class operator_lt): Same. (class operator_le): Same. (class operator_gt): Same. (class operator_ge): Same. (class operator_plus): Same. (class operator_minus): Same. (class operator_mult): Same. (class operator_exact_divide): Same. (class operator_lshift): Same. (class operator_rshift): Same. (class operator_cast): Same. (class operator_logical_and): Same. (class operator_bitwise_and): Same. (class operator_logical_or): Same. (class operator_bitwise_or): Same. (class operator_bitwise_xor): Same. (class operator_trunc_mod): Same. (class operator_logical_not): Same. (class operator_bitwise_not): Same. (class operator_cst): Same. (class operator_identity): Same. (class operator_unknown): Same. (class operator_abs): Same. (class operator_negate): Same. (class operator_addr_expr): Same. (class pointer_or_operator): Same. (operator_plus::op1_range): Adjust for vrange. (operator_minus::op1_range): Same. (operator_mult::op1_range): Same. (operator_cast::op1_range): Same. (operator_bitwise_not::fold_range): Same. (operator_negate::fold_range): Same. (range_op_handler): Rename to... (get_handler): ...this. (range_op_handler::range_op_handler): New. (range_op_handler::fold_range): New. (range_op_handler::op1_range): New. (range_op_handler::op2_range): New. (range_op_handler::lhs_op1_relation): New. (range_op_handler::lhs_op2_relation): New. (range_op_handler::op1_op2_relation): New. (range_cast): Adjust for vrange. * range-op.h (range_op_handler): Remove function. (range_cast): Adjust for vrange. (class range_op_handler): New. (get_bool_state): Adjust for vrange. (empty_range_varying): Same. (relop_early_resolve): Same. * tree-data-ref.cc (compute_distributive_range): Same. * tree-vrp.cc (get_range_op_handler): Remove. (range_fold_binary_symbolics_p): Use range_op_handler class instead of get_range_op_handler. (range_fold_unary_symbolics_p): Same. (range_fold_binary_expr): Same. (range_fold_unary_expr): Same. * value-query.cc (range_query::get_tree_range): Adjust for vrange.
2022-05-20Use "final" and "override" directly, rather than via macrosDavid Malcolm1-4/+4
As of GCC 11 onwards we have required a C++11 compiler, such as GCC 4.8 or later. On the assumption that any such compiler correctly implements "final" and "override", this patch updates the source tree to stop using the FINAL and OVERRIDE macros from ansidecl.h, in favor of simply using "final" and "override" directly. libcpp/ChangeLog: * lex.cc: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". gcc/analyzer/ChangeLog: * analyzer-pass.cc: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * call-info.h: Likewise. * checker-path.h: Likewise. * constraint-manager.cc: Likewise. * diagnostic-manager.cc: Likewise. * engine.cc: Likewise. * exploded-graph.h: Likewise. * feasible-graph.h: Likewise. * pending-diagnostic.h: Likewise. * region-model-impl-calls.cc: Likewise. * region-model.cc: Likewise. * region-model.h: Likewise. * region.h: Likewise. * sm-file.cc: Likewise. * sm-malloc.cc: Likewise. * sm-pattern-test.cc: Likewise. * sm-sensitive.cc: Likewise. * sm-signal.cc: Likewise. * sm-taint.cc: Likewise. * state-purge.h: Likewise. * store.cc: Likewise. * store.h: Likewise. * supergraph.h: Likewise. * svalue.h: Likewise. * trimmed-graph.h: Likewise. * varargs.cc: Likewise. gcc/c-family/ChangeLog: * c-format.cc: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * c-pretty-print.h: Likewise. gcc/cp/ChangeLog: * cxx-pretty-print.h: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * error.cc: Likewise. gcc/jit/ChangeLog: * jit-playback.h: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * jit-recording.cc: Likewise. * jit-recording.h: Likewise. gcc/ChangeLog: * config/aarch64/aarch64-sve-builtins-base.cc: Replace uses of "FINAL" and "OVERRIDE" with "final" and "override". * config/aarch64/aarch64-sve-builtins-functions.h: Likewise. * config/aarch64/aarch64-sve-builtins-shapes.cc: Likewise. * config/aarch64/aarch64-sve-builtins-sve2.cc: Likewise. * diagnostic-path.h: Likewise. * digraph.cc: Likewise. * gcc-rich-location.h: Likewise. * gimple-array-bounds.cc: Likewise. * gimple-loop-versioning.cc: Likewise. * gimple-range-cache.cc: Likewise. * gimple-range-cache.h: Likewise. * gimple-range-fold.cc: Likewise. * gimple-range-fold.h: Likewise. * gimple-range-tests.cc: Likewise. * gimple-range.h: Likewise. * gimple-ssa-evrp.cc: Likewise. * input.cc: Likewise. * json.h: Likewise. * read-rtl-function.cc: Likewise. * tree-complex.cc: Likewise. * tree-diagnostic-path.cc: Likewise. * tree-ssa-ccp.cc: Likewise. * tree-ssa-copy.cc: Likewise. * tree-vrp.cc: Likewise. * value-query.h: Likewise. * vr-values.h: Likewise. Signed-off-by: David Malcolm <dmalcolm@redhat.com>
2022-05-13Move VREL values to their own enumerated type.Andrew MacLeod1-14/+14
Re-using some common things like EQ_EXPR and other relationals made certain things easier, but complicated debugging and added extra overhead when accessing lookup tables. With forthcoming additional relation types, it makes more sense to simple have a distinct relation kind. * gimple-range-fold.cc (fold_using_range::range_of_phi): Use new VREL_* enumerated values. * gimple-range-path.cc (maybe_register_phi_relation): Ditto. * range-op.cc (*::lhs_op1_relation): Return relation_kind, and use new VREL enumerated values. (*::lhs_op2_relation): Ditto. (*::op1_op2_relation): Ditto. (*::fold_range): Use new VREL enumerated values. (minus_op1_op2_relation_effect): Ditto. (range_relational_tests): Ditto. * range-op.h (fold_range, op1_range, op2_range): Use VREL_VARYING. (lhs_op1_relation, lhs_op2_relation, op1_op2_relation): Return relation_kind. (*_op1_op2_relation): Return relation_kind. (relop_early_resolve): Use VREL_UNDEFINED. * value-query.cc (range_query::query_relation): Use VREL_VARYING. * value-relation.cc (VREL_LAST): Change enumerated value. (vrel_range_assert): Delete. (print_relation): Remove range assert. (rr_negate_table): Adjust table to use new enumerated values.. (relation_negate): Remove range assert. (rr_swap_table): Adjust. (relation_swap): Remove range assert. (rr_intersect_table): Adjust. (relation_intersect): Remove range assert. (rr_union_table): Adjust. (relation_union): Remove range assert. (rr_transitive_table): Adjust. (relation_transitive): Remove range assert. (equiv_oracle::query_relation): Use new VREL enumerated values. (equiv_oracle::register_relation): Ditto. (relation_oracle::register_stmt): Ditto. (dom_oracle::set_one_relation): Ditto. (dom_oracle::register_transitives): Ditto. (dom_oracle::query_relation): Ditto. (path_oracle::register_relation): Ditto. (path_oracle::query_relation): Ditto. * value-relation.h (enum relation_kind_t): New relation_kind. (*_op1_op2_relation): Adjust prototypes.
2022-05-13Add relation between op1 & op2 to lhs_opN_relation API.Andrew MacLeod1-2/+2
We use the relation between op1 and op2 to help fold a statement, but it was not provided to the lhs_op1_relation and lhs_op2_relation routines to determine if is also creates a relation between the LHS and either operand. gcc/ PR tree-optimization/104547 * gimple-range-fold.cc (fold_using_range::range_of_range_op): Add the op1/op2 relation to the relation call. * range-op.cc (*::lhs_op1_relation): Add param. (*::lhs_op2_relation): Ditto. (operator_minus::lhs_op1_relation): New. (range_relational_tests): Add relation param. * range-op.h (lhs_op1_relation, lhs_op2_relation): Adjust prototype. gcc/testsuite/ * g++.dg/pr104547.C: New.
2022-05-13Make gimple_build main workers more flexibleRichard Biener1-0/+1
The following makes the main gimple_build API take a gimple_stmt_iterator, whether to insert before or after and an iterator update argument to make it more convenient to use in certain situations (see the tree-vect-generic.cc hunks for an example). It also makes the case we insert into the IL somewhat distinct from inserting into a standalone sequence in that it simplifies built expressions the same way as inserting and calling fold_stmt (..., follow_all_ssa_edges) would. When inserting into a standalone sequence we restrict simplification to defs within the currently building sequence. The patch only amends the tree_code gimple_build API, I will followup with converting the rest as well. The patch got larger than intended because the template forwarders now use gsi_last which introduces a dependency on gimple-iterator.h requiring mass #include re-org across the tree. There are two frontend specific files including gimple-fold.h just for some padding clearing stuff - I've removed the include and instead moved the declarations to fold-const.h (but not the implementations). Otherwise I'd have to include half of the middle-end headers in those files which I didn't much like. 2022-05-12 Richard Biener <rguenther@suse.de> gcc/cp/ * constexpr.cc: Remove gimple-fold.h include. gcc/c-family/ * c-omp.cc: Remove gimple-fold.h include. gcc/analyzer/ * supergraph.cc: Re-order gimple-fold.h include. gcc/ * gimple-fold.cc (gimple_build): Adjust for new main API. * gimple-fold.h (gimple_build): New main APIs with iterator, insert direction and iterator update. (gimple_build): New forwarder template. (clear_padding_type_may_have_padding_p): Remove. (clear_type_padding_in_mask): Likewise. (arith_overflowed_p): Likewise. * fold-const.h (clear_padding_type_may_have_padding_p): Declare. (clear_type_padding_in_mask): Likewise. (arith_overflowed_p): Likewise. * tree-vect-generic.cc (gimplify_build3): Use main gimple_build API. (gimplify_build2): Likewise. (gimplify_build1): Likewise. * ubsan.cc (ubsan_expand_ptr_ifn): Likewise, avoid extra compare stmt. * gengtype.cc (open_base_files): Re-order includes. * builtins.cc: Re-order gimple-fold.h include. * calls.cc: Likewise. * cgraphbuild.cc: Likewise. * cgraphunit.cc: Likewise. * config/rs6000/rs6000-builtin.cc: Likewise. * config/rs6000/rs6000-call.cc: Likewise. * config/rs6000/rs6000.cc: Likewise. * config/s390/s390.cc: Likewise. * expr.cc: Likewise. * fold-const.cc: Likewise. * function-tests.cc: Likewise. * gimple-match-head.cc: Likewise. * gimple-range-fold.cc: Likewise. * gimple-ssa-evrp-analyze.cc: Likewise. * gimple-ssa-evrp.cc: Likewise. * gimple-ssa-sprintf.cc: Likewise. * gimple-ssa-warn-access.cc: Likewise. * gimplify.cc: Likewise. * graphite-isl-ast-to-gimple.cc: Likewise. * ipa-cp.cc: Likewise. * ipa-devirt.cc: Likewise. * ipa-prop.cc: Likewise. * omp-low.cc: Likewise. * pointer-query.cc: Likewise. * range-op.cc: Likewise. * tree-cfg.cc: Likewise. * tree-if-conv.cc: Likewise. * tree-inline.cc: Likewise. * tree-object-size.cc: Likewise. * tree-ssa-ccp.cc: Likewise. * tree-ssa-dom.cc: Likewise. * tree-ssa-forwprop.cc: Likewise. * tree-ssa-ifcombine.cc: Likewise. * tree-ssa-loop-ivcanon.cc: Likewise. * tree-ssa-math-opts.cc: Likewise. * tree-ssa-pre.cc: Likewise. * tree-ssa-propagate.cc: Likewise. * tree-ssa-reassoc.cc: Likewise. * tree-ssa-sccvn.cc: Likewise. * tree-ssa-strlen.cc: Likewise. * tree-ssa.cc: Likewise. * value-pointer-equiv.cc: Likewise. * vr-values.cc: Likewise. gcc/testsuite/ * gcc.dg/plugin/diagnostic_group_plugin.c: Reorder or remove gimple-fold.h include. * gcc.dg/plugin/diagnostic_plugin_show_trees.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_inlining.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_metadata.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_paths.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_string_literals.c: Likewise. * gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c: Likewise. * gcc.dg/plugin/finish_unit_plugin.c: Likewise. * gcc.dg/plugin/ggcplug.c: Likewise. * gcc.dg/plugin/must_tail_call_plugin.c: Likewise. * gcc.dg/plugin/one_time_plugin.c: Likewise. * gcc.dg/plugin/selfassign.c: Likewise. * gcc.dg/plugin/start_unit_plugin.c: Likewise. * g++.dg/plugin/selfassign.c: Likewise.
2022-04-29Make irange::intersect(wide_int, wide_int) private.Aldy Hernandez1-3/+3
This method should have been private, and somehow seeped into the API. Tested and benchmarked on x86-64 Linux. gcc/ChangeLog: * gimple-range-cache.h (non_null_ref::adjust_range): Do not use irange::intersect (wide_int, wide_int). * gimple-range-fold.cc (adjust_pointer_diff_expr): Same. (adjust_imagpart_expr): Same. * value-range.h (irange::intersect (wide_int, wide_int)): Make private.
2022-02-22ranger: Fix up REALPART_EXPR/IMAGPART_EXPR handling [PR104604]Jakub Jelinek1-2/+4
The following testcase is miscompiled since r12-3328. That change assumed that if rhs1 of a GIMPLE_ASSIGN is COMPLEX_CST, then that is the value of the lhs of the stmt, but that is not the case always, only if it is a GIMPLE_SINGLE_RHS stmt. If it is e.g. GIMPLE_UNARY_RHS or GIMPLE_BINARY_RHS (the latter happens in the testcase), then it can be e.g. __complex__ (3, 0) / var and the REALPART_EXPR of that isn't 3, but the realpart of the division. I assume once the ranger can do complex numbers adjust_*part_expr will just fetch one or the other range from a underlying complex range, but until then, we should limit this to what r12-3328 meant to do. 2022-02-22 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/104604 * gimple-range-fold.cc (adjust_imagpart_expr, adjust_realpart_expr): Only check if gimple_assign_rhs1 is COMPLEX_CST if gimple_assign_rhs_code is COMPLEX_CST. * gcc.c-torture/execute/pr104604.c: New test.
2022-02-15Use GORI to evaluate arguments of a COND_EXPR.Andrew MacLeod1-0/+12
Provide an API into gori to perform a basic evaluation of the arguments of a COND_EXPR if they are in the dependency chain of the condition. PR tree-optimization/104526 gcc/ * gimple-range-fold.cc (fold_using_range::range_of_cond_expr): Call new routine. * gimple-range-gori.cc (range_def_chain::get_def_chain): Force a build of dependency chain if there isn't one. (gori_compute::condexpr_adjust): New. * gimple-range-gori.h (class gori_compute): New prototype. gcc/testsuite/ * gcc.dg/pr104526.c: New.
2022-02-03ranger: fix small thinko in fur_list constructorAldy Hernandez1-1/+1
The fur_list constructor for two ranges is leaving [1] in an undefined state. The reason we haven't noticed is because after all the shuffling in the last cycle there are no remaining users of it (similarly for fur_list(unsigned, irange *)). Since it's very late in the cycle, I would prefer to fix this, rather than removing unused constructors altogether. Besides, we have uses of them queued up for the next release. gcc/ChangeLog: * gimple-range-fold.cc (fur_list::fur_list): Set m_local[1] correctly.
2022-01-03Update copyright years.Jakub Jelinek1-1/+1
2021-11-30Always track arguments, even when ignoring equiv params.Andrew MacLeod1-12/+9
To "ignore" ranges from equivalences, we should track the range separately, but still do the other name processing which determiens if there is a single name or not for equivalence. Otherwise we mistakently think we can introduce an equivalences. gcc/ PR tree-optimization/103440 * gimple-range-fold.cc (fold_using_range::range_of_phi): Continue normal param processing for equiv params. gcc/testsuite/ * gcc.dg/pr103440.c: New.
2021-11-25Check for equivalences between PHI argument and def.Andrew MacLeod1-0/+16
If a PHI argument on an edge is equivalent with the DEF, then it doesn't provide any new information, defer processing it unless they are all equivalences. PR tree-optimization/103359 gcc/ * gimple-range-fold.cc (fold_using_range::range_of_phi): If arg is equivalent to def, don't initially include it's range. gcc/testsuite/ * gcc.dg/pr103359.c: New.
2021-11-17ranger: Fix up fold_using_range::range_of_address [PR103255]Jakub Jelinek1-5/+11
If on &base->member the offset isn't constant or isn't zero and -fdelete-null-pointer-checks and not -fwrapv-pointer and base has a range that doesn't include NULL, we return the range of the base. Usually it isn't a big deal, because for most pointers we just use varying, range_zero and range_nonzero ranges and nothing beyond that, but if a pointer is initialized from a constant, we actually track the exact range and in that case this causes miscompilation. As discussed on IRC, I think doing something like: offset_int off2; if (off_cst && off.is_constant (&off2)) { tree cst = wide_int_to_tree (sizetype, off2 / BITS_PER_UNIT); // adjust range r with POINTER_PLUS_EXPR cst if (!range_includes_zero_p (&r)) return true; } // Fallback r = range_nonzero (TREE_TYPE (gimple_assign_rhs1 (stmt))); return true; could work, given that most of the pointer ranges are just the simple ones perhaps it is too much for little benefit. 2021-11-17 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/103255 * gimple-range-fold.cc (fold_using_range::range_of_address): Return range_nonzero rather than unadjusted base's range. Formatting fixes. * gcc.c-torture/execute/pr103255.c: New test.
2021-11-03For ranges, PHIs don't need to process arg == def.Andrew MacLeod1-0/+4
If an argument of a phi is the same as the DEF of the phi, then the range on the incoming edge doesn't need to be taken into account since it can't be anything other than itself. * gimple-range-fold.cc (fold_using_range::range_of_phi): Don't import a range from edge if arg == phidef.
2021-11-03Check for constant builtin value first.Andrew MacLeod1-6/+6
The original code imported from EVRP for evaluating built_in_constant_p didn't check to see if the value was a constant before checking the inlining flag. Now we check for a constant first. * gimple-range-fold.cc (fold_using_range::range_of_builtin_call): Test for constant before any other processing.
2021-10-27Reorder relation calculating code in the path solver.Aldy Hernandez1-0/+2
Enabling the fully resolving threader triggers various relation ordering issues that have previously been dormant because the VRP hybrid threader (forward threader based) never gives us long enough paths for this to matter. The new threader spares no punches in finding non-obvious paths, so getting the relations right is paramount. This patch fixes a couple oversights that have gone undetected. First, some background. There are 3 types of relations along a path: a) Relations inherent in a PHI. b) Relations as a side-effect of evaluating a statement. c) Outgoing relations between blocks in a path. We must calculate these in their proper order, otherwise we can run into ordering issues. The current ordering is wrong, as we precalculate PHIs for _all_ blocks before anything else, and then proceed to register the relations throughout the path. Also, we fail to realize that a PHI whose argument is also defined in the PHIs block cannot be registered as an equivalence without causing more ordering issues. This patch fixes all the problems described above. With it we get a handful more net threads, but most importantly, we disallow some threads that were wrong. Tested on x86-64 and ppc64le Linux on the usual regstrap, plus by comparing the different thread counts before and after this patch. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_range_op): Dump operands as well as relation. * gimple-range-path.cc (path_range_query::compute_ranges_in_block): Compute PHI relations first. Compute outgoing relations at the end. (path_range_query::compute_ranges): Remove call to compute_relations. (path_range_query::compute_relations): Remove. (path_range_query::maybe_register_phi_relation): New. (path_range_query::compute_phi_relations): Abstract out registering one PHI relation to... (path_range_query::compute_outgoing_relations): ...here. * gimple-range-path.h (class path_range_query): Remove compute_relations. Add maybe_register_phi_relation.
2021-10-06Add range intersect with 2 wide-ints.Andrew MacLeod1-9/+5
Add a more efficent intersect using a lower/upper bound single pair of wide_ints. * gimple-range-cache.cc (non_null_ref::adjust_range): Call new intersect routine. * gimple-range-fold.cc (adjust_pointer_diff_expr): Ditto. (adjust_imagpart_expr): Ditto. * value-range.cc (irange::irange_intersect): Call new routine if RHS is a single pair. (irange::intersect): New wide_int version. * value-range.h (class irange): New prototype.
2021-09-23Look for a relation between operands only when possible.Andrew MacLeod1-0/+4
Do not look for a relation between 2 operands if there is no range-ops handler. gcc/ PR tree-optimization/102463 * gimple-range-fold.cc (fold_using_range::relation_fold_and_or): If there is no range-ops handler, don't look for a relation. gcc/testsuite/ * gcc.dg/pr102463.c: New.
2021-09-23Remove dominator check in fold_using_range::range_of_phi.Aldy Hernandez1-3/+1
Revert the following patch, as it was an artifact of diagnostic code being run with improper IL. commit 64b80b8819f9ea74712625bceb0ec4388e25f67d Author: Aldy Hernandez <aldyh@redhat.com> Date: Tue Sep 21 08:28:28 2021 +0200 Do not query SCEV in range_of_phi unless dominators are available. SCEV won't work without dominators and we can get called without dominators from debug_ranger. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_phi): Remove dominator check.
2021-09-22Check for BB before calling register_outgoing_edges.Aldy Hernandez1-5/+3
We may be asked to fold an artificial statement not in the CFG. Since there are no outgoing edges from those, avoid calling register_outgoing_edges. Tested on x86-64 Linux. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_range_op): Move check for non-empty BB here. (fur_source::register_outgoing_edges): ...from here.
2021-09-21Move postfold_gcond_edges into fur_source.Aldy Hernandez1-22/+22
The code registering outgoing edges from a cond is living in fold_using_range, which makes it difficult to be called from other places. Also, it refuses to register relations on the outgoing destinations that have more than one predecessor. This latter issue is a problem because we would like to register outgoing edges along a path in the path solver (regardless of single_pred_p). gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_range_op): Rename postfold_gcond_edges to register_outgoing_edges and adapt. (fold_using_range::postfold_gcond_edges): Rename... (fur_source::register_outgoing_edges): ...to this. * gimple-range-fold.h (postfold_gcond_edges): Rename to register_outgoing_edges and move to fur_source.
2021-09-21Do not query SCEV in range_of_phi unless dominators are available.Aldy Hernandez1-1/+3
SCEV won't work without dominators and we can get called without dominators from debug_ranger. Another option would be to rename scev_initialized_p to something like scev_available_p and move the check there. For now, this will do. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_phi): Check dom_info_available_p.