Simplify more EXACT_DIV_EXPR comparisons

Martin Sebor msebor@gmail.com
Tue May 21 02:13:00 GMT 2019


On 5/20/19 3:16 AM, Richard Biener wrote:
> On Mon, May 20, 2019 at 10:16 AM Marc Glisse <marc.glisse@inria.fr> wrote:
>>
>> On Mon, 20 May 2019, Richard Biener wrote:
>>
>>> 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?
>>
>> I will check, but I don't think walloca uses any kind of on-demand VRP, so
>> we still need some pass to update the ranges after sinking, which doesn't
>> seem to happen until the next DOM pass.
> 
> Oh, ok...  Aldy, why's this a separate pass anyways?  I think similar
> other warnigns are emitted from RTL expansion?  So maybe we can
> indeed move the pass towards warn_restrict or late_warn_uninit.

I thought there was a preference to add new middle-end warnings
into passes of their own rather than into existing passes.  Is
that not so (either in general or in this specific case)?

 From my POV, the main (only?) benefit of putting warnings in their
own passes is modularity.  Are there any others?

The biggest drawback I see is that it makes it hard to then share
data across multiple passes.  The sharing can help not just
warnings (reduce both false positive and false negative rates) but
also optimization.  That's why I'm merging the strlen and sprintf
passes, and want to eventually also look into merging
the -Wstringop-overflow warnings there (also emitted just before
RTL expansion.  Did I miss any downsides?

I don't know if there's the -Walloca pass would benefit from merging
with any of the others or vice versa, but superficially it seems like
it might be worth thinking about integrating the -Walloc-larger-than
warnings into the -Walloca pass, if only to keep similar functionality
in the same place.

> I also see that the Og pass pipeline misses the second walloca pass
> completely (and also the warn_restrict pass).

That's worth fixing.

Martin

> 
> Given code sinkings obvious effects on SSA value-range representation
> it may make sense to add another instance of that pass earlier.
> 
> 
> 
>>
>> --
>> Marc Glisse



More information about the Gcc-patches mailing list