diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index 539f70c31f9..799f13b5e91 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp @@ -2074,9 +2074,15 @@ const Type* ReverseLNode::Value(PhaseGVN* phase) const { return bottom_type(); } -Node* InvolutionNode::Identity(PhaseGVN* phase) { - // Op ( Op x ) => x - if (in(1)->Opcode() == Opcode()) { +Node* ReverseINode::Identity(PhaseGVN* phase) { + if (in(1)->Opcode() == Op_ReverseI) { + return in(1)->in(1); + } + return this; +} + +Node* ReverseLNode::Identity(PhaseGVN* phase) { + if (in(1)->Opcode() == Op_ReverseL) { return in(1)->in(1); } return this; diff --git a/src/hotspot/share/opto/subnode.hpp b/src/hotspot/share/opto/subnode.hpp index 9a411f3d20e..57a501ecbc3 100644 --- a/src/hotspot/share/opto/subnode.hpp +++ b/src/hotspot/share/opto/subnode.hpp @@ -439,18 +439,11 @@ public: virtual uint ideal_reg() const { return Op_RegI; } }; -//------------------------------InvolutionNode---------------------------------- -// Represents a self-inverse operation, i.e., op(op(x)) = x for any x -class InvolutionNode : public Node { -public: - InvolutionNode(Node* in) : Node(nullptr, in) {} - virtual Node* Identity(PhaseGVN* phase); -}; //------------------------------NegNode---------------------------------------- -class NegNode : public InvolutionNode { +class NegNode : public Node { public: - NegNode(Node* in1) : InvolutionNode(in1) { + NegNode(Node* in1) : Node(nullptr, in1) { init_class_id(Class_Neg); } }; @@ -562,18 +555,16 @@ public: }; -class ReverseBytesNode : public InvolutionNode { +class ReverseBytesNode : public Node { public: - ReverseBytesNode(Node* in) : InvolutionNode(in) {} + ReverseBytesNode(Node* in) : Node(nullptr, in) {} virtual const Type* Value(PhaseGVN* phase) const; }; //-------------------------------ReverseBytesINode-------------------------------- // reverse bytes of an integer class ReverseBytesINode : public ReverseBytesNode { public: - ReverseBytesINode(Node* in) : ReverseBytesNode(in) { - } - + ReverseBytesINode(Node* in) : ReverseBytesNode(in) {} virtual int Opcode() const; const Type* bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } @@ -611,23 +602,25 @@ public: //-------------------------------ReverseINode-------------------------------- // reverse bits of an int -class ReverseINode : public InvolutionNode { +class ReverseINode : public Node { public: - ReverseINode(Node* in) : InvolutionNode(in) {} + ReverseINode(Node* in) : Node(nullptr,in) {} virtual int Opcode() const; const Type* bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } + virtual Node* Identity(PhaseGVN* phase); virtual const Type* Value(PhaseGVN* phase) const; }; //-------------------------------ReverseLNode-------------------------------- // reverse bits of a long -class ReverseLNode : public InvolutionNode { +class ReverseLNode : public Node { public: - ReverseLNode(Node* in) : InvolutionNode(in) {} + ReverseLNode(Node* in) : Node(nullptr, in) {} virtual int Opcode() const; const Type* bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } + virtual Node* Identity(PhaseGVN* phase); virtual const Type* Value(PhaseGVN* phase) const; }; diff --git a/test/hotspot/jtreg/compiler/c2/irTests/InvolutionIdentityTests.java b/test/hotspot/jtreg/compiler/c2/irTests/InvolutionIdentityTests.java deleted file mode 100644 index e1945c8a519..00000000000 --- a/test/hotspot/jtreg/compiler/c2/irTests/InvolutionIdentityTests.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2025, 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 compiler.lib.generators.Generator; -import compiler.lib.generators.Generators; -import compiler.lib.generators.RestrictableGenerator; -import compiler.lib.ir_framework.DontCompile; -import compiler.lib.ir_framework.IR; -import compiler.lib.ir_framework.IRNode; -import compiler.lib.ir_framework.Run; -import compiler.lib.ir_framework.Test; -import compiler.lib.ir_framework.TestFramework; -import jdk.test.lib.Asserts; - -/* - * @test - * @bug 8350988 - * @summary Test that Identity simplifications of Involution nodes are being performed as expected. - * @library /test/lib / - * @run driver compiler.c2.irTests.InvolutionIdentityTests - */ -public class InvolutionIdentityTests { - - public static final RestrictableGenerator GEN_CHAR = Generators.G.safeRestrict(Generators.G.ints(), Character.MIN_VALUE, Character.MAX_VALUE); - public static final RestrictableGenerator GEN_SHORT = Generators.G.safeRestrict(Generators.G.ints(), Short.MIN_VALUE, Short.MAX_VALUE); - public static final RestrictableGenerator GEN_LONG = Generators.G.longs(); - public static final RestrictableGenerator GEN_INT = Generators.G.ints(); - public static final Generator GEN_FLOAT = Generators.G.floats(); - public static final Generator GEN_DOUBLE = Generators.G.doubles(); - - public static void main(String[] args) { - TestFramework.run(); - } - - @Run(test = { - "testI1", "testI2", - "testL1", "testL2", - "testS1", - "testUS1", - "testF1", - "testD1" - }) - public void runMethod() { - int ai = GEN_INT.next(); - - int mini = Integer.MIN_VALUE; - int maxi = Integer.MAX_VALUE; - - assertResultI(0); - assertResultI(ai); - assertResultI(mini); - assertResultI(maxi); - - long al = GEN_LONG.next(); - - long minl = Long.MIN_VALUE; - long maxl = Long.MAX_VALUE; - - assertResultL(0); - assertResultL(al); - assertResultL(minl); - assertResultL(maxl); - - short as = GEN_SHORT.next().shortValue(); - - short mins = Short.MIN_VALUE; - short maxs = Short.MAX_VALUE; - - assertResultS((short) 0); - assertResultS(as); - assertResultS(mins); - assertResultS(maxs); - - char ac = (char) GEN_CHAR.next().intValue(); - - char minc = Character.MIN_VALUE; - char maxc = Character.MAX_VALUE; - - assertResultUS((char) 0); - assertResultUS(ac); - assertResultUS(minc); - assertResultUS(maxc); - - float af = GEN_FLOAT.next(); - float inf = Float.POSITIVE_INFINITY; - float nanf = Float.NaN; - - assertResultF(0f); - assertResultF(-0f); - assertResultF(af); - assertResultF(inf); - assertResultF(nanf); - - double ad = GEN_DOUBLE.next(); - double ind = Double.POSITIVE_INFINITY; - double nand = Double.NaN; - - assertResultD(0d); - assertResultD(-0d); - assertResultD(ad); - assertResultD(ind); - assertResultD(nand); - - } - - @DontCompile - public void assertResultI(int a) { - Asserts.assertEQ(Integer.reverseBytes(Integer.reverseBytes(a)), testI1(a)); - Asserts.assertEQ(Integer.reverse(Integer.reverse(a)) , testI2(a)); - } - - @DontCompile - public void assertResultL(long a) { - Asserts.assertEQ(Long.reverseBytes(Long.reverseBytes(a)), testL1(a)); - Asserts.assertEQ(Long.reverse(Long.reverse(a)) , testL2(a)); - } - - @DontCompile - public void assertResultS(short a) { - Asserts.assertEQ(Short.reverseBytes(Short.reverseBytes(a)), testS1(a)); - } - - @DontCompile - public void assertResultUS(char a) { - Asserts.assertEQ(Character.reverseBytes(Character.reverseBytes(a)), testUS1(a)); - } - - @DontCompile - public void assertResultF(float a) { - Asserts.assertEQ(Float.floatToRawIntBits(-(-a)), Float.floatToRawIntBits(testF1(a))); - } - - @DontCompile - public void assertResultD(double a) { - Asserts.assertEQ(Double.doubleToRawLongBits(-(-a)), Double.doubleToRawLongBits(testD1(a))); - } - - @Test - @IR(failOn = {IRNode.REVERSE_BYTES_I}) - public int testI1(int x) { - return Integer.reverseBytes(Integer.reverseBytes(x)); - } - - @Test - @IR(failOn = {IRNode.REVERSE_I}) - public int testI2(int x) { - return Integer.reverse(Integer.reverse(x)); - } - - @Test - @IR(failOn = {IRNode.REVERSE_BYTES_L}) - public long testL1(long x) { - return Long.reverseBytes(Long.reverseBytes(x)); - } - - @Test - @IR(failOn = {IRNode.REVERSE_L}) - public long testL2(long x) { - return Long.reverse(Long.reverse(x)); - } - - @Test - @IR(failOn = {IRNode.REVERSE_BYTES_S}) - public short testS1(short x) { - return Short.reverseBytes(Short.reverseBytes(x)); - } - - @Test - @IR(failOn = {IRNode.REVERSE_BYTES_US}) - public char testUS1(char x) { - return Character.reverseBytes(Character.reverseBytes(x)); - } - - @Test - @IR(failOn = {IRNode.NEG_F}) - public float testF1(float x) { - return -(-x); - } - - @Test - @IR(failOn = {IRNode.NEG_D}) - public double testD1(double x) { - return -(-x); - } -} diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 96b62a2b12a..f53bb45bd43 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -1469,16 +1469,6 @@ public class IRNode { superWordNodes(MAX_REDUCTION_V, "MaxReductionV"); } - public static final String NEG_F = PREFIX + "NEG_F" + POSTFIX; - static { - beforeMatchingNameRegex(NEG_F, "NegF"); - } - - public static final String NEG_D = PREFIX + "NEG_D" + POSTFIX; - static { - beforeMatchingNameRegex(NEG_D, "NegD"); - } - public static final String NEG_VF = VECTOR_PREFIX + "NEG_VF" + POSTFIX; static { vectorNode(NEG_VF, "NegVF", TYPE_FLOAT);