Skip to content

Commit 33f4d80

Browse files
cost0muchPaul Hohensee
authored andcommitted
8280120: [IR Framework] Add attribute to @ir to enable/disable IR matching based on the architecture
Backport-of: a8549b6
1 parent db914b7 commit 33f4d80

File tree

6 files changed

+284
-5
lines changed

6 files changed

+284
-5
lines changed

test/hotspot/jtreg/compiler/lib/ir_framework/IR.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,23 +108,44 @@
108108
*/
109109
String[] applyIf() default {};
110110

111+
/**
112+
* Accepts a single pair composed of a platform string followed by a true/false
113+
* value where a true value necessitates that we are currently testing on that platform and vice-versa.
114+
* IR checks are enforced only if the specified platform constraint is met.
115+
*/
116+
String[] applyIfPlatform() default {};
117+
118+
/**
119+
* Accepts a list of pairs where each pair is composed of a platform string followed by a true/false
120+
* value where a true value necessitates that we are currently testing on that platform and vice-versa.
121+
* IR checks are enforced only if all the specified platform constraints are met.
122+
*/
123+
String[] applyIfPlatformAnd() default {};
124+
125+
/**
126+
* Accepts a list of pairs where each pair is composed of a platform string followed by a true/false
127+
* value where a true value necessitates that we are currently testing on that platform and vice-versa.
128+
* IR checks are enforced if any of the specified platform constraints are met.
129+
*/
130+
String[] applyIfPlatformOr() default {};
131+
111132
/**
112133
* Accepts a single feature pair which is composed of CPU feature string followed by a true/false
113-
* value where a true value necessities existence of CPU feature and vice-versa.
134+
* value where a true value necessitates existence of CPU feature and vice-versa.
114135
* IR verifications checks are enforced only if the specified feature constraint is met.
115136
*/
116137
String[] applyIfCPUFeature() default {};
117138

118139
/**
119140
* Accepts a list of feature pairs where each pair is composed of target feature string followed by a true/false
120-
* value where a true value necessities existence of target feature and vice-versa.
141+
* value where a true value necessitates existence of target feature and vice-versa.
121142
* IR verifications checks are enforced only if all the specified feature constraints are met.
122143
*/
123144
String[] applyIfCPUFeatureAnd() default {};
124145

125146
/**
126147
* Accepts a list of feature pairs where each pair is composed of target feature string followed by a true/false
127-
* value where a true value necessities existence of target feature and vice-versa.
148+
* value where a true value necessitates existence of target feature and vice-versa.
128149
* IR verifications checks are enforced if any of the specified feature constraint is met.
129150
*/
130151
String[] applyIfCPUFeatureOr() default {};

test/hotspot/jtreg/compiler/lib/ir_framework/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,11 @@ Sometimes, an `@IR` rule should only be applied if a certain CPU feature is pres
128128

129129
If a `@Test` annotated method has multiple preconditions (for example `applyIf` and `applyIfCPUFeature`), they are evaluated as a logical conjunction. It's worth noting that flags in `applyIf` are checked only if the CPU features in `applyIfCPUFeature` are matched when they are both specified. This avoids the VM flag being evaluated on hardware that does not support it. An example with both `applyIfCPUFeatureXXX` and `applyIfXXX` can be found in [TestPreconditions](../../../testlibrary_tests/ir_framework/tests/TestPreconditions.java) (internal framework test).
130130

131+
#### Disable/Enable IR Rules based on Platform
132+
`@IR` rules based on the platform can be specified using `applyIfPlatformXXX` in [@IR](./IR.java). A reference for using these attributes can be found in [TestPlatformChecks](../../../testlibrary_tests/ir_framework/tests/TestPlatformChecks.java) (internal framework test).
133+
134+
Platform attributes are evaluated as a logical conjunction, and take precedence over VM Flag attributes. An example with both `applyIfPlatformXXX` and `applyIfXXX` can be found in [TestPreconditions](../../../testlibrary_tests/ir_framework/tests/TestPreconditions.java) (internal framework test).
135+
131136
#### Implicitly Skipping IR Verification
132137
An IR verification cannot always be performed. Certain VM flags explicitly disable IR verification, change the IR shape in unexpected ways letting IR rules fail or even make IR verification impossible:
133138

test/hotspot/jtreg/compiler/lib/ir_framework/test/IREncodingPrinter.java

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import compiler.lib.ir_framework.IRNode;
2828
import compiler.lib.ir_framework.TestFramework;
2929
import compiler.lib.ir_framework.shared.*;
30+
import jdk.test.lib.Platform;
3031
import jdk.test.whitebox.WhiteBox;
3132

