[llvm-dev] Should analyses be able to hold AssertingVH to IR? (related to PR28400)
Sanjoy Das via llvm-dev
llvm-dev at lists.llvm.org
Mon Jul 11 19:51:51 PDT 2016
Hi Sean,
Sean Silva wrote:
> While building test-suite with the new PM, I ran into problems with
> AssertingVH being triggered which is obvious in retrospect:
> https://llvm.org/bugs/show_bug.cgi?id=28400
>
> Both cases I ran into revolve around LVI which holds AssertingVH.
> Essentially, what happens is this:
>
> 1. LVI holds an AssertingVH pointing at a BasicBlock
> 2. Some other pass ends up deleting that BB (e.g. SimplifyCFG)
> 3. BOOM
>
> Notice that this ends up happening even though SimplifyCFG ultimately
> invalidates LVI. But that only happens after the AssertingVH has been
> triggered.
>
> We would avoid this issue in principle by just switching those
> AssertingVH to observing pointers, but then we would have dangling
> pointers. I'm pretty sure that any analysis that keeps pointers to IR is
> in fact ending up with dangling pointers like this.
>
> I've noticed that AssumptionCache using CallbackVH that allow it to
> update its data structures correctly in this case.
>
> Just using regular pointers will end up with dangling pointers in this
> scenario. This isn't a problem in practice since the analysis will
> hopefully be invalidated and stop holding the dangling pointers, but it
> just seems weird. Thankfully, ASan can generally catch problems if we do
> try to access through any of these dangling pointers.
But asan won't catch problems (insofar I understand how it works) if
the free'ed BasicBlock is used as a key in a DenseMap or something --
if another BasicBlock gets allocated to the same location we'll end up
returning bad cached results.
I think the Right Solution(TM) here is to create a new wrapper around
(Small)DenseMap that in debug mode uses a CallbackVH in a way that:
- The map is "poisoned" if a key is deleted.
- A poisoned map can only be cleared; inserting, removing or looking
up elements in a poisoned map fails a assertions.
If needed, we can allow erasing deleted keys from poisoned maps, but
then we won't catch bugs like:
M[k] = v;
delete k;
k1 = new Key(); // allocated to the same location as k1
M.erase(k1); // "successful" deletion.
However, this quite a bit of work, and I'm not sure if the payoff will
be worth it.
-- Sanjoy
> Thoughts? For the moment I have put in a workaround (r274457) that makes
> jump-threading invalidate LVI.
>
> -- Sean Silva
More information about the llvm-dev
mailing list