--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java 2019-05-06 15:58:59.123369540 +0200 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.phases.common/src/org/graalvm/compiler/phases/common/ConditionalEliminationPhase.java 2019-05-06 15:58:58.727367004 +0200 @@ -88,6 +88,7 @@ import org.graalvm.compiler.nodes.extended.IntegerSwitchNode; import org.graalvm.compiler.nodes.extended.LoadHubNode; import org.graalvm.compiler.nodes.extended.ValueAnchorNode; +import org.graalvm.compiler.nodes.java.InstanceOfNode; import org.graalvm.compiler.nodes.java.TypeSwitchNode; import org.graalvm.compiler.nodes.spi.NodeWithState; import org.graalvm.compiler.nodes.spi.StampInverter; @@ -364,7 +365,38 @@ node.setCondition(LogicConstantNode.forBoolean(result, node.graph()), node.isNegated()); // Don't kill this branch immediately, see `processGuard`. } - debug.log("Kill fixed guard guard"); + + if (guard instanceof DeoptimizingGuard && !node.isNegated() && !((DeoptimizingGuard) guard).isNegated()) { + LogicNode newCondition = ((DeoptimizingGuard) guard.asNode()).getCondition(); + if (newCondition instanceof InstanceOfNode) { + InstanceOfNode inst = (InstanceOfNode) newCondition; + ValueNode originalValue = GraphUtil.skipPi(inst.getValue()); + PiNode pi = null; + // Ensure that any Pi that's weaker than what the instanceof proves is + // replaced by one derived from the instanceof itself. + for (PiNode existing : guard.asNode().usages().filter(PiNode.class).snapshot()) { + if (!existing.isAlive()) { + continue; + } + if (originalValue != GraphUtil.skipPi(existing.object())) { + // Somehow these are unrelated values so leave it alone + continue; + } + // If the pi has a weaker stamp or the same stamp but a different input + // then replace it. + boolean strongerStamp = !existing.piStamp().join(inst.getCheckedStamp()).equals(inst.getCheckedStamp()); + boolean differentStamp = !existing.piStamp().equals(inst.getCheckedStamp()); + boolean differentObject = existing.object() != inst.getValue(); + if (!strongerStamp && (differentStamp || differentObject)) { + if (pi == null) { + pi = graph.unique(new PiNode(inst.getValue(), inst.getCheckedStamp(), (ValueNode) guard)); + } + existing.replaceAndDelete(pi); + } + } + } + } + debug.log("Kill fixed guard %s", node); return true; })) { registerNewCondition(node.condition(), node.isNegated(), node);