From 4c1e90a7217df9cc7f90544638bb35e7800245a4 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Mon, 6 Sep 2021 09:54:44 -0400 Subject: [PATCH 1/9] v0 --- src/hotspot/share/opto/mulnode.cpp | 26 ++++++ .../integerArithmetic/TestNegMultiply.java | 88 +++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index 5d2b91a704a14..ed7af6f20d60d 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -201,6 +201,19 @@ const Type* MulNode::Value(PhaseGVN* phase) const { //------------------------------Ideal------------------------------------------ // Check for power-of-2 multiply, then try the regular MulNode::Ideal Node *MulINode::Ideal(PhaseGVN *phase, bool can_reshape) { + // convert "(-a)*(-b)" into "a*b" + Node *in1 = in(1); + Node *in2 = in(2); + if (in1->Opcode() == Op_SubI && in2->Opcode() == Op_SubI) { + Node* n11 = in1->in(1); + Node* n21 = in2->in(1); + const Type* t11 = phase->type(n11); + const Type* t21 = phase->type(n21); + if (t11 == TypeInt::ZERO && t21 == TypeInt::ZERO) { + return new MulINode(in1->in(2), in2->in(2)); + } + } + // Swap constant to right jint con; if ((con = in(1)->find_int_con(0)) != 0) { @@ -296,6 +309,19 @@ const Type *MulINode::mul_ring(const Type *t0, const Type *t1) const { //------------------------------Ideal------------------------------------------ // Check for power-of-2 multiply, then try the regular MulNode::Ideal Node *MulLNode::Ideal(PhaseGVN *phase, bool can_reshape) { + // convert "(-a)*(-b)" into "a*b" + Node *in1 = in(1); + Node *in2 = in(2); + if (in1->Opcode() == Op_SubL && in2->Opcode() == Op_SubL) { + Node* n11 = in1->in(1); + Node* n21 = in2->in(1); + const Type* t11 = phase->type(n11); + const Type* t21 = phase->type(n21); + if (t11 == TypeLong::ZERO && t21 == TypeLong::ZERO) { + return new MulLNode(in1->in(2), in2->in(2)); + } + } + // Swap constant to right jlong con; if ((con = in(1)->find_long_con(0)) != 0) { diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java new file mode 100644 index 0000000000000..3c7a023e0da0f --- /dev/null +++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021, Red Hat, Inc. 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. + */ + +/** + * @test + * @bug 8270366 + * @summary Test transformation (-a)*(-b) = a*b + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestAssociative + * + */ + +public class Test { + private static final int[][2] intParams = { + {Integer.MAX_VALUE, Integer.MAX_VALUE}, + {Integer.MIN_VALUE, Integer.MIN_VALUE}, + {Integer.MAX_VALUE, Integer.MIN_VALUE}, + {232, 34}, + {-23, 445}, + {-244, -84}, + {233, -99} + }; + + private static int intTest(int a, int b) { + return (-a) * (-b); + } + + private static void runIntTest() { + for (int index = 0; index < intParams.length; index ++) { + int result = intTest(intParams[index][0], intParams[index][1]); + for (int i = 0; i < 20_000; i++) { + if (result != intTest(intParams[index][0], intParams[index][1])) { + throw new RuntimeException("incorrect result"); + } + } + } + } + + private static final int[][2] longParams = { + {Long.MAX_VALUE, Long.MAX_VALUE}, + {Long.MIN_VALUE, Long.MIN_VALUE}, + {Long.MAX_VALUE, Long.MIN_VALUE}, + {232L, 34L}, + {-23L, 445L}, + {-244L, -84L}, + {233L, -99L} + }; + + private static long longTest(long a, long b) { + return (-a) * (-b); + } + + private static void runLongTest() { + for (int index = 0; index < intParams.length; index ++) { + long result = longTest(longParams[index][0], longParams[index][1]); + for (int i = 0; i < 20_000; i++) { + if (result != longTest(longParams[index][0], longParams[index][1])) { + throw new RuntimeException("incorrect result"); + } + } + } + } + + public static void main(String[] args) { + runIntTest(); + runLongTest(); + } +} From 1ed1d7e1139f962df61bebdd8352d5ac4d0846c7 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Mon, 6 Sep 2021 10:24:35 -0400 Subject: [PATCH 2/9] v1 --- src/hotspot/share/opto/mulnode.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index ed7af6f20d60d..631d3aede6b76 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -207,9 +207,8 @@ Node *MulINode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in1->Opcode() == Op_SubI && in2->Opcode() == Op_SubI) { Node* n11 = in1->in(1); Node* n21 = in2->in(1); - const Type* t11 = phase->type(n11); - const Type* t21 = phase->type(n21); - if (t11 == TypeInt::ZERO && t21 == TypeInt::ZERO) { + if (phase->type(n11)->higher_equal(TypeInt::ZERO) && + phase->type(n21)->higher_equal(TypeInt::ZERO)) { return new MulINode(in1->in(2), in2->in(2)); } } @@ -315,9 +314,8 @@ Node *MulLNode::Ideal(PhaseGVN *phase, bool can_reshape) { if (in1->Opcode() == Op_SubL && in2->Opcode() == Op_SubL) { Node* n11 = in1->in(1); Node* n21 = in2->in(1); - const Type* t11 = phase->type(n11); - const Type* t21 = phase->type(n21); - if (t11 == TypeLong::ZERO && t21 == TypeLong::ZERO) { + if (phase->type(n11)->higher_equal(TypeLong::ZERO) && + phase->type(n21)->higher_equal(TypeLong::ZERO)) { return new MulLNode(in1->in(2), in2->in(2)); } } From c55a3273d96a2da29bcff2cacc251aa17a7c7b65 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 7 Sep 2021 22:04:54 -0400 Subject: [PATCH 3/9] Fix test --- .../jtreg/compiler/integerArithmetic/TestNegMultiply.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java index 3c7a023e0da0f..b706339434c81 100644 --- a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java +++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java @@ -26,12 +26,12 @@ * @bug 8270366 * @summary Test transformation (-a)*(-b) = a*b * - * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestAssociative + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestNegMultiply * */ -public class Test { - private static final int[][2] intParams = { +public class TestNegMultiply { + private static final int[][] intParams = { {Integer.MAX_VALUE, Integer.MAX_VALUE}, {Integer.MIN_VALUE, Integer.MIN_VALUE}, {Integer.MAX_VALUE, Integer.MIN_VALUE}, @@ -56,7 +56,7 @@ private static void runIntTest() { } } - private static final int[][2] longParams = { + private static final long[][] longParams = { {Long.MAX_VALUE, Long.MAX_VALUE}, {Long.MIN_VALUE, Long.MIN_VALUE}, {Long.MAX_VALUE, Long.MIN_VALUE}, From be01f17df177555856958d2f234f860440740dc0 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Thu, 9 Sep 2021 09:17:20 -0400 Subject: [PATCH 4/9] @theRealELiu and @TobiHartmann's comments --- src/hotspot/share/opto/mulnode.cpp | 36 ++---- src/hotspot/share/opto/mulnode.hpp | 6 + .../integerArithmetic/TestNegMultiply.java | 114 ++++++++++++------ 3 files changed, 94 insertions(+), 62 deletions(-) diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index 631d3aede6b76..94a9d05d0bc22 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -63,9 +63,19 @@ Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) { const Type *t2 = phase->type( in(2) ); Node *progress = NULL; // Progress flag - // convert "max(a,b) * min(a,b)" into "a*b". + // convert "(-a)*(-b)" into "a*b" Node *in1 = in(1); Node *in2 = in(2); + if (in1->is_Sub() && in2->is_Sub()) { + Node* n11 = in1->in(1); + Node* n21 = in2->in(1); + if (phase->type(n11)->is_zero_type() && + phase->type(n21)->is_zero_type()) { + return make(in1->in(2), in2->in(2)); + } + } + + // convert "max(a,b) * min(a,b)" into "a*b". if ((in(1)->Opcode() == max_opcode() && in(2)->Opcode() == min_opcode()) || (in(1)->Opcode() == min_opcode() && in(2)->Opcode() == max_opcode())) { Node *in11 = in(1)->in(1); @@ -201,18 +211,6 @@ const Type* MulNode::Value(PhaseGVN* phase) const { //------------------------------Ideal------------------------------------------ // Check for power-of-2 multiply, then try the regular MulNode::Ideal Node *MulINode::Ideal(PhaseGVN *phase, bool can_reshape) { - // convert "(-a)*(-b)" into "a*b" - Node *in1 = in(1); - Node *in2 = in(2); - if (in1->Opcode() == Op_SubI && in2->Opcode() == Op_SubI) { - Node* n11 = in1->in(1); - Node* n21 = in2->in(1); - if (phase->type(n11)->higher_equal(TypeInt::ZERO) && - phase->type(n21)->higher_equal(TypeInt::ZERO)) { - return new MulINode(in1->in(2), in2->in(2)); - } - } - // Swap constant to right jint con; if ((con = in(1)->find_int_con(0)) != 0) { @@ -308,18 +306,6 @@ const Type *MulINode::mul_ring(const Type *t0, const Type *t1) const { //------------------------------Ideal------------------------------------------ // Check for power-of-2 multiply, then try the regular MulNode::Ideal Node *MulLNode::Ideal(PhaseGVN *phase, bool can_reshape) { - // convert "(-a)*(-b)" into "a*b" - Node *in1 = in(1); - Node *in2 = in(2); - if (in1->Opcode() == Op_SubL && in2->Opcode() == Op_SubL) { - Node* n11 = in1->in(1); - Node* n21 = in2->in(1); - if (phase->type(n11)->higher_equal(TypeLong::ZERO) && - phase->type(n21)->higher_equal(TypeLong::ZERO)) { - return new MulLNode(in1->in(2), in2->in(2)); - } - } - // Swap constant to right jlong con; if ((con = in(1)->find_long_con(0)) != 0) { diff --git a/src/hotspot/share/opto/mulnode.hpp b/src/hotspot/share/opto/mulnode.hpp index d399af5a990d1..aae45c53b565a 100644 --- a/src/hotspot/share/opto/mulnode.hpp +++ b/src/hotspot/share/opto/mulnode.hpp @@ -80,6 +80,8 @@ class MulNode : public Node { // Supplied function to return the multiplicative opcode virtual int min_opcode() const = 0; + + virtual MulNode* make(Node* in1, Node* in2) const = 0; }; //------------------------------MulINode--------------------------------------- @@ -98,6 +100,7 @@ class MulINode : public MulNode { int min_opcode() const { return Op_MinI; } const Type *bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } + virtual MulNode* make(Node* in1, Node* in2) const { return new MulINode(in1, in2); } }; //------------------------------MulLNode--------------------------------------- @@ -116,6 +119,7 @@ class MulLNode : public MulNode { int min_opcode() const { return Op_MinL; } const Type *bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } + virtual MulNode* make(Node* in1, Node* in2) const { return new MulLNode(in1, in2); } }; @@ -134,6 +138,7 @@ class MulFNode : public MulNode { int min_opcode() const { return Op_MinF; } const Type *bottom_type() const { return Type::FLOAT; } virtual uint ideal_reg() const { return Op_RegF; } + virtual MulNode* make(Node* in1, Node* in2) const { return new MulFNode(in1, in2); } }; //------------------------------MulDNode--------------------------------------- @@ -151,6 +156,7 @@ class MulDNode : public MulNode { int min_opcode() const { return Op_MinD; } const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } + virtual MulNode* make(Node* in1, Node* in2) const { return new MulDNode(in1, in2); } }; //-------------------------------MulHiLNode------------------------------------ diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java index b706339434c81..8e5e44b70982e 100644 --- a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java +++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java @@ -23,66 +23,106 @@ /** * @test - * @bug 8270366 + * @bug 8273454 * @summary Test transformation (-a)*(-b) = a*b * * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestNegMultiply * */ +import java.util.Random; + public class TestNegMultiply { - private static final int[][] intParams = { - {Integer.MAX_VALUE, Integer.MAX_VALUE}, - {Integer.MIN_VALUE, Integer.MIN_VALUE}, - {Integer.MAX_VALUE, Integer.MIN_VALUE}, - {232, 34}, - {-23, 445}, - {-244, -84}, - {233, -99} - }; + private static Random random = new Random(); + private static final int TEST_COUNT = 2000; + + private static int test(int a, int b) { + return (-a) * (-b); + } + private static void testInt(int a, int b) { + int expected = (-a) * (-b); + for (int i = 0; i < 20_000; i++) { + if (expected != test(a, b)) { + throw new RuntimeException("Incorrect result."); + } + } + } - private static int intTest(int a, int b) { + private static long test(long a, long b) { return (-a) * (-b); } - private static void runIntTest() { - for (int index = 0; index < intParams.length; index ++) { - int result = intTest(intParams[index][0], intParams[index][1]); - for (int i = 0; i < 20_000; i++) { - if (result != intTest(intParams[index][0], intParams[index][1])) { - throw new RuntimeException("incorrect result"); - } + private static void testLong(long a, long b) { + long expected = (-a) * (-b); + for (int i = 0; i < 20_000; i++) { + if (expected != test(a, b)) { + throw new RuntimeException("Incorrect result."); } } } - private static final long[][] longParams = { - {Long.MAX_VALUE, Long.MAX_VALUE}, - {Long.MIN_VALUE, Long.MIN_VALUE}, - {Long.MAX_VALUE, Long.MIN_VALUE}, - {232L, 34L}, - {-23L, 445L}, - {-244L, -84L}, - {233L, -99L} - }; + private static float test(float a, float b) { + return (-a) * (-b); + } + + private static void testFloat(float a, float b) { + float expected = (-a) * (-b); + for (int i = 0; i < 20_000; i++) { + if (expected != test(a, b)) { + throw new RuntimeException("Incorrect result."); + } + } + } - private static long longTest(long a, long b) { + private static double test(double a, double b) { return (-a) * (-b); } - private static void runLongTest() { - for (int index = 0; index < intParams.length; index ++) { - long result = longTest(longParams[index][0], longParams[index][1]); - for (int i = 0; i < 20_000; i++) { - if (result != longTest(longParams[index][0], longParams[index][1])) { - throw new RuntimeException("incorrect result"); - } + private static void testDouble(double a, double b) { + double expected = (-a) * (-b); + for (int i = 0; i < 20_000; i++) { + if (expected != test(a, b)) { + throw new RuntimeException("Incorrect result."); } } } + private static void runIntTests() { + for (int index = 0; index < TEST_COUNT; index ++) { + int a = random.nextInt(); + int b = random.nextInt(); + testInt(a, b); + } + } + + private static void runLongTests() { + for (int index = 0; index < TEST_COUNT; index ++) { + long a = random.nextLong(); + long b = random.nextLong(); + testLong(a, b); + } + } + + private static void runFloatTests() { + for (int index = 0; index < TEST_COUNT; index ++) { + float a = random.nextFloat(); + float b = random.nextFloat(); + testFloat(a, b); + } + } + + private static void runDoubleTests() { + for (int index = 0; index < TEST_COUNT; index ++) { + double a = random.nextDouble(); + double b = random.nextDouble(); + testDouble(a, b); + } + } + public static void main(String[] args) { - runIntTest(); - runLongTest(); + runIntTests(); + runLongTests(); + runFloatTests(); + runDoubleTests(); } } From 8f7f241f6a5e909f79e54b4986202ee60a52c1e9 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Thu, 9 Sep 2021 09:20:41 -0400 Subject: [PATCH 5/9] Spacing --- .../jtreg/compiler/integerArithmetic/TestNegMultiply.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java index 8e5e44b70982e..e69042656ea84 100644 --- a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java +++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java @@ -39,6 +39,7 @@ public class TestNegMultiply { private static int test(int a, int b) { return (-a) * (-b); } + private static void testInt(int a, int b) { int expected = (-a) * (-b); for (int i = 0; i < 20_000; i++) { From 71aa6ac439b67b27828e9aabe51845fa34602837 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Thu, 9 Sep 2021 10:51:54 -0400 Subject: [PATCH 6/9] Fix node in place instead of creating new node --- src/hotspot/share/opto/mulnode.cpp | 9 ++++++++- src/hotspot/share/opto/mulnode.hpp | 6 ------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index 94a9d05d0bc22..f0a5fd1e4dc99 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -71,7 +71,14 @@ Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node* n21 = in2->in(1); if (phase->type(n11)->is_zero_type() && phase->type(n21)->is_zero_type()) { - return make(in1->in(2), in2->in(2)); + set_req(1, in1->in(2)); + set_req(2, in2->in(2)); + PhaseIterGVN* igvn = phase->is_IterGVN(); + if (igvn) { + igvn->_worklist.push(in1); + igvn->_worklist.push(in2); + } + progress = this; } } diff --git a/src/hotspot/share/opto/mulnode.hpp b/src/hotspot/share/opto/mulnode.hpp index aae45c53b565a..d399af5a990d1 100644 --- a/src/hotspot/share/opto/mulnode.hpp +++ b/src/hotspot/share/opto/mulnode.hpp @@ -80,8 +80,6 @@ class MulNode : public Node { // Supplied function to return the multiplicative opcode virtual int min_opcode() const = 0; - - virtual MulNode* make(Node* in1, Node* in2) const = 0; }; //------------------------------MulINode--------------------------------------- @@ -100,7 +98,6 @@ class MulINode : public MulNode { int min_opcode() const { return Op_MinI; } const Type *bottom_type() const { return TypeInt::INT; } virtual uint ideal_reg() const { return Op_RegI; } - virtual MulNode* make(Node* in1, Node* in2) const { return new MulINode(in1, in2); } }; //------------------------------MulLNode--------------------------------------- @@ -119,7 +116,6 @@ class MulLNode : public MulNode { int min_opcode() const { return Op_MinL; } const Type *bottom_type() const { return TypeLong::LONG; } virtual uint ideal_reg() const { return Op_RegL; } - virtual MulNode* make(Node* in1, Node* in2) const { return new MulLNode(in1, in2); } }; @@ -138,7 +134,6 @@ class MulFNode : public MulNode { int min_opcode() const { return Op_MinF; } const Type *bottom_type() const { return Type::FLOAT; } virtual uint ideal_reg() const { return Op_RegF; } - virtual MulNode* make(Node* in1, Node* in2) const { return new MulFNode(in1, in2); } }; //------------------------------MulDNode--------------------------------------- @@ -156,7 +151,6 @@ class MulDNode : public MulNode { int min_opcode() const { return Op_MinD; } const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } - virtual MulNode* make(Node* in1, Node* in2) const { return new MulDNode(in1, in2); } }; //-------------------------------MulHiLNode------------------------------------ From f9d7d6126509b7dda120f4343d0e8802875801dc Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Wed, 15 Sep 2021 11:02:01 -0400 Subject: [PATCH 7/9] @TobiHartmann's comments --- src/hotspot/share/opto/mulnode.cpp | 6 +- .../integerArithmetic/TestNegMultiply.java | 88 +++++++++---------- 2 files changed, 42 insertions(+), 52 deletions(-) diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index f0a5fd1e4dc99..be5039268b287 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -67,10 +67,8 @@ Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) { Node *in1 = in(1); Node *in2 = in(2); if (in1->is_Sub() && in2->is_Sub()) { - Node* n11 = in1->in(1); - Node* n21 = in2->in(1); - if (phase->type(n11)->is_zero_type() && - phase->type(n21)->is_zero_type()) { + if (phase->type(in1->in(1))->is_zero_type() && + phase->type(in2->in(1))->is_zero_type()) { set_req(1, in1->in(2)); set_req(2, in2->in(2)); PhaseIterGVN* igvn = phase->is_IterGVN(); diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java index e69042656ea84..bcb337708378e 100644 --- a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java +++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java @@ -23,100 +23,92 @@ /** * @test + * @key randomness * @bug 8273454 * @summary Test transformation (-a)*(-b) = a*b * - * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestNegMultiply + * @library /test/lib + * + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:CompileCommand="dontinline,TestNegMultiply::test*" TestNegMultiply * */ import java.util.Random; +import jdk.test.lib.Utils; +import jdk.test.lib.Asserts; + public class TestNegMultiply { - private static Random random = new Random(); + private static final Random random = Utils.getRandomInstance(); private static final int TEST_COUNT = 2000; - private static int test(int a, int b) { + private static int testInt(int a, int b) { return (-a) * (-b); } - - private static void testInt(int a, int b) { - int expected = (-a) * (-b); - for (int i = 0; i < 20_000; i++) { - if (expected != test(a, b)) { - throw new RuntimeException("Incorrect result."); - } - } - } - - private static long test(long a, long b) { + private static long testLong(long a, long b) { return (-a) * (-b); } - - private static void testLong(long a, long b) { - long expected = (-a) * (-b); - for (int i = 0; i < 20_000; i++) { - if (expected != test(a, b)) { - throw new RuntimeException("Incorrect result."); - } - } - } - - private static float test(float a, float b) { + private static float testFloat(float a, float b) { return (-a) * (-b); } - - private static void testFloat(float a, float b) { - float expected = (-a) * (-b); - for (int i = 0; i < 20_000; i++) { - if (expected != test(a, b)) { - throw new RuntimeException("Incorrect result."); - } - } - } - - private static double test(double a, double b) { + private static double testDouble(double a, double b) { return (-a) * (-b); } - private static void testDouble(double a, double b) { - double expected = (-a) * (-b); + private static void runIntTests() { + // Ensure testInt() is JIT-ed for (int i = 0; i < 20_000; i++) { - if (expected != test(a, b)) { - throw new RuntimeException("Incorrect result."); - } + testInt(1, 2); } - } - - private static void runIntTests() { for (int index = 0; index < TEST_COUNT; index ++) { int a = random.nextInt(); int b = random.nextInt(); - testInt(a, b); + int expected = (-a) * (-b); + int res = testInt(a, b); + Asserts.assertEQ(res, expected); } } private static void runLongTests() { + // Ensure testLong() is JIT-ed + for (int i = 0; i < 20_000; i++) { + testLong(1L, 2L); + } + for (int index = 0; index < TEST_COUNT; index ++) { long a = random.nextLong(); long b = random.nextLong(); - testLong(a, b); + long expected = (-a) * (-b); + long res = testLong(a, b); + Asserts.assertEQ(res, expected); } } private static void runFloatTests() { + // Ensure testFloat() is JIT-ed + for (int i = 0; i < 20_000; i++) { + testFloat(1.0f, 2.0f); + } for (int index = 0; index < TEST_COUNT; index ++) { float a = random.nextFloat(); float b = random.nextFloat(); - testFloat(a, b); + float expected = (-a) * (-b); + float res = testFloat(a, b); + Asserts.assertEQ(res, expected); } } private static void runDoubleTests() { + // Ensure testDouble() is JIT-ed + for (int i = 0; i < 20_000; i++) { + testDouble(1.0, 2.0); + } for (int index = 0; index < TEST_COUNT; index ++) { double a = random.nextDouble(); double b = random.nextDouble(); - testDouble(a, b); + double expected = (-a) * (-b); + double res = testDouble(a, b); + Asserts.assertEQ(res, expected); } } From 3f3eeb01c49955289ab5aa81c1d1ad0b5a358404 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Wed, 15 Sep 2021 11:23:41 -0400 Subject: [PATCH 8/9] Trailing space --- .../jtreg/compiler/integerArithmetic/TestNegMultiply.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java index bcb337708378e..5bcff56eb901a 100644 --- a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java +++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java @@ -28,7 +28,7 @@ * @summary Test transformation (-a)*(-b) = a*b * * @library /test/lib - * + * * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:CompileCommand="dontinline,TestNegMultiply::test*" TestNegMultiply * */ @@ -37,7 +37,6 @@ import jdk.test.lib.Utils; import jdk.test.lib.Asserts; - public class TestNegMultiply { private static final Random random = Utils.getRandomInstance(); private static final int TEST_COUNT = 2000; From 57d1ecf2f997eba355437fd6b364bda26eca4dd7 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Thu, 16 Sep 2021 14:22:47 -0400 Subject: [PATCH 9/9] @TobiHartmann's comments --- .../integerArithmetic/TestNegMultiply.java | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java index 5bcff56eb901a..a702dd7afa6b5 100644 --- a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java +++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java @@ -29,7 +29,7 @@ * * @library /test/lib * - * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:CompileCommand="dontinline,TestNegMultiply::test*" TestNegMultiply + * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand="dontinline,TestNegMultiply::test*" TestNegMultiply * */ @@ -39,7 +39,8 @@ public class TestNegMultiply { private static final Random random = Utils.getRandomInstance(); - private static final int TEST_COUNT = 2000; + // Enough cycles to ensure test methods are JIT-ed + private static final int TEST_COUNT = 20_000; private static int testInt(int a, int b) { return (-a) * (-b); @@ -55,10 +56,6 @@ private static double testDouble(double a, double b) { } private static void runIntTests() { - // Ensure testInt() is JIT-ed - for (int i = 0; i < 20_000; i++) { - testInt(1, 2); - } for (int index = 0; index < TEST_COUNT; index ++) { int a = random.nextInt(); int b = random.nextInt(); @@ -69,11 +66,6 @@ private static void runIntTests() { } private static void runLongTests() { - // Ensure testLong() is JIT-ed - for (int i = 0; i < 20_000; i++) { - testLong(1L, 2L); - } - for (int index = 0; index < TEST_COUNT; index ++) { long a = random.nextLong(); long b = random.nextLong(); @@ -84,10 +76,6 @@ private static void runLongTests() { } private static void runFloatTests() { - // Ensure testFloat() is JIT-ed - for (int i = 0; i < 20_000; i++) { - testFloat(1.0f, 2.0f); - } for (int index = 0; index < TEST_COUNT; index ++) { float a = random.nextFloat(); float b = random.nextFloat(); @@ -98,10 +86,6 @@ private static void runFloatTests() { } private static void runDoubleTests() { - // Ensure testDouble() is JIT-ed - for (int i = 0; i < 20_000; i++) { - testDouble(1.0, 2.0); - } for (int index = 0; index < TEST_COUNT; index ++) { double a = random.nextDouble(); double b = random.nextDouble();