https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117574
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- And we compute the "noloop" condition as noloop = fold_build2 (GT_EXPR, boolean_type_node, iv0->base, fold_build2 (PLUS_EXPR, type1, iv1->base, tmod)); where tmod is 47 (that's STEP - DELTA %[fl] STEP in the IVs type - mind, DELTA is unsigned!). So the noloop condition is (long int) ((int) d.3_5 + 40) + 1 >= (long int) ((int) d.3_5 + 76) which is wrong, it should compute true. What's fishy here is the negative DELTA (so there is IV overflow in that compute) and then the use of unsigned FLOOR_MOD to compute the adjustment for the final value and the noloop condition (I'm not sure why that needs the mod adjustment at all?!). I'm going to test the naiive diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index 9518bf969cd..1be4b552206 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -1200,17 +1200,6 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1, if (integer_zerop (assumption)) return false; } - if (mpz_cmp (mmod, bnds->below) < 0) - noloop = boolean_false_node; - else if (POINTER_TYPE_P (type)) - noloop = fold_build2 (GT_EXPR, boolean_type_node, - iv0->base, - fold_build_pointer_plus (iv1->base, tmod)); - else - noloop = fold_build2 (GT_EXPR, boolean_type_node, - iv0->base, - fold_build2 (PLUS_EXPR, type1, - iv1->base, tmod)); } else { @@ -1226,21 +1215,15 @@ number_of_iterations_lt_to_ne (tree type, affine_iv *iv0, affine_iv *iv1, if (integer_zerop (assumption)) return false; } - if (mpz_cmp (mmod, bnds->below) < 0) - noloop = boolean_false_node; - else if (POINTER_TYPE_P (type)) - noloop = fold_build2 (GT_EXPR, boolean_type_node, - fold_build_pointer_plus (iv0->base, - fold_build1 (NEGATE_EXPR, - type1, tmod)), - iv1->base); - else - noloop = fold_build2 (GT_EXPR, boolean_type_node, - fold_build2 (MINUS_EXPR, type1, - iv0->base, tmod), - iv1->base); } + /* IV0 < IV1 does not loop if IV0->base >= IV1->base. */ + if (mpz_cmp (mmod, bnds->below) < 0) + noloop = boolean_false_node; + else + noloop = fold_build2 (GE_EXPR, boolean_type_node, + iv0->base, iv1->base); + if (!integer_nonzerop (assumption)) niter->assumptions = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, niter->assumptions,