Skip to content

Commit a613998

Browse files
author
Pengfei Li
committed
8297689: Fix incorrect result of Short.reverseBytes() call in loops
Reviewed-by: thartmann, jbhateja
1 parent f8f4630 commit a613998

File tree

6 files changed

+164
-6
lines changed

6 files changed

+164
-6
lines changed

src/hotspot/share/opto/vectornode.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,18 @@ int VectorNode::opcode(int sopc, BasicType bt) {
169169
case Op_ReverseL:
170170
return (is_integral_type(bt) ? Op_ReverseV : 0);
171171
case Op_ReverseBytesS:
172+
case Op_ReverseBytesUS:
173+
// Subword operations in superword usually don't have precise info
174+
// about signedness. But the behavior of reverseBytes for short and
175+
// char are exactly the same.
176+
return ((bt == T_SHORT || bt == T_CHAR) ? Op_ReverseBytesV : 0);
172177
case Op_ReverseBytesI:
178+
// There is no reverseBytes() in Byte class but T_BYTE may appear
179+
// in VectorAPI calls. We still use ReverseBytesI for T_BYTE to
180+
// ensure vector intrinsification succeeds.
181+
return ((bt == T_INT || bt == T_BYTE) ? Op_ReverseBytesV : 0);
173182
case Op_ReverseBytesL:
174-
case Op_ReverseBytesUS:
175-
return (is_integral_type(bt) ? Op_ReverseBytesV : 0);
183+
return (bt == T_LONG ? Op_ReverseBytesV : 0);
176184
case Op_CompressBits:
177185
// Not implemented. Returning 0 temporarily
178186
return 0;

src/hotspot/share/prims/vectorSupport.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -520,8 +520,13 @@ int VectorSupport::vop2ideal(jint id, BasicType bt) {
520520
}
521521
case VECTOR_OP_REVERSE_BYTES: {
522522
switch (bt) {
523-
case T_BYTE:
524-
case T_SHORT:
523+
case T_SHORT: return Op_ReverseBytesS;
524+
// Superword requires type consistency between the ReverseBytes*
525+
// node and the data. But there's no ReverseBytesB node because
526+
// no reverseBytes() method in Java Byte class. T_BYTE can only
527+
// appear in VectorAPI calls. We reuse Op_ReverseBytesI for this
528+
// to ensure vector intrinsification succeeds.
529+
case T_BYTE: // Intentionally fall-through
525530
case T_INT: return Op_ReverseBytesI;
526531
case T_LONG: return Op_ReverseBytesL;
527532
default: fatal("REVERSE_BYTES: %s", type2name(bt));

test/hotspot/jtreg/compiler/vectorization/TestReverseBytes.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@
2525
* @bug 8288112
2626
* @summary Auto-vectorization of ReverseBytes operations.
2727
* @requires vm.compiler2.enabled
28-
* @requires vm.cpu.features ~= ".*avx2.*"
29-
* @requires os.simpleArch == "x64"
28+
* @requires (os.simpleArch == "x64" & vm.cpu.features ~= ".*avx2.*") | os.simpleArch == "AArch64"
3029
* @library /test/lib /
3130
* @run driver compiler.vectorization.TestReverseBytes
3231
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright (c) 2022, Arm Limited. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package compiler.vectorization;
25+
26+
import compiler.lib.ir_framework.*;
27+
28+
/*
29+
* @test
30+
* @bug 8297689
31+
* @summary Test miscompilation of reverseBytes call from subword types
32+
* @library /test/lib /
33+
* @requires vm.compiler2.enabled
34+
* @run driver compiler.vectorization.TestSubwordReverseBytes
35+
*/
36+
37+
public class TestSubwordReverseBytes {
38+
private static final int SIZE = 32000;
39+
40+
private static int[] idx = new int[SIZE];
41+
private static short[] rbs = new short[SIZE];
42+
private static char[] rbc = new char[SIZE];
43+
44+
static {
45+
for (int i = 0; i < SIZE; i++) {
46+
idx[i] = i;
47+
}
48+
for (short s = 0; s < SIZE; s++) {
49+
rbs[s] = Short.reverseBytes(s);
50+
}
51+
for (char c = 0; c < SIZE; c++) {
52+
rbc[c] = Character.reverseBytes(c);
53+
}
54+
}
55+
56+
@Test
57+
@IR(failOn = {IRNode.REVERSE_BYTES_V})
58+
public static int[] testShortReverseBytes() {
59+
int[] res = new int[SIZE];
60+
for (int i = 0; i < SIZE; i++) {
61+
res[i] = Short.reverseBytes((short) idx[i]);
62+
}
63+
return res;
64+
}
65+
66+
@Run(test = "testShortReverseBytes")
67+
public static void testShort() {
68+
int[] res = testShortReverseBytes();
69+
for (int i = 0; i < SIZE; i++) {
70+
if (res[i] != rbs[i]) {
71+
throw new RuntimeException("Wrong result: expected = " +
72+
(int) rbs[i] + ", actual = " + res[i]);
73+
}
74+
}
75+
}
76+
77+
@Test
78+
@IR(failOn = {IRNode.REVERSE_BYTES_V})
79+
public static int[] testCharacterReverseBytes() {
80+
int[] res = new int[SIZE];
81+
for (int i = 0; i < SIZE; i++) {
82+
res[i] = Character.reverseBytes((char) idx[i]);
83+
}
84+
return res;
85+
}
86+
87+
@Run(test = "testCharacterReverseBytes")
88+
public static void testChar() {
89+
int[] res = testCharacterReverseBytes();
90+
for (int i = 0; i < SIZE; i++) {
91+
if (res[i] != rbc[i]) {
92+
throw new RuntimeException("Wrong result: expected = " +
93+
(int) rbc[i] + ", actual = " + res[i]);
94+
}
95+
}
96+
}
97+
98+
public static void main(String[] args) {
99+
TestFramework.run();
100+
}
101+
}
102+

test/hotspot/jtreg/compiler/vectorization/runner/BasicCharOpTest.java

+22
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,18 @@ public class BasicCharOpTest extends VectorizationTestRunner {
4747
private char[] a;
4848
private char[] b;
4949
private char[] c;
50+
private int[] idx;
5051

5152
public BasicCharOpTest() {
5253
a = new char[SIZE];
5354
b = new char[SIZE];
5455
c = new char[SIZE];
56+
idx = new int[SIZE];
5557
for (int i = 0; i < SIZE; i++) {
5658
a[i] = (char) (20 * i);
5759
b[i] = (char) (i + 44444);
5860
c[i] = (char) 10000;
61+
idx[i] = i;
5962
}
6063
}
6164

@@ -189,5 +192,24 @@ public char[] vectorUnsignedShiftRight() {
189192
}
190193
return res;
191194
}
195+
196+
// ------------- ReverseBytes -------------
197+
@Test
198+
public char[] reverseBytesWithChar() {
199+
char[] res = new char[SIZE];
200+
for (int i = 0; i < SIZE; i++) {
201+
res[i] = Character.reverseBytes(a[i]);
202+
}
203+
return res;
204+
}
205+
206+
@Test
207+
public int[] reverseBytesWithInt() {
208+
int[] res = new int[SIZE];
209+
for (int i = 0; i < SIZE; i++) {
210+
res[i] = Character.reverseBytes((char) idx[i]);
211+
}
212+
return res;
213+
}
192214
}
193215

test/hotspot/jtreg/compiler/vectorization/runner/BasicShortOpTest.java

+22
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,18 @@ public class BasicShortOpTest extends VectorizationTestRunner {
4747
private short[] a;
4848
private short[] b;
4949
private short[] c;
50+
private int[] idx;
5051

5152
public BasicShortOpTest() {
5253
a = new short[SIZE];
5354
b = new short[SIZE];
5455
c = new short[SIZE];
56+
idx = new int[SIZE];
5557
for (int i = 0; i < SIZE; i++) {
5658
a[i] = (short) (-12 * i);
5759
b[i] = (short) (9 * i + 8888);
5860
c[i] = (short) -32323;
61+
idx[i] = i;
5962
}
6063
}
6164

@@ -187,5 +190,24 @@ public short[] vectorUnsignedShiftRight() {
187190
}
188191
return res;
189192
}
193+
194+
// ------------- ReverseBytes -------------
195+
@Test
196+
public short[] reverseBytesWithShort() {
197+
short[] res = new short[SIZE];
198+
for (int i = 0; i < SIZE; i++) {
199+
res[i] = Short.reverseBytes(a[i]);
200+
}
201+
return res;
202+
}
203+
204+
@Test
205+
public int[] reverseBytesWithInt() {
206+
int[] res = new int[SIZE];
207+
for (int i = 0; i < SIZE; i++) {
208+
res[i] = Short.reverseBytes((short) idx[i]);
209+
}
210+
return res;
211+
}
190212
}
191213

0 commit comments

Comments
 (0)