8286279: [vectorapi] Only check index of masked lanes if offset is out of array boundary for masked store

Reviewed-by: psandoz
This commit is contained in:
Xiaohong Gong 2022-06-07 01:16:52 +00:00
parent 645be42f76
commit ef7cc2105c
9 changed files with 216 additions and 37 deletions

View File

@ -3008,7 +3008,7 @@ public abstract class ByteVector extends AbstractVector<Byte> {
byte[] a, int offset,
VectorMask<Byte> m) {
ByteSpecies vsp = (ByteSpecies) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromArray0(a, offset, m);
}
@ -3164,7 +3164,7 @@ public abstract class ByteVector extends AbstractVector<Byte> {
boolean[] a, int offset,
VectorMask<Byte> m) {
ByteSpecies vsp = (ByteSpecies) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
ByteVector zero = vsp.zero();
return vsp.dummyVector().fromBooleanArray0(a, offset, m);
}
@ -3352,7 +3352,7 @@ public abstract class ByteVector extends AbstractVector<Byte> {
ByteOrder bo,
VectorMask<Byte> m) {
ByteSpecies vsp = (ByteSpecies) species;
if (offset >= 0 && offset <= (ms.byteSize() - species.vectorByteSize())) {
if (VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
return vsp.dummyVector().fromMemorySegment0(ms, offset, m).maybeSwap(bo);
}
@ -3424,7 +3424,9 @@ public abstract class ByteVector extends AbstractVector<Byte> {
intoArray(a, offset);
} else {
ByteSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoArray0(a, offset, m);
}
}
@ -3579,7 +3581,9 @@ public abstract class ByteVector extends AbstractVector<Byte> {
intoBooleanArray(a, offset);
} else {
ByteSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoBooleanArray0(a, offset, m);
}
}
@ -3709,7 +3713,9 @@ public abstract class ByteVector extends AbstractVector<Byte> {
throw new UnsupportedOperationException("Attempt to write a read-only segment");
}
ByteSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, ms.byteSize());
if (!VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
checkMaskFromIndexSize(offset, vsp, m, 1, ms.byteSize());
}
maybeSwap(bo).intoMemorySegment0(ms, offset, m);
}
}

View File

@ -2805,7 +2805,7 @@ public abstract class DoubleVector extends AbstractVector<Double> {
double[] a, int offset,
VectorMask<Double> m) {
DoubleSpecies vsp = (DoubleSpecies) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromArray0(a, offset, m);
}
@ -3038,7 +3038,7 @@ public abstract class DoubleVector extends AbstractVector<Double> {
ByteOrder bo,
VectorMask<Double> m) {
DoubleSpecies vsp = (DoubleSpecies) species;
if (offset >= 0 && offset <= (ms.byteSize() - species.vectorByteSize())) {
if (VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
return vsp.dummyVector().fromMemorySegment0(ms, offset, m).maybeSwap(bo);
}
@ -3110,7 +3110,9 @@ public abstract class DoubleVector extends AbstractVector<Double> {
intoArray(a, offset);
} else {
DoubleSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoArray0(a, offset, m);
}
}
@ -3266,7 +3268,9 @@ public abstract class DoubleVector extends AbstractVector<Double> {
throw new UnsupportedOperationException("Attempt to write a read-only segment");
}
DoubleSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 8, ms.byteSize());
if (!VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
checkMaskFromIndexSize(offset, vsp, m, 8, ms.byteSize());
}
maybeSwap(bo).intoMemorySegment0(ms, offset, m);
}
}

View File

@ -2829,7 +2829,7 @@ public abstract class FloatVector extends AbstractVector<Float> {
float[] a, int offset,
VectorMask<Float> m) {
FloatSpecies vsp = (FloatSpecies) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromArray0(a, offset, m);
}
@ -3044,7 +3044,7 @@ public abstract class FloatVector extends AbstractVector<Float> {
ByteOrder bo,
VectorMask<Float> m) {
FloatSpecies vsp = (FloatSpecies) species;
if (offset >= 0 && offset <= (ms.byteSize() - species.vectorByteSize())) {
if (VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
return vsp.dummyVector().fromMemorySegment0(ms, offset, m).maybeSwap(bo);
}
@ -3116,7 +3116,9 @@ public abstract class FloatVector extends AbstractVector<Float> {
intoArray(a, offset);
} else {
FloatSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoArray0(a, offset, m);
}
}
@ -3253,7 +3255,9 @@ public abstract class FloatVector extends AbstractVector<Float> {
throw new UnsupportedOperationException("Attempt to write a read-only segment");
}
FloatSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 4, ms.byteSize());
if (!VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
checkMaskFromIndexSize(offset, vsp, m, 4, ms.byteSize());
}
maybeSwap(bo).intoMemorySegment0(ms, offset, m);
}
}

View File

@ -2986,7 +2986,7 @@ public abstract class IntVector extends AbstractVector<Integer> {
int[] a, int offset,
VectorMask<Integer> m) {
IntSpecies vsp = (IntSpecies) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromArray0(a, offset, m);
}
@ -3201,7 +3201,7 @@ public abstract class IntVector extends AbstractVector<Integer> {
ByteOrder bo,
VectorMask<Integer> m) {
IntSpecies vsp = (IntSpecies) species;
if (offset >= 0 && offset <= (ms.byteSize() - species.vectorByteSize())) {
if (VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
return vsp.dummyVector().fromMemorySegment0(ms, offset, m).maybeSwap(bo);
}
@ -3273,7 +3273,9 @@ public abstract class IntVector extends AbstractVector<Integer> {
intoArray(a, offset);
} else {
IntSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoArray0(a, offset, m);
}
}
@ -3410,7 +3412,9 @@ public abstract class IntVector extends AbstractVector<Integer> {
throw new UnsupportedOperationException("Attempt to write a read-only segment");
}
IntSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 4, ms.byteSize());
if (!VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
checkMaskFromIndexSize(offset, vsp, m, 4, ms.byteSize());
}
maybeSwap(bo).intoMemorySegment0(ms, offset, m);
}
}

View File

@ -2847,7 +2847,7 @@ public abstract class LongVector extends AbstractVector<Long> {
long[] a, int offset,
VectorMask<Long> m) {
LongSpecies vsp = (LongSpecies) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromArray0(a, offset, m);
}
@ -3080,7 +3080,7 @@ public abstract class LongVector extends AbstractVector<Long> {
ByteOrder bo,
VectorMask<Long> m) {
LongSpecies vsp = (LongSpecies) species;
if (offset >= 0 && offset <= (ms.byteSize() - species.vectorByteSize())) {
if (VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
return vsp.dummyVector().fromMemorySegment0(ms, offset, m).maybeSwap(bo);
}
@ -3152,7 +3152,9 @@ public abstract class LongVector extends AbstractVector<Long> {
intoArray(a, offset);
} else {
LongSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoArray0(a, offset, m);
}
}
@ -3308,7 +3310,9 @@ public abstract class LongVector extends AbstractVector<Long> {
throw new UnsupportedOperationException("Attempt to write a read-only segment");
}
LongSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 8, ms.byteSize());
if (!VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
checkMaskFromIndexSize(offset, vsp, m, 8, ms.byteSize());
}
maybeSwap(bo).intoMemorySegment0(ms, offset, m);
}
}

View File

@ -3009,7 +3009,7 @@ public abstract class ShortVector extends AbstractVector<Short> {
short[] a, int offset,
VectorMask<Short> m) {
ShortSpecies vsp = (ShortSpecies) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromArray0(a, offset, m);
}
@ -3158,7 +3158,7 @@ public abstract class ShortVector extends AbstractVector<Short> {
char[] a, int offset,
VectorMask<Short> m) {
ShortSpecies vsp = (ShortSpecies) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromCharArray0(a, offset, m);
}
@ -3351,7 +3351,7 @@ public abstract class ShortVector extends AbstractVector<Short> {
ByteOrder bo,
VectorMask<Short> m) {
ShortSpecies vsp = (ShortSpecies) species;
if (offset >= 0 && offset <= (ms.byteSize() - species.vectorByteSize())) {
if (VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
return vsp.dummyVector().fromMemorySegment0(ms, offset, m).maybeSwap(bo);
}
@ -3423,7 +3423,9 @@ public abstract class ShortVector extends AbstractVector<Short> {
intoArray(a, offset);
} else {
ShortSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoArray0(a, offset, m);
}
}
@ -3570,7 +3572,9 @@ public abstract class ShortVector extends AbstractVector<Short> {
intoCharArray(a, offset);
} else {
ShortSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoCharArray0(a, offset, m);
}
}
@ -3695,7 +3699,9 @@ public abstract class ShortVector extends AbstractVector<Short> {
throw new UnsupportedOperationException("Attempt to write a read-only segment");
}
ShortSpecies vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 2, ms.byteSize());
if (!VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
checkMaskFromIndexSize(offset, vsp, m, 2, ms.byteSize());
}
maybeSwap(bo).intoMemorySegment0(ms, offset, m);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022, 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
@ -44,6 +44,11 @@ import java.util.Objects;
return new IllegalArgumentException(msg);
}
@ForceInline
static boolean indexInRange(long ix, long vlen, long length) {
return ix >= 0 && ix <= (length - vlen);
}
@ForceInline
static int checkFromIndexSize(int ix, int vlen, int length) {
switch (VectorIntrinsics.VECTOR_ACCESS_OOB_CHECK) {

View File

@ -3583,7 +3583,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
$type$[] a, int offset,
VectorMask<$Boxtype$> m) {
$Type$Species vsp = ($Type$Species) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromArray0(a, offset, m);
}
@ -3804,7 +3804,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
char[] a, int offset,
VectorMask<$Boxtype$> m) {
$Type$Species vsp = ($Type$Species) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
return vsp.dummyVector().fromCharArray0(a, offset, m);
}
@ -3963,7 +3963,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
boolean[] a, int offset,
VectorMask<$Boxtype$> m) {
$Type$Species vsp = ($Type$Species) species;
if (offset >= 0 && offset <= (a.length - species.length())) {
if (VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
$abstractvectortype$ zero = vsp.zero();
return vsp.dummyVector().fromBooleanArray0(a, offset, m);
}
@ -4161,7 +4161,7 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
ByteOrder bo,
VectorMask<$Boxtype$> m) {
$Type$Species vsp = ($Type$Species) species;
if (offset >= 0 && offset <= (ms.byteSize() - species.vectorByteSize())) {
if (VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
return vsp.dummyVector().fromMemorySegment0(ms, offset, m).maybeSwap(bo);
}
@ -4233,7 +4233,9 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
intoArray(a, offset);
} else {
$Type$Species vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoArray0(a, offset, m);
}
}
@ -4451,7 +4453,9 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
intoCharArray(a, offset);
} else {
$Type$Species vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoCharArray0(a, offset, m);
}
}
@ -4613,7 +4617,9 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
intoBooleanArray(a, offset);
} else {
$Type$Species vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
if (!VectorIntrinsics.indexInRange(offset, vsp.length(), a.length)) {
checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
}
intoBooleanArray0(a, offset, m);
}
}
@ -4744,7 +4750,9 @@ public abstract class $abstractvectortype$ extends AbstractVector<$Boxtype$> {
throw new UnsupportedOperationException("Attempt to write a read-only segment");
}
$Type$Species vsp = vspecies();
checkMaskFromIndexSize(offset, vsp, m, $sizeInBytes$, ms.byteSize());
if (!VectorIntrinsics.indexInRange(offset, vsp.vectorByteSize(), ms.byteSize())) {
checkMaskFromIndexSize(offset, vsp, m, $sizeInBytes$, ms.byteSize());
}
maybeSwap(bo).intoMemorySegment0(ms, offset, m);
}
}

