https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127405

--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Biener <[email protected]>:

https://gcc.gnu.org/g:9f6eb7d2993046e5720275f590098db0ac0188d4

commit r17-4392-g9f6eb7d2993046e5720275f590098db0ac0188d4
Author: Richard Biener <[email protected]>
Date:   Thu Sep 17 13:14:04 2026 +0200

    tree-optimization/127405 fix epilogue iteration bound when the control IV
wraps

    tree_transform_and_unroll_loop records an upper bound of FACTOR - 1
    latch iterations on the epilogue loop it creates.  That is justified by
    the main unrolled loop consuming all but less than FACTOR iterations,
    i.e. by ENTER_MAIN_COND being false implying that less than FACTOR
    iterations are left.

    determine_exit_conditions however builds ENTER_MAIN_COND by rewriting a
    NE_EXPR exit test into a LT_EXPR/GT_EXPR comparison of the control IV,
    which is only valid when that IV does not wrap.  For

      void test (unsigned long n, int *a, int *b)
      {
        for (unsigned long i = n - 2; i + 2 != 0; --i)
          a[i+2] = b[i+2] - a[i+3] - a[i+5] + (int)(i + 2);
      }

    the control IV runs from n - 3 downwards to (unsigned long) -2, so with
    FACTOR 3 the guard that BOUND - DELTA does not overflow is constant
    false and ENTER_MAIN_COND folds to false.  Predictive commoning then
    unrolls, the main loop is removed as unreachable and the epilogue - which
    performs all n iterations - is left claiming an upper bound of 2.  Loop
    peeling subsequently peeled three iterations and dropped the loop, so at
    -O3 the testcase was miscompiled.

    Only set the epilogue bound (and scale its profile accordingly) when the
    exit test is not a NE_EXPR one or the control IV is known not to wrap.
    In the remaining case the epilogue keeps the bound inherited from the
    original loop, which is correct whether or not the main loop is entered.

            PR tree-optimization/127405
            * tree-ssa-loop-manip.cc (tree_transform_and_unroll_loop): Only
            set nb_iterations_upper_bound of the epilogue loop and scale its
            profile when the control IV is known not to wrap.

            * gcc.dg/tree-ssa/predcom-10.c: New test.

Reply via email to