This is an archive of the discontinued LLVM Phabricator instance.

[clang][dataflow] Weaken abstract comparison to enable loop termination.
ClosedPublic

Authored by ymandel on Apr 12 2022, 4:33 AM.

Details

Summary

Currently, when the framework is used with an analysis that does not override
compareEquivalent, it does not terminate for most loops. The root cause is the
interaction of (the default implementation of) environment comparison
(compareEquivalent) and the means by which locations and values are
allocated. Specifically, the creation of certain values (including: reference
and pointer values; merged values) results in allocations of fresh locations in
the environment. As a result, analysis of even trivial loop bodies produces
different (if isomorphic) environments, on identical inputs. At the same time,
the default analysis relies on strict equality (versus some relaxed notion of
equivalence). Together, when the analysis compares these isomorphic, yet
unequal, environments, to determine whether the successors of the given block
need to be (re)processed, the result is invariably "yes", thus preventing loop
analysis from reaching a fixed point.

There are many possible solutions to this problem, including equivalence that is
less than strict pointer equality (like structural equivalence) and/or the
introduction of an explicit widening operation. However, these solutions will
require care to be implemented correctly. While a high priority, it seems more
urgent that we fix the current default implentation to allow
termination. Therefore, this patch proposes, essentially, to change the default
comparison to trivally equate any two values. As a result, we can say precisely
that the analysis will process the loop exactly twice -- once to establish an
initial result state and the second to produce an updated result which will
(always) compare equal to the previous. While clearly unsound -- we are not
reaching a fix point of the transfer function, in practice, this level of
analysis will find many practical issues where a single iteration of the loop
impacts abstract program state.

Note, however, that the change to the default merge operation does not affect
soundness, because the framework already produces a fresh (sound) abstraction of
the value when the two values are distinct. The previous setting was overly
conservative.

Diff Detail

Event Timeline

ymandel created this revision.Apr 12 2022, 4:33 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 12 2022, 4:33 AM
ymandel requested review of this revision.Apr 12 2022, 4:33 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 12 2022, 4:33 AM
xazax.hun accepted this revision.Apr 12 2022, 4:16 PM

Yeah, this is a hard problem in general. This looks like a sensible workaround for the short term, but I'm looking forward to a better solution. I'm a bit worried that the memory model will need some upgrades to properly solve this problem.

This revision is now accepted and ready to land.Apr 12 2022, 4:16 PM

Yeah, this is a hard problem in general. This looks like a sensible workaround for the short term, but I'm looking forward to a better solution. I'm a bit worried that the memory model will need some upgrades to properly solve this problem.

Thanks for the quick review! Yes, I have my concerns as well. It seems like some amount of a) additional allocation stabilization/memoization, b) introduction of explicit widening operator and c) structural comparison will fully solve the problem. Solving this properly is a high priority.

Yeah, this is a hard problem in general. This looks like a sensible workaround for the short term, but I'm looking forward to a better solution. I'm a bit worried that the memory model will need some upgrades to properly solve this problem.

Thanks for the quick review! Yes, I have my concerns as well. It seems like some amount of a) additional allocation stabilization/memoization, b) introduction of explicit widening operator and c) structural comparison will fully solve the problem. Solving this properly is a high priority.

This is a complicated topic. If you have a plan I think it might be a good idea to share it on the forums just in case someone has some input before fully implementing it.

Yeah, this is a hard problem in general. This looks like a sensible workaround for the short term, but I'm looking forward to a better solution. I'm a bit worried that the memory model will need some upgrades to properly solve this problem.

Thanks for the quick review! Yes, I have my concerns as well. It seems like some amount of a) additional allocation stabilization/memoization, b) introduction of explicit widening operator and c) structural comparison will fully solve the problem. Solving this properly is a high priority.

This is a complicated topic. If you have a plan I think it might be a good idea to share it on the forums just in case someone has some input before fully implementing it.

Yes, definitely! At the least, I was hoping for *your* input before we start sending you patches. :)

This revision was landed with ongoing or failed builds.Apr 13 2022, 12:51 PM
This revision was automatically updated to reflect the committed changes.