Skip to content

8322077: Add Ideal transformation: (~a) | (~b) => ~(a & b) #16334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
46c25c6
include new optimization and tests.
CptGit Oct 24, 2023
063fb10
remove tabs.
CptGit Oct 24, 2023
cf2edb4
connect test with correct bug id.
CptGit Dec 21, 2023
5072eb1
update the copyright dates.
CptGit Jan 5, 2024
3b95720
address comments.
CptGit Jan 5, 2024
6ee5f18
use utility functions.
CptGit Jan 5, 2024
ecb2098
update the copyright dates.
CptGit Jan 5, 2024
7697ab2
include new optimization and tests.
CptGit Oct 24, 2023
05bd720
include bug id.
CptGit Dec 14, 2023
8c5697b
use common helpful functions.
CptGit Dec 15, 2023
706857d
untabify.
CptGit Dec 15, 2023
ab28c85
address comments.
CptGit Oct 24, 2023
ffc297e
update the copyright dates.
CptGit Jan 5, 2024
15a38bd
remove unused code from tests.
CptGit Jan 5, 2024
d8ed0f3
Add tests for using De Morgan's Law for both optimizations.
CptGit Jan 6, 2024
981e869
Update test/hotspot/jtreg/compiler/c2/irTests/DeMorganLawIntTests.java
CptGit Jan 9, 2024
6eb29ae
Update test/hotspot/jtreg/compiler/c2/irTests/DeMorganLawLongTests.java
CptGit Jan 9, 2024
afa0737
Update src/hotspot/share/opto/addnode.cpp
CptGit Jan 9, 2024
c4fa2e4
address minor comments.
CptGit Jan 9, 2024
7a962d6
move the two helper functions to member functions of the node class.
CptGit Jan 9, 2024
648b64e
Merge branch 'andnode-PNewDeMorganLawAndToOr' into ornode-PNewDeMorga…
CptGit Jan 9, 2024
0c8d107
adapt changes from the dependent pr.
CptGit Jan 9, 2024
3665de2
update copyright dates.
CptGit Jan 9, 2024
4ee8b08
move make_not back to AddNode because it cannot compile for architect…
CptGit Jan 9, 2024
a31f536
Merge branch 'andnode-PNewDeMorganLawAndToOr' into ornode-PNewDeMorga…
CptGit Jan 9, 2024
b21e242
adapt to new changes from the dependant pr.
CptGit Jan 9, 2024
fb08ef0
Revert "move make_not back to AddNode because it cannot compile for a…
CptGit Jan 9, 2024
8539f1f
Revert "update copyright dates."
CptGit Jan 9, 2024
6594222
Revert "move the two helper functions to member functions of the node…
CptGit Jan 9, 2024
ec08ccc
Revert "adapt to new changes from the dependant pr."
CptGit Jan 9, 2024
a7dddd5
Revert "adapt changes from the dependent pr."
CptGit Jan 9, 2024
cc9ea39
Merge branch 'andnode-PNewDeMorganLawAndToOr' into ornode-PNewDeMorga…
CptGit Jan 9, 2024
dc60a54
update copyright dates.
CptGit Jan 9, 2024
f908668
Merge branch 'master' of https://github.com/openjdk/jdk into ornode-P…
CptGit Jan 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/hotspot/share/opto/addnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,13 @@ Node* OrINode::Ideal(PhaseGVN* phase, bool can_reshape) {
return new RotateRightNode(in(1)->in(1), shift, TypeInt::INT);
}
}

// Convert "~a | ~b" into "~(a & b)"
if (AddNode::is_not(phase, in(1), T_INT) && AddNode::is_not(phase, in(2), T_INT)) {
Node* and_a_b = new AndINode(in(1)->in(1), in(2)->in(1));
Node* tn = phase->transform(and_a_b);
return AddNode::make_not(phase, tn, T_INT);
}
return nullptr;
}

Expand Down Expand Up @@ -872,6 +879,14 @@ Node* OrLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
return new RotateRightNode(in(1)->in(1), shift, TypeLong::LONG);
}
}

// Convert "~a | ~b" into "~(a & b)"
if (AddNode::is_not(phase, in(1), T_LONG) && AddNode::is_not(phase, in(2), T_LONG)) {
Node* and_a_b = new AndLNode(in(1)->in(1), in(2)->in(1));
Node* tn = phase->transform(and_a_b);
return AddNode::make_not(phase, tn, T_LONG);
}

