8241041: C2: "assert((Value(phase) == t) || (t != TypeInt::CC_GT && t != TypeInt::CC_EQ)) failed: missing Value() optimization" still happens after fix for 8239335

Reviewed-by: thartmann, neliasso
This commit is contained in:
Roland Westrelin 2020-03-23 10:06:33 +01:00
parent fc9389c164
commit 048c5c0ddd
2 changed files with 114 additions and 5 deletions

View File

@ -24,9 +24,11 @@
#include "precompiled.hpp"
#include "opto/addnode.hpp"
#include "opto/callnode.hpp"
#include "opto/connode.hpp"
#include "opto/convertnode.hpp"
#include "opto/phaseX.hpp"
#include "opto/rootnode.hpp"
#include "opto/subnode.hpp"
#include "opto/subtypenode.hpp"
@ -131,12 +133,21 @@ Node *SubTypeCheckNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (addr != NULL) {
intptr_t con = 0;
Node* obj = AddPNode::Ideal_base_and_offset(addr, phase, con);
if (con == oopDesc::klass_offset_in_bytes() && obj != NULL && phase->type(obj)->isa_oopptr()) {
if (con == oopDesc::klass_offset_in_bytes() && obj != NULL) {
assert(phase->type(obj)->isa_oopptr(), "only for oop input");
set_req(ObjOrSubKlass, obj);
return this;
}
}
// AllocateNode might have more accurate klass input
Node* allocated_klass = AllocateNode::Ideal_klass(obj_or_subklass, phase);
if (allocated_klass != NULL) {
assert(phase->type(obj_or_subklass)->isa_oopptr(), "only for oop input");
set_req(ObjOrSubKlass, allocated_klass);
return this;
}
// Verify that optimizing the subtype check to a simple code pattern
// when possible would not constant fold better
#ifdef ASSERT
@ -152,8 +163,19 @@ Node *SubTypeCheckNode::Ideal(PhaseGVN *phase, bool can_reshape) {
subklass = obj_or_subklass;
}
Node* res = new CmpPNode(subklass, superklass);
const Type* t = phase->type(phase->transform(res));
assert((Value(phase) == t) || (t != TypeInt::CC_GT && t != TypeInt::CC_EQ), "missing Value() optimization");
Node* cmp = phase->transform(res);
const Type* t = phase->type(cmp);
if (!((Value(phase) == t) || (t != TypeInt::CC_GT && t != TypeInt::CC_EQ))) {
Value(phase)->dump(); tty->cr();
t->dump(); tty->cr();
obj_or_subklass->dump();
subklass->dump();
superklass->dump();
cmp->dump();
tty->print_cr("==============================");
phase->C->root()->dump(9999);
fatal("missing Value() optimization");
}
if (phase->is_IterGVN()) {
phase->is_IterGVN()->_worklist.push(res);
}
@ -188,8 +210,20 @@ Node *SubTypeCheckNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *nkls = phase->transform(LoadKlassNode::make(*phase, NULL, kmem, p2, phase->type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL));
Node* res = new CmpPNode(superklass, nkls);
const Type* t = phase->type(phase->transform(res));
assert((Value(phase) == t) || (t != TypeInt::CC_GT && t != TypeInt::CC_EQ), "missing Value() optimization");
Node* cmp = phase->transform(res);
const Type* t = phase->type(cmp);
if (!((Value(phase) == t) || (t != TypeInt::CC_GT && t != TypeInt::CC_EQ))) {
Value(phase)->dump(); tty->cr();
t->dump(); tty->cr();
obj_or_subklass->dump();
subklass->dump();
superklass->dump();
nkls->dump();
cmp->dump();
tty->print_cr("==============================");
phase->C->root()->dump(9999);
fatal("missing Value() optimization");
}
if (phase->is_IterGVN()) {
phase->is_IterGVN()->_worklist.push(res);
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2020, Red Hat, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8241041
* @summary C2: "assert((Value(phase) == t) || (t != TypeInt::CC_GT && t != TypeInt::CC_EQ)) failed: missing Value() optimization" still happens after fix for 8239335
*
* @run main/othervm -XX:-BackgroundCompilation TestSubTypeCheckNewObjectNotConstant
*
*/
public class TestSubTypeCheckNewObjectNotConstant {
public static void main(String[] args) throws CloneNotSupportedException {
for (int i = 0; i < 20_000; i++) {
test();
test_helper1(test_helper2(0));
}
}
private static boolean test() throws CloneNotSupportedException {
int i = 0;
for (; i < 10; i++);
AbstractClass o = test_helper2(i);
return test_helper1(o);
}
private static AbstractClass test_helper2(int i) {
AbstractClass o;
if (i == 10) {
o = new ConcreteSubClass1();
} else {
o = new ConcreteSubClass2();
}
return o;
}
private static boolean test_helper1(AbstractClass o) throws CloneNotSupportedException {
final Object c = o.clone();
return c instanceof ConcreteSubClass1;
}
static abstract class AbstractClass implements Cloneable{
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
static class ConcreteSubClass1 extends AbstractClass {
}
static class ConcreteSubClass2 extends AbstractClass {
}
}