8287525: Extend IR annotation with new options to test specific target feature.
Co-authored-by: Jatin Bhateja <jbhateja@openjdk.org> Reviewed-by: chagedorn, kvn
This commit is contained in:
parent
86c9241cce
commit
03dca565cf
@ -938,6 +938,8 @@ void VM_Version::get_processor_features() {
|
||||
_features &= ~CPU_HT;
|
||||
}
|
||||
|
||||
// Note: Any modifications to following suppressed feature list for KNL target
|
||||
// should also be applied to test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java
|
||||
if (is_intel()) { // Intel cpus specific settings
|
||||
if (is_knights_family()) {
|
||||
_features &= ~CPU_VZEROUPPER;
|
||||
|
@ -98,6 +98,27 @@ public @interface IR {
|
||||
*/
|
||||
String[] applyIf() default {};
|
||||
|
||||
/**
|
||||
* Accepts a single feature pair which is composed of CPU feature string followed by a true/false
|
||||
* value where a true value necessities existence of CPU feature and vice-versa.
|
||||
* IR verifications checks are enforced only if the specified feature constraint is met.
|
||||
*/
|
||||
String[] applyIfCPUFeature() default {};
|
||||
|
||||
/**
|
||||
* Accepts a list of feature pairs where each pair is composed of target feature string followed by a true/false
|
||||
* value where a true value necessities existence of target feature and vice-versa.
|
||||
* IR verifications checks are enforced only if all the specified feature constraints are met.
|
||||
*/
|
||||
String[] applyIfCPUFeatureAnd() default {};
|
||||
|
||||
/**
|
||||
* Accepts a list of feature pairs where each pair is composed of target feature string followed by a true/false
|
||||
* value where a true value necessities existence of target feature and vice-versa.
|
||||
* IR verifications checks are enforced if any of the specified feature constraint is met.
|
||||
*/
|
||||
String[] applyIfCPUFeatureOr() default {};
|
||||
|
||||
/**
|
||||
* Define a single VM flag precondition which <i>must <b>not</b> hold</i> when applying the IR rule. If, however,
|
||||
* the VM flag precondition holds, then the IR rule is not applied. This could also be defined as <i>negative</i>
|
||||
|
@ -166,6 +166,7 @@ public class IRNode {
|
||||
public static final String ADD_I = START + "AddI" + MID + END;
|
||||
public static final String ADD_L = START + "AddL" + MID + END;
|
||||
public static final String ADD_VD = START + "AddVD" + MID + END;
|
||||
public static final String ADD_VI = START + "AddVI" + MID + END;
|
||||
public static final String SUB = START + "Sub(I|L|F|D)" + MID + END;
|
||||
public static final String SUB_I = START + "SubI" + MID + END;
|
||||
public static final String SUB_L = START + "SubL" + MID + END;
|
||||
|
@ -33,6 +33,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* Prints an encoding to the dedicated test framework socket whether @IR rules of @Test methods should be applied or not.
|
||||
@ -72,7 +73,7 @@ public class IREncodingPrinter {
|
||||
for (IR irAnno : irAnnos) {
|
||||
ruleIndex = i + 1;
|
||||
try {
|
||||
if (shouldApplyIrRule(irAnno)) {
|
||||
if (shouldApplyIrRule(irAnno, m.getName())) {
|
||||
validRules.add(ruleIndex);
|
||||
}
|
||||
} catch (TestFormatException e) {
|
||||
@ -94,25 +95,72 @@ public class IREncodingPrinter {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldApplyIrRule(IR irAnno) {
|
||||
private boolean shouldApplyIrRule(IR irAnno, String m) {
|
||||
checkIRAnnotations(irAnno);
|
||||
if (isDefaultRegexUnsupported(irAnno)) {
|
||||
return false;
|
||||
}
|
||||
if (irAnno.applyIf().length != 0) {
|
||||
return hasAllRequiredFlags(irAnno.applyIf(), "applyIf");
|
||||
boolean check = hasAllRequiredFlags(irAnno.applyIf(), "applyIf");
|
||||
if (!check) {
|
||||
TestFrameworkSocket.write("Disabling IR matching for " + m + ": Flag constraint not met.",
|
||||
"[IREncodingPrinter]", true);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
|
||||
if (irAnno.applyIfNot().length != 0) {
|
||||
return hasNoRequiredFlags(irAnno.applyIfNot(), "applyIfNot");
|
||||
boolean check = hasNoRequiredFlags(irAnno.applyIfNot(), "applyIfNot");
|
||||
if (!check) {
|
||||
TestFrameworkSocket.write("Disabling IR matching for " + m + ": Flag constraint not met.",
|
||||
"[IREncodingPrinter]", true);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
|
||||
if (irAnno.applyIfAnd().length != 0) {
|
||||
return hasAllRequiredFlags(irAnno.applyIfAnd(), "applyIfAnd");
|
||||
boolean check = hasAllRequiredFlags(irAnno.applyIfAnd(), "applyIfAnd");
|
||||
if (!check) {
|
||||
TestFrameworkSocket.write("Disabling IR matching for " + m + ": All flag constraints not met.",
|
||||
"[IREncodingPrinter]", true);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
|
||||
if (irAnno.applyIfOr().length != 0) {
|
||||
return !hasNoRequiredFlags(irAnno.applyIfOr(), "applyIfOr");
|
||||
boolean check = hasNoRequiredFlags(irAnno.applyIfOr(), "applyIfOr");
|
||||
if (check) {
|
||||
TestFrameworkSocket.write("Disabling IR matching for " + m + ": None of the flag constraint met.",
|
||||
"[IREncodingPrinter]", true);
|
||||
}
|
||||
return !check;
|
||||
}
|
||||
|
||||
if (irAnno.applyIfCPUFeature().length != 0) {
|
||||
boolean check = hasAllRequiredCPUFeature(irAnno.applyIfCPUFeature());
|
||||
if (!check) {
|
||||
TestFrameworkSocket.write("Disabling IR matching for " + m + ": Feature constraint not met.",
|
||||
"[IREncodingPrinter]", true);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
|
||||
if (irAnno.applyIfCPUFeatureAnd().length != 0) {
|
||||
boolean check = hasAllRequiredCPUFeature(irAnno.applyIfCPUFeatureAnd());
|
||||
if (!check) {
|
||||
TestFrameworkSocket.write("Disabling IR matching for " + m + ": All feature constraints not met.",
|
||||
"[IREncodingPrinter]", true);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
|
||||
if (irAnno.applyIfCPUFeatureOr().length != 0) {
|
||||
boolean check = hasAnyRequiredCPUFeature(irAnno.applyIfCPUFeatureOr());
|
||||
if (!check) {
|
||||
TestFrameworkSocket.write("Disabling IR matching for " + m + ": None of the feature constraint met.",
|
||||
"[IREncodingPrinter]", true);
|
||||
}
|
||||
return check;
|
||||
}
|
||||
// No conditions, always apply.
|
||||
return true;
|
||||
@ -121,29 +169,45 @@ public class IREncodingPrinter {
|
||||
private void checkIRAnnotations(IR irAnno) {
|
||||
TestFormat.checkNoThrow(irAnno.counts().length != 0 || irAnno.failOn().length != 0,
|
||||
"Must specify either counts or failOn constraint" + failAt());
|
||||
int applyRules = 0;
|
||||
int flagConstraints = 0;
|
||||
int cpuFeatureConstraints = 0;
|
||||
if (irAnno.applyIfAnd().length != 0) {
|
||||
applyRules++;
|
||||
flagConstraints++;
|
||||
TestFormat.checkNoThrow(irAnno.applyIfAnd().length > 2,
|
||||
"Use applyIf or applyIfNot or at least 2 conditions for applyIfAnd" + failAt());
|
||||
}
|
||||
if (irAnno.applyIfOr().length != 0) {
|
||||
applyRules++;
|
||||
flagConstraints++;
|
||||
TestFormat.checkNoThrow(irAnno.applyIfOr().length > 2,
|
||||
"Use applyIf or applyIfNot or at least 2 conditions for applyIfOr" + failAt());
|
||||
}
|
||||
if (irAnno.applyIf().length != 0) {
|
||||
applyRules++;
|
||||
flagConstraints++;
|
||||
TestFormat.checkNoThrow(irAnno.applyIf().length <= 2,
|
||||
"Use applyIfAnd or applyIfOr or only 1 condition for applyIf" + failAt());
|
||||
}
|
||||
if (irAnno.applyIfCPUFeature().length != 0) {
|
||||
cpuFeatureConstraints++;
|
||||
TestFormat.checkNoThrow(irAnno.applyIfCPUFeature().length == 2,
|
||||
"applyIfCPUFeature expects single CPU feature pair" + failAt());
|
||||
}
|
||||
if (irAnno.applyIfCPUFeatureAnd().length != 0) {
|
||||
cpuFeatureConstraints++;
|
||||
TestFormat.checkNoThrow((irAnno.applyIfCPUFeatureAnd().length % 2) == 0 && irAnno.applyIfCPUFeatureAnd().length >= 2,
|
||||
"applyIfCPUFeatureAnd expects more than one CPU feature pair" + failAt());
|
||||
}
|
||||
if (irAnno.applyIfCPUFeatureOr().length != 0) {
|
||||
cpuFeatureConstraints++;
|
||||
TestFormat.checkNoThrow((irAnno.applyIfCPUFeatureOr().length % 2) == 0 && irAnno.applyIfCPUFeatureOr().length >= 2,
|
||||
"applyIfCPUFeatureOr expects more than one CPU feature pair" + failAt());
|
||||
}
|
||||
if (irAnno.applyIfNot().length != 0) {
|
||||
applyRules++;
|
||||
flagConstraints++;
|
||||
TestFormat.checkNoThrow(irAnno.applyIfNot().length <= 2,
|
||||
"Use applyIfAnd or applyIfOr or only 1 condition for applyIfNot" + failAt());
|
||||
}
|
||||
TestFormat.checkNoThrow(applyRules <= 1,
|
||||
"Can only specify one apply constraint " + failAt());
|
||||
TestFormat.checkNoThrow(flagConstraints <= 1, "Can only specify one flag constraint" + failAt());
|
||||
TestFormat.checkNoThrow(cpuFeatureConstraints <= 1, "Can only specify one CPU feature constraint" + failAt());
|
||||
}
|
||||
|
||||
private boolean isDefaultRegexUnsupported(IR irAnno) {
|
||||
@ -176,6 +240,72 @@ public class IREncodingPrinter {
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private boolean hasAllRequiredCPUFeature(String[] andRules) {
|
||||
boolean returnValue = true;
|
||||
for (int i = 0; i < andRules.length; i++) {
|
||||
String feature = andRules[i].trim();
|
||||
i++;
|
||||
String value = andRules[i].trim();
|
||||
returnValue &= checkCPUFeature(feature, value);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private boolean hasAnyRequiredCPUFeature(String[] orRules) {
|
||||
boolean returnValue = false;
|
||||
for (int i = 0; i < orRules.length; i++) {
|
||||
String feature = orRules[i].trim();
|
||||
i++;
|
||||
String value = orRules[i].trim();
|
||||
returnValue |= checkCPUFeature(feature, value);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private boolean checkCPUFeature(String feature, String value) {
|
||||
if (feature.isEmpty()) {
|
||||
TestFormat.failNoThrow("Provided empty feature" + failAt());
|
||||
return false;
|
||||
}
|
||||
if (value.isEmpty()) {
|
||||
TestFormat.failNoThrow("Provided empty value for feature " + feature + failAt());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean trueValue = value.contains("true");
|
||||
boolean falseValue = value.contains("false");
|
||||
|
||||
if (!trueValue && !falseValue) {
|
||||
TestFormat.failNoThrow("Provided incorrect value for feature " + feature + failAt());
|
||||
return false;
|
||||
}
|
||||
String cpuFeatures = WHITE_BOX.getCPUFeatures();
|
||||
// Following feature list is in sync with suppressed feature list for KNL target.
|
||||
// Please refer vm_version_x86.cpp for details.
|
||||
HashSet<String> knlFeatureSet = new HashSet<>();
|
||||
knlFeatureSet.add("AVX512BW");
|
||||
knlFeatureSet.add("AVX512VL");
|
||||
knlFeatureSet.add("AVX512DQ");
|
||||
knlFeatureSet.add("AVX512_VNNI");
|
||||
knlFeatureSet.add("AVX512_VAES");
|
||||
knlFeatureSet.add("AVX512_VPOPCNTDQ");
|
||||
knlFeatureSet.add("AVX512_VPCLMULQDQ");
|
||||
knlFeatureSet.add("AVX512_VBMI");
|
||||
knlFeatureSet.add("AVX512_VBMI2");
|
||||
knlFeatureSet.add("CLWB");
|
||||
knlFeatureSet.add("FLUSHOPT");
|
||||
knlFeatureSet.add("GFNI");
|
||||
knlFeatureSet.add("AVX512_BITALG");
|
||||
Boolean isKNLFlagEnabled = WHITE_BOX.getBooleanVMFlag("UseKNLSetting");
|
||||
// Perform the feature check if UseKNLSetting flag is set to off or if
|
||||
// feature is supported by KNL target.
|
||||
if (isKNLFlagEnabled == null ||
|
||||
(isKNLFlagEnabled && (!knlFeatureSet.contains(feature.toUpperCase()) || falseValue))) {
|
||||
return (trueValue && cpuFeatures.contains(feature)) || (falseValue && !cpuFeatures.contains(feature));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasNoRequiredFlags(String[] orRules, String ruleType) {
|
||||
boolean returnValue = true;
|
||||
for (int i = 0; i < orRules.length; i++) {
|
||||
|
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 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
|
||||
* 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.vectorapi;
|
||||
|
||||
import compiler.lib.ir_framework.*;
|
||||
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
|
||||
|
||||
/*
|
||||
* @test 8287525
|
||||
* @summary Extend IR annotation with new options to test specific target feature.
|
||||
* @requires vm.cpu.features ~= ".*avx512f.*"
|
||||
* @requires os.arch=="amd64" | os.arch=="x86_64"
|
||||
* @library /test/lib /
|
||||
* @run driver compiler.vectorapi.TestCPUFeatureCheck
|
||||
*/
|
||||
|
||||
public class TestCPUFeatureCheck {
|
||||
private static int a[] = new int[1000];
|
||||
private static int b[] = new int[1000];
|
||||
private static int res[] = new int[1000];
|
||||
|
||||
public static void setup() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
a[i] = i;
|
||||
b[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
setup();
|
||||
TestFramework.runWithFlags("-XX:-TieredCompilation",
|
||||
"-XX:UseAVX=3",
|
||||
"-XX:+UseKNLSetting",
|
||||
"-XX:CompileThresholdScaling=0.3");
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD_VI, "> 0"}, applyIfCPUFeature = {"avx512bw", "false"})
|
||||
public static void test1() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
res[i] = a[i] + b[i];
|
||||
}
|
||||
}
|
||||
|
||||
// IR rule is enforced if all the feature conditions holds good
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD_VI, "> 0"}, applyIfCPUFeatureAnd = {"avx512bw", "false", "avx512f", "true"})
|
||||
public static void test2() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
res[i] = a[i] + b[i];
|
||||
}
|
||||
}
|
||||
|
||||
// IR rule is enforced if any of the feature condition holds good
|
||||
@Test
|
||||
@IR(counts = {IRNode.ADD_VI, "> 0"}, applyIfCPUFeatureOr = {"avx512bw", "true", "avx512f", "true"})
|
||||
public static void test3() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
res[i] = a[i] + b[i];
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user