diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index a19dbd664eb..e596db8e0c7 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -289,10 +289,17 @@ static Node *step_through_mergemem(PhaseGVN *phase, MergeMemNode *mmem, const T toop->isa_instptr() && toop->is_instptr()->instance_klass()->is_java_lang_Object() && toop->offset() == Type::OffsetBot)) { - // compress paths and change unreachable cycles to TOP - // If not, we can update the input infinitely along a MergeMem cycle - // Equivalent code in PhiNode::Ideal - Node* m = phase->transform(mmem); + // IGVN _delay_transform may be set to true and if that is the case and mmem + // is already a registered node then the validation inside transform will + // complain. + Node* m = mmem; + PhaseIterGVN* igvn = phase->is_IterGVN(); + if (igvn == nullptr || !igvn->delay_transform()) { + // compress paths and change unreachable cycles to TOP + // If not, we can update the input infinitely along a MergeMem cycle + // Equivalent code in PhiNode::Ideal + m = phase->transform(mmem); + } // If transformed to a MergeMem, get the desired slice // Otherwise the returned node represents memory for every slice mem = (m->is_MergeMem())? m->as_MergeMem()->memory_at(alias_idx) : m; diff --git a/test/hotspot/jtreg/compiler/escapeAnalysis/TestReduceAllocationAndSetTypeTwice.java b/test/hotspot/jtreg/compiler/escapeAnalysis/TestReduceAllocationAndSetTypeTwice.java new file mode 100644 index 00000000000..b44e70f5362 --- /dev/null +++ b/test/hotspot/jtreg/compiler/escapeAnalysis/TestReduceAllocationAndSetTypeTwice.java @@ -0,0 +1,62 @@ +/* + * 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. + */ + +/* + * @test + * @bug 8352681 + * @summary Check that RAM does not crash when split load through phi + * tries to register an old node twice with IGVN. + * @run main/othervm -XX:CompileCommand=compileonly,*TestReduceAllocationAndSetTypeTwice*::* + * -XX:CompileCommand=dontinline,*TestReduceAllocationAndSetTypeTwice*::* + * -Xcomp compiler.escapeAnalysis.TestReduceAllocationAndSetTypeTwice + * @run main compiler.escapeAnalysis.TestReduceAllocationAndSetTypeTwice + */ + +package compiler.escapeAnalysis; + +public class TestReduceAllocationAndSetTypeTwice { + public static double dummy() { + return 3.1415; + } + + public static double test(double param) { + Double double_1 = -26.335025324149626D; + Double double_2 = 87.9546734116494D; + + for (int i = 0, j = 0; i < 256; i++) { + if (param != param) { + j--; + } else if (dummy() > 0) { + return (j < 1234 ? double_1 : double_2); + } + } + + return 10.0; + } + + public static void main(String[] args) { + for (int i = 0; i < 512; i++) { + test(-3.1415); + } + } +}