src/share/vm/opto/ifnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/ifnode.cpp

Print this page
rev 7610 : 8027626: assert(Opcode() != Op_If || outcnt() == 2) failed: bad if #1
Summary: IGVN encounters IfNode with single projection when optimizing dying subgraph
Reviewed-by:


 448 int IfNode::is_range_check(Node* &range, Node* &index, jint &offset) {
 449   Node* b = in(1);
 450   if (b == NULL || !b->is_Bool())  return 0;
 451   BoolNode* bn = b->as_Bool();
 452   Node* cmp = bn->in(1);
 453   if (cmp == NULL)  return 0;
 454   if (cmp->Opcode() != Op_CmpU)  return 0;
 455 
 456   Node* l = cmp->in(1);
 457   Node* r = cmp->in(2);
 458   int flip_test = 1;
 459   if (bn->_test._test == BoolTest::le) {
 460     l = cmp->in(2);
 461     r = cmp->in(1);
 462     flip_test = 2;
 463   } else if (bn->_test._test != BoolTest::lt) {
 464     return 0;
 465   }
 466   if (l->is_top())  return 0;   // Top input means dead test
 467   if (r->Opcode() != Op_LoadRange)  return 0;



 468 
 469   // We have recognized one of these forms:
 470   //  Flip 1:  If (Bool[<] CmpU(l, LoadRange)) ...
 471   //  Flip 2:  If (Bool[<=] CmpU(LoadRange, l)) ...
 472 
 473   // Make sure it's a real range check by requiring an uncommon trap
 474   // along the OOB path.  Otherwise, it's possible that the user wrote
 475   // something which optimized to look like a range check but behaves
 476   // in some other way.
 477   Node* iftrap = proj_out(flip_test == 2 ? true : false);
 478   bool found_trap = false;
 479   if (iftrap != NULL) {
 480     Node* u = iftrap->unique_ctrl_out();
 481     if (u != NULL) {
 482       // It could be a merge point (Region) for uncommon trap.
 483       if (u->is_Region()) {
 484         Node* c = u->unique_ctrl_out();
 485         if (c != NULL) {
 486           iftrap = u;
 487           u = c;




 448 int IfNode::is_range_check(Node* &range, Node* &index, jint &offset) {
 449   Node* b = in(1);
 450   if (b == NULL || !b->is_Bool())  return 0;
 451   BoolNode* bn = b->as_Bool();
 452   Node* cmp = bn->in(1);
 453   if (cmp == NULL)  return 0;
 454   if (cmp->Opcode() != Op_CmpU)  return 0;
 455 
 456   Node* l = cmp->in(1);
 457   Node* r = cmp->in(2);
 458   int flip_test = 1;
 459   if (bn->_test._test == BoolTest::le) {
 460     l = cmp->in(2);
 461     r = cmp->in(1);
 462     flip_test = 2;
 463   } else if (bn->_test._test != BoolTest::lt) {
 464     return 0;
 465   }
 466   if (l->is_top())  return 0;   // Top input means dead test
 467   if (r->Opcode() != Op_LoadRange)  return 0;
 468   if (outcnt() != 2) {
 469     return 0;
 470   }
 471 
 472   // We have recognized one of these forms:
 473   //  Flip 1:  If (Bool[<] CmpU(l, LoadRange)) ...
 474   //  Flip 2:  If (Bool[<=] CmpU(LoadRange, l)) ...
 475 
 476   // Make sure it's a real range check by requiring an uncommon trap
 477   // along the OOB path.  Otherwise, it's possible that the user wrote
 478   // something which optimized to look like a range check but behaves
 479   // in some other way.
 480   Node* iftrap = proj_out(flip_test == 2 ? true : false);
 481   bool found_trap = false;
 482   if (iftrap != NULL) {
 483     Node* u = iftrap->unique_ctrl_out();
 484     if (u != NULL) {
 485       // It could be a merge point (Region) for uncommon trap.
 486       if (u->is_Region()) {
 487         Node* c = u->unique_ctrl_out();
 488         if (c != NULL) {
 489           iftrap = u;
 490           u = c;


src/share/vm/opto/ifnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File