https://gcc.gnu.org/g:6f375445ef09d5c97d5bcc0fcb6069612217963e
commit r16-571-g6f375445ef09d5c97d5bcc0fcb6069612217963e Author: Andrew MacLeod <amacl...@redhat.com> Date: Mon May 12 11:41:37 2025 -0400 Add dispatch for casts between integer and float. GCC currently does not implement range operators for casting between integers and float. This patch adds the missing dispatch patterns and routines to facilitate implmenting these casts. PR tree-optimization/120231 * range-op-float.cc (operator_cast::fold_range): New variants. (operator_cast::op1_range): Likewise. * range-op-mixed.h (operator_cast::fold_range): Likewise. (operator_cast::op1_range): Likewise * range-op.cc (range_op_handler::fold_range): Add RO_FIF dispatch. (range_op_handler::op1_range): Add RO_IFF and RO_FII patterns. (range_operator::fold_range): Provide new variant default. (range_operator::op1_range): Likewise. * range-op.h (range_operator): Add new variant methods. Diff: --- gcc/range-op-float.cc | 31 +++++++++++++++++++++++++++++++ gcc/range-op-mixed.h | 18 ++++++++++++++++++ gcc/range-op.cc | 38 ++++++++++++++++++++++++++++++++++++++ gcc/range-op.h | 13 ++++++++++++- 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 4719829974de..dafd9c0688c0 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -2899,6 +2899,37 @@ private: } } fop_div; +// Implement fold for a cast from float to an int. +bool +operator_cast::fold_range (irange &, tree, const frange &, + const irange &, relation_trio) const +{ + return false; +} + +// Implement op1_range for a cast from float to an int. +bool +operator_cast::op1_range (frange &, tree, const irange &, + const irange &, relation_trio) const +{ + return false; +} + +// Implement fold for a cast from int to a float. +bool +operator_cast::fold_range (frange &, tree, const irange &, + const frange &, relation_trio) const +{ + return false; +} + +// Implement op1_range for a cast from int to a float. +bool +operator_cast::op1_range (irange &, tree, const frange &, + const frange &, relation_trio) const +{ + return false; +} // Initialize any float operators to the primary table diff --git a/gcc/range-op-mixed.h b/gcc/range-op-mixed.h index bb8e90aeddd6..3fb7bff90bdb 100644 --- a/gcc/range-op-mixed.h +++ b/gcc/range-op-mixed.h @@ -473,6 +473,15 @@ public: bool fold_range (prange &r, tree type, const irange &op1, const prange &op2, relation_trio rel = TRIO_VARYING) const final override; + bool fold_range (irange &r, tree type, + const frange &lh, + const irange &rh, + relation_trio = TRIO_VARYING) const; + bool fold_range (frange &r, tree type, + const irange &lh, + const frange &rh, + relation_trio = TRIO_VARYING) const; + bool op1_range (irange &r, tree type, const irange &lhs, const irange &op2, relation_trio rel = TRIO_VARYING) const final override; @@ -485,6 +494,15 @@ public: bool op1_range (prange &r, tree type, const irange &lhs, const prange &op2, relation_trio rel = TRIO_VARYING) const final override; + bool op1_range (frange &r, tree type, + const irange &lhs, + const irange &op2, + relation_trio = TRIO_VARYING) const; + bool op1_range (irange &r, tree type, + const frange &lhs, + const frange &op2, + relation_trio = TRIO_VARYING) const; + relation_kind lhs_op1_relation (const irange &lhs, const irange &op1, const irange &op2, relation_kind) const final override; diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 35b3e18ebed2..06d357f5199f 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -164,6 +164,8 @@ dispatch_trio (unsigned lhs, unsigned op1, unsigned op2) // These are the supported dispatch patterns. These map to the parameter list // of the routines in range_operator. Note the last 3 characters are // shorthand for the LHS, OP1, and OP2 range discriminator class. +// Reminder, single operand instructions use the LHS type for op2, even if +// unused. so FLOAT = INT would be RO_FIF. const unsigned RO_III = dispatch_trio (VR_IRANGE, VR_IRANGE, VR_IRANGE); const unsigned RO_IFI = dispatch_trio (VR_IRANGE, VR_FRANGE, VR_IRANGE); @@ -246,6 +248,10 @@ range_op_handler::fold_range (vrange &r, tree type, return m_operator->fold_range (as_a <frange> (r), type, as_a <irange> (lh), as_a <irange> (rh), rel); + case RO_FIF: + return m_operator->fold_range (as_a <frange> (r), type, + as_a <irange> (lh), + as_a <frange> (rh), rel); case RO_PPP: return m_operator->fold_range (as_a <prange> (r), type, as_a <prange> (lh), @@ -292,6 +298,10 @@ range_op_handler::op1_range (vrange &r, tree type, return m_operator->op1_range (as_a <irange> (r), type, as_a <irange> (lhs), as_a <irange> (op2), rel); + case RO_IFF: + return m_operator->op1_range (as_a <irange> (r), type, + as_a <frange> (lhs), + as_a <frange> (op2), rel); case RO_PPP: return m_operator->op1_range (as_a <prange> (r), type, as_a <prange> (lhs), @@ -312,6 +322,10 @@ range_op_handler::op1_range (vrange &r, tree type, return m_operator->op1_range (as_a <frange> (r), type, as_a <irange> (lhs), as_a <frange> (op2), rel); + case RO_FII: + return m_operator->op1_range (as_a <frange> (r), type, + as_a <irange> (lhs), + as_a <irange> (op2), rel); case RO_FFF: return m_operator->op1_range (as_a <frange> (r), type, as_a <frange> (lhs), @@ -761,6 +775,30 @@ range_operator::fold_range (irange &r, tree type, return true; } + +bool +range_operator::fold_range (frange &, tree, const irange &, + const frange &, relation_trio) const +{ + return false; +} + +bool +range_operator::op1_range (irange &, tree, const frange &, + const frange &, relation_trio) const +{ + return false; +} + +bool +range_operator::op1_range (frange &, tree, const irange &, + const irange &, relation_trio) const +{ + return false; +} + + + // The default for op1_range is to return false. bool diff --git a/gcc/range-op.h b/gcc/range-op.h index 594e6782dc38..107578613783 100644 --- a/gcc/range-op.h +++ b/gcc/range-op.h @@ -86,6 +86,10 @@ public: const irange &lh, const irange &rh, relation_trio = TRIO_VARYING) const; + virtual bool fold_range (frange &r, tree type, + const irange &lh, + const frange &rh, + relation_trio = TRIO_VARYING) const; virtual bool fold_range (prange &r, tree type, const prange &lh, const prange &rh, @@ -146,7 +150,14 @@ public: const irange &lhs, const frange &op2, relation_trio = TRIO_VARYING) const; - + virtual bool op1_range (irange &r, tree type, + const frange &lhs, + const frange &op2, + relation_trio = TRIO_VARYING) const; + virtual bool op1_range (frange &r, tree type, + const irange &lhs, + const irange &op2, + relation_trio = TRIO_VARYING) const; virtual bool op2_range (irange &r, tree type, const irange &lhs,