< prev index next >

src/hotspot/share/opto/mulnode.cpp

Print this page
*** 195,10 ***
--- 195,22 ---
      const Type *zero = add_id();        // The multiplicative zero
      if( t1->higher_equal( zero ) ) return zero;
      if( t2->higher_equal( zero ) ) return zero;
    }
  
+   // Code pattern on return from a call that returns an __Value.  Can
+   // be optimized away if the return value turns out to be an oop.
+   if (op == Op_AndX &&
+       in(1) != nullptr &&
+       in(1)->Opcode() == Op_CastP2X &&
+       in(1)->in(1) != nullptr &&
+       phase->type(in(1)->in(1))->isa_oopptr() &&
+       t2->isa_intptr_t()->_lo >= 0 &&
+       t2->isa_intptr_t()->_hi <= MinObjAlignmentInBytesMask) {
+     return add_id();
+   }
+ 
    // Either input is BOTTOM ==> the result is the local BOTTOM
    if( t1 == Type::BOTTOM || t2 == Type::BOTTOM )
      return bottom_type();
  
  #if defined(IA32)

*** 736,10 ***
--- 748,18 ---
          jlong mask = max_julong >> shift;
          if( (mask&con) == mask )  // If AND is useless, skip it
            return usr;
        }
      }
+ 
+     // Check if this is part of an inline type test
+     if (con == markWord::inline_type_pattern && in(1)->is_Load() &&
+         phase->type(in(1)->in(MemNode::Address))->is_inlinetypeptr() &&
+         phase->type(in(1)->in(MemNode::Address))->is_ptr()->offset() == oopDesc::mark_offset_in_bytes()) {
+       assert(EnableValhalla, "should only be used for inline types");
+       return in(2); // Obj is known to be an inline type
+     }
    }
    return MulNode::Identity(phase);
  }
  
  //------------------------------Ideal------------------------------------------
< prev index next >