https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102546

--- Comment #8 from Andrew Macleod <amacleod at redhat dot com> ---
On 10/1/21 5:18 AM, aldyh at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102546
>
> Aldy Hernandez <aldyh at gcc dot gnu.org> changed:
>
>             What    |Removed                     |Added
> ----------------------------------------------------------------------------
>     Last reconfirmed|                            |2021-10-01
>               Status|UNCONFIRMED                 |NEW
>       Ever confirmed|0                           |1
>             Assignee|unassigned at gcc dot gnu.org      |aldyh at gcc dot 
> gnu.org
>
> --- Comment #5 from Aldy Hernandez <aldyh at gcc dot gnu.org> ---
> (In reply to Richard Biener from comment #4)
>> (In reply to Aldy Hernandez from comment #2)
>>> By VRP1 we seem to be calculating the following:
>>>
>>> (f_8 << f_8) && (f_8 == 0)
>>>
>>> This would fold to false, which would elide the foo():
>>>
>>>   <bb 7> [local count: 59055800]:
>>>    b = 0;
>>>    _3 = f_8 << f_8;
>>>    _4 = (char) _3;
>>>    _5 = (int) _4;
>>>    if (_4 > 0)
>>>      goto <bb 8>; [64.06%]
>>>    else
>>>      goto <bb 10>; [35.94%]
>>>
>>>    <bb 8> [local count: 34842922]:
>>>    if (f_8 == 0)
>>>      goto <bb 9>; [71.10%]
>>>    else
>>>      goto <bb 10>; [28.90%]
>>>
>>>    <bb 9> [local count: 12809203]:
>>>    foo ();
>> I think it's similar to in the other PR, with old EVRP when visiting BB 8
>> we pushed [1, +INF] as the global range for _4, then supposedly ranger
>> manages to evaluate f_8 == 0 with its backward infering somehow.
>>
>> We no longer do this "path sensitive" adjustment of (global) ranges since
>> you removed the EVRP DOM walk algorithm.
> The hybrid threader does path sensitive ranges and relationals.  What's 
> missing
> is the range-op entry for the following relation:
>
>    ~[0,0] = x << x
>
> In this case, we know that X cannot be 0.  Fixing this, causes all the right
> things to happen.
>
> However, I see that the none of the op1_range entries are being called with a
> relation.  Presumably this was an oversight on Andrew's part, but can easily 
> be
> fixed.

Not an oversight.  I believe I added the infrastructure to pass 
relations to GORI when I introduce relations to range-ops for folding, 
but there has not been time to flush out actually utilizing them yet.

I can maybe take a look at that next week. maybe.  It also opens up some 
possibilities for solving unsigned overflow questions:

c_1 = a_2 + 2
if (c_1 < a_2)  // check overflow condition

On the true edge, solving [1,1] = c_1 < a_2...  would propagate c_1 < 
a_2 to the defining insn as:
[varying] = a_2 + 2, (LHS < a_2).
op1_range for PLUS can use that relation to determine that a_2 must be 
fully contained in  [INF - 1, INF] on the TRUE side, and therefore c_1  
is [0,1].
The false side would then also calculate a_2 =  [0, INF - 2] and c_1 as 
[2, INF]


> Interestingly on this case, the VRP threader shouldn't even need to step up
> here.  VRP1 should have folded the conditional in BB8.  The new evrp can
> though.  If I tweak range-ops, and call execute_early_vrp() from VRP1, evrp
> folds the conditional and there's no need to thread.
>
> Now before Andrew asks why evrp doesn't clean this up earlier (with the
> range-ops tweak), it's because the IL is different.  See my question about the
> "a" present in earlier passes. ;-)
>
> So...mine.  I'll address all the issues pointed out.
>

Reply via email to