View File

@ -0,0 +1,138 @@
//
// Copyright (c) 2022, Arm Limited. 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 org.openjdk.bench.jdk.incubator.vector;
import java.util.concurrent.TimeUnit;
import jdk.incubator.vector.*;
import org.openjdk.jmh.annotations.*;
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 5, time = 1)
@Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
public class StoreMaskedBenchmark {
@Param({"1024"})
private int size;
private byte[] byteIn;
private byte[] byteOut;
private short[] shortIn;
private short[] shortOut;
private int[] intIn;
private int[] intOut;
private long[] longIn;
private long[] longOut;
private float[] floatIn;
private float[] floatOut;
private double[] doubleIn;
private double[] doubleOut;
private boolean[] m;
private static final VectorSpecies<Byte> bspecies = VectorSpecies.ofLargestShape(byte.class);
private static final VectorSpecies<Short> sspecies = VectorSpecies.ofLargestShape(short.class);
private static final VectorSpecies<Integer> ispecies = VectorSpecies.ofLargestShape(int.class);
private static final VectorSpecies<Long> lspecies = VectorSpecies.ofLargestShape(long.class);
private static final VectorSpecies<Float> fspecies = VectorSpecies.ofLargestShape(float.class);
private static final VectorSpecies<Double> dspecies = VectorSpecies.ofLargestShape(double.class);
@Setup(Level.Trial)
public void Setup() {
byteIn = new byte[size];
byteOut = new byte[size];
shortIn = new short[size];
shortOut = new short[size];
intIn = new int[size];
intOut = new int[size];
longIn = new long[size];
longOut = new long[size];
floatIn = new float[size];
floatOut = new float[size];
doubleIn = new double[size];
doubleOut = new double[size];
m = new boolean[size];
for (int i = 0; i < size; i++) {
byteIn[i] = (byte) i;
shortIn[i] = (short) i;
intIn[i] = i;
longIn[i] = i;
floatIn[i] = (float) i;
doubleIn[i] = (double) i;
}
for (int i = 0; i < size; i++) {
m[i] = i % 2 == 0;
}
}
@Benchmark
public void byteStoreArrayMask() {
for (int i = 0; i < size; i += bspecies.length()) {
VectorMask<Byte> mask = VectorMask.fromArray(bspecies, m, i);
ByteVector.fromArray(bspecies, byteIn, i).intoArray(byteOut, i, mask);
}
}
@Benchmark
public void shortStoreArrayMask() {
for (int i = 0; i < size; i += sspecies.length()) {
VectorMask<Short> mask = VectorMask.fromArray(sspecies, m, i);
ShortVector.fromArray(sspecies, shortIn, i).intoArray(shortOut, i, mask);
}
}
@Benchmark
public void intStoreArrayMask() {
for (int i = 0; i < size; i += ispecies.length()) {
VectorMask<Integer> mask = VectorMask.fromArray(ispecies, m, i);
IntVector.fromArray(ispecies, intIn, i).intoArray(intOut, i, mask);
}
}
@Benchmark
public void longStoreArrayMask() {
for (int i = 0; i < size; i += lspecies.length()) {
VectorMask<Long> mask = VectorMask.fromArray(lspecies, m, i);
LongVector.fromArray(lspecies, longIn, i).intoArray(longOut, i, mask);
}
}
@Benchmark
public void floatStoreArrayMask() {
for (int i = 0; i < size; i += fspecies.length()) {
VectorMask<Float> mask = VectorMask.fromArray(fspecies, m, i);
FloatVector.fromArray(fspecies, floatIn, i).intoArray(floatOut, i, mask);
}
}
@Benchmark
public void doubleStoreArrayMask() {
for (int i = 0; i < size; i += dspecies.length()) {
VectorMask<Double> mask = VectorMask.fromArray(dspecies, m, i);
DoubleVector.fromArray(dspecies, doubleIn, i).intoArray(doubleOut, i, mask);
}
}
}