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

Andrew Macleod <amacleod at redhat dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |amacleod at redhat dot com

--- Comment #5 from Andrew Macleod <amacleod at redhat dot com> ---

These are the sorts of things we want to eventually enable doing.

It would be possible to invoke the ranger where ever the warnings are being
generated.  For this program, our branch's ranger VRP pass currently generates
a return range of [0, 10] for the function.

the possible ranges being fed into the return value PHI node at the end of the
function show as [1,4], [5,6], [7,10] and [0].  When combined into a
representable value_range, we get a conservative [0,10], which means we should
be able to determine that there is no conversion issue.

however, you do need to be careful.  The compiler tends to do unsigned
operations like minus by adding a value, ie  pin - 2 is calculated as pin + 253
and the overflow bit is ignored since its unsigned. I don't know anything about
the warning code, so I don't know how it determines to issue a warning.

ie, the first snippet:

   if (pin >= 3 && pin <= 6) return pin - 2;

shows as 

pin_5(D)        [0, 255] unsigned char
    <bb 2> :
    _1 = pin_5(D) + 253;
    if (_1 <= 3)
      goto <bb 3>; [INV]
    else
      goto <bb 4>; [INV]

2->3  (T) _1 :  [0, 3] unsigned char
2->3  (T) pin_5(D) :    [3, 6] unsigned char

=========== BB 3 ============
pin_5(D)        [3, 6] unsigned char
    <bb 3> :
    _9 = pin_5(D) + 254;
    // predicted unlikely by early return (on trees) predictor.
    goto <bb 8>; [INV]

_9 : [1, 4] unsigned char


And _9 is used in the return PHI:

=========== BB 8 ============
    <bb 8> :
    # _4 = PHI <_9(3), _8(5), _7(7), 0(6)>
    return _4;


So the range knowledge could be available if one were to want to use it.

THe problem is distinguishing when to trigger I guess.  If I change it to :

   if (pin >= 3 && pin <= 6) return pin - 4;

we want it to trigger the warning, and the code looks the same, except for:

=========== BB 3 ============
pin_5(D)        [3, 6] unsigned char
    <bb 3> :
    _9 = pin_5(D) + 252;
    // predicted unlikely by early return (on trees) predictor.
    goto <bb 8>; [INV]

_9 : [0, 2][255, 255] unsigned char


Im not sure how you look at the and consistently determine the warning needs to
be issued.. Check to see if the sign bit is set in any result? I dont know if
that always works.. pin_5 + 128 is perfectly valid and sets the sign bit too.
Perhaps the warning code already has the smarts and just needs ranges...

Maybe you can work on flow sensitive warnings next year :-)

Reply via email to