diff --git a/src/hotspot/share/opto/callGenerator.cpp b/src/hotspot/share/opto/callGenerator.cpp index 36fca9f61b691..23ca25603fd31 100644 --- a/src/hotspot/share/opto/callGenerator.cpp +++ b/src/hotspot/share/opto/callGenerator.cpp @@ -933,6 +933,9 @@ JVMState* PredictedCallGenerator::generate(JVMState* jvms) { // Make the hot call: JVMState* new_jvms = _if_hit->generate(kit.sync_jvms()); + if (kit.failing()) { + return nullptr; + } if (new_jvms == nullptr) { // Inline failed, so make a direct call. assert(_if_hit->is_inline(), "must have been a failed inline"); @@ -1260,6 +1263,9 @@ JVMState* PredicatedIntrinsicGenerator::generate(JVMState* jvms) { PreserveJVMState pjvms(&kit); // Generate intrinsic code: JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms()); + if (kit.failing()) { + return nullptr; + } if (new_jvms == nullptr) { // Intrinsic failed, use normal compilation path for this predicate. slow_region->add_req(kit.control()); diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index fcf6b920884dd..f130f4f81065e 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -4309,7 +4309,12 @@ Node* LibraryCallKit::generate_array_guard_common(Node* kls, RegionNode* region, if (obj != nullptr && is_array_ctrl != nullptr && is_array_ctrl != top()) { // Keep track of the fact that 'obj' is an array to prevent // array specific accesses from floating above the guard. - *obj = _gvn.transform(new CastPPNode(is_array_ctrl, *obj, TypeAryPtr::BOTTOM)); + Node* cast = _gvn.transform(new CastPPNode(is_array_ctrl, *obj, TypeAryPtr::BOTTOM)); + // Check for top because in rare cases, the type system can determine that + // the object can't be an array but the layout helper check is not folded. + if (!cast->is_top()) { + *obj = cast; + } } return ctrl; } diff --git a/src/hotspot/share/opto/library_call.hpp b/src/hotspot/share/opto/library_call.hpp index 25a853a6feff8..4f2650cfb64a8 100644 --- a/src/hotspot/share/opto/library_call.hpp +++ b/src/hotspot/share/opto/library_call.hpp @@ -106,6 +106,10 @@ class LibraryCallKit : public GraphKit { void push_result() { // Push the result onto the stack. if (!stopped() && result() != nullptr) { + if (result()->is_top()) { + assert(false, "Can't determine return value."); + C->record_method_not_compilable("Can't determine return value."); + } BasicType bt = result()->bottom_type()->basic_type(); push_node(bt, result()); } diff --git a/test/hotspot/jtreg/compiler/intrinsics/TestArrayGuardWithInterfaces.java b/test/hotspot/jtreg/compiler/intrinsics/TestArrayGuardWithInterfaces.java new file mode 100644 index 0000000000000..b9c26222c1604 --- /dev/null +++ b/test/hotspot/jtreg/compiler/intrinsics/TestArrayGuardWithInterfaces.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. 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. + */ + +import java.lang.reflect.Array; +import jdk.test.lib.Asserts; + +/** + * @test + * @bug 8348631 + * @summary Test folding of array guards used by intrinsics. + * @library /test/lib + * @run main/othervm -Xcomp -XX:-TieredCompilation + * -XX:CompileCommand=compileonly,TestArrayGuardWithInterfaces::test* + * TestArrayGuardWithInterfaces + */ +public class TestArrayGuardWithInterfaces { + + public static interface MyInterface { } + + public static int test1(Object obj) { + // Should be folded, arrays can never imlement 'MyInterface' + return Array.getLength((MyInterface)obj); + } + + public static int test2(Object obj) { + // Should not be folded, arrays implement 'Cloneable' + return Array.getLength((Cloneable)obj); + } + + public static void main(String[] args) { + // Warmup + Class c = MyInterface.class; + Array.getLength(args); + + try { + test1(null); + throw new RuntimeException("No exception thrown"); + } catch (Exception e) { + // Expected + } + Asserts.assertEQ(test2(new int[1]), 1); + } +}