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