diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PiNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PiNode.java index 223e6a3c06a2..3e64a566aec3 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PiNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/nodes/PiNode.java @@ -27,6 +27,8 @@ import static jdk.graal.compiler.nodeinfo.NodeCycles.CYCLES_0; import static jdk.graal.compiler.nodeinfo.NodeSize.SIZE_0; +import java.util.List; + import jdk.graal.compiler.core.common.SuppressFBWarnings; import jdk.graal.compiler.core.common.type.AbstractPointerStamp; import jdk.graal.compiler.core.common.type.FloatStamp; @@ -243,7 +245,6 @@ public void virtualize(VirtualizerTool tool) { @SuppressFBWarnings(value = {"NP"}, justification = "We null check it before") public static ValueNode canonical(ValueNode object, Stamp piStamp, GuardingNode guard, ValueNode self) { - // GR-52557 GraalError.guarantee(piStamp != null && object != null, "Invariant piStamp=%s object=%s guard=%s self=%s", piStamp, object, guard, self); // Use most up to date stamp. @@ -325,7 +326,9 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean if (guardNode.hasNoUsages()) { return; } - for (PiNode pi : guardNode.usages().filter(PiNode.class).snapshot()) { + + List pis = guardNode.usages().filter(PiNode.class).snapshot(); + for (PiNode pi : pis) { if (!pi.isAlive()) { continue; } @@ -335,6 +338,8 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean } /* + * RECURSE CALL + * * If there are PiNodes still anchored at this guard then either they must simplify away * because they are no longer necessary or this node must be replaced with a * ValueAnchorNode because the type injected by the PiNode is only true at this point in @@ -348,6 +353,16 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean tryEvacuate(tool, otherGuard, false); } } + /* + * A note on the RECURSE CALL above: When we have pis with input pis on the same guard + * (which should actually be combined) it can be that the recurse call (processing the + * same pis again) already deletes this node (very special stamp setups necessary). + * Thus, it can be that pi is dead at this point already, so we have to check for this + * again. + */ + if (!pi.isAlive()) { + continue; + } Node canonical = pi.canonical(tool); if (canonical != pi) { if (!canonical.isAlive()) {