[LLVMdev] Possible SelectionDAG Bug

David Greene dag at cray.com
Mon Mar 1 07:26:21 PST 2010


On Friday 26 February 2010 19:09:01 Dan Gohman wrote:

> I've now looked at your latest patch.  In summary, it does expose a
> subtle problem. I haven't seen anything that here would lead to
> observable misbehavior yet though.

Well, I'm definitely observing misbehavior.  I know it has something to do
with local changes here but I haven't isolated it yet.

> X86GenDAGISel.inc has code like this:
>
>    SDValue N1 = N->getOperand(1);
>    ...
>    SDNode *ResNode = CurDAG->SelectNodeTo(N, ...);
>    ...
>    ReplaceUses(SDValue(N1.getNode(), 1), SDValue(ResNode, 2));
>
> If N was the only user of N1, and N1 isn't in the new operand list, then
> the SelectNodeTo call will make N1 dead. SelectNodeTo will automatically
> delete nodes that are made dead by the transformation. This means that
> the "from" node in the subsequent ReplaceUses call will be a deleted
> node
> in that case.

Ok, so that should be easy to fix.

> This doesn't break in practice because deleted node aren't actually
> deallocated, they're just put on a linked list of nodes ready to be
> reused next time a new node is created, and no new nodes are created
> between the SelectNodeTo call and the ReplaceUses call.

Right.

> Another observation here is that the ReplaceUses call in such cases
> doesn't do anything, because the From node has no uses.

Right.

> Perhaps this can be fixed by making the code skip the ReplaceUses
> call in the case where there are no uses to replace.  That's not trivial
> to detect though.

Why not just check the same thing the added asserts check?

What I'm seeing is a problem in ReplaceAllUsesOf itself.  It recurses
down and eventually replaces the node under the iterator in this use
loop:

  SDNode::use_iterator UI = From.getNode()->use_begin(),
                       UE = From.getNode()->use_end();
  while (UI != UE) {
    SDNode *User = *UI;
    bool UserRemovedFromCSEMaps = false;


UI goes bad and we blow up after returning from a deeply recursed call.

It's simply not safe to iterate over a set that may change.  Unfortunately,
any of the nodes under the iterators may change so I don't see an easy
way to fix this.

                                               -Dave




More information about the llvm-dev mailing list