diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index 6451d90eee2..f18876b4c46 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp @@ -2023,10 +2023,12 @@ const Type* SqrtHFNode::Value(PhaseGVN* phase) const { static const Type* reverse_bytes(int opcode, const Type* con) { switch (opcode) { - case Op_ReverseBytesS: return TypeInt::make(byteswap(checked_cast(con->is_int()->get_con()))); - case Op_ReverseBytesUS: return TypeInt::make(byteswap(checked_cast(con->is_int()->get_con()))); - case Op_ReverseBytesI: return TypeInt::make(byteswap(checked_cast(con->is_int()->get_con()))); - case Op_ReverseBytesL: return TypeLong::make(byteswap(checked_cast(con->is_long()->get_con()))); + // It is valid in bytecode to load any int and pass it to a method that expects a smaller type (i.e., short, char). + // Let's cast the value to match the Java behavior. + case Op_ReverseBytesS: return TypeInt::make(byteswap(static_cast(con->is_int()->get_con()))); + case Op_ReverseBytesUS: return TypeInt::make(byteswap(static_cast(con->is_int()->get_con()))); + case Op_ReverseBytesI: return TypeInt::make(byteswap(con->is_int()->get_con())); + case Op_ReverseBytesL: return TypeLong::make(byteswap(con->is_long()->get_con())); default: ShouldNotReachHere(); } } diff --git a/test/hotspot/jtreg/compiler/c2/gvn/ReverseBytesConstantsHelper.jasm b/test/hotspot/jtreg/compiler/c2/gvn/ReverseBytesConstantsHelper.jasm new file mode 100644 index 00000000000..0ac3aa154ba --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/gvn/ReverseBytesConstantsHelper.jasm @@ -0,0 +1,44 @@ +/* + * 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. + * + */ +package compiler/c2/gvn; + +public class ReverseBytesConstantsHelper { + public Method "":"()V" stack 1 locals 1 { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + + public static Method reverseBytesShort:"(I)S" stack 1 locals 1 { + iload_0; + invokestatic Method java/lang/Short."reverseBytes":"(S)S"; + ireturn; + } + + public static Method reverseBytesChar:"(I)C" stack 1 locals 1 { + iload_0; + invokestatic Method java/lang/Character."reverseBytes":"(C)C"; + ireturn; + } +} diff --git a/test/hotspot/jtreg/compiler/c2/gvn/ReverseBytesConstantsTests.java b/test/hotspot/jtreg/compiler/c2/gvn/ReverseBytesConstantsTests.java index 13461771cc9..d9e06b47275 100644 --- a/test/hotspot/jtreg/compiler/c2/gvn/ReverseBytesConstantsTests.java +++ b/test/hotspot/jtreg/compiler/c2/gvn/ReverseBytesConstantsTests.java @@ -34,9 +34,10 @@ import jdk.test.lib.Asserts; /* * @test - * @bug 8353551 + * @bug 8353551 8359678 * @summary Test that ReverseBytes operations constant-fold. * @library /test/lib / + * @compile ReverseBytesConstantsHelper.jasm * @run driver compiler.c2.gvn.ReverseBytesConstantsTests */ public class ReverseBytesConstantsTests { @@ -51,14 +52,14 @@ public class ReverseBytesConstantsTests { private static final int C_INT = GEN_INT.next(); public static void main(String[] args) { - TestFramework.run(); + TestFramework.runWithFlags("-XX:CompileCommand=inline,compiler.c2.gvn.ReverseBytesConstantsHelper::*"); } @Run(test = { - "testI1", "testI2", "testI3", - "testL1", "testL2", "testL3", - "testS1", "testS2", "testS3", - "testUS1", "testUS2", "testUS3", + "testI1", "testI2", "testI3", "testI4", + "testL1", "testL2", "testL3", "testL4", + "testS1", "testS2", "testS3", "testS4", + "testUS1", "testUS2", "testUS3", "testUS4", }) public void runMethod() { assertResultI(); @@ -171,6 +172,18 @@ public class ReverseBytesConstantsTests { return Short.reverseBytes(C_SHORT); } + @Test + @IR(failOn = {IRNode.REVERSE_BYTES_S, IRNode.CALL}) + public short testS5() { + return ReverseBytesConstantsHelper.reverseBytesShort(C_INT); + } + + @Test + @IR(failOn = {IRNode.REVERSE_BYTES_S, IRNode.CALL}) + public short testS6() { + return ReverseBytesConstantsHelper.reverseBytesShort(C_CHAR); + } + @Test @IR(failOn = {IRNode.REVERSE_BYTES_US}) public char testUS1() { @@ -195,4 +208,16 @@ public class ReverseBytesConstantsTests { return Character.reverseBytes(C_CHAR); } + @Test + @IR(failOn = {IRNode.REVERSE_BYTES_US, IRNode.CALL}) + public char testUS5() { + return ReverseBytesConstantsHelper.reverseBytesChar(C_INT); + } + + @Test + @IR(failOn = {IRNode.REVERSE_BYTES_US, IRNode.CALL}) + public char testUS6() { + return ReverseBytesConstantsHelper.reverseBytesChar(C_SHORT); + } + }