Skip to content

Commit 96c396b

Browse files
author
Ningsheng Jian
committedNov 5, 2021
8276151: AArch64: Incorrect result for double to int vector conversion
Reviewed-by: aph, psandoz
1 parent 7281861 commit 96c396b

File tree

4 files changed

+172
-32
lines changed

4 files changed

+172
-32
lines changed
 

‎src/hotspot/cpu/aarch64/aarch64_neon.ad

+15-6
Original file line numberDiff line numberDiff line change
@@ -506,12 +506,21 @@ instruct vcvt2Dto2I(vecD dst, vecX src)
506506
%{
507507
predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_INT);
508508
match(Set dst (VectorCastD2X src));
509-
format %{ "fcvtzs $dst, T2D, $src\n\t"
510-
"xtn $dst, T2S, $dst, T2D\t# convert 2D to 2I vector"
511-
%}
512-
ins_encode %{
513-
__ fcvtzs(as_FloatRegister($dst$$reg), __ T2D, as_FloatRegister($src$$reg));
514-
__ xtn(as_FloatRegister($dst$$reg), __ T2S, as_FloatRegister($dst$$reg), __ T2D);
509+
effect(TEMP_DEF dst);
510+
format %{ "ins $dst, D, $src, 0, 1\n\t"
511+
"fcvtzdw rscratch1, $src\n\t"
512+
"fcvtzdw rscratch2, $dst\n\t"
513+
"fmovs $dst, rscratch1\n\t"
514+
"mov $dst, T2S, 1, rscratch2\t#convert 2D to 2I vector"
515+
%}
516+
ins_encode %{
517+
__ ins(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), 0, 1);
518+
// We can't use fcvtzs(vector, integer) instruction here because we need
519+
// saturation arithmetic. See JDK-8276151.
520+
__ fcvtzdw(rscratch1, as_FloatRegister($src$$reg));
521+
__ fcvtzdw(rscratch2, as_FloatRegister($dst$$reg));
522+
__ fmovs(as_FloatRegister($dst$$reg), rscratch1);
523+
__ mov(as_FloatRegister($dst$$reg), __ T2S, 1, rscratch2);
515524
%}
516525
ins_pipe(pipe_slow);
517526
%}

‎src/hotspot/cpu/aarch64/aarch64_neon_ad.m4

