On 11/5/20 2:29 PM, Martin Sebor wrote:
On 10/1/20 11:25 AM, Martin Sebor wrote:


I have applied the patch and ran some tests.  There are quite
a few failures (see the list below).  I have only looked at
a couple.  The one in in gcc.dg/tree-ssa/builtin-sprintf-warn-3.c
boils down to the following test case.  There should be no warning
for either sprintf call.  The one in h() is a false positive and
the reason for at least some of the regressions.  Somehow,
the conversions between int and char are causing Ranger to lose
the range.

$ cat t.c && gcc -O2 -S -Wall t.c
char a[2];

extern int x;

signed char f (int min, int max)
{
  signed char i = x;
  return i < min || max < i ? min : i;
}

void ff (signed char i)
{
  __builtin_sprintf (a, "%i", f (0, 9));   // okay
}

signed char g (signed char min, signed char max)
{
  signed char i = x;
  return i < min || max < i ? min : i;
}

void gg (void)
{
  __builtin_sprintf (a, "%i", g (0, 9));   // bogus warning
}



The latest changes resolve the issues witg the gg() case.
you will now get a range of [0,9] for the temporary:
=========== BB 4 ============
    <bb 4> :
    # iftmp.3_10 = PHI <0(2), i_6(3)>
    _2 = (int) iftmp.3_10;
    __builtin_sprintf (&a, "%i", _2);
    return;

_2 : int [0, 9]
iftmp.3_10 : signed char [0, 9]




The code issued for the 2 routines is very different. The first routine produces:

 =========== BB 2 ============
    <bb 2> :
    x.0_4 = x;
    i_6 = (signed char) x.0_4;
    _7 = (int) i_6;
    if (_7 < 0)
      goto <bb 4>; [50.00%]
    else
      goto <bb 3>; [50.00%]

_7 : int [-128, 127]
2->4  (T) x.0_4 :       int [-INF, -257][-128, -1][128, +INF]
2->4  (T) i_6 :         signed char [-INF, -1]
2->4  (T) _7 :  int [-128, -1]
2->3  (F) x.0_4 :       int [-INF, -129][0, 127][256, +INF]
2->3  (F) i_6 :         signed char [0, +INF]
2->3  (F) _7 :  int [0, 127]

=========== BB 3 ============
i_6     signed char [0, +INF]
_7      int [0, 127]
    <bb 3> :
    if (_7 > 9)
      goto <bb 4>; [50.00%]
    else
      goto <bb 5>; [50.00%]

3->4  (T) _7 :  int [10, 127]
3->5  (F) _7 :  int [0, 9]

=========== BB 4 ============
    <bb 4> :

=========== BB 5 ============
    <bb 5> :
    # iftmp.1_9 = PHI <i_6(3), 0(4)>
    _2 = (int) iftmp.1_9;
    __builtin_sprintf (&a, "%i", _2);
    return;

_2 : int [0, 127]
iftmp.1_9 : signed char [0, +INF]


Note that we figure out that _7 is [0,9] from 3->5,  except the PHI node in block 5 refers to i_6...

i_6 is not referred to in BB3, so this generation of ranger doesnt see it as an exportable value, and thus doesnt do a calculation for it like it does in BB2, where it is defined.  So it only picks up the first of the 2 conditions for i_6 that is live on entry to BB3 ([0, +INF])

2 things are in the pipe which will resolve this
1 - equivalences.  _7 is a cast-copy of i_6.  since the range of _7 falls within the range of a signed char, the forthcoming equivalency/relational work will have i_6 match the same value as _7. 2 - The next generation GORI engine will allow for recalculation of dependency chains from outside the block when appropriate, so this will cause i_6 to also be an exportable value from BB 3 as well. which will also then get the [0,9] range in circumstances in which it isnt a simply copy.


Neither of which helps you right now with the perfect precision  :-P

Andrew


Reply via email to