RFR(XS): 8027626: assert(Opcode() != Op_If || outcnt() == 2) failed: bad if #1

Roland Westrelin roland.westrelin at oracle.com
Wed Jan 7 22:02:25 UTC 2015


>>>> Can we simple use replace_input_of(in(0), 0, NULL) in
>>>> If{False,True}Node::Identity()? It will disconnect IfNode's control
>>>> edge and put it on worklist.
>>> 
>>> But that’s a PhaseIterGVN’s method and Identity is passed a
>>> PhaseTransform?
>> 
>> An other suggestion is to delay If{False,True}Node::Identity()
>> optimization until not taken branch is removed: (outcnt() < 2). But it
>> will need to place taken ProjNode back on worklist when we removed other
>> branch.
> 
> Add IfNode to has_special_unique_user() so the code in PhaseIterGVN::remove_globally_dead_node() will do it for you.


Thanks for the suggestion, Vladimir. Does that look ok?

http://cr.openjdk.java.net/~roland/8027626/webrev.01/

Roland.

> 
> Thanks,
> Vladimir
> 
>> 
>>> 
>>> It seems in other locations in the code, the code is robust to broken
>>> if subgraphs. This for instance:
>> 
>> I think it is too late as this bug shows. We should not allow 2 control
>> users at any time in a graph (except for IfNode)!
>> 
>> Vladimir
>> 
>>> 
>>> IfNode::Ideal()
>>> 
>>>   // Another variation of a dead if
>>>   if (outcnt() < 2)  return NULL;
>>> 
>>> Why isn’t it good enough here?
>>> 
>>> Roland.
>>> 
>>>> 
>>>> Thanks,
>>>> Vladimir
>>>> 
>>>> On 1/6/15 5:38 AM, Roland Westrelin wrote:
>>>>>> Is it again the problem with IGVN list processing order?
>>>>>> What happens in a simple test case when only one branch is taking?
>>>>>> How projection and If nodes are removed?
>>>>> 
>>>>> IfNode::Value() returns either TypeTuple::IFFALSE or TypeTuple::IFTRUE
>>>>> If{False,True}Node::Identity() replaces the taken projection with
>>>>> the If’s control input.
>>>>> ProjNode::Value() returns top for the non taken projection and the
>>>>> dead branch is killed by propagating top.
>>>>> 
>>>>> So yes, it’s an IGVN list processing order problem.
>>>>> 
>>>>> Roland.
>>>>> 
>>>>> 
>>>>>> 
>>>>>> Vladimir
>>>>>> 
>>>>>> On 1/5/15 1:33 PM, Roland Westrelin wrote:
>>>>>>> Hi Vladimir,
>>>>>>> 
>>>>>>> Thanks for looking at this.
>>>>>>> 
>>>>>>>> I think correct fix will be eager dead 12212 If node elimination
>>>>>>>> when 12214 is replaced by 18733. Keep it connected to graph can
>>>>>>>> cause problems in other places.
>>>>>>> 
>>>>>>> IfFalseNode::Identity() is what optimizes 12212/12214 out. Should
>>>>>>> I make it an Ideal transformation so that I can call
>>>>>>> igvn->remove_dead_node() on the dead branch?
>>>>>>> 
>>>>>>> Roland.
>>>>>>> 
>>>>>>>> 
>>>>>>>> Thanks,
>>>>>>>> Vladimir
>>>>>>>> 
>>>>>>>> On 1/5/15 7:48 AM, Roland Westrelin wrote:
>>>>>>>>> http://cr.openjdk.java.net/~roland/8027626/webrev.00/
>>>>>>>>> 
>>>>>>>>> The following subgraph is where the bug shows up:
>>>>>>>>> 
>>>>>>>>> If (18732)
>>>>>>>>> |     \
>>>>>>>>> IfTrue IfFalse
>>>>>>>>> (18734) (18733)
>>>>>>>>> | |
>>>>>>>>> | If (12212)
>>>>>>>>> | |     \
>>>>>>>>> | IfFalse IfTrue
>>>>>>>>> | (12214)
>>>>>>>>> | |
>>>>>>>>> Region (12183)
>>>>>>>>> 
>>>>>>>>> Condition to 12212 is always false so 12214 is replaced by 18733
>>>>>>>>> and both branches of If 18732 are directly connected to Region
>>>>>>>>> 12183. 18733 still has dead 12212 as output.
>>>>>>>>> 12183 doesn't have phis so when it's transformed, If 18732 is
>>>>>>>>> considered for removal. IfTrue 18734 doesn't have uses anymore
>>>>>>>>> so it goes away but IfFalse 18733 still has some (dead branch
>>>>>>>>> 12212 is not yet removed).
>>>>>>>>> An If in the dead branch 12212 is processed. Range check
>>>>>>>>> smearing follows dominator controls until 18733, tests whether
>>>>>>>>> the If is a range check and the assert fires because the If only
>>>>>>>>> has one projection.
>>>>>>>>> 
>>>>>>>>> So we’re trying to optimize a dead branch. I fixed it by making
>>>>>>>>> the range check code more robust.
>>>>>>>>> 
>>>>>>>>> Roland.
>>>>>>>>> 
>>>>>>> 
>>>>> 
>>> 



More information about the hotspot-compiler-dev mailing list