Skip to content

Commit 4dd8a9d

Browse files
Merge with master.
2 parents 57e511e + befb4fb commit 4dd8a9d

34 files changed

+914
-282
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package org.graalvm.compiler.nodes.test;
27+
28+
import org.graalvm.compiler.core.test.GraalCompilerTest;
29+
import org.graalvm.compiler.nodes.StructuredGraph;
30+
import org.junit.Test;
31+
32+
public class AndNodeCanonicalizationTest extends GraalCompilerTest {
33+
34+
public static int andDeMorganSnippet(int x, int y) {
35+
return ~x & ~y;
36+
}
37+
38+
public static int andDeMorganReferenceSnippet(int x, int y) {
39+
return ~(x | y);
40+
}
41+
42+
@Test
43+
public void andDeMorgan() {
44+
testAgainstReference("andDeMorganReferenceSnippet", "andDeMorganSnippet");
45+
test("andDeMorganSnippet", 23, 42);
46+
}
47+
48+
public static int andSelfNegationLeftIntSnippet(int x) {
49+
return ~x & x;
50+
}
51+
52+
public static int andSelfNegationRightIntSnippet(int x) {
53+
return x & ~x;
54+
}
55+
56+
public static int andSelfNegationIntReferenceSnippet(@SuppressWarnings("unused") int x) {
57+
return -1;
58+
}
59+
60+
@Test
61+
public void andSelfNegationInt() {
62+
testAgainstReference("andSelfNegationIntReferenceSnippet", "andSelfNegationLeftIntSnippet");
63+
testAgainstReference("andSelfNegationIntReferenceSnippet", "andSelfNegationRightIntSnippet");
64+
test("andSelfNegationLeftIntSnippet", 42);
65+
test("andSelfNegationRightIntSnippet", 42);
66+
}
67+
68+
public static long andSelfNegationLeftLongSnippet(long x) {
69+
return ~x & x;
70+
}
71+
72+
public static long andSelfNegationRightLongSnippet(long x) {
73+
return x & ~x;
74+
}
75+
76+
public static long andSelfNegationLongReferenceSnippet(@SuppressWarnings("unused") long x) {
77+
return -1L;
78+
}
79+
80+
@Test
81+
public void andSelfNegationLong() {
82+
testAgainstReference("andSelfNegationLongReferenceSnippet", "andSelfNegationLeftLongSnippet");
83+
testAgainstReference("andSelfNegationLongReferenceSnippet", "andSelfNegationRightLongSnippet");
84+
test("andSelfNegationLeftLongSnippet", 42L);
85+
test("andSelfNegationRightLongSnippet", 42L);
86+
}
87+
88+
private void testAgainstReference(String referenceSnippet, String testSnippet) {
89+
StructuredGraph referenceGraph = parseForCompile(getResolvedJavaMethod(referenceSnippet));
90+
StructuredGraph testGraph = parseForCompile(getResolvedJavaMethod(testSnippet));
91+
createCanonicalizerPhase().apply(testGraph, getDefaultHighTierContext());
92+
assertEquals(referenceGraph, testGraph, true, false);
93+
}
94+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package org.graalvm.compiler.nodes.test;
27+
28+
import org.graalvm.compiler.core.test.GraalCompilerTest;
29+
import org.graalvm.compiler.nodes.StructuredGraph;
30+
import org.junit.Test;
31+
32+
public class OrNodeCanonicalizationTest extends GraalCompilerTest {
33+
34+
public static int orDeMorganSnippet(int x, int y) {
35+
return ~x | ~y;
36+
}
37+
38+
public static int orDeMorganReferenceSnippet(int x, int y) {
39+
return ~(x & y);
40+
}
41+
42+
@Test
43+
public void orDeMorgan() {
44+
testAgainstReference("orDeMorganReferenceSnippet", "orDeMorganSnippet");
45+
test("orDeMorganSnippet", 23, 42);
46+
}
47+
48+
public static int orSelfNegationLeftIntSnippet(int x) {
49+
return ~x | x;
50+
}
51+
52+
public static int orSelfNegationRightIntSnippet(int x) {
53+
return x | ~x;
54+
}
55+
56+
public static int orSelfNegationIntReferenceSnippet(@SuppressWarnings("unused") int x) {
57+
return -1;
58+
}
59+
60+
@Test
61+
public void orSelfNegationInt() {
62+
testAgainstReference("orSelfNegationIntReferenceSnippet", "orSelfNegationLeftIntSnippet");
63+
testAgainstReference("orSelfNegationIntReferenceSnippet", "orSelfNegationRightIntSnippet");
64+
test("orSelfNegationLeftIntSnippet", 42);
65+
test("orSelfNegationRightIntSnippet", 42);
66+
}
67+
68+
public static long orSelfNegationLeftLongSnippet(long x) {
69+
return ~x | x;
70+
}
71+
72+
public static long orSelfNegationRightLongSnippet(long x) {
73+
return x | ~x;
74+
}
75+
76+
public static long orSelfNegationLongReferenceSnippet(@SuppressWarnings("unused") long x) {
77+
return -1L;
78+
}
79+
80+
@Test
81+
public void orSelfNegationLong() {
82+
testAgainstReference("orSelfNegationLongReferenceSnippet", "orSelfNegationLeftLongSnippet");
83+
testAgainstReference("orSelfNegationLongReferenceSnippet", "orSelfNegationRightLongSnippet");
84+
test("orSelfNegationLeftLongSnippet", 42L);
85+
test("orSelfNegationRightLongSnippet", 42L);
86+
}
87+
88+
private void testAgainstReference(String referenceSnippet, String testSnippet) {
89+
StructuredGraph referenceGraph = parseForCompile(getResolvedJavaMethod(referenceSnippet));
90+
StructuredGraph testGraph = parseForCompile(getResolvedJavaMethod(testSnippet));
91+
createCanonicalizerPhase().apply(testGraph, getDefaultHighTierContext());
92+
assertEquals(referenceGraph, testGraph, true, false);
93+
}
94+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package org.graalvm.compiler.nodes.test;
27+
28+
import org.graalvm.compiler.core.test.GraalCompilerTest;
29+
import org.graalvm.compiler.nodes.StructuredGraph;
30+
import org.junit.Test;
31+
32+
public class XorNodeCanonicalizationTest extends GraalCompilerTest {
33+
34+
public static int xorDeMorganSnippet(int x, int y) {
35+
return ~x ^ ~y;
36+
}
37+
38+
public static int xorDeMorganReferenceSnippet(int x, int y) {
39+
return x ^ y;
40+
}
41+
42+
@Test
43+
public void xorDeMorgan() {
44+
testAgainstReference("xorDeMorganReferenceSnippet", "xorDeMorganSnippet");
45+
test("xorDeMorganSnippet", 23, 42);
46+
}
47+
48+
public static int xorSelfNegationLeftIntSnippet(int x) {
49+
return ~x ^ x;
50+
}
51+
52+
public static int xorSelfNegationRightIntSnippet(int x) {
53+
return x ^ ~x;
54+
}
55+
56+
public static int xorSelfNegationIntReferenceSnippet(@SuppressWarnings("unused") int x) {
57+
return -1;
58+
}
59+
60+
@Test
61+
public void xorSelfNegationInt() {
62+
testAgainstReference("xorSelfNegationIntReferenceSnippet", "xorSelfNegationLeftIntSnippet");
63+
testAgainstReference("xorSelfNegationIntReferenceSnippet", "xorSelfNegationRightIntSnippet");
64+
}
65+
66+
public static long xorSelfNegationLeftLongSnippet(long x) {
67+
return ~x ^ x;
68+
}
69+
70+
public static long xorSelfNegationRightLongSnippet(long x) {
71+
return x ^ ~x;
72+
}
73+
74+
public static long xorSelfNegationLongReferenceSnippet(@SuppressWarnings("unused") long x) {
75+
return -1L;
76+
}
77+
78+
@Test
79+
public void xorSelfNegationLong() {
80+
testAgainstReference("xorSelfNegationLongReferenceSnippet", "xorSelfNegationLeftLongSnippet");
81+
testAgainstReference("xorSelfNegationLongReferenceSnippet", "xorSelfNegationRightLongSnippet");
82+
}
83+
84+
private void testAgainstReference(String referenceSnippet, String testSnippet) {
85+
StructuredGraph referenceGraph = parseForCompile(getResolvedJavaMethod(referenceSnippet));
86+
StructuredGraph testGraph = parseForCompile(getResolvedJavaMethod(testSnippet));
87+
createCanonicalizerPhase().apply(testGraph, getDefaultHighTierContext());
88+
assertEquals(referenceGraph, testGraph, true, false);
89+
}
90+
}

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,13 +30,13 @@
3030
import org.graalvm.compiler.core.common.type.IntegerStamp;
3131
import org.graalvm.compiler.core.common.type.Stamp;
3232
import org.graalvm.compiler.graph.NodeClass;
33-
import org.graalvm.compiler.nodes.spi.Canonicalizable.BinaryCommutative;
34-
import org.graalvm.compiler.nodes.spi.CanonicalizerTool;
3533
import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
3634
import org.graalvm.compiler.nodeinfo.NodeInfo;
3735
import org.graalvm.compiler.nodes.ConstantNode;
3836
import org.graalvm.compiler.nodes.NodeView;
3937
import org.graalvm.compiler.nodes.ValueNode;
38+
import org.graalvm.compiler.nodes.spi.Canonicalizable.BinaryCommutative;
39+
import org.graalvm.compiler.nodes.spi.CanonicalizerTool;
4040
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
4141
import org.graalvm.compiler.nodes.util.GraphUtil;
4242

@@ -192,8 +192,13 @@ private static ValueNode canonical(AndNode self, BinaryOp<And> op, ValueNode for
192192
return reassociateMatchedValues(self != null ? self : (AndNode) new AndNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
193193
}
194194
if (forX instanceof NotNode && forY instanceof NotNode) {
195+
// ~x & ~y |-> ~(x | y)
195196
return new NotNode(OrNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
196197
}
198+
if (forY instanceof NotNode && ((NotNode) forY).getValue() == forX) {
199+
// x & ~x |-> 0
200+
return ConstantNode.forIntegerStamp(rawXStamp, 0L);
201+
}
197202
return self != null ? self : new AndNode(forX, forY).maybeCommuteInputs();
198203
}
199204

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,13 +30,13 @@
3030
import org.graalvm.compiler.core.common.type.IntegerStamp;
3131
import org.graalvm.compiler.core.common.type.Stamp;
3232
import org.graalvm.compiler.graph.NodeClass;
33-
import org.graalvm.compiler.nodes.spi.Canonicalizable.BinaryCommutative;
34-
import org.graalvm.compiler.nodes.spi.CanonicalizerTool;
3533
import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
3634
import org.graalvm.compiler.nodeinfo.NodeInfo;
3735
import org.graalvm.compiler.nodes.ConstantNode;
3836
import org.graalvm.compiler.nodes.NodeView;
3937
import org.graalvm.compiler.nodes.ValueNode;
38+
import org.graalvm.compiler.nodes.spi.Canonicalizable.BinaryCommutative;
39+
import org.graalvm.compiler.nodes.spi.CanonicalizerTool;
4040
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
4141
import org.graalvm.compiler.nodes.util.GraphUtil;
4242

@@ -106,8 +106,13 @@ private static ValueNode canonical(OrNode self, BinaryOp<Or> op, ValueNode forX,
106106
}
107107

108108
if (forX instanceof NotNode && forY instanceof NotNode) {
109+
// ~x | ~y |-> ~(x & y)
109110
return new NotNode(AndNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view));
110111
}
112+
if (forY instanceof NotNode && ((NotNode) forY).getValue() == forX) {
113+
// x | ~x |-> -1
114+
return ConstantNode.forIntegerStamp(rawXStamp, -1L);
115+
}
111116
return self != null ? self : new OrNode(forX, forY).maybeCommuteInputs();
112117
}
113118

compiler/src/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,13 +30,13 @@
3030
import org.graalvm.compiler.core.common.type.PrimitiveStamp;
3131
import org.graalvm.compiler.core.common.type.Stamp;
3232
import org.graalvm.compiler.graph.NodeClass;
33-
import org.graalvm.compiler.nodes.spi.Canonicalizable.BinaryCommutative;
34-
import org.graalvm.compiler.nodes.spi.CanonicalizerTool;
3533
import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
3634
import org.graalvm.compiler.nodeinfo.NodeInfo;
3735
import org.graalvm.compiler.nodes.ConstantNode;
3836
import org.graalvm.compiler.nodes.NodeView;
3937
import org.graalvm.compiler.nodes.ValueNode;
38+
import org.graalvm.compiler.nodes.spi.Canonicalizable.BinaryCommutative;
39+
import org.graalvm.compiler.nodes.spi.CanonicalizerTool;
4040
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
4141
import org.graalvm.compiler.nodes.util.GraphUtil;
4242

@@ -116,6 +116,14 @@ private static ValueNode canonical(XorNode self, BinaryOp<Xor> op, Stamp stamp,
116116
}
117117
return reassociateMatchedValues(self != null ? self : (XorNode) new XorNode(forX, forY).maybeCommuteInputs(), ValueNode.isConstantPredicate(), forX, forY, view);
118118
}
119+
if (forX instanceof NotNode && forY instanceof NotNode) {
120+
// ~x ^ ~y |-> x ^ y
121+
return XorNode.create(((NotNode) forX).getValue(), ((NotNode) forY).getValue(), view);
122+
}
123+
if (forY instanceof NotNode && ((NotNode) forY).getValue() == forX) {
124+
// x ^ ~x |-> -1
125+
return ConstantNode.forIntegerStamp(forX.stamp(NodeView.DEFAULT), -1L);
126+
}
119127
return self != null ? self : new XorNode(forX, forY).maybeCommuteInputs();
120128
}
121129

0 commit comments

Comments
 (0)