-
Notifications
You must be signed in to change notification settings - Fork 75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Basic incremental can be more precise than from-scratch due to type-based interval widening #626
Comments
It's probably possible to create a much simpler non-incremental program, which contains the same behavior, but this very likely wouldn't be observable since any assertion/branching would account for the more precise bound from def_exc. There are multiple ways this could be worked around in the int domains:
But much more notable is still the fact that certain valid widenings may not have some intuitively nice property of "not jumping over" and this is actually observable from our incremental analysis results. |
I would actually be interested whether this works out of the box. Can you try with |
I tried now and it doesn't. The reason is "visible" from the implementation of refining intervals with exclusion sets (in this case an empty exclusion set): analyzer/src/cdomains/intDomain.ml Lines 877 to 891 in 6958d4b
It doesn't get as argument the range of def_exc, only the list of values. Meanwhile the ik argument corresponds to the outer 64bit type.
|
I will try to enhance this refinement such that the def_exc range is also passed to intervals and used for refining. Then we can at least see how many of the internal precision comparisons from incremental bench are due to this. |
This specific case was closed by #640. |
On knot_comb from our bench, basic incremental analysis is surprisingly more precise than from-scratch analysis. A manually minimized program that still shows the same behavior is the following:
With the following patch:
The precision comparison says that
line
in incremental is more precise than in from-scratch:Note the inconsistency in the first offset's int domains: def_exc has 32bit range, but intervals have 64bit range.
This occurs due to the following widening taking place in the
main
loop (for the address offset):Notably, def_exc simply joins, while intervals widen to the type's maximum bounds, which in this case are
ptrdiff_t
64bit bounds. This isn't a bug in the interval domain because it is correctly widening to infinity (for the type).The reason this allows basic incremental to be more precise is because it reuses the locally stored value, initially has no widening point, the
main
loop reaches fixpoint immediately with the stored value and hence widening is never applied!This demonstrates a pitfall we have suspected a long ago, but not yet seen in Goblint: widening may allow "jumping over" certain values. That is, if
a leq b leq c leq d
anda widen (a join c) = d
andb widen (b join c) = c
, then surprisingly widening from a lower valuea
toc
may jump over compared to if the widening happens from a higher valueb
.The text was updated successfully, but these errors were encountered: