On Tue, Sep 1, 2026 at 2:51 PM Andrea Pinski <[email protected]> wrote: > > This was an oversight of not knowing there are a few different > integer divisions and how they will round. > When `a < b` and for non-negative a and b, `a/b` will be 0 iff for > truncate (TRUNC_DIV_EXPR), exact (EXACT_DIV_EXPR) > and floor division (FLOOR_DIV_EXPR). > Ceiling division (CEIL_DIV_EXPR) will be 1 for positive a and zero when a is > 0. > Rounding division (ROUND_DIV_EXPR) it is based on the how far a is from b. > We can skip the ceiling division case since it is not used that much. > And rounding division case is too hard to figure out here so that is skipped > also. > > Bootstrapped and tested on x86_64-linux-gnu.
OK. > PR tree-optimization/127092 > > gcc/ChangeLog: > > * range-op.cc (operator_div::op1_op2_relation_effect): Only > handle TRUNC_DIV_EXPR, EXACT_DIV_EXPR and FLOOR_DIV_EXPR > for the `a < b` case. > > gcc/testsuite/ChangeLog: > > * gfortran.dg/pr127092-1.f90: New test. > > Signed-off-by: Andrea Pinski <[email protected]> > --- > gcc/range-op.cc | 9 ++++++++- > gcc/testsuite/gfortran.dg/pr127092-1.f90 | 21 +++++++++++++++++++++ > 2 files changed, 29 insertions(+), 1 deletion(-) > create mode 100644 gcc/testsuite/gfortran.dg/pr127092-1.f90 > > diff --git a/gcc/range-op.cc b/gcc/range-op.cc > index 76c52bf897e..350548951f4 100644 > --- a/gcc/range-op.cc > +++ b/gcc/range-op.cc > @@ -2647,8 +2647,15 @@ operator_div::op1_op2_relation_effect (irange > &lhs_range, > /* op1/op2 = 0 if op1 < op2 and both op1 and op2 > are known positives. */ > case VREL_LT: > + // Exact, and truncate division will produce 0 for this case. > + // Floor division will be treated similar to truncate div as rounding > towards > + // to 0 is the same as rounding towards -inf for positive values. > + if (m_code != EXACT_DIV_EXPR > + && m_code != TRUNC_DIV_EXPR > + && m_code != FLOOR_DIV_EXPR) > + return false; > if (!op1_range.nonnegative_p () > - || !op2_range.nonnegative_p ()) > + || !op2_range.nonnegative_p ()) > return false; > rel_range.set_zero (type); > break; > diff --git a/gcc/testsuite/gfortran.dg/pr127092-1.f90 > b/gcc/testsuite/gfortran.dg/pr127092-1.f90 > new file mode 100644 > index 00000000000..0602e88c512 > --- /dev/null > +++ b/gcc/testsuite/gfortran.dg/pr127092-1.f90 > @@ -0,0 +1,21 @@ > +! PR tree-optimization/127092 > +! { dg-do run } > + > + > +program main > + implicit none > + if (transfer_count(3, 8) /= 1) error stop 1 > +contains > + integer function transfer_count(n, m) > + integer, intent(in) :: n, m > + character(len=n) :: source > + character(len=m) :: mold(1) > + if (len(source, kind=8) >= len(mold, kind=8)) then > + transfer_count = -1 > + return > + end if > + source = "" > + mold = "" > + transfer_count = size(transfer(source, mold)) > + end function > +end program > -- > 2.43.0 >