+32-14
Original file line numberDiff line numberDiff line change
@@ -272,25 +272,43 @@ dnl $1 $2 $3 $4 $5
272272
VECTOR_CAST_F2I(2, F, I, D, 2S)
273273
VECTOR_CAST_F2I(4, F, I, X, 4S)
274274
VECTOR_CAST_F2I(2, D, L, X, 2D)
275-
dnl
276-
define(`VECTOR_CAST_F2I_L', `
277-
instruct vcvt$1$2to$1$3`'(vec$4 dst, vec$5 src)
275+
276+
instruct vcvt4Fto4S(vecD dst, vecX src)
278277
%{
279-
predicate(n->as_Vector()->length() == $1 && n->bottom_type()->is_vect()->element_basic_type() == T_`'TYPE2DATATYPE($3));
280-
match(Set dst (VectorCast$2`'2X src));
281-
format %{ "fcvtzs $dst, T$6, $src\n\t"
282-
"xtn $dst, T$7, $dst, T$6\t# convert $1$2 to $1$3 vector"
278+
predicate(n->as_Vector()->length() == 4 && n->bottom_type()->is_vect()->element_basic_type() == T_SHORT);
279+
match(Set dst (VectorCastF2X src));
280+
format %{ "fcvtzs $dst, T4S, $src\n\t"
281+
"xtn $dst, T4H, $dst, T4S\t# convert 4F to 4S vector"
283282
%}
284283
ins_encode %{
285-
__ fcvtzs(as_FloatRegister($dst$$reg), __ T$6, as_FloatRegister($src$$reg));
286-
__ xtn(as_FloatRegister($dst$$reg), __ T$7, as_FloatRegister($dst$$reg), __ T$6);
284+
__ fcvtzs(as_FloatRegister($dst$$reg), __ T4S, as_FloatRegister($src$$reg));
285+
__ xtn(as_FloatRegister($dst$$reg), __ T4H, as_FloatRegister($dst$$reg), __ T4S);
287286
%}
288287
ins_pipe(pipe_slow);
289-
%}')dnl
290-
dnl $1 $2 $3 $4 $5 $6 $7
291-
VECTOR_CAST_F2I_L(4, F, S, D, X, 4S, 4H)
292-
VECTOR_CAST_F2I_L(2, D, I, D, X, 2D, 2S)
293-
dnl
288+
%}
289+
290+
instruct vcvt2Dto2I(vecD dst, vecX src)
291+
%{
292+
predicate(n->as_Vector()->length() == 2 && n->bottom_type()->is_vect()->element_basic_type() == T_INT);
293+
match(Set dst (VectorCastD2X src));
294+
effect(TEMP_DEF dst);
295+
format %{ "ins $dst, D, $src, 0, 1\n\t"
296+
"fcvtzdw rscratch1, $src\n\t"
297+
"fcvtzdw rscratch2, $dst\n\t"
298+
"fmovs $dst, rscratch1\n\t"
299+
"mov $dst, T2S, 1, rscratch2\t#convert 2D to 2I vector"
300+
%}
301+
ins_encode %{
302+
__ ins(as_FloatRegister($dst$$reg), __ D, as_FloatRegister($src$$reg), 0, 1);
303+
// We can't use fcvtzs(vector, integer) instruction here because we need
304+
// saturation arithmetic. See JDK-8276151.
305+
__ fcvtzdw(rscratch1, as_FloatRegister($src$$reg));
306+
__ fcvtzdw(rscratch2, as_FloatRegister($dst$$reg));
307+
__ fmovs(as_FloatRegister($dst$$reg), rscratch1);
308+
__ mov(as_FloatRegister($dst$$reg), __ T2S, 1, rscratch2);
309+
%}
310+
ins_pipe(pipe_slow);
311+
%}
294312

295313
instruct vcvt4Fto4B(vecD dst, vecX src)
296314
%{

‎test/hotspot/jtreg/compiler/vectorapi/VectorCastShape128Test.java

+63-6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
package compiler.vectorapi;
2525

2626
import java.util.Random;
27+
import jdk.test.lib.Utils;
2728

2829
import jdk.incubator.vector.ByteVector;
2930
import jdk.incubator.vector.DoubleVector;
@@ -39,9 +40,11 @@
3940
/**
4041
* @test
4142
* @bug 8268966
43+
* @key randomness
4244
* @summary AArch64: 'bad AD file' in some vector conversion tests
45+
* @library /test/lib
4346
* @modules jdk.incubator.vector
44-
* @run testng/othervm -XX:-TieredCompilation compiler.vectorapi.VectorCastShape128Test
47+
* @run testng/othervm -XX:-TieredCompilation -XX:CompileThreshold=100 compiler.vectorapi.VectorCastShape128Test
4548
*/
4649

4750

@@ -54,8 +57,8 @@ public class VectorCastShape128Test {
5457
private static final VectorSpecies<Float> fspec = FloatVector.SPECIES_128;
5558
private static final VectorSpecies<Double> dspec = DoubleVector.SPECIES_128;
5659

57-
private static final int NUM_ITER = 50000;
58-
private static final int LENGTH = 512;
60+
private static final int NUM_ITER = 10000;
61+
private static final int LENGTH = 1024;
5962
private static int[] ia;
6063
private static int[] ib;
6164
private static byte[] ba;
@@ -69,6 +72,51 @@ public class VectorCastShape128Test {
6972
private static float[] fa;
7073
private static float[] fb;
7174

75+
public static float [] fspecial = {
76+
0.0f,
77+
-0.0f,
78+
Float.MAX_VALUE,
79+
Float.MIN_VALUE,
80+
-Float.MAX_VALUE,
81+
-Float.MIN_VALUE,
82+
Float.NaN,
83+
Float.POSITIVE_INFINITY,
84+
Float.NEGATIVE_INFINITY,
85+
Integer.MAX_VALUE,
86+
Integer.MIN_VALUE,
87+
Long.MAX_VALUE,
88+
Long.MIN_VALUE,
89+
};
90+
91+
public static double [] dspecial = {
92+
0.0,
93+
-0.0,
94+
Double.MAX_VALUE,
95+
Double.MIN_VALUE,
96+
-Double.MAX_VALUE,
97+
-Double.MIN_VALUE,
98+
Double.NaN,
99+
Double.POSITIVE_INFINITY,
100+
Double.NEGATIVE_INFINITY,
101+
Integer.MAX_VALUE,
102+
Integer.MIN_VALUE,
103+
Long.MIN_VALUE,
104+
Long.MAX_VALUE,
105+
};
106+
107+
public static int [] ispecial = {
108+
0,
109+
Integer.MAX_VALUE,
110+
Integer.MIN_VALUE,
111+
};
112+
113+
public static long [] lspecial = {
114+
0,
115+
Long.MAX_VALUE,
116+
Long.MIN_VALUE,
117+
};
118+
119+
72120
private static void initialize() {
73121
ia = new int[LENGTH];
74122
ib = new int[LENGTH];
@@ -82,14 +130,23 @@ private static void initialize() {
82130
fb = new float[LENGTH];
83131
da = new double[LENGTH];
84132
db = new double[LENGTH];
85-
Random r = new Random();
133+
Random r = Utils.getRandomInstance();
86134
for (int i = 0; i < LENGTH; i++) {
87135
ia[i] = r.nextInt();
88136
la[i] = r.nextLong();
89137
sa[i] = (short) r.nextInt();
90138
ba[i] = (byte) r.nextInt();
91-
fa[i] = r.nextFloat();
92-
da[i] = r.nextDouble();
139+
fa[i] = ia[i] + r.nextFloat();
140+
da[i] = la[i] + r.nextDouble();
141+
}
142+
143+
// Replicate to make sure the values get tested, as some elements may be
144+
// ignored for some vector conversions.
145+
for (int i = 0; i < 4; i++) {
146+
System.arraycopy(ispecial, 0, ia, ispecial.length * i, ispecial.length);
147+
System.arraycopy(lspecial, 0, la, lspecial.length * i, lspecial.length);
148+
System.arraycopy(fspecial, 0, fa, fspecial.length * i, fspecial.length);
149+
System.arraycopy(dspecial, 0, da, dspecial.length * i, dspecial.length);
93150
}
94151
}
95152

‎test/hotspot/jtreg/compiler/vectorapi/VectorCastShape64Test.java

+62-6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
package compiler.vectorapi;
2525

2626
import java.util.Random;
27+
import jdk.test.lib.Utils;
2728

2829
import jdk.incubator.vector.ByteVector;
2930
import jdk.incubator.vector.DoubleVector;
@@ -39,9 +40,11 @@
3940
/**
4041
* @test
4142
* @bug 8268966
43+
* @key randomness
4244
* @summary AArch64: 'bad AD file' in some vector conversion tests
45+
* @library /test/lib
4346
* @modules jdk.incubator.vector
44-
* @run testng/othervm -XX:-TieredCompilation compiler.vectorapi.VectorCastShape64Test
47+
* @run testng/othervm -XX:-TieredCompilation -XX:CompileThreshold=100 compiler.vectorapi.VectorCastShape64Test
4548
*/
4649

4750

@@ -54,8 +57,8 @@ public class VectorCastShape64Test {
5457
private static final VectorSpecies<Float> fspec = FloatVector.SPECIES_64;
5558
private static final VectorSpecies<Double> dspec = DoubleVector.SPECIES_64;
5659

57-
private static final int NUM_ITER = 50000;
58-
private static final int LENGTH = 512;
60+
private static final int NUM_ITER = 10000;
61+
private static final int LENGTH = 1024;
5962
private static int[] ia;
6063
private static int[] ib;
6164
private static byte[] ba;
@@ -69,6 +72,50 @@ public class VectorCastShape64Test {
6972
private static float[] fa;
7073
private static float[] fb;
7174

75+
public static float [] fspecial = {
76+
0.0f,
77+
-0.0f,
78+
Float.MAX_VALUE,
79+
Float.MIN_VALUE,
80+
-Float.MAX_VALUE,
81+
-Float.MIN_VALUE,
82+
Float.NaN,
83+
Float.POSITIVE_INFINITY,
84+
Float.NEGATIVE_INFINITY,
85+
Integer.MAX_VALUE,
86+
Integer.MIN_VALUE,
87+
Long.MAX_VALUE,
88+
Long.MIN_VALUE,
89+
};
90+
91+
public static double [] dspecial = {
92+
0.0,
93+
-0.0,
94+
Double.MAX_VALUE,
95+
Double.MIN_VALUE,
96+
-Double.MAX_VALUE,
97+
-Double.MIN_VALUE,
98+
Double.NaN,
99+
Double.POSITIVE_INFINITY,
100+
Double.NEGATIVE_INFINITY,
101+
Integer.MAX_VALUE,
102+
Integer.MIN_VALUE,
103+
Long.MIN_VALUE,
104+
Long.MAX_VALUE,
105+
};
106+
107+
public static int [] ispecial = {
108+
0,
109+
Integer.MAX_VALUE,
110+
Integer.MIN_VALUE,
111+
};
112+
113+
public static long [] lspecial = {
114+
0,
115+
Long.MAX_VALUE,
116+
Long.MIN_VALUE,
117+
};
118+
72119
private static void initialize() {
73120
ia = new int[LENGTH];
74121
ib = new int[LENGTH];
@@ -82,14 +129,23 @@ private static void initialize() {
82129
fb = new float[LENGTH];
83130
da = new double[LENGTH];
84131
db = new double[LENGTH];
85-
Random r = new Random();
132+
Random r = Utils.getRandomInstance();
86133
for (int i = 0; i < LENGTH; i++) {
87134
ia[i] = r.nextInt();
88135
la[i] = r.nextLong();
89136
sa[i] = (short) r.nextInt();
90137
ba[i] = (byte) r.nextInt();
91-
fa[i] = r.nextFloat();
92-
da[i] = r.nextDouble();
138+
fa[i] = ia[i] + r.nextFloat();
139+
da[i] = la[i] + r.nextDouble();
140+
}
141+
142+
// Replicate to make sure the values get tested, as some elements may be
143+
// ignored for some vector conversions.
144+
for (int i = 0; i < 4; i++) {
145+
System.arraycopy(ispecial, 0, ia, ispecial.length * i, ispecial.length);
146+
System.arraycopy(lspecial, 0, la, lspecial.length * i, lspecial.length);
147+
System.arraycopy(fspecial, 0, fa, fspecial.length * i, fspecial.length);
148+
System.arraycopy(dspecial, 0, da, dspecial.length * i, dspecial.length);
93149
}
94150
}
95151

0 commit comments

Comments
 (0)
Please sign in to comment.