RFR(XS): 8027626: assert(Opcode() != Op_If || outcnt() == 2) failed: bad if #1
Roland Westrelin
roland.westrelin at oracle.com
Thu Jan 8 09:27:15 UTC 2015
> Good.
>
> I don't like *virtual* methods :) and we can do with (t->field_at(1 - _con) == Type::TOP) but your code is more clear.
>
> May be change method to return bool:
>
> virtual bool always_taken(const TypeTuple* t) const { return (t == TypeTuple::IFFALSE); }
Thanks for the review and comments. I’ll make that change before I push it.
Roland.
>
> Thanks,
> Vladimir
>
>
> On 1/7/15 2:02 PM, Roland Westrelin wrote:
>>>>>> 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