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
>

Reply via email to