return nullptr;
}

Expand Down
109 changes: 109 additions & 0 deletions test/hotspot/jtreg/compiler/c2/irTests/DeMorganLawIntTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2024, 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.c2.irTests;

import jdk.test.lib.Asserts;
import compiler.lib.ir_framework.*;

/*
* @test
* @bug 8322077
* @summary Test that Ideal transformations on the De Morgan's Law perform
as expected for int.
* @library /test/lib /
* @run driver compiler.c2.irTests.DeMorganLawIntTests
*/
public class DeMorganLawIntTests {

public static void main(String[] args) {
TestFramework.run();
}

@Run(test = { "test1", "test2", "test3", "test4" })
public void runMethod() {
int a = RunInfo.getRandom().nextInt();
int b = RunInfo.getRandom().nextInt();
int c = RunInfo.getRandom().nextInt();
int d = RunInfo.getRandom().nextInt();

int min = Integer.MIN_VALUE;
int max = Integer.MAX_VALUE;

assertResult(0, 0, 0, 0);
assertResult(a, b, c, d);
assertResult(min, min, min, min);
assertResult(max, max, max, max);
}

@DontCompile
public void assertResult(int a, int b, int c, int d) {
Asserts.assertEQ((~a | ~b) & (~c | ~d), test1(a, b, c, d));
Asserts.assertEQ((~a & ~b) | (~c & ~d), test2(a, b, c, d));
Asserts.assertEQ((~a | ~b) | (~c | ~d), test3(a, b, c, d));
Asserts.assertEQ((~a & ~b) & (~c & ~d), test4(a, b, c, d));
}

// Checks (~a | ~b) & (~c | ~d)
// => ~(a & b) & ~(c & d)
// => ~((a & b) | (c & d))
@Test
@IR(counts = { IRNode.AND , "2",
IRNode.OR , "1",
IRNode.XOR, "1", })
public int test1(int a, int b, int c, int d) {
return (~a | ~b) & (~c | ~d);
}

// Checks (~a & ~b) | (~c & ~d)
// => ~(a | b) | ~(c | d)
// => ~((a | b) & (c | d))
@Test
@IR(counts = { IRNode.AND , "1",
IRNode.OR , "2",
IRNode.XOR, "1", })
public int test2(int a, int b, int c, int d) {
return (~a & ~b) | (~c & ~d);
}

// Checks (~a | ~b) | (~c | ~d)
// => ~(a & b) | ~(c & d)
// => ~((a & b) & (c & d))
@Test
@IR(failOn = { IRNode.OR })
@IR(counts = { IRNode.AND , "3",
IRNode.XOR, "1", })
public int test3(int a, int b, int c, int d) {
return (~a | ~b) | (~c | ~d);
}

// Checks (~a & ~b) & (~c & ~d)
// => ~(a | b) & ~(c | d)
// => ~((a | b) | (c | d))
@Test
@IR(failOn = { IRNode.AND })
@IR(counts = { IRNode.OR , "3",
IRNode.XOR, "1", })
public int test4(int a, int b, int c, int d) {
return (~a & ~b) & (~c & ~d);
}
}
109 changes: 109 additions & 0 deletions test/hotspot/jtreg/compiler/c2/irTests/DeMorganLawLongTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2024, 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.c2.irTests;

import jdk.test.lib.Asserts;
import compiler.lib.ir_framework.*;