3233
import java.lang.reflect.Method;
@@ -55,6 +56,27 @@ public class IREncodingPrinter {
5556
private Method method;
5657
private int ruleIndex;
5758

59+
// Platforms for use in IR preconditions. Please verify that e.g. there is
60+
// a corresponding use in a jtreg @requires annotation before adding new platforms,
61+
// as adding non-existent platforms can lead to skipped tests.
62+
private static final List<String> irTestingPlatforms = new ArrayList<String>(Arrays.asList(
63+
// os.family
64+
"linux",
65+
"mac",
66+
"windows",
67+
// vm.simpleArch
68+
"aarch64",
69+
"arm",
70+
"ppc",
71+
"riscv64",
72+
"s390",
73+
"x64",
74+
"x86",
75+
// corresponds to vm.bits
76+
"32-bit",
77+
"64-bit"
78+
));
79+
5880
// Please verify new CPU features before adding them. If we allow non-existent features
5981
// on this list, we will ignore tests and never execute them. Consult CPU_FEATURE_FLAGS
6082
// in corresponding vm_version_.hpp file to find correct cpu feature's name.
@@ -134,6 +156,15 @@ private boolean shouldApplyIrRule(IR irAnno, String m, int ruleIndex, int ruleMa
134156
checkIRAnnotations(irAnno);
135157
if (isIRNodeUnsupported(irAnno)) {
136158
return false;
159+
} else if (irAnno.applyIfPlatform().length != 0 && !hasAllRequiredPlatform(irAnno.applyIfPlatform())) {
160+
printDisableReason(m, "Constraint not met (applyIfPlatform)", irAnno.applyIfPlatform(), ruleIndex, ruleMax);
161+
return false;
162+
} else if (irAnno.applyIfPlatformAnd().length != 0 && !hasAllRequiredPlatform(irAnno.applyIfPlatformAnd())) {
163+
printDisableReason(m, "Not all constraints are met (applyIfPlatformAnd)", irAnno.applyIfPlatformAnd(), ruleIndex, ruleMax);
164+
return false;
165+
} else if (irAnno.applyIfPlatformOr().length != 0 && !hasAnyRequiredPlatform(irAnno.applyIfPlatformOr())) {
166+
printDisableReason(m, "None of the constraints are met (applyIfPlatformOr)", irAnno.applyIfPlatformOr(), ruleIndex, ruleMax);
167+
return false;
137168
} else if (irAnno.applyIfCPUFeature().length != 0 && !hasAllRequiredCPUFeature(irAnno.applyIfCPUFeature())) {
138169
printDisableReason(m, "Feature constraint not met (applyIfCPUFeature)", irAnno.applyIfCPUFeature(), ruleIndex, ruleMax);
139170
return false;
@@ -165,6 +196,7 @@ private void checkIRAnnotations(IR irAnno) {
165196
TestFormat.checkNoThrow(irAnno.counts().length != 0 || irAnno.failOn().length != 0,
166197
"Must specify either counts or failOn constraint" + failAt());
167198
int flagConstraints = 0;
199+
int platformConstraints = 0;
168200
int cpuFeatureConstraints = 0;
169201
if (irAnno.applyIfAnd().length != 0) {
170202
flagConstraints++;
@@ -181,6 +213,21 @@ private void checkIRAnnotations(IR irAnno) {
181213
TestFormat.checkNoThrow(irAnno.applyIf().length <= 2,
182214
"Use applyIfAnd or applyIfOr or only 1 condition for applyIf" + failAt());
183215
}
216+
if (irAnno.applyIfPlatform().length != 0) {
217+
platformConstraints++;
218+
TestFormat.checkNoThrow(irAnno.applyIfPlatform().length == 2,
219+
"applyIfPlatform expects single platform pair" + failAt());
220+
}
221+
if (irAnno.applyIfPlatformAnd().length != 0) {
222+
platformConstraints++;
223+
TestFormat.checkNoThrow(irAnno.applyIfPlatformAnd().length % 2 == 0,
224+
"applyIfPlatformAnd expects more than one platform pair" + failAt());
225+
}
226+
if (irAnno.applyIfPlatformOr().length != 0) {
227+
platformConstraints++;
228+
TestFormat.checkNoThrow(irAnno.applyIfPlatformOr().length % 2 == 0,
229+
"applyIfPlatformOr expects more than one platform pair" + failAt());
230+
}
184231
if (irAnno.applyIfCPUFeature().length != 0) {
185232
cpuFeatureConstraints++;
186233
TestFormat.checkNoThrow(irAnno.applyIfCPUFeature().length == 2,
@@ -202,6 +249,7 @@ private void checkIRAnnotations(IR irAnno) {
202249
"Use applyIfAnd or applyIfOr or only 1 condition for applyIfNot" + failAt());
203250
}
204251
TestFormat.checkNoThrow(flagConstraints <= 1, "Can only specify one flag constraint" + failAt());
252+
TestFormat.checkNoThrow(platformConstraints <= 1, "Can only specify one platform constraint" + failAt());
205253
TestFormat.checkNoThrow(cpuFeatureConstraints <= 1, "Can only specify one CPU feature constraint" + failAt());
206254
}
207255

@@ -235,6 +283,82 @@ private boolean hasAllRequiredFlags(String[] andRules, String ruleType) {
235283
return returnValue;
236284
}
237285

286+
private boolean hasAllRequiredPlatform(String[] andRules) {
287+
boolean returnValue = true;
288+
for (int i = 0; i < andRules.length; i++) {
289+
String platform = andRules[i].trim();
290+
i++;
291+
String value = andRules[i].trim();
292+
returnValue &= checkPlatform(platform, value);
293+
}
294+
return returnValue;
295+
}
296+
297+
private boolean hasAnyRequiredPlatform(String[] orRules) {
298+
boolean returnValue = false;
299+
for (int i = 0; i < orRules.length; i++) {
300+
String platform = orRules[i].trim();
301+
i++;
302+
String value = orRules[i].trim();
303+
returnValue |= checkPlatform(platform, value);
304+
}
305+
return returnValue;
306+
}
307+
308+
private boolean checkPlatform(String platform, String value) {
309+
if (platform.isEmpty()) {
310+
TestFormat.failNoThrow("Provided empty platform" + failAt());
311+
return false;
312+
}
313+
if (value.isEmpty()) {
314+
TestFormat.failNoThrow("Provided empty value for platform " + platform + failAt());
315+
return false;
316+
}
317+
318+
if (!irTestingPlatforms.contains(platform)) {
319+
TestFormat.failNoThrow("Provided platform is not in verified list: " + platform + failAt());
320+
return false;
321+
}
322+
323+
boolean trueValue = value.contains("true");
324+
boolean falseValue = value.contains("false");
325+
326+
if (!trueValue && !falseValue) {
327+
TestFormat.failNoThrow("Provided incorrect value for platform " + platform + failAt());
328+
return false;
329+
}
330+
331+
String os = "";
332+
if (Platform.isLinux()) {
333+
os = "linux";
334+
} else if (Platform.isOSX()) {
335+
os = "mac";
336+
} else if (Platform.isWindows()) {
337+
os = "windows";
338+
}
339+
340+
String arch = "";
341+
if (Platform.isAArch64()) {
342+
arch = "aarch64";
343+
} else if (Platform.isARM()) {
344+
arch = "arm";
345+
} else if (Platform.isPPC()) {
346+
arch = "ppc";
347+
} else if (Platform.isRISCV64()) {
348+
arch = "riscv64";
349+
} else if (Platform.isS390x()) {
350+
arch = "s390";
351+
} else if (Platform.isX64()) {
352+
arch = "x64";
353+
} else if (Platform.isX86()) {
354+
arch = "x86";
355+
}
356+
357+
String currentPlatform = os + " " + arch + " " + (Platform.is32bit() ? "32-bit" : "64-bit");
358+
359+
return (trueValue && currentPlatform.contains(platform)) || (falseValue && !currentPlatform.contains(platform));
360+
}
361+
238362
private boolean hasAllRequiredCPUFeature(String[] andRules) {
239363
boolean returnValue = true;
240364
for (int i = 0; i < andRules.length; i++) {

test/hotspot/jtreg/compiler/loopopts/superword/SumRed_Long.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
* @test
2626
* @bug 8076276
2727
* @summary Add C2 x86 Superword support for scalar sum reduction optimizations : long test
28-
* @requires vm.bits == "64"
2928
* @library /test/lib /
3029
* @run driver compiler.loopopts.superword.SumRed_Long
3130
*/
@@ -93,7 +92,8 @@ public static void sumReductionInit(
9392
@Test
9493
@IR(applyIf = {"SuperWordReductions", "false"},
9594
failOn = {IRNode.ADD_REDUCTION_VL})
96-
@IR(applyIfCPUFeature = {"avx2", "true"},
95+
@IR(applyIfPlatform = {"32-bit", "false"},
96+
applyIfCPUFeature = {"avx2", "true"},
9797
applyIfAnd = {"SuperWordReductions", "true", "LoopMaxUnroll", ">= 8"},
9898
counts = {IRNode.ADD_REDUCTION_VL, ">= 1", IRNode.ADD_REDUCTION_VL, "<= 2"}) // one for main-loop, one for vector-post-loop
9999
public static long sumReductionImplement(
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. 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 ir_framework.tests;
25+
26+
import compiler.lib.ir_framework.*;
27+
import compiler.lib.ir_framework.driver.irmatching.IRViolationException;
28+
29+
/*
30+
* @test 8280120
31+
* @summary Add attribute to IR to enable/disable IR matching based on the architecture
32+
* @library /test/lib /
33+
* @run driver ir_framework.tests.TestPlatformChecks
34+
*/
35+
36+
public class TestPlatformChecks {
37+
private static final int SIZE = 1000;
38+
private static int[] a = new int[SIZE];
39+
private static int[] b = new int[SIZE];
40+
private static int[] res = new int[SIZE];
41+
42+
public static void setup() {
43+
for (int i = 0; i < SIZE; i++) {
44+
a[i] = i;
45+
b[i] = i;
46+
}
47+
}
48+
49+
public static void main(String[] args) {
50+
setup();
51+
TestFramework.run();
52+
}
53+
54+
@Test
55+
@IR(counts = {IRNode.ADD_VI, "> 0"},
56+
applyIfPlatform = {"x64", "true"},
57+
applyIfCPUFeature = {"sse4.1", "true"})
58+
public static void test1() {
59+
for (int i = 0; i < SIZE; i++) {
60+
res[i] = a[i] + b[i];
61+
}
62+
}
63+
64+
// IR rule is enforced if all the platform constraints hold
65+
@Test
66+
@IR(counts = {IRNode.ADD_VI, "> 0"},
67+
applyIfPlatformAnd = {"x64", "true", "linux", "true"},
68+
applyIfCPUFeatureAnd = {"sse4.1", "true", "avx2", "true"})
69+
public static void test2() {
70+
for (int i = 0; i < SIZE; i++) {
71+
res[i] = a[i] + b[i];
72+
}
73+
}
74+
75+
// IR rule is enforced if any of the platform constraints hold
76+
@Test
77+
@IR(counts = {IRNode.ADD_VI, "> 0"},
78+
applyIfPlatformOr = {"linux", "true", "mac", "true"},
79+
applyIfCPUFeatureOr = {"sse4.1", "true", "avx2", "true"})
80+
public static void test3() {
81+
for (int i = 0; i < SIZE; i++) {
82+
res[i] = a[i] + b[i];
83+
}
84+
}
85+
}

test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPreconditions.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,48 @@ public static void testApplyBoth2() {}
8181
applyIfAnd = {"UseAVX", "= 2", "LoopMaxUnroll", "= 0"},
8282
counts = {IRNode.LOOP, ">= 1000"})
8383
public static void testApplyBoth3() {}
84+
85+
// The IR check should not be applied, since OS can not be both linux and mac.
86+
@Test
87+
@IR(applyIfPlatformAnd = {"linux", "true", "mac", "true"},
88+
counts = {IRNode.LOOP, ">= 1000"})
89+
public static void testApplyBothOs() {}
90+
91+
// The IR check should not be applied, since we can't have both 32-bit and 64-bit data model.
92+
@Test
93+
@IR(applyIfPlatformAnd = {"32-bit", "true", "64-bit", "true"},
94+
counts = {IRNode.LOOP, ">= 1000"})
95+
public static void testApplyBothDataModel() {}
96+
97+
// The IR check should not be applied, since the arch can't be both x64 and aarch64.
98+
@Test
99+
@IR(applyIfPlatformAnd = {"x64", "true", "aarch64", "true"},
100+
counts = {IRNode.LOOP, ">= 1000"})
101+
public static void testApplyBothArch() {}
102+
103+
// Platform versions of testApplyBoth2/3.
104+
@Test
105+
@IR(applyIfPlatform = {"aarch64", "true"},
106+
applyIfAnd = {"UseSVE", "= 0", "LoopMaxUnroll", "= 0"},
107+
counts = {IRNode.LOOP, ">= 1000"})
108+
public static void testApplyPlatformSVE() {}
109+
110+
@Test
111+
@IR(applyIfPlatform = {"x64", "true"},
112+
applyIfAnd = {"UseAVX", "= 2", "LoopMaxUnroll", "= 0"},
113+
counts = {IRNode.LOOP, ">= 1000"})
114+
public static void testApplyPlatformAVX() {}
115+
116+
@Test
117+
@IR(applyIfPlatformAnd = {"x64", "true", "linux", "true"},
118+
applyIfAnd = {"UseAVX", "= 2", "LoopMaxUnroll", "= 0"},
119+
counts = {IRNode.LOOP, ">= 1000"})
120+
public static void testApplyPlatformAVXAnd() {}
121+
122+
@Test
123+
@IR(applyIfPlatformOr = {"x64", "true", "x86", "true"},
124+
applyIfAnd = {"UseSSE", "= 4", "LoopMaxUnroll", "= 0"},
125+
counts = {IRNode.LOOP, ">= 1000"})
126+
public static void testApplyPlatformSSEOr() {}
127+
84128
}

0 commit comments

Comments
 (0)