8359678: C2: assert(static_cast<T1>(result) == thing) caused by ReverseBytesNode::Value()

Reviewed-by: chagedorn
Backport-of: e5ab210713f76c5307287bd97ce63f9e22d0ab8e
This commit is contained in:
Tobias Hartmann 2025-07-15 11:35:53 +00:00
parent ce85123f3a
commit 7aa3f31724
3 changed files with 81 additions and 10 deletions

View File

@ -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<jshort>(con->is_int()->get_con())));
case Op_ReverseBytesUS: return TypeInt::make(byteswap(checked_cast<jchar>(con->is_int()->get_con())));
case Op_ReverseBytesI: return TypeInt::make(byteswap(checked_cast<jint>(con->is_int()->get_con())));
case Op_ReverseBytesL: return TypeLong::make(byteswap(checked_cast<jlong>(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<jshort>(con->is_int()->get_con())));
case Op_ReverseBytesUS: return TypeInt::make(byteswap(static_cast<jchar>(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();
}
}

View File

@ -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 "<init>":"()V" stack 1 locals 1 {
aload_0;
invokespecial Method java/lang/Object."<init>":"()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;
}
}

View File

@ -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);
}
}