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

--- Comment #3 from Andrew Macleod <amacleod at redhat dot com> ---
On 3/31/23 03:17, rguenth at gcc dot gnu.org wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109350
>
> Richard Biener <rguenth at gcc dot gnu.org> changed:
>
>             What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                   CC|                            |amacleod at redhat dot com
>
> --- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
> Hmm, the same reproduces with r_imin_imax as ptrdiff_t but the IL is a bit
> more obvious:
>
> <bb 2> [local count: 1073741824]:
> _27 ={v} signed_value_source;
> _4 = (unsigned long) _27;
> _8 = _4 + 2147483648;
> if (_8 > 4294967295)
>    goto <bb 8>; [50.00%]
> else
>    goto <bb 3>; [50.00%]
>
> <bb 3> [local count: 536870913]:
> _30 = _27 + 1;
> _28 = (sizetype) _30;
> if (_4 <= 4611686018427387900)
>    goto <bb 4>; [50.00%]
> else
>    goto <bb 5>; [50.00%]
>
> <bb 5> [local count: 268435458]:
> _12 = operator new [] (18446744073709551615);
> __builtin_memcpy (_12, &MEM <const char[37]> [(void
> *)"0123456789abcdefghijklmnopqrstuvwxyz" + 35B], 2);
> sink (_12);
> if (_28 <= 4611686018427387900)
>    goto <bb 9>; [100.00%]
> else
>    goto <bb 7>; [0.00%]
>
> <bb 9> [local count: 0]:
> iftmp.2_37 = _28 * 2;
> _39 = operator new [] (iftmp.2_37);
> __builtin_memcpy (_39, &MEM <const char[37]> [(void
> *)"0123456789abcdefghijklmnopqrstuvwxyz" + 34B], 3);
>
> so we have (unsigned long)[int_min, int_max] > 4611686018427387900
> && (unsigned long)[int_min+1, int_max+1] <= 4611686018427387900 to
> constrain _4.  I don't see how we can arrive at [0,0] for iftmp.2_37.


Looking at what ranger produces for vrp2 (same code just a few passes 
later):

=========== BB 2 ============
Imports: _28
Exports: _4  _10  _28
          _4 : _28(I)
          _10 : _4  _28(I)
Partial equiv (_4 pe64 _28)
Relational : (_10 != _4)
     <bb 2> [local count: 1073741824]:
     _28 ={v} signed_value_source;
     _4 = (unsigned long) _28;
     _10 = _4 + 2147483648;
     if (_10 > 4294967295)
       goto <bb 8>; [50.00%]
     else
       goto <bb 3>; [50.00%]

2->3  (F) _4 :  [irange] unsigned long [0, 
2147483647][18446744071562067968, +INF]
2->3  (F) _10 :         [irange] unsigned long [0, 4294967295] NONZERO 
0xffffffff
2->3  (F) _28 :         [irange] long int [-2147483648, 2147483647]

on entry top BB3 , _28 has the full range of a signed int in a long int 
body.


=========== BB 3 ============

_4      [irange] unsigned long [0, 2147483647][18446744071562067968, +INF]
_28     [irange] long int [-2147483648, 2147483647]
Partial equiv (r_imin_imax_8 pe32 _28)
Relational : (_31 > r_imin_imax_8)
     <bb 3> [local count: 536870913]:
     r_imin_imax_8 = (int) _28;                           << THIs is 
varying, which is why it isnt printed anywhere
     _31 = r_imin_imax_8 + 1;      <<   signed traps on overflowt,  so 
this would be [min+1, +INF]
     _29 = (sizetype) _31;          <<  sizetype is a larger unsigned 
object,so the possible values for it are [0, 
2147483647][18446744071562067969, +INF]
     if (_4 <= 4611686018427387900)       << this leaves _4 with 
possible values of [18446744071562067968, +INF] on the FALSE branch.
       goto <bb 4>; [50.00%]
     else
       goto <bb 5>; [50.00%]


_29 : [irange] sizetype [0, 2147483647][18446744071562067969, +INF]
_31 : [irange] int [-2147483647, +INF]

When we recalculate values based on the range of _4 on the false 
branch,  intersected with their knowns ranges, it comes up with this


3->5  (F) _4 :  [irange] unsigned long [18446744071562067968, +INF]
3->5  (F) r_imin_imax_8 :       [irange] int [-INF, -1]
3->5  (F) _28 :         [irange] long int [-2147483648, -1]
3->5  (F) _29 :         [irange] sizetype [0, 0][18446744071562067969, +INF]
3->5  (F) _31 :         [irange] int [-2147483647, 0]

when we feed that value of _4 into

[18446744071562067968, +INF] = (unsigned long)28

in BB2, we discover the only possible valiues of _28 are [-2147483648, 
-1] on this branch.
We now go an recalculate r_imin_imax_8, _31 and _29 based on this new 
value of _28 and come up with those ranges

that means when we get to bb5, and see
     if (_29 <= 4611686018427387900)
       goto <bb 9>; [100.00%]

the only possible value of _29 on this branch is a [0,0]   And thats a 
direct result of _31 = [-INF, -1] + 1  before _20 is created with the cast.

yikes.  talk about convoluted...


>
> In fact if I put this into a separate testcase like
>
> void __attribute__((noipa))
> foo (long signed_value_source)
> {
>    unsigned long temu = signed_value_source;
>    if (temu + 2147483648 > 4294967295)
>      ;
>    else
>      {
>       long tems = signed_value_source + 1;
>       unsigned long temu2 = tems;
>       if (temu > 4611686018427387900)
>         if (temu2 <= 4611686018427387900)
>           {
>             unsigned long iftmp = temu2 * 2;
>             if (iftmp == 0)
>               __builtin_abort ();
>           }
>      }
> }
>
> then we optimize this to
>
>    <bb 2> [local count: 1073741824]:
>    temu_3 = (long unsigned int) signed_value_source_2(D);
>    _1 = temu_3 + 2147483648;
>    if (_1 > 4294967295)
>      goto <bb 5>; [50.00%]
>    else
>      goto <bb 3>; [50.00%]
>
>    <bb 3> [local count: 536870913]:
>    if (signed_value_source_2(D) == -1)
>      goto <bb 4>; [0.00%]
>    else
>      goto <bb 5>; [100.00%]
>
>    <bb 4> [count: 0]:
>    __builtin_abort ();
>
> and the outer if doesn't change the inner range result.
>
I bet if we used temu_3 at the abort point it would.  I changed it to 
bar (temu) from the abort:

            if (iftmp == 0)
              bar (temu);

 From EVRP:

   temu_5 = (long unsigned int) signed_value_source_4(D);
   _1 = temu_5 + 2147483648;
   if (_1 > 4294967295)
     goto <bb 6>; [INV]
   else
     goto <bb 3>; [INV]

   <bb 3> :
   tems_7 = signed_value_source_4(D) + 1;
   temu2_8 = (long unsigned int) tems_7;
   if (temu_5 > 4611686018427387900)
     goto <bb 4>; [INV]
   else
     goto <bb 6>; [INV]

   <bb 4> :
   if (temu2_8 <= 4611686018427387900)
     goto <bb 5>; [INV]
   else
     goto <bb 6>; [INV]

   <bb 5> :
   bar (-1);


Andrew

Reply via email to