8311130: AArch64: Sync SVE related CPU features with VM options

Reviewed-by: aph, xgong
This commit is contained in:
Pengfei Li 2023-07-20 09:35:45 +00:00
parent a7427678e1
commit 32833285bf
10 changed files with 156 additions and 51 deletions

View File

@ -2302,7 +2302,7 @@ bool Matcher::match_rule_supported(int opcode) {
break;
case Op_ExpandBits:
case Op_CompressBits:
if (!(UseSVE > 1 && VM_Version::supports_svebitperm())) {
if (!VM_Version::supports_svebitperm()) {
ret_value = false;
}
break;

View File

@ -216,13 +216,13 @@ source %{
}
break;
case Op_VectorLongToMask:
if (UseSVE < 2 || vlen > 64 || !VM_Version::supports_svebitperm()) {
if (vlen > 64 || !VM_Version::supports_svebitperm()) {
return false;
}
break;
case Op_CompressBitsV:
case Op_ExpandBitsV:
if (UseSVE < 2 || !VM_Version::supports_svebitperm()) {
if (!VM_Version::supports_svebitperm()) {
return false;
}
break;

View File

@ -206,13 +206,13 @@ source %{
}
break;
case Op_VectorLongToMask:
if (UseSVE < 2 || vlen > 64 || !VM_Version::supports_svebitperm()) {
if (vlen > 64 || !VM_Version::supports_svebitperm()) {
return false;
}
break;
case Op_CompressBitsV:
case Op_ExpandBitsV:
if (UseSVE < 2 || !VM_Version::supports_svebitperm()) {
if (!VM_Version::supports_svebitperm()) {
return false;
}
break;

View File

@ -100,7 +100,7 @@ void VM_Version::initialize() {
PrefetchCopyIntervalInBytes = 32760;
}
if (AllocatePrefetchDistance !=-1 && (AllocatePrefetchDistance & 7)) {
if (AllocatePrefetchDistance != -1 && (AllocatePrefetchDistance & 7)) {
warning("AllocatePrefetchDistance must be multiple of 8");
AllocatePrefetchDistance &= ~7;
}
@ -187,7 +187,7 @@ void VM_Version::initialize() {
}
// Cortex A53
if (_cpu == CPU_ARM && (_model == 0xd03 || _model2 == 0xd03)) {
if (_cpu == CPU_ARM && model_is(0xd03)) {
_features |= CPU_A53MAC;
if (FLAG_IS_DEFAULT(UseSIMDForArrayEquals)) {
FLAG_SET_DEFAULT(UseSIMDForArrayEquals, false);
@ -195,7 +195,7 @@ void VM_Version::initialize() {
}
// Cortex A73
if (_cpu == CPU_ARM && (_model == 0xd09 || _model2 == 0xd09)) {
if (_cpu == CPU_ARM && model_is(0xd09)) {
if (FLAG_IS_DEFAULT(SoftwarePrefetchHintDistance)) {
FLAG_SET_DEFAULT(SoftwarePrefetchHintDistance, -1);
}
@ -206,9 +206,7 @@ void VM_Version::initialize() {
}
// Neoverse N1, N2 and V1
if (_cpu == CPU_ARM && ((_model == 0xd0c || _model2 == 0xd0c)
|| (_model == 0xd49 || _model2 == 0xd49)
|| (_model == 0xd40 || _model2 == 0xd40))) {
if (_cpu == CPU_ARM && (model_is(0xd0c) || model_is(0xd49) || model_is(0xd40))) {
if (FLAG_IS_DEFAULT(UseSIMDForMemoryOps)) {
FLAG_SET_DEFAULT(UseSIMDForMemoryOps, true);
}
@ -228,15 +226,6 @@ void VM_Version::initialize() {
}
}
char buf[512];
int buf_used_len = os::snprintf_checked(buf, sizeof(buf), "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
if (_model2) os::snprintf_checked(buf + buf_used_len, sizeof(buf) - buf_used_len, "(0x%03x)", _model2);
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) if (VM_Version::supports_##name()) strcat(buf, ", " #name);
CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
#undef ADD_FEATURE_IF_SUPPORTED
_features_string = os::strdup(buf);
if (FLAG_IS_DEFAULT(UseCRC32)) {
UseCRC32 = VM_Version::supports_crc32();
}
@ -247,7 +236,7 @@ void VM_Version::initialize() {
}
// Neoverse V1
if (_cpu == CPU_ARM && (_model == 0xd40 || _model2 == 0xd40)) {
if (_cpu == CPU_ARM && model_is(0xd40)) {
if (FLAG_IS_DEFAULT(UseCryptoPmullForCRC32)) {
FLAG_SET_DEFAULT(UseCryptoPmullForCRC32, true);
}
@ -390,14 +379,14 @@ void VM_Version::initialize() {
}
if (_features & CPU_ASIMD) {
if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
UseChaCha20Intrinsics = true;
}
if (FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
UseChaCha20Intrinsics = true;
}
} else if (UseChaCha20Intrinsics) {
if (!FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
warning("ChaCha20 intrinsic requires ASIMD instructions");
}
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
if (!FLAG_IS_DEFAULT(UseChaCha20Intrinsics)) {
warning("ChaCha20 intrinsic requires ASIMD instructions");
}
FLAG_SET_DEFAULT(UseChaCha20Intrinsics, false);
}
if (FLAG_IS_DEFAULT(UseBASE64Intrinsics)) {
@ -574,6 +563,30 @@ void VM_Version::initialize() {
_spin_wait = get_spin_wait_desc();
check_virtualizations();
// Sync SVE related CPU features with flags
if (UseSVE < 2) {
_features &= ~CPU_SVE2;
_features &= ~CPU_SVEBITPERM;
}
if (UseSVE < 1) {
_features &= ~CPU_SVE;
}
// Construct the "features" string
char buf[512];
int buf_used_len = os::snprintf_checked(buf, sizeof(buf), "0x%02x:0x%x:0x%03x:%d", _cpu, _variant, _model, _revision);
if (_model2) {
os::snprintf_checked(buf + buf_used_len, sizeof(buf) - buf_used_len, "(0x%03x)", _model2);
}
#define ADD_FEATURE_IF_SUPPORTED(id, name, bit) \
do { \
if (VM_Version::supports_##name()) strcat(buf, ", " #name); \
} while(0);
CPU_FEATURE_FLAGS(ADD_FEATURE_IF_SUPPORTED)
#undef ADD_FEATURE_IF_SUPPORTED
_features_string = os::strdup(buf);
}
#if defined(LINUX)

View File

@ -151,6 +151,10 @@ enum Ampere_CPU_Model {
static int cpu_variant() { return _variant; }
static int cpu_revision() { return _revision; }
static bool model_is(int cpu_model) {
return _model == cpu_model || _model2 == cpu_model;
}
static bool is_zva_enabled() { return 0 <= _zva_length; }
static int zva_length() {
assert(is_zva_enabled(), "ZVA not available");

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2023, 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.
*/
/*
* @test
* @bug 8311130
* @summary Test synchronization between SVE arguments and CPU features
*
* @requires os.arch == "aarch64" & vm.compiler2.enabled
* @library /test/lib /
* @build jdk.test.whitebox.WhiteBox
* @run driver jdk.test.lib.helpers.ClassFileInstaller
* jdk.test.whitebox.WhiteBox
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI -XX:UseSVE=0
* compiler.arguments.TestSyncCPUFeaturesWithSVEFlags
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI -XX:UseSVE=1
* compiler.arguments.TestSyncCPUFeaturesWithSVEFlags
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI -XX:UseSVE=2
* compiler.arguments.TestSyncCPUFeaturesWithSVEFlags
*
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI -XX:MaxVectorSize=8
* compiler.arguments.TestSyncCPUFeaturesWithSVEFlags
*/
package compiler.arguments;
import java.util.List;
import java.util.Arrays;
import jdk.test.lib.Asserts;
import jdk.test.whitebox.WhiteBox;
public class TestSyncCPUFeaturesWithSVEFlags {
private static final WhiteBox WB = WhiteBox.getWhiteBox();
public static void main(String[] args) {
int sve_level = WB.getUintVMFlag("UseSVE").intValue();
List<String> features = Arrays.asList(WB.getCPUFeatures().split(", "));
boolean has_sve = features.contains("sve");
boolean has_sve2 = features.contains("sve2");
switch (sve_level) {
case 0: {
// No sve and sve2
Asserts.assertFalse(has_sve);
Asserts.assertFalse(has_sve2);
break;
}
case 1: {
// Only has sve, no sve2
Asserts.assertTrue(has_sve);
Asserts.assertFalse(has_sve2);
break;
}
case 2: {
// Has both sve and sve2
Asserts.assertTrue(has_sve);
Asserts.assertTrue(has_sve2);
break;
}
default: {
// Should not reach here
Asserts.assertTrue(false);
break;
}
}
}
}

View File

@ -30,8 +30,7 @@
* @requires (((os.arch=="x86" | os.arch=="amd64" | os.arch=="x86_64") &
* (vm.cpu.features ~= ".*bmi2.*" & vm.cpu.features ~= ".*bmi1.*" &
* vm.cpu.features ~= ".*sse2.*")) |
* ((vm.opt.UseSVE == "null" | vm.opt.UseSVE > 1) &
* os.arch=="aarch64" & vm.cpu.features ~= ".*svebitperm.*"))
* (os.arch=="aarch64" & vm.cpu.features ~= ".*svebitperm.*"))
* @library /test/lib /
* @run driver compiler.intrinsics.TestBitShuffleOpers
*/

View File

@ -164,7 +164,7 @@ public class VectorLogicalOpIdentityTest {
@Test
@Warmup(10000)
@IR(counts = {IRNode.LOAD_VECTOR, ">=1"})
@IR(failOn = IRNode.AND_V, applyIfCPUFeature = {"asimd", "true"}, applyIf = {"UseSVE", "0"})
@IR(failOn = IRNode.AND_V, applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
public static void testMaskedAndMinusOne2() {
VectorMask<Byte> mask = VectorMask.fromArray(B_SPECIES, m, 0);
ByteVector av = ByteVector.fromArray(B_SPECIES, ba, 0);
@ -185,7 +185,7 @@ public class VectorLogicalOpIdentityTest {
@Test
@Warmup(10000)
@IR(counts = {IRNode.STORE_VECTOR, ">=1"})
@IR(failOn = IRNode.AND_V, applyIfCPUFeature = {"asimd", "true"}, applyIf = {"UseSVE", "0"})
@IR(failOn = IRNode.AND_V, applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
public static void testMaskedAndZero1() {
VectorMask<Short> mask = VectorMask.fromArray(S_SPECIES, m, 0);
ShortVector av = ShortVector.fromArray(S_SPECIES, sa, 0);
@ -302,8 +302,7 @@ public class VectorLogicalOpIdentityTest {
// Transform AndV(AndV(a, b, m), b, m) ==> AndV(a, b, m)
@Test
@Warmup(10000)
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeature = {"sve", "true"}, applyIf = {"UseSVE", "> 0"})
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeature = {"avx512", "true"})
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeatureOr = {"sve", "true", "avx512", "true"})
public static void testAndMaskSameValue1() {
VectorMask<Integer> mask = VectorMask.fromArray(I_SPECIES, m, 0);
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
@ -324,8 +323,7 @@ public class VectorLogicalOpIdentityTest {
// Transform AndV(AndV(a, b, m), a, m) ==> AndV(a, b, m)
@Test
@Warmup(10000)
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeature = {"sve", "true"}, applyIf = {"UseSVE", "> 0"})
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeature = {"avx512", "true"})
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeatureOr = {"sve", "true", "avx512", "true"})
public static void testAndMaskSameValue2() {
VectorMask<Long> mask = VectorMask.fromArray(L_SPECIES, m, 0);
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
@ -346,8 +344,7 @@ public class VectorLogicalOpIdentityTest {
// Transform AndV(a, AndV(a, b, m), m) ==> AndV(a, b, m)
@Test
@Warmup(10000)
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeature = {"sve", "true"}, applyIf = {"UseSVE", "> 0"})
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeature = {"avx512", "true"})
@IR(counts = {IRNode.AND_V, "1"}, applyIfCPUFeatureOr = {"sve", "true", "avx512", "true"})
public static void testAndMaskSameValue3() {
VectorMask<Integer> mask = VectorMask.fromArray(I_SPECIES, m, 0);
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
@ -412,7 +409,7 @@ public class VectorLogicalOpIdentityTest {
@Test
@Warmup(10000)
@IR(counts = {IRNode.STORE_VECTOR, ">=1"})
@IR(failOn = IRNode.OR_V, applyIfCPUFeature = {"asimd", "true"}, applyIf = {"UseSVE", "0"})
@IR(failOn = IRNode.OR_V, applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
public static void testMaskedOrMinusOne1() {
VectorMask<Byte> mask = VectorMask.fromArray(B_SPECIES, m, 0);
ByteVector av = ByteVector.fromArray(B_SPECIES, ba, 0);
@ -471,7 +468,7 @@ public class VectorLogicalOpIdentityTest {
@Test
@Warmup(10000)
@IR(counts = {IRNode.LOAD_VECTOR, ">=1"})
@IR(failOn = IRNode.OR_V, applyIfCPUFeature = {"asimd", "true"}, applyIf = {"UseSVE", "0"})
@IR(failOn = IRNode.OR_V, applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
public static void testMaskedOrZero2() {
VectorMask<Byte> mask = VectorMask.fromArray(B_SPECIES, m, 0);
ByteVector av = ByteVector.fromArray(B_SPECIES, ba, 0);
@ -569,8 +566,7 @@ public class VectorLogicalOpIdentityTest {
// Transform OrV(OrV(a, b, m), b, m) ==> OrV(a, b, m)
@Test
@Warmup(10000)
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeature = {"sve", "true"}, applyIf = {"UseSVE", "> 0"})
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeature = {"avx512", "true"})
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeatureOr = {"sve", "true", "avx512", "true"})
public static void testOrMaskSameValue1() {
VectorMask<Integer> mask = VectorMask.fromArray(I_SPECIES, m, 0);
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
@ -591,8 +587,7 @@ public class VectorLogicalOpIdentityTest {
// Transform OrV(OrV(a, b, m), a, m) ==> OrV(a, b, m)
@Test
@Warmup(10000)
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeature = {"sve", "true"}, applyIf = {"UseSVE", "> 0"})
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeature = {"avx512", "true"})
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeatureOr = {"sve", "true", "avx512", "true"})
public static void testOrMaskSameValue2() {
VectorMask<Long> mask = VectorMask.fromArray(L_SPECIES, m, 0);
LongVector av = LongVector.fromArray(L_SPECIES, la, 0);
@ -613,8 +608,7 @@ public class VectorLogicalOpIdentityTest {
// Transform OrV(a, OrV(a, b, m), m) ==> OrV(a, b, m)
@Test
@Warmup(10000)
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeature = {"sve", "true"}, applyIf = {"UseSVE", "> 0"})
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeature = {"avx512", "true"})
@IR(counts = {IRNode.OR_V, "1"}, applyIfCPUFeatureOr = {"sve", "true", "avx512", "true"})
public static void testOrMaskSameValue3() {
VectorMask<Integer> mask = VectorMask.fromArray(I_SPECIES, m, 0);
IntVector av = IntVector.fromArray(I_SPECIES, ia, 0);
@ -653,7 +647,7 @@ public class VectorLogicalOpIdentityTest {
@Test
@Warmup(10000)
@IR(counts = {IRNode.STORE_VECTOR, ">=1"})
@IR(failOn = IRNode.XOR_V, applyIfCPUFeature = {"asimd", "true"}, applyIf = {"UseSVE", "0"})
@IR(failOn = IRNode.XOR_V, applyIfCPUFeatureAnd = {"asimd", "true", "sve", "false"})
public static void testMaskedXorSame() {
VectorMask<Short> mask = VectorMask.fromArray(S_SPECIES, m, 0);
ShortVector av = ShortVector.fromArray(S_SPECIES, sa, 0);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Arm Limited. All rights reserved.
* Copyright (c) 2022, 2023, 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
@ -27,7 +27,7 @@
* @summary Test vectorization of numberOfTrailingZeros/numberOfLeadingZeros for Long
* @requires vm.compiler2.enabled
* @requires (os.simpleArch == "x64" & vm.cpu.features ~= ".*avx2.*") |
* (os.simpleArch == "aarch64" & vm.cpu.features ~= ".*sve.*" & (vm.opt.UseSVE == "null" | vm.opt.UseSVE > 0))
* (os.simpleArch == "aarch64" & vm.cpu.features ~= ".*sve.*")
* @library /test/lib /
* @run driver compiler.vectorization.TestNumberOfContinuousZeros
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2023, 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
@ -27,7 +27,7 @@
* @summary Test vectorization of loop induction variable usage in the loop
* @requires vm.compiler2.enabled
* @requires (os.simpleArch == "x64" & vm.cpu.features ~= ".*avx2.*") |
* (os.simpleArch == "aarch64" & vm.cpu.features ~= ".*sve.*" & (vm.opt.UseSVE == "null" | vm.opt.UseSVE > 0))
* (os.simpleArch == "aarch64" & vm.cpu.features ~= ".*sve.*")
* @library /test/lib /
* @run driver compiler.vectorization.TestPopulateIndex
*/