On December 13, 2017 5:18:16 PM GMT+01:00, Jeff Law <l...@redhat.com> wrote:
>On 12/13/2017 09:02 AM, David Malcolm wrote:
>> On Wed, 2017-12-13 at 08:46 -0700, Jeff Law wrote:
>>> On 12/13/2017 03:06 AM, Richard Biener wrote:
>>>> On December 12, 2017 9:50:38 PM GMT+01:00, David Malcolm <dmalcolm@
>>>> redhat.com> wrote:
>>>>> PR tree-optimization/83312 reports a false positive from
>>>>> -Warray-bounds.
>>>>> The root cause is that VRP both:
>>>>>
>>>>> (a) updates a GIMPLE_COND to be always false, and
>>>>>
>>>>> (b) updates an ARRAY_REF in the now-unreachable other path to use
>>>>> an
>>>>>    ASSERT_EXPR with a negative index:
>>>>>      def_stmt j_6 = ASSERT_EXPR <j_9, j_9 < 0>;
>>>>>
>>>>> When vrp_prop::check_all_array_refs () runs, the CFG hasn't yet
>>>>> been
>>>>> updated to take account of (a), and so a false positive is
>>>>> emitted
>>>>> when (b) is encountered.
>>>>>
>>>>> This patch fixes the false warning by converting
>>>>>  vrp_prop::check_all_array_refs
>>>>> from a simple iteration over all BBs to use a new dom_walker
>>>>> subclass,
>>>>> using the "skip_unreachable_blocks = true" mechanism to avoid
>>>>> analyzing
>>>>> (b).
>>>>>
>>>>> There didn't seem to be a pre-existing way to determine the
>>>>> unique
>>>>> out-edge after a GIMPLE_COND (if it has a constant cond), so I
>>>>> added
>>>>> a new gimple_cond_get_unique_successor_edge function.  Similarly,
>>>>> something similar may apply for switches, so I put in a
>>>>> gimple_get_unique_successor_edge (though I wasn't able to create
>>>>> a
>>>>> reproducer that used a switch).
>>>>>
>>>>> Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.
>>>>>
>>>>> OK for trunk?
>>>>
>>>> I don't like the GIMPLE.c bits a lot. Can't you use the existing
>>>> known taken edge helper (too lazy to look up from my phone...)
>>>> basically splitting out some code from cond processing in evrp for
>>>> example? 
>>>
>>> I'm not sure those bits are needed at all. I think the right things
>>> will
>>> happen if we clear EDGE_EXECUTABLE on the appropriate edge in
>>> vrp_folder::fold_predicate_in.
>>>
>>> That should cause the block in question to become unreachable (zero
>>> preds).  So later when we do the domwal dom_walker::walk will see
>the
>>> block as unreachable -- which avoids walking into it and also
>>> triggers
>>> the call to propagate_unreachable_to_edges which marks the outgoing
>>> edges as not executable.
>> 
>> AIUI, dom_walker::bb_reachable only honors the EDGE_EXECUTABLE flags
>if
>> m_skip_unreachable_blocks is set on the dom_walker.
>> 
>> However, dom_walker's ctor clears all of the EDGE_EXECUTABLE if that
>> bool is set.
>Ugh.  How unfortunate, though I understand why it would be written that
>way.
>
>> 
>> So, as written any edge flags that are touched in
>> vrp_folder::fold_predicate_in will get reset when the dom walker is
>> created.
>> 
>> So should the dom walker get created before the vrp_folder runs?
>That would probably work, but something doesn't feel right about it.
>
>Alternately we could to the dom_walker ctor that an initial state of
>EDGE_EXECUTABLE is already set.

I'm quite sure that wouldn't help for VRP. 
I think David's approach is fine just we don't need any other API to get at a 
known executable outgoing edge. We can improve the existing one or just add the 
trivial folding required. 

Richard. 

>Jeff

Reply via email to