https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108757
Jiu Fu Guo <guojiufu at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |guojiufu at gcc dot gnu.org --- Comment #20 from Jiu Fu Guo <guojiufu at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #19) > Note in the loop case we know it does not wrap because there is a check > already: > <bb 2> [local count: 118111600]: > if (rows_8(D) > 3) > goto <bb 5>; [89.00%] > else > goto <bb 4>; [11.00%] > > <bb 5> [local count: 105119324]: > _13 = rows_8(D) + 18446744073709551612; > _15 = _13 / 4; > doloop.6_5 = _15 + 1; Checking why below code does not work: /* Simplify ((t + -N*M) / N + M) -> t / N: (t + -C) >> N + (C>>N) ==> t >> N */ (for div (trunc_div round_div) (simplify (plus (rshift (plus @0 INTEGER_CST@1) INTEGER_CST@2) INTEGER_CST@3) (if (ANY_INTEGRAL_TYPE_P (type) && (wi::to_wide (@3) << wi::to_wide (@2)) == -wi::to_wide (@1)) (if (TYPE_OVERFLOW_UNDEFINED (type)) (div @0 @2) #if GIMPLE (with { bool overflowed = true; value_range vr0; if (INTEGRAL_TYPE_P (type) && get_global_range_query ()->range_of_expr (vr0, @0) && !vr0.varying_p () && !vr0.undefined_p ()) { wide_int wmin0 = vr0.lower_bound (); wide_int wmax0 = vr0.upper_bound (); wide_int w1 = -wi::to_wide (@1); wi::overflow_type min_ovf, max_ovf; wi::add (wmin0, w1, TYPE_SIGN (type), &min_ovf); wi::add (wmax0, w1, TYPE_SIGN (type), &max_ovf); if (min_ovf == wi::OVF_NONE && max_ovf == wi::OVF_NONE) overflowed = false; } } (if (!overflowed) (div @0 @2))) #endif )))) Interesting thing: the VR is always VR_VARYING, even for the below simple case: typedef unsigned long INT; INT __attribute__ ((noinline)) foo (INT x) { if (x < 4) return 0; INT a = x + 18446744073709551612ULL; INT b = a >> 2; return b + 1; }