Simplify more EXACT_DIV_EXPR comparisons

Richard Biener richard.guenther@gmail.com
Mon May 20 08:04:00 GMT 2019


On Sun, May 19, 2019 at 6:16 PM Marc Glisse <marc.glisse@inria.fr> wrote:
>
> Hello,
>
> 2 pieces:
>
> - the first one handles the case where the denominator is negative. It
> doesn't happen often with exact_div, so I don't handle it everywhere, but
> this one looked trivial
>
> - handle the case where a pointer difference is cast to an unsigned type
> before being compared to a constant (I hit this in std::vector). With some
> range info we could probably handle some non-constant cases as well...
>
> The second piece breaks Walloca-13.c (-Walloca-larger-than=100 -O2)
>
> void f (void*);
> void g (int *p, int *q)
> {
>    __SIZE_TYPE__ n = (__SIZE_TYPE__)(p - q);
>    if (n < 100)
>      f (__builtin_alloca (n));
> }
>
> At the time of walloca2, we have
>
>    _1 = p_5(D) - q_6(D);
>    # RANGE [-2305843009213693952, 2305843009213693951]
>    _2 = _1 /[ex] 4;
>    # RANGE ~[2305843009213693952, 16140901064495857663]
>    n_7 = (long unsigned intD.10) _2;
>    _11 = (long unsigned intD.10) _1;
>    if (_11 <= 396)
> [...]
>    _3 = allocaD.1059 (n_7);
>
> and warn.

That's indeed to complicated relation of _11 to n_7 for
VRP predicate discovery.

> However, DOM3 later produces
>
>    _1 = p_5(D) - q_6(D);
>    _11 = (long unsigned intD.10) _1;
>    if (_11 <= 396)

while _11 vs. _1 works fine.

> [...]
>    # RANGE [0, 99] NONZERO 127
>    _2 = _1 /[ex] 4;
>    # RANGE [0, 99] NONZERO 127
>    n_7 = (long unsigned intD.10) _2;
>    _3 = allocaD.1059 (n_7);
>
> so I am tempted to say that the walloca2 pass is too early, xfail the
> testcase and file an issue...

Hmm, there's a DOM pass before walloca2 already and moving
walloca2 after loop opts doesn't look like the best thing to do?
I suppose it's not DOM but sinking that does the important transform
here?  That is,

Index: gcc/passes.def
===================================================================
--- gcc/passes.def      (revision 271395)
+++ gcc/passes.def      (working copy)
@@ -241,9 +241,9 @@ along with GCC; see the file COPYING3.
       NEXT_PASS (pass_optimize_bswap);
       NEXT_PASS (pass_laddress);
       NEXT_PASS (pass_lim);
-      NEXT_PASS (pass_walloca, false);
       NEXT_PASS (pass_pre);
       NEXT_PASS (pass_sink_code);
+      NEXT_PASS (pass_walloca, false);
       NEXT_PASS (pass_sancov);
       NEXT_PASS (pass_asan);
       NEXT_PASS (pass_tsan);

fixes it?

> A single_use restriction would also probably fix this testcase, but I
> don't think that's a good idea, the new code is better because the
> division is now in the branch.

OK.

Can you test the pass motion above?

Thanks,
Richard.

> 2019-05-20  Marc Glisse  <marc.glisse@inria.fr>
>
> gcc/
>         * match.pd (X/[ex]D<Y/[ex]D): Handle negative denominator.
>         ((size_t)(A /[ex] B) CMP C): New transformation.
>
> gcc/testsuite/
>         * gcc.dg/tree-ssa/cmpexactdiv-3.c: New file.
>         * gcc.dg/tree-ssa/cmpexactdiv-4.c: New file.
>
> --
> Marc Glisse



More information about the Gcc-patches mailing list