If the klass ptr carries enough information, we can fold flat/null-free layout helper checks even if the exact type is not known:
--- a/src/hotspot/share/opto/mulnode.cpp
+++ b/src/hotspot/share/opto/mulnode.cpp
@@ -488,6 +488,19 @@ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *load = in(1);
uint lop = load->Opcode();
+ if (lop == Op_LoadI) {
+ Node* adr = load->in(LoadNode::Address);
+ const TypePtr* tp = phase->type(adr)->isa_ptr();
+ if (tp->isa_klassptr() && tp->is_not_null_free() && (mask == Klass::_lh_null_free_bit_inplace ||
+ mask == Klass::_lh_array_tag_vt_value_bit_inplace)) {
+ set_req(1, phase->intcon(0)); // Never null-free (=> never flat)
+ } else if (tp->isa_klassptr() && tp->is_not_flat() && mask == Klass::_lh_array_tag_vt_value_bit_inplace) {
+ set_req(1, phase->intcon(0)); // Never flat
+ }
+ }
We should also add more tests. This seems to only rarely trigger with current ones.
--- a/src/hotspot/share/opto/mulnode.cpp
+++ b/src/hotspot/share/opto/mulnode.cpp
@@ -488,6 +488,19 @@ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *load = in(1);
uint lop = load->Opcode();
+ if (lop == Op_LoadI) {
+ Node* adr = load->in(LoadNode::Address);
+ const TypePtr* tp = phase->type(adr)->isa_ptr();
+ if (tp->isa_klassptr() && tp->is_not_null_free() && (mask == Klass::_lh_null_free_bit_inplace ||
+ mask == Klass::_lh_array_tag_vt_value_bit_inplace)) {
+ set_req(1, phase->intcon(0)); // Never null-free (=> never flat)
+ } else if (tp->isa_klassptr() && tp->is_not_flat() && mask == Klass::_lh_array_tag_vt_value_bit_inplace) {
+ set_req(1, phase->intcon(0)); // Never flat
+ }
+ }
We should also add more tests. This seems to only rarely trigger with current ones.