https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102131
--- Comment #6 from Jiu Fu Guo <guojiufu at gcc dot gnu.org> --- Drafted a patch as below. With this patch, those cases can pass. diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 7af92d1c893..a400c42919b 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -1866,6 +1866,24 @@ number_of_iterations_cond (class loop *loop, || !iv0->no_overflow || !iv1->no_overflow)) return false; + /* GT/GE has been transformed to LT/LE already. + cmp_code could be LT, LE or NE + + For LE/LT transform + {iv0.base, iv0.step} LT/LE {iv1.base, iv1.step} + to + {iv0.base, iv0.step - iv1.step} LT/LE {iv1.base, 0} + Negative iv0.step - iv1.step means decreasing until wrap, + then the transform is not accurate. + + For example: + {1, +, 1} <= {4, +, 3} + is not same with + {1, +, -2} <= {4, +, 0} + */ + if ((code == LE_EXPR || code == LT_EXPR) && tree_int_cst_sign_bit (step)) + return false; + iv0->step = step; if (!POINTER_TYPE_P (type)) iv0->no_overflow = false;