aboutsummaryrefslogtreecommitdiff
path: root/gcc/range-op.cc
AgeCommit message (Collapse)AuthorFilesLines
2023-07-12[range-op] Take known mask into account for bitwise ands [PR107043]Aldy Hernandez1-0/+8
PR tree-optimization/107043 gcc/ChangeLog: * range-op.cc (operator_bitwise_and::op1_range): Update bitmask. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr107043.c: New test.
2023-07-12[range-op] Enable value/mask propagation in range-op.Aldy Hernandez1-31/+22
Throw the switch in range-ops to make full use of the value/mask information instead of only the nonzero bits. This will cause most of the operators implemented in range-ops to use the value/mask information calculated by CCP's bit_value_binop() function which range-ops uses. This opens up more optimization opportunities. In follow-up patches I will change the global range setter (set_range_info) to be able to save the value/mask pair, and make both CCP and IPA be able to save the known ones bit info, instead of throwing it away. gcc/ChangeLog: * range-op.cc (irange_to_masked_value): Remove. (update_known_bitmask): Update irange value/mask pair instead of only updating nonzero bits. gcc/testsuite/ChangeLog: * gcc.dg/pr83073.c: Adjust testcase.
2023-07-07Implement value/mask tracking for irange.Aldy Hernandez1-6/+10
Integer ranges (irange) currently track known 0 bits. We've wanted to track known 1 bits for some time, and instead of tracking known 0 and known 1's separately, it has been suggested we track a value/mask pair similarly to what we do for CCP and RTL. This patch implements such a thing. With this we now track a VALUE integer which are the known values, and a MASK which tells us which bits contain meaningful information. This allows us to fix a handful of enhancement requests, such as PR107043 and PR107053. There is a 4.48% performance penalty for VRP and 0.42% in overall compilation for this entire patchset. It is expected and in line with the loss incurred when we started tracking known 0 bits. This patch just provides the value/mask tracking support. All the nonzero users (range-op, IPA, CCP, etc), are still using the nonzero nomenclature. For that matter, this patch reimplements the nonzero accessors with the value/mask functionality. In follow-up patches I will enhance these passes to use the value/mask information, and fix the aforementioned PRs. gcc/ChangeLog: * data-streamer-in.cc (streamer_read_value_range): Adjust for value/mask. * data-streamer-out.cc (streamer_write_vrange): Same. * range-op.cc (operator_cast::fold_range): Same. * value-range-pretty-print.cc (vrange_printer::print_irange_bitmasks): Same. * value-range-storage.cc (irange_storage::write_lengths_address): Same. (irange_storage::set_irange): Same. (irange_storage::get_irange): Same. (irange_storage::size): Same. (irange_storage::dump): Same. * value-range-storage.h: Same. * value-range.cc (debug): New. (irange_bitmask::dump): New. (add_vrange): Adjust for value/mask. (irange::operator=): Same. (irange::set): Same. (irange::verify_range): Same. (irange::operator==): Same. (irange::contains_p): Same. (irange::irange_single_pair_union): Same. (irange::union_): Same. (irange::intersect): Same. (irange::invert): Same. (irange::get_nonzero_bits_from_range): Rename to... (irange::get_bitmask_from_range): ...this. (irange::set_range_from_nonzero_bits): Rename to... (irange::set_range_from_bitmask): ...this. (irange::set_nonzero_bits): Rename to... (irange::update_bitmask): ...this. (irange::get_nonzero_bits): Rename to... (irange::get_bitmask): ...this. (irange::intersect_nonzero_bits): Rename to... (irange::intersect_bitmask): ...this. (irange::union_nonzero_bits): Rename to... (irange::union_bitmask): ...this. (irange_bitmask::verify_mask): New. * value-range.h (class irange_bitmask): New. (irange_bitmask::set_unknown): New. (irange_bitmask::unknown_p): New. (irange_bitmask::irange_bitmask): New. (irange_bitmask::get_precision): New. (irange_bitmask::get_nonzero_bits): New. (irange_bitmask::set_nonzero_bits): New. (irange_bitmask::operator==): New. (irange_bitmask::union_): New. (irange_bitmask::intersect): New. (class irange): Friend vrange_printer. (irange::varying_compatible_p): Adjust for bitmask. (irange::set_varying): Same. (irange::set_nonzero): Same. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr107009.c: Adjust irange dumping for value/mask changes. * gcc.dg/tree-ssa/vrp-unreachable.c: Same. * gcc.dg/tree-ssa/vrp122.c: Same.
2023-06-12Add some overrides.Andrew MacLeod1-2/+8
PR tree-optimization/110205 * range-op-float.cc (range_operator::fold_range): Add default FII fold routine. * range-op-mixed.h (class operator_gt): Add missing final overrides. * range-op.cc (range_op_handler::fold_range): Add RO_FII case. (operator_lshift ::update_bitmask): Add final override. (operator_rshift ::update_bitmask): Add final override. * range-op.h (range_operator::fold_range): Add FII prototype.
2023-06-12Provide interface for non-standard operators.Andrew MacLeod1-5/+6
THis removes the hack introduced for WIDEN_MULT which exported a pointer to the operator and the gimple-range-op.cc set the operator to this pointer whenn it was appropriate. Instead, we simple change the range-op table to be unsigned indexed, and add new opcodes to the end of the table, allowing them to be indexed directly via range_op_handler::range_op. * gimple-range-op.cc (gimple_range_op_handler::maybe_non_standard): Use range_op_handler directly. * range-op.cc (range_op_handler::range_op_handler): Unsigned param instead of tree-code. (ptr_op_widen_plus_signed): Delete. (ptr_op_widen_plus_unsigned): Delete. (ptr_op_widen_mult_signed): Delete. (ptr_op_widen_mult_unsigned): Delete. (range_op_table::initialize_integral_ops): Add new opcodes. * range-op.h (range_op_handler): Use unsigned. (OP_WIDEN_MULT_SIGNED): New. (OP_WIDEN_MULT_UNSIGNED): New. (OP_WIDEN_PLUS_SIGNED): New. (OP_WIDEN_PLUS_UNSIGNED): New. (RANGE_OP_TABLE_SIZE): New. (range_op_table::operator []): Use unsigned. (range_op_table::set): Use unsigned. (m_range_tree): Make unsigned. (ptr_op_widen_mult_signed): Remove. (ptr_op_widen_mult_unsigned): Remove. (ptr_op_widen_plus_signed): Remove. (ptr_op_widen_plus_unsigned): Remove.
2023-06-12Provide a default range_operator via range_op_handler.Andrew MacLeod1-2/+30
range_op_handler now provides a default range_operator for any opcode, so there is no longer a need to check for a valid operator. * gimple-range-op.cc (gimple_range_op_handler): Set m_operator manually as there is no access to the default operator. (cfn_copysign::fold_range): Don't check for validity. (cfn_ubsan::fold_range): Ditto. (gimple_range_op_handler::maybe_builtin_call): Don't set to NULL. * range-op.cc (default_operator): New. (range_op_handler::range_op_handler): Use default_operator instead of NULL. (range_op_handler::operator bool): Move from header, compare against default operator. (range_op_handler::range_op): New. * range-op.h (range_op_handler::operator bool): Move.
2023-06-12Switch from unified table to range_op_table. There can be only one.Andrew MacLeod1-9/+5
Now that there is only a single range_op_table, make the base table the only table. * range-op.cc (unified_table): Delete. (range_op_table operator_table): Instantiate. (range_op_table::range_op_table): Rename from unified_table. (range_op_handler::range_op_handler): Use range_op_table. * range-op.h (range_op_table::operator []): Inline. (range_op_table::set): Inline.
2023-06-12Remove type from range_op_handler table selectionAndrew MacLeod1-30/+9
With the unified table complete, we no loonger need to specify a type to choose a table when setting a range_op_handler. * gimple-range-gori.cc (gori_compute::condexpr_adjust): Do not pass type. * gimple-range-op.cc (get_code): Rename from get_code_and_type and simplify. (gimple_range_op_handler::supported_p): No need for type. (gimple_range_op_handler::gimple_range_op_handler): Ditto. (cfn_copysign::fold_range): Ditto. (cfn_ubsan::fold_range): Ditto. * ipa-cp.cc (ipa_vr_operation_and_type_effects): Ditto. * ipa-fnsummary.cc (evaluate_conditions_for_known_args): Ditto. * range-op-float.cc (operator_plus::op1_range): Ditto. (operator_mult::op1_range): Ditto. (range_op_float_tests): Ditto. * range-op.cc (get_op_handler): Remove. (range_op_handler::set_op_handler): Remove. (operator_plus::op1_range): No need for type. (operator_minus::op1_range): Ditto. (operator_mult::op1_range): Ditto. (operator_exact_divide::op1_range): Ditto. (operator_cast::op1_range): Ditto. (perator_bitwise_not::fold_range): Ditto. (operator_negate::fold_range): Ditto. * range-op.h (range_op_handler::range_op_handler): Remove type param. (range_cast): No need for type. (range_op_table::operator[]): Check for enum_code >= 0. * tree-data-ref.cc (compute_distributive_range): No need for type. * tree-ssa-loop-unswitch.cc (unswitch_predicate): Ditto. * value-query.cc (range_query::get_tree_range): Ditto. * value-relation.cc (relation_oracle::validate_relation): Ditto. * vr-values.cc (range_of_var_in_loop): Ditto. (simplify_using_ranges::fold_cond_with_ops): Ditto.
2023-06-12Add a hybrid MAX_EXPR operator for integer and pointer.Andrew MacLeod1-8/+2
This adds an operator to the unified table for MAX_EXPR which will select either the pointer or integer version based on the type passed to the method. This is for use until we have a seperate PRANGE class. THIs also removes the pointer table which is no longer needed. * range-op-mixed.h (operator_max): Remove final. * range-op-ptr.cc (pointer_table::pointer_table): Remove MAX_EXPR. (pointer_table::pointer_table): Remove. (class hybrid_max_operator): New. (range_op_table::initialize_pointer_ops): Add hybrid_max_operator. * range-op.cc (pointer_tree_table): Remove. (unified_table::unified_table): Comment out MAX_EXPR. (get_op_handler): Remove check of pointer table. * range-op.h (class pointer_table): Remove.
2023-06-12Add a hybrid MIN_EXPR operator for integer and pointer.Andrew MacLeod1-1/+1
This adds an operator to the unified table for MIN_EXPR which will select either the pointer or integer version based on the type passed to the method. This is for use until we have a seperate PRANGE class. * range-op-mixed.h (operator_min): Remove final. * range-op-ptr.cc (pointer_table::pointer_table): Remove MIN_EXPR. (class hybrid_min_operator): New. (range_op_table::initialize_pointer_ops): Add hybrid_min_operator. * range-op.cc (unified_table::unified_table): Comment out MIN_EXPR.
2023-06-12Add a hybrid BIT_IOR_EXPR operator for integer and pointer.Andrew MacLeod1-2/+2
This adds an operator to the unified table for BIT_IOR_EXPR which will select either the pointer or integer version based on the type passed to the method. This is for use until we have a seperate PRANGE class. * range-op-mixed.h (operator_bitwise_or): Remove final. * range-op-ptr.cc (pointer_table::pointer_table): Remove BIT_IOR_EXPR. (class hybrid_or_operator): New. (range_op_table::initialize_pointer_ops): Add hybrid_or_operator. * range-op.cc (unified_table::unified_table): Comment out BIT_IOR_EXPR.
2023-06-12Add a hybrid BIT_AND_EXPR operator for integer and pointer.Andrew MacLeod1-3/+6
This adds an operator to the unified table for BIT_AND_EXPR which will select either the pointer or integer version based on the type passed to the method. This is for use until we have a seperate PRANGE class. * range-op-mixed.h (operator_bitwise_and): Remove final. * range-op-ptr.cc (pointer_table::pointer_table): Remove BIT_AND_EXPR. (class hybrid_and_operator): New. (range_op_table::initialize_pointer_ops): Add hybrid_and_operator. * range-op.cc (unified_table::unified_table): Comment out BIT_AND_EXPR.
2023-06-12Split pointer ibased range operators to range-op-ptr.ccAndrew MacLeod1-256/+2
MOve the pointer table and all pointer specific operators into a new file for pointers. * Makefile.in (OBJS): Add range-op-ptr.o. * range-op-mixed.h (update_known_bitmask): Move prototype here. (minus_op1_op2_relation_effect): Move prototype here. (wi_includes_zero_p): Move function to here. (wi_zero_p): Ditto. * range-op.cc (update_known_bitmask): Remove static. (wi_includes_zero_p): Move to header. (wi_zero_p): Move to header. (minus_op1_op2_relation_effect): Remove static. (operator_pointer_diff): Move class and routines to range-op-ptr.cc. (pointer_plus_operator): Ditto. (pointer_min_max_operator): Ditto. (pointer_and_operator): Ditto. (pointer_or_operator): Ditto. (pointer_table): Ditto. (range_op_table::initialize_pointer_ops): Ditto. * range-op-ptr.cc: New.
2023-06-12Move operator_max to the unified range-op table.Andrew MacLeod1-26/+8
Also remove the integral table. * range-op-mixed.h (class operator_max): Move from... * range-op.cc (unified_table::unified_table): Add MAX_EXPR. (get_op_handler): Remove the integral table. (class operator_max): Move from here. (integral_table::integral_table): Delete. * range-op.h (class integral_table): Delete.
2023-06-12Move operator_min to the unified range-op table.Andrew MacLeod1-11/+7
* range-op-mixed.h (class operator_min): Move from... * range-op.cc (unified_table::unified_table): Add MIN_EXPR. (class operator_min): Move from here. (integral_table::integral_table): Remove MIN_EXPR.
2023-06-12Move operator_bitwise_or to the unified range-op table.Andrew MacLeod1-21/+7
* range-op-mixed.h (class operator_bitwise_or): Move from... * range-op.cc (unified_table::unified_table): Add BIT_IOR_EXPR. (class operator_bitwise_or): Move from here. (integral_table::integral_table): Remove BIT_IOR_EXPR.
2023-06-12Move operator_bitwise_and to the unified range-op table.Andrew MacLeod1-34/+15
At this point, the remaining 4 integral operation have different impllementations than pointers, so we now check for a pointer table entry first, then if there is nothing, look at the Unified table. * range-op-mixed.h (class operator_bitwise_and): Move from... * range-op.cc (unified_table::unified_table): Add BIT_AND_EXPR. (get_op_handler): Check for a pointer table entry first. (class operator_bitwise_and): Move from here. (integral_table::integral_table): Remove BIT_AND_EXPR.
2023-06-12Move operator_bitwise_xor to the unified range-op table.Andrew MacLeod1-29/+7
* range-op-mixed.h (class operator_bitwise_xor): Move from... * range-op.cc (unified_table::unified_table): Add BIT_XOR_EXPR. (class operator_bitwise_xor): Move from here. (integral_table::integral_table): Remove BIT_XOR_EXPR. (pointer_table::pointer_table): Remove BIT_XOR_EXPR.
2023-06-12Move operator_bitwise_not to the unified range-op table.Andrew MacLeod1-18/+3
* range-op-mixed.h (class operator_bitwise_not): Move from... * range-op.cc (unified_table::unified_table): Add BIT_NOT_EXPR. (class operator_bitwise_not): Move from here. (integral_table::integral_table): Remove BIT_NOT_EXPR. (pointer_table::pointer_table): Remove BIT_NOT_EXPR.
2023-06-12Move operator_addr_expr to the unified range-op table.Andrew MacLeod1-18/+5
* range-op-mixed.h (class operator_addr_expr): Move from... * range-op.cc (unified_table::unified_table): Add ADDR_EXPR. (class operator_addr_expr): Move from here. (integral_table::integral_table): Remove ADDR_EXPR. (pointer_table::pointer_table): Remove ADDR_EXPR.
2023-06-09Unify MULT_EXPR range operatorAndrew MacLeod1-46/+7
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_mult_div_base): Delete. (foperator_mult_div_base::find_range): Make static local function. (foperator_mult): Remove. Move prototypes to range-op-mixed.h (operator_mult::op1_range): Rename from foperator_mult. (operator_mult::op2_range): Ditto. (operator_mult::rv_fold): Ditto. (float_table::float_table): Remove MULT_EXPR. (class foperator_div): Inherit from range_operator. (float_table::float_table): Delete. * range-op-mixed.h (class operator_mult): Combined from integer and float files. * range-op.cc (float_tree_table): Delete. (op_mult): New object. (unified_table::unified_table): Add MULT_EXPR. (get_op_handler): Do not check float table any longer. (class cross_product_operator): Move to range-op-mixed.h. (class operator_mult): Move to range-op-mixed.h. (integral_table::integral_table): Remove MULT_EXPR. (pointer_table::pointer_table): Remove MULT_EXPR. * range-op.h (float_table): Remove.
2023-06-09Unify NEGATE_EXPR range operatorAndrew MacLeod1-16/+2
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_negate): Remove. Move prototypes to range-op-mixed.h (operator_negate::fold_range): Rename from foperator_negate. (operator_negate::op1_range): Ditto. (float_table::float_table): Remove NEGATE_EXPR. * range-op-mixed.h (class operator_negate): Combined from integer and float files. * range-op.cc (op_negate): New object. (unified_table::unified_table): Add NEGATE_EXPR. (class operator_negate): Move to range-op-mixed.h. (integral_table::integral_table): Remove NEGATE_EXPR. (pointer_table::pointer_table): Remove NEGATE_EXPR.
2023-06-09Unify MINUS_EXPR range operatorAndrew MacLeod1-32/+7
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_minus): Remove. Move prototypes to range-op-mixed.h (operator_minus::fold_range): Rename from foperator_minus. (operator_minus::op1_range): Ditto. (operator_minus::op2_range): Ditto. (operator_minus::rv_fold): Ditto. (float_table::float_table): Remove MINUS_EXPR. * range-op-mixed.h (class operator_minus): Combined from integer and float files. * range-op.cc (op_minus): New object. (unified_table::unified_table): Add MINUS_EXPR. (class operator_minus): Move to range-op-mixed.h. (integral_table::integral_table): Remove MINUS_EXPR. (pointer_table::pointer_table): Remove MINUS_EXPR.
2023-06-09Unify ABS_EXPR range operatorAndrew MacLeod1-16/+2
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_abs): Remove. Move prototypes to range-op-mixed.h (operator_abs::fold_range): Rename from foperator_abs. (operator_abs::op1_range): Ditto. (float_table::float_table): Remove ABS_EXPR. * range-op-mixed.h (class operator_abs): Combined from integer and float files. * range-op.cc (op_abs): New object. (unified_table::unified_table): Add ABS_EXPR. (class operator_abs): Move to range-op-mixed.h. (integral_table::integral_table): Remove ABS_EXPR. (pointer_table::pointer_table): Remove ABS_EXPR.
2023-06-09Unify PLUS_EXPR range operatorAndrew MacLeod1-30/+7
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_plus): Remove. Move prototypes to range-op-mixed.h (operator_plus::fold_range): Rename from foperator_plus. (operator_plus::op1_range): Ditto. (operator_plus::op2_range): Ditto. (operator_plus::rv_fold): Ditto. (float_table::float_table): Remove PLUS_EXPR. * range-op-mixed.h (class operator_plus): Combined from integer and float files. * range-op.cc (op_plus): New object. (unified_table::unified_table): Add PLUS_EXPR. (class operator_plus): Move to range-op-mixed.h. (integral_table::integral_table): Remove PLUS_EXPR. (pointer_table::pointer_table): Remove PLUS_EXPR.
2023-06-09Unify operator_cast range operatorAndrew MacLeod1-30/+4
Move the declaration of the class to the range-op-mixed header, and use it in the new unified table. * range-op-mixed.h (class operator_cast): Combined from integer and float files. * range-op.cc (op_cast): New object. (unified_table::unified_table): Add op_cast (class operator_cast): Move to range-op-mixed.h. (integral_table::integral_table): Remove op_cast (pointer_table::pointer_table): Remove op_cast.
2023-06-09Unify operator_cst range operatorAndrew MacLeod1-13/+3
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (operator_cst::fold_range): New. * range-op-mixed.h (class operator_cst): Move from integer file. * range-op.cc (op_cst): New object. (unified_table::unified_table): Add op_cst. Also use for REAL_CST. (class operator_cst): Move to range-op-mixed.h. (integral_table::integral_table): Remove op_cst. (pointer_table::pointer_table): Remove op_cst.
2023-06-09Unify Identity range operatorAndrew MacLeod1-24/+5
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_identity): Remove. Move prototypes to range-op-mixed.h (operator_identity::fold_range): Rename from foperator_identity. (operator_identity::op1_range): Ditto. (float_table::float_table): Remove fop_identity. * range-op-mixed.h (class operator_identity): Combined from integer and float files. * range-op.cc (op_identity): New object. (unified_table::unified_table): Add op_identity. (class operator_identity): Move to range-op-mixed.h. (integral_table::integral_table): Remove identity. (pointer_table::pointer_table): Remove identity.
2023-06-09Unify GE_EXPR range operatorAndrew MacLeod1-31/+8
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_ge): Remove. Move prototypes to range-op-mixed.h (operator_ge::fold_range): Rename from foperator_ge. (operator_ge::op1_range): Ditto. (float_table::float_table): Remove GE_EXPR. * range-op-mixed.h (class operator_ge): Combined from integer and float files. * range-op.cc (op_ge): New object. (unified_table::unified_table): Add GE_EXPR. (class operator_ge): Move to range-op-mixed.h. (ge_op1_op2_relation): Fold into operator_ge::op1_op2_relation. (integral_table::integral_table): Remove GE_EXPR. (pointer_table::pointer_table): Remove GE_EXPR. * range-op.h (ge_op1_op2_relation): Delete.
2023-06-09Unify GT_EXPR range operatorAndrew MacLeod1-32/+8
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_gt): Remove. Move prototypes to range-op-mixed.h (operator_gt::fold_range): Rename from foperator_gt. (operator_gt::op1_range): Ditto. (float_table::float_table): Remove GT_EXPR. * range-op-mixed.h (class operator_gt): Combined from integer and float files. * range-op.cc (op_gt): New object. (unified_table::unified_table): Add GT_EXPR. (class operator_gt): Move to range-op-mixed.h. (gt_op1_op2_relation): Fold into operator_gt::op1_op2_relation. (integral_table::integral_table): Remove GT_EXPR. (pointer_table::pointer_table): Remove GT_EXPR. * range-op.h (gt_op1_op2_relation): Delete.
2023-06-09Unify LE_EXPR range operatorAndrew MacLeod1-31/+8
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_le): Remove. Move prototypes to range-op-mixed.h (operator_le::fold_range): Rename from foperator_le. (operator_le::op1_range): Ditto. (float_table::float_table): Remove LE_EXPR. * range-op-mixed.h (class operator_le): Combined from integer and float files. * range-op.cc (op_le): New object. (unified_table::unified_table): Add LE_EXPR. (class operator_le): Move to range-op-mixed.h. (le_op1_op2_relation): Fold into operator_le::op1_op2_relation. (integral_table::integral_table): Remove LE_EXPR. (pointer_table::pointer_table): Remove LE_EXPR. * range-op.h (le_op1_op2_relation): Delete.
2023-06-09Unify LT_EXPR range operatorAndrew MacLeod1-31/+8
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_lt): Remove. Move prototypes to range-op-mixed.h (operator_lt::fold_range): Rename from foperator_lt. (operator_lt::op1_range): Ditto. (float_table::float_table): Remove LT_EXPR. * range-op-mixed.h (class operator_lt): Combined from integer and float files. * range-op.cc (op_lt): New object. (unified_table::unified_table): Add LT_EXPR. (class operator_lt): Move to range-op-mixed.h. (lt_op1_op2_relation): Fold into operator_lt::op1_op2_relation. (integral_table::integral_table): Remove LT_EXPR. (pointer_table::pointer_table): Remove LT_EXPR. * range-op.h (lt_op1_op2_relation): Delete.
2023-06-09Unify NE_EXPR range operatorAndrew MacLeod1-31/+10
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_not_equal): Remove. Move prototypes to range-op-mixed.h (operator_equal::fold_range): Rename from foperator_not_equal. (operator_equal::op1_range): Ditto. (float_table::float_table): Remove NE_EXPR. * range-op-mixed.h (class operator_not_equal): Combined from integer and float files. * range-op.cc (op_equal): New object. (unified_table::unified_table): Add NE_EXPR. (class operator_not_equal): Move to range-op-mixed.h. (not_equal_op1_op2_relation): Fold into operator_not_equal::op1_op2_relation. (integral_table::integral_table): Remove NE_EXPR. (pointer_table::pointer_table): Remove NE_EXPR. * range-op.h (not_equal_op1_op2_relation): Delete.
2023-06-09Unify EQ_EXPR range operatorAndrew MacLeod1-32/+13
Move the declaration of the class to the range-op-mixed header, add the floating point prototypes as well, and use it in the new unified table. * range-op-float.cc (foperator_equal): Remove. Move prototypes to range-op-mixed.h (operator_equal::fold_range): Rename from foperator_equal. (operator_equal::op1_range): Ditto. (float_table::float_table): Remove EQ_EXPR. * range-op-mixed.h (class operator_equal): Combined from integer and float files. * range-op.cc (op_equal): New object. (unified_table::unified_table): Add EQ_EXPR. (class operator_equal): Move to range-op-mixed.h. (equal_op1_op2_relation): Fold into operator_equal::op1_op2_relation. (integral_table::integral_table): Remove EQ_EXPR. (pointer_table::pointer_table): Remove EQ_EXPR. * range-op.h (equal_op1_op2_relation): Delete.
2023-06-09Provide a unified range-op table.Andrew MacLeod1-28/+61
Create a table to prepare for unifying all operations into a single table. Move any operators which only occur in one table to the approriate initialization routine. Provide a mixed header file for range-ops with multiple categories. * range-op-float.cc (class float_table): Move to header. (float_table::float_table): Move float only operators to... (range_op_table::initialize_float_ops): Here. * range-op-mixed.h: New. * range-op.cc (integral_tree_table, pointer_tree_table): Moved to top of file. (float_tree_table): Moved from range-op-float.cc. (unified_tree_table): New. (unified_table::unified_table): New. Call initialize routines. (get_op_handler): Check unified table first. (range_op_handler::range_op_handler): Handle no type constructor. (integral_table::integral_table): Move integral only operators to... (range_op_table::initialize_integral_ops): Here. (pointer_table::pointer_table): Move pointer only operators to... (range_op_table::initialize_pointer_ops): Here. * range-op.h (enum bool_range_state): Move to range-op-mixed.h. (get_bool_state): Ditto. (empty_range_varying): Ditto. (relop_early_resolve): Ditto. (class range_op_table): Add new init methods for range types. (class integral_table): Move declaration to here. (class pointer_table): Move declaration to here. (class float_table): Move declaration to here.
2023-06-09Relocate range_cast to header, and add a generic version.Andrew MacLeod1-18/+0
Make range_cast inlinable by moving it to the header file. Also trap if the destination is not capable of representing the cast type. Add a generic version which can change range classes.. ie float to int. * range-op.cc (range_cast): Move to... * range-op.h (range_cast): Here and add generic a version.
2023-06-08Provide a new dispatch mechanism for range-ops.Andrew MacLeod1-220/+250
Simplify range_op_handler to have a single range_operator pointer and provide a more flexible dispatch mechanism for calls via generic vrange classes. This is more extensible for adding new classes of range support. Any unsupported dispatch patterns will simply return FALSE now rather than generating compile time exceptions, aleviating the need to constantly check for supoprted types. * gimple-range-op.cc (gimple_range_op_handler::gimple_range_op_handler): Adjust. (gimple_range_op_handler::maybe_builtin_call): Adjust. * gimple-range-op.h (operand1, operand2): Use m_operator. * range-op.cc (integral_table, pointer_table): Relocate. (get_op_handler): Rename from get_handler and handle all types. (range_op_handler::range_op_handler): Relocate. (range_op_handler::set_op_handler): Relocate and adjust. (range_op_handler::range_op_handler): Relocate. (dispatch_trio): New. (RO_III, RO_IFI, RO_IFF, RO_FFF, RO_FIF, RO_FII): New consts. (range_op_handler::dispatch_kind): New. (range_op_handler::fold_range): Relocate and Use new dispatch value. (range_op_handler::op1_range): Ditto. (range_op_handler::op2_range): Ditto. (range_op_handler::lhs_op1_relation): Ditto. (range_op_handler::lhs_op2_relation): Ditto. (range_op_handler::op1_op2_relation): Ditto. (range_op_handler::set_op_handler): Use m_operator member. * range-op.h (range_op_handler::operator bool): Use m_operator. (range_op_handler::dispatch_kind): New. (range_op_handler::m_valid): Delete. (range_op_handler::m_int): Delete (range_op_handler::m_float): Delete (range_op_handler::m_operator): New. (range_op_table::operator[]): Relocate from .cc file. (range_op_table::set): Ditto. * value-range.h (class vrange): Make range_op_handler a friend.
2023-06-08Unify range_operators to one class.Andrew MacLeod1-1/+11
Range_operator and range_operator_float are 2 different classes, making generalized dispatch difficult. The distinction between what is a float operator and what is an integral operator also blurs when some methods have multiple types. ie, casts : INT = FLOAT and FLOAT = INT This patch unifies all possible invocation patterns in one class, and switches the float table to use the general range_op_table. * gimple-range-op.cc (cfn_constant_float_p): Change base class. (cfn_pass_through_arg1): Adjust using statemenmt. (cfn_signbit): Change base class, adjust using statement. (cfn_copysign): Ditto. (cfn_sqrt): Ditto. (cfn_sincos): Ditto. * range-op-float.cc (fold_range): Change class to range_operator. (rv_fold): Ditto. (op1_range): Ditto (op2_range): Ditto (lhs_op1_relation): Ditto. (lhs_op2_relation): Ditto. (op1_op2_relation): Ditto. (foperator_*): Ditto. (class float_table): New. Inherit from range_op_table. (floating_tree_table) Change to range_op_table pointer. (class floating_op_table): Delete. * range-op.cc (operator_equal): Adjust using statement. (operator_not_equal): Ditto. (operator_lt, operator_le, operator_gt, operator_ge): Ditto. (operator_minus, operator_cast): Ditto. (operator_bitwise_and, pointer_plus_operator): Ditto. (get_float_handle): Change return type. * range-op.h (range_operator_float): Delete. Relocate all methods into class range_operator. (range_op_handler::m_float): Change type to range_operator. (floating_op_table): Delete. (floating_tree_table): Change type.
2023-06-08Remove tree_code from range-operator.Andrew MacLeod1-33/+77
Range_operator had a tree code added last release to facilitate bitmask operations. This removes the tree_code and replaces it with a virtual routine to peform the masking. Remove any duplicate instances which are no longer needed. * range-op.cc (range_operator::fold_range): Call virtual routine. (range_operator::update_bitmask): New. (operator_equal::update_bitmask): New. (operator_not_equal::update_bitmask): New. (operator_lt::update_bitmask): New. (operator_le::update_bitmask): New. (operator_gt::update_bitmask): New. (operator_ge::update_bitmask): New. (operator_ge::update_bitmask): New. (operator_plus::update_bitmask): New. (operator_minus::update_bitmask): New. (operator_pointer_diff::update_bitmask): New. (operator_min::update_bitmask): New. (operator_max::update_bitmask): New. (operator_mult::update_bitmask): New. (operator_div:operator_div):New. (operator_div::update_bitmask): New. (operator_div::m_code): New member. (operator_exact_divide::operator_exact_divide): New constructor. (operator_lshift::update_bitmask): New. (operator_rshift::update_bitmask): New. (operator_bitwise_and::update_bitmask): New. (operator_bitwise_or::update_bitmask): New. (operator_bitwise_xor::update_bitmask): New. (operator_trunc_mod::update_bitmask): New. (op_ident, op_unknown, op_ptr_min_max): New. (op_nop, op_convert): Delete. (op_ssa, op_paren, op_obj_type): Delete. (op_realpart, op_imagpart): Delete. (op_ptr_min, op_ptr_max): Delete. (pointer_plus_operator:update_bitmask): New. (range_op_table::set): Do not use m_code. (integral_table::integral_table): Adjust to single instances. * range-op.h (range_operator::range_operator): Delete. (range_operator::m_code): Delete. (range_operator::update_bitmask): New.
2023-05-01Convert internal representation of irange to wide_ints.Aldy Hernandez1-1/+2
gcc/ChangeLog: * range-op.cc (update_known_bitmask): Adjust for irange containing wide_ints internally. * tree-ssanames.cc (set_nonzero_bits): Same. * tree-ssanames.h (set_nonzero_bits): Same. * value-range-storage.cc (irange_storage::set_irange): Same. (irange_storage::get_irange): Same. * value-range.cc (irange::operator=): Same. (irange::irange_set): Same. (irange::irange_set_1bit_anti_range): Same. (irange::irange_set_anti_range): Same. (irange::set): Same. (irange::verify_range): Same. (irange::contains_p): Same. (irange::irange_single_pair_union): Same. (irange::union_): Same. (irange::irange_contains_p): Same. (irange::intersect): Same. (irange::invert): Same. (irange::set_range_from_nonzero_bits): Same. (irange::set_nonzero_bits): Same. (mask_to_wi): Same. (irange::intersect_nonzero_bits): Same. (irange::union_nonzero_bits): Same. (gt_ggc_mx): Same. (gt_pch_nx): Same. (tree_range): Same. (range_tests_strict_enum): Same. (range_tests_misc): Same. (range_tests_nonzero_bits): Same. * value-range.h (irange::type): Same. (irange::varying_compatible_p): Same. (irange::irange): Same. (int_range::int_range): Same. (irange::set_undefined): Same. (irange::set_varying): Same. (irange::lower_bound): Same. (irange::upper_bound): Same.
2023-05-01Replace vrp_val* with wide_ints.Aldy Hernandez1-11/+8
This patch removes all uses of vrp_val_{min,max} in favor for a irange_val_* which are wide_int based. This will leave only one use of vrp_val_* which returns trees in range_of_ssa_name_with_loop_info() because it needs to work with non-integers (floats, etc). In a follow-up patch, this function will also be cleaned up such that vrp_val_* can be deleted. The functions min_limit and max_limit in range-op.cc are now useless as they're basically irange_val*. I didn't rename them yet to avoid churn. I'll do it in a later patch. gcc/ChangeLog: * gimple-range-fold.cc (adjust_pointer_diff_expr): Rewrite with irange_val*. (vrp_val_max): New. (vrp_val_min): New. * gimple-range-op.cc (cfn_strlen::fold_range): Use irange_val_*. * range-op.cc (max_limit): Same. (min_limit): Same. (plus_minus_ranges): Same. (operator_rshift::op1_range): Same. (operator_cast::inside_domain_p): Same. * value-range.cc (vrp_val_is_max): Delete. (vrp_val_is_min): Delete. (range_tests_misc): Use irange_val_*. * value-range.h (vrp_val_is_min): Delete. (vrp_val_is_max): Delete. (vrp_val_max): Delete. (irange_val_min): New. (vrp_val_min): Delete. (irange_val_max): New. * vr-values.cc (check_for_binary_op_overflow): Use irange_val_*.
2023-05-01Conversion to irange wide_int API.Aldy Hernandez1-132/+131
This converts the irange API to use wide_ints exclusively, along with its users. This patch will slow down VRP, as there will be more useless wide_int to tree conversions. However, this slowdown is only temporary, as a follow-up patch will convert the internal representation of iranges to wide_ints for a net overall gain in performance. gcc/ChangeLog: * fold-const.cc (expr_not_equal_to): Convert to irange wide_int API. * gimple-fold.cc (size_must_be_zero_p): Same. * gimple-loop-versioning.cc (loop_versioning::prune_loop_conditions): Same. * gimple-range-edge.cc (gcond_edge_range): Same. (gimple_outgoing_range::calc_switch_ranges): Same. * gimple-range-fold.cc (adjust_imagpart_expr): Same. (adjust_realpart_expr): Same. (fold_using_range::range_of_address): Same. (fold_using_range::relation_fold_and_or): Same. * gimple-range-gori.cc (gori_compute::gori_compute): Same. (range_is_either_true_or_false): Same. * gimple-range-op.cc (cfn_toupper_tolower::get_letter_range): Same. (cfn_clz::fold_range): Same. (cfn_ctz::fold_range): Same. * gimple-range-tests.cc (class test_expr_eval): Same. * gimple-ssa-warn-alloca.cc (alloca_call_type): Same. * ipa-cp.cc (ipa_value_range_from_jfunc): Same. (propagate_vr_across_jump_function): Same. (decide_whether_version_node): Same. * ipa-prop.cc (ipa_get_value_range): Same. * ipa-prop.h (ipa_range_set_and_normalize): Same. * range-op.cc (get_shift_range): Same. (value_range_from_overflowed_bounds): Same. (value_range_with_overflow): Same. (create_possibly_reversed_range): Same. (equal_op1_op2_relation): Same. (not_equal_op1_op2_relation): Same. (lt_op1_op2_relation): Same. (le_op1_op2_relation): Same. (gt_op1_op2_relation): Same. (ge_op1_op2_relation): Same. (operator_mult::op1_range): Same. (operator_exact_divide::op1_range): Same. (operator_lshift::op1_range): Same. (operator_rshift::op1_range): Same. (operator_cast::op1_range): Same. (operator_logical_and::fold_range): Same. (set_nonzero_range_from_mask): Same. (operator_bitwise_or::op1_range): Same. (operator_bitwise_xor::op1_range): Same. (operator_addr_expr::fold_range): Same. (pointer_plus_operator::wi_fold): Same. (pointer_or_operator::op1_range): Same. (INT): Same. (UINT): Same. (INT16): Same. (UINT16): Same. (SCHAR): Same. (UCHAR): Same. (range_op_cast_tests): Same. (range_op_lshift_tests): Same. (range_op_rshift_tests): Same. (range_op_bitwise_and_tests): Same. (range_relational_tests): Same. * range.cc (range_zero): Same. (range_nonzero): Same. * range.h (range_true): Same. (range_false): Same. (range_true_and_false): Same. * tree-data-ref.cc (split_constant_offset_1): Same. * tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Same. * tree-ssa-loop-unswitch.cc (struct unswitch_predicate): Same. (find_unswitching_predicates_for_bb): Same. * tree-ssa-phiopt.cc (value_replacement): Same. * tree-ssa-threadbackward.cc (back_threader::find_taken_edge_cond): Same. * tree-ssanames.cc (ssa_name_has_boolean_range): Same. * tree-vrp.cc (find_case_label_range): Same. * value-query.cc (range_query::get_tree_range): Same. * value-range.cc (irange::set_nonnegative): Same. (frange::contains_p): Same. (frange::singleton_p): Same. (frange::internal_singleton_p): Same. (irange::irange_set): Same. (irange::irange_set_1bit_anti_range): Same. (irange::irange_set_anti_range): Same. (irange::set): Same. (irange::operator==): Same. (irange::singleton_p): Same. (irange::contains_p): Same. (irange::set_range_from_nonzero_bits): Same. (DEFINE_INT_RANGE_INSTANCE): Same. (INT): Same. (UINT): Same. (SCHAR): Same. (UINT128): Same. (UCHAR): Same. (range): New. (tree_range): New. (range_int): New. (range_uint): New. (range_uint128): New. (range_uchar): New. (range_char): New. (build_range3): Convert to irange wide_int API. (range_tests_irange3): Same. (range_tests_int_range_max): Same. (range_tests_strict_enum): Same. (range_tests_misc): Same. (range_tests_nonzero_bits): Same. (range_tests_nan): Same. (range_tests_signed_zeros): Same. * value-range.h (Value_Range::Value_Range): Same. (irange::set): Same. (irange::nonzero_p): Same. (irange::contains_p): Same. (range_includes_zero_p): Same. (irange::set_nonzero): Same. (irange::set_zero): Same. (contains_zero_p): Same. (frange::contains_p): Same. * vr-values.cc (simplify_using_ranges::op_with_boolean_value_range_p): Same. (bounds_of_var_in_loop): Same. (simplify_using_ranges::legacy_fold_cond_overflow): Same.
2023-04-26Remove legacy range support.Aldy Hernandez1-1/+1
This patch removes all the code paths guarded by legacy_mode_p(), thus allowing us to re-use the int_range<1> idiom for a range of one sub-range. This allows us to represent these simple ranges in a more efficient manner. gcc/ChangeLog: * range-op.cc (range_op_cast_tests): Remove legacy support. * value-range-storage.h (vrange_allocator::alloc_irange): Same. * value-range.cc (irange::operator=): Same. (get_legacy_range): Same. (irange::copy_legacy_to_multi_range): Delete. (irange::copy_to_legacy): Delete. (irange::irange_set_anti_range): Delete. (irange::set): Remove legacy support. (irange::verify_range): Same. (irange::legacy_lower_bound): Delete. (irange::legacy_upper_bound): Delete. (irange::legacy_equal_p): Delete. (irange::operator==): Remove legacy support. (irange::singleton_p): Same. (irange::value_inside_range): Same. (irange::contains_p): Same. (intersect_ranges): Delete. (irange::legacy_intersect): Delete. (union_ranges): Delete. (irange::legacy_union): Delete. (irange::legacy_verbose_union_): Delete. (irange::legacy_verbose_intersect): Delete. (irange::irange_union): Remove legacy support. (irange::irange_intersect): Same. (irange::intersect): Same. (irange::invert): Same. (ranges_from_anti_range): Delete. (gt_pch_nx): Adjust for legacy removal. (gt_ggc_mx): Same. (range_tests_legacy): Delete. (range_tests_misc): Adjust for legacy removal. (range_tests): Same. * value-range.h (class irange): Same. (irange::legacy_mode_p): Delete. (ranges_from_anti_range): Delete. (irange::nonzero_p): Adjust for legacy removal. (irange::lower_bound): Same. (irange::upper_bound): Same. (irange::union_): Same. (irange::intersect): Same. (irange::set_nonzero): Same. (irange::set_zero): Same. * vr-values.cc (simplify_using_ranges::legacy_fold_cond_overflow): Same.
2023-04-26Fix swapping of ranges.Aldy Hernandez1-4/+6
The legacy range code has logic to swap out of order endpoints in the irange constructor. The new irange code expects the caller to fix any inconsistencies, thus speeding up the common case. However, this means that when we remove legacy, any stragglers must be fixed. This patch fixes the 3 culprits found during the conversion. gcc/ChangeLog: * range-op.cc (operator_cast::op1_range): Use create_possibly_reversed_range. (operator_bitwise_and::simple_op1_range_solver): Same. * value-range.cc (swap_out_of_order_endpoints): Delete. (irange::set): Remove call to swap_out_of_order_endpoints.
2023-03-23ranger: Ranger meets aspellJakub Jelinek1-13/+13
I've noticed a comment typo in tree-vrp.cc and decided to quickly skim aspell -c on the ranger sources (with quick I on everything that looked ok or roughly ok). But not being a native English speaker, I could get stuff wrong. 2023-03-23 Jakub Jelinek <jakub@redhat.com> * value-range.cc (irange::irange_union, irange::intersect): Fix comment spelling bugs. * gimple-range-trace.cc (range_tracer::do_header): Likewise. * gimple-range-trace.h: Likewise. * gimple-range-edge.cc: Likewise. (gimple_outgoing_range_stmt_p, gimple_outgoing_range::switch_edge_range, gimple_outgoing_range::edge_range_p): Likewise. * gimple-range.cc (gimple_ranger::prefill_stmt_dependencies, gimple_ranger::fold_stmt, gimple_ranger::register_transitive_infer, assume_query::assume_query, assume_query::calculate_phi): Likewise. * gimple-range-edge.h: Likewise. * value-range.h (Value_Range::set, Value_Range::lower_bound, Value_Range::upper_bound, frange::set_undefined): Likewise. * gimple-range-gori.h (range_def_chain::depend, gori_map::m_outgoing, gori_compute): Likewise. * gimple-range-fold.h (fold_using_range): Likewise. * gimple-range-path.cc (path_range_query::compute_ranges_in_phis): Likewise. * gimple-range-gori.cc (range_def_chain::in_chain_p, range_def_chain::dump, gori_map::calculate_gori, gori_compute::compute_operand_range_switch, gori_compute::logical_combine, gori_compute::refine_using_relation, gori_compute::compute_operand1_range, gori_compute::may_recompute_p): Likewise. * gimple-range.h: Likewise. (enable_ranger): Likewise. * range-op.h (empty_range_varying): Likewise. * value-query.h (value_query): Likewise. * gimple-range-cache.cc (block_range_cache::set_bb_range, block_range_cache::dump, ssa_global_cache::clear_global_range, temporal_cache::temporal_value, temporal_cache::current_p, ranger_cache::range_of_def, ranger_cache::propagate_updated_value, ranger_cache::range_from_dom, ranger_cache::register_inferred_value): Likewise. * gimple-range-fold.cc (fur_edge::get_phi_operand, fur_stmt::get_operand, gimple_range_adjustment, fold_using_range::range_of_phi, fold_using_range::relation_fold_and_or): Likewise. * value-range-storage.h (irange_storage_slot::MAX_INTS): Likewise. * value-query.cc (range_query::value_of_expr, range_query::value_on_edge, range_query::query_relation): Likewise. * tree-vrp.cc (remove_unreachable::remove_and_update_globals, intersect_range_with_nonzero_bits): Likewise. * gimple-range-infer.cc (gimple_infer_range::check_assume_func, exit_range): Likewise. * value-relation.h: Likewise. (equiv_oracle, relation_trio::relation_trio, value_relation, value_relation::value_relation, pe_min): Likewise. * range-op-float.cc (range_operator_float::rv_fold, frange_arithmetic, foperator_unordered_equal::op1_range, foperator_div::rv_fold): Likewise. * gimple-range-op.cc (cfn_clz::fold_range): Likewise. * value-relation.cc (equiv_oracle::query_relation, equiv_oracle::register_equiv, equiv_oracle::add_equiv_to_block, value_relation::apply_transitive, relation_chain_head::find_relation, dom_oracle::query_relation, dom_oracle::find_relation_block, dom_oracle::find_relation_dom, path_oracle::register_equiv): Likewise. * range-op.cc (range_operator::wi_fold_in_parts_equiv, create_possibly_reversed_range, adjust_op1_for_overflow, operator_mult::wi_fold, operator_exact_divide::op1_range, operator_cast::lhs_op1_relation, operator_cast::fold_pair, operator_cast::fold_range, operator_abs::wi_fold, range_op_cast_tests, range_op_lshift_tests): Likewise.
2023-03-12ranger: Add range-ops for widen addition and widen multiplication [PR108583]Tamar Christina1-0/+131
This adds range-ops for widening addition and widening multiplication. I couldn't figure out how to write a test for this. It looks like there are self tests but not a way to write standalone ones? I did create testcases in the patch 3/4 which tests the end result. gcc/ChangeLog: PR target/108583 * gimple-range-op.h (gimple_range_op_handler): Add maybe_non_standard. * gimple-range-op.cc (gimple_range_op_handler::gimple_range_op_handler): Use it. (gimple_range_op_handler::maybe_non_standard): New. * range-op.cc (class operator_widen_plus_signed, operator_widen_plus_signed::wi_fold, class operator_widen_plus_unsigned, operator_widen_plus_unsigned::wi_fold, class operator_widen_mult_signed, operator_widen_mult_signed::wi_fold, class operator_widen_mult_unsigned, operator_widen_mult_unsigned::wi_fold, ptr_op_widen_mult_signed, ptr_op_widen_mult_unsigned, ptr_op_widen_plus_signed, ptr_op_widen_plus_unsigned): New. * range-op.h (ptr_op_widen_mult_signed, ptr_op_widen_mult_unsigned, ptr_op_widen_plus_signed, ptr_op_widen_plus_unsigned): New Co-Authored-By: Andrew MacLeod <amacleod@redhat.com>
2023-02-03range-op: Handle op?.undefined_p () in op[12]_range of comparisons [PR108647]Jakub Jelinek1-2/+28
As mentioned in the PR, we ICE because lhs is singleton [0, 0] or [1, 1] but op2 (or in other cases op1) is undefined and op?.*_bound () ICEs on those because there are no pairs for UNDEFINED. The following patch makes us set r to varying or return false in those cases. 2023-02-03 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/108647 * range-op.cc (operator_equal::op1_range, operator_not_equal::op1_range): Don't test op2 bound equality if op2.undefined_p (), instead set_varying. (operator_lt::op1_range, operator_le::op1_range, operator_gt::op1_range, operator_ge::op1_range): Return false if op2.undefined_p (). (operator_lt::op2_range, operator_le::op2_range, operator_gt::op2_range, operator_ge::op2_range): Return false if op1.undefined_p (). * g++.dg/torture/pr108647.C: New test.
2023-01-31Add op2_range to pointer_plus.Andrew MacLeod1-0/+23
Implement op2_range for pointer_plus to determine the offset (operand 2) is zero or non-zero based on equality/inequality between the LHS and op1. Also allow GORI computations to continue if the LHS is VARYING and there is also a relation. PR tree-optimization/108385 gcc/ * gimple-range-gori.cc (gori_compute::compute_operand_range): Allow VARYING computations to continue if there is a relation. * range-op.cc (pointer_plus_operator::op2_range): New. gcc/testsuite/ * gcc.dg/pr108385.c: New.
2023-01-31Utilize op1 == op2 when invoking range-ops folding.Andrew MacLeod1-0/+54
If there exists an equivalence relationship between op1 and op2, any binary operation can be broken into individual operations and unioned if there are sufficently few elements in the set. PR tree-optimization/108359 gcc/ * range-op.cc (range_operator::wi_fold_in_parts_equiv): New. (range_operator::fold_range): If op1 is equivalent to op2 then invoke new fold_in_parts_equiv to operate on sub-components. * range-op.h (wi_fold_in_parts_equiv): New prototype. gcc/testsuite/ * gcc.dg/pr108359.c: New.
2023-01-31Properly set GORI relation trios.Andrew MacLeod1-2/+2
When relation trios were added to GORI, there was only one use. As they are utilized more by range-ops, it is apparent that the implelemtation was not complete. This patch fleshes it out completely so that every GORI operation has a complete relation trio. * gimple-range-gori.cc (gori_compute::compute_operand_range): Do not abort calculations if there is a valid relation available. (gori_compute::refine_using_relation): Pass correct relation trio. (gori_compute::compute_operand1_range): Create trio and use it. (gori_compute::compute_operand2_range): Ditto. * range-op.cc (operator_plus::op1_range): Use correct trio member. (operator_minus::op1_range): Use correct trio member. * value-relation.cc (value_relation::create_trio): New. * value-relation.h (value_relation::create_trio): New prototype.