/*
* @test
* @bug 8322077
* @summary Test that Ideal transformations on the De Morgan's Law perform
as expected for long.
* @library /test/lib /
* @run driver compiler.c2.irTests.DeMorganLawLongTests
*/
public class DeMorganLawLongTests {

public static void main(String[] args) {
TestFramework.run();
}

@Run(test = { "test1", "test2", "test3", "test4" })
public void runMethod() {
long a = RunInfo.getRandom().nextLong();
long b = RunInfo.getRandom().nextLong();
long c = RunInfo.getRandom().nextLong();
long d = RunInfo.getRandom().nextLong();

long min = Long.MIN_VALUE;
long max = Long.MAX_VALUE;

assertResult(0, 0, 0, 0);
assertResult(a, b, c, d);
assertResult(min, min, min, min);
assertResult(max, max, max, max);
}

@DontCompile
public void assertResult(long a, long b, long c, long d) {
Asserts.assertEQ((~a | ~b) & (~c | ~d), test1(a, b, c, d));
Asserts.assertEQ((~a & ~b) | (~c & ~d), test2(a, b, c, d));
Asserts.assertEQ((~a | ~b) | (~c | ~d), test3(a, b, c, d));
Asserts.assertEQ((~a & ~b) & (~c & ~d), test4(a, b, c, d));
}

// Checks (~a | ~b) & (~c | ~d)
// => ~(a & b) & ~(c & d)
// => ~((a & b) | (c & d))
@Test
@IR(counts = { IRNode.AND , "2",
IRNode.OR , "1",
IRNode.XOR, "1", })
public long test1(long a, long b, long c, long d) {
return (~a | ~b) & (~c | ~d);
}

// Checks (~a & ~b) | (~c & ~d)
// => ~(a | b) | ~(c | d)
// => ~((a | b) & (c | d))
@Test
@IR(counts = { IRNode.AND , "1",
IRNode.OR , "2",
IRNode.XOR, "1", })
public long test2(long a, long b, long c, long d) {
return (~a & ~b) | (~c & ~d);
}

// Checks (~a | ~b) | (~c | ~d)
// => ~(a & b) | ~(c & d)
// => ~((a & b) & (c & d))
@Test
@IR(failOn = { IRNode.OR })
@IR(counts = { IRNode.AND , "3",
IRNode.XOR, "1", })
public long test3(long a, long b, long c, long d) {
return (~a | ~b) | (~c | ~d);
}

// Checks (~a & ~b) & (~c & ~d)
// => ~(a | b) & ~(c | d)
// => ~((a | b) | (c | d))
@Test
@IR(failOn = { IRNode.AND })
@IR(counts = { IRNode.OR , "3",
IRNode.XOR, "1", })
public long test4(long a, long b, long c, long d) {
return (~a & ~b) & (~c & ~d);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2024, 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.c2.irTests;

import jdk.test.lib.Asserts;
import compiler.lib.ir_framework.*;

/*
* @test
* @bug 8322077
* @summary Test that Ideal transformations of OrINode* are being performed as expected.
* @library /test/lib /
* @run driver compiler.c2.irTests.OrINodeIdealizationTests
*/
public class OrINodeIdealizationTests {

public static void main(String[] args) {
TestFramework.run();
}

@Run(test = { "test1" })
public void runMethod() {
int a = RunInfo.getRandom().nextInt();
int b = RunInfo.getRandom().nextInt();

int min = Integer.MIN_VALUE;
int max = Integer.MAX_VALUE;

assertResult(0, 0);
assertResult(a, b);
assertResult(min, min);
assertResult(max, max);
}

@DontCompile
public void assertResult(int a, int b) {
Asserts.assertEQ((~a) | (~b), test1(a, b));
}

// Checks (~a) | (~b) => ~(a & b)
@Test
@IR(failOn = { IRNode.OR })
@IR(counts = { IRNode.AND, "1",
IRNode.XOR, "1" })
public int test1(int a, int b) {
return (~a) | (~b);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2024, 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.c2.irTests;

import jdk.test.lib.Asserts;
import compiler.lib.ir_framework.*;

/*
* @test
* @bug 8322077
* @summary Test that Ideal transformations of OrLNode* are being performed as expected.
* @library /test/lib /
* @run driver compiler.c2.irTests.OrLNodeIdealizationTests
*/
public class OrLNodeIdealizationTests {

public static void main(String[] args) {
TestFramework.run();
}

@Run(test = { "test1" })
public void runMethod() {
long a = RunInfo.getRandom().nextLong();
long b = RunInfo.getRandom().nextLong();

long min = Long.MIN_VALUE;
long max = Long.MAX_VALUE;

assertResult(0, 0);
assertResult(a, b);
assertResult(min, min);
assertResult(max, max);
}

@DontCompile
public void assertResult(long a, long b) {
Asserts.assertEQ((~a) | (~b), test1(a, b));
}

// Checks (~a) | (~b) => ~(a & b)
@Test
@IR(failOn = { IRNode.OR })
@IR(counts = { IRNode.AND, "1",
IRNode.XOR, "1" })
public long test1(long a, long b) {
return (~a) | (~b);
}
}