diff --git a/src/hotspot/share/opto/subnode.cpp b/src/hotspot/share/opto/subnode.cpp index c317759585a..f6790172351 100644 --- a/src/hotspot/share/opto/subnode.cpp +++ b/src/hotspot/share/opto/subnode.cpp @@ -152,6 +152,16 @@ static bool ok_to_convert(Node* inc, Node* var) { return !(is_cloop_increment(inc) || var->is_cloop_ind_var()); } +static bool is_cloop_condition(BoolNode* bol) { + for (DUIterator_Fast imax, i = bol->fast_outs(imax); i < imax; i++) { + Node* out = bol->fast_out(i); + if (out->is_CountedLoopEnd()) { + return true; + } + } + return false; +} + //------------------------------Ideal------------------------------------------ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ Node *in1 = in(1); @@ -1556,15 +1566,15 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) { // and "cmp (add X min_jint) c" into "cmpu X (c + min_jint)" if (cop == Op_CmpI && cmp1_op == Op_AddI && - !is_cloop_increment(cmp1) && - phase->type(cmp1->in(2)) == TypeInt::MIN) { + phase->type(cmp1->in(2)) == TypeInt::MIN && + !is_cloop_condition(this)) { if (cmp2_op == Op_ConI) { Node* ncmp2 = phase->intcon(java_add(cmp2->get_int(), min_jint)); Node* ncmp = phase->transform(new CmpUNode(cmp1->in(1), ncmp2)); return new BoolNode(ncmp, _test._test); } else if (cmp2_op == Op_AddI && - !is_cloop_increment(cmp2) && - phase->type(cmp2->in(2)) == TypeInt::MIN) { + phase->type(cmp2->in(2)) == TypeInt::MIN && + !is_cloop_condition(this)) { Node* ncmp = phase->transform(new CmpUNode(cmp1->in(1), cmp2->in(1))); return new BoolNode(ncmp, _test._test); } @@ -1574,15 +1584,15 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) { // and "cmp (add X min_jlong) c" into "cmpu X (c + min_jlong)" if (cop == Op_CmpL && cmp1_op == Op_AddL && - !is_cloop_increment(cmp1) && - phase->type(cmp1->in(2)) == TypeLong::MIN) { + phase->type(cmp1->in(2)) == TypeLong::MIN && + !is_cloop_condition(this)) { if (cmp2_op == Op_ConL) { Node* ncmp2 = phase->longcon(java_add(cmp2->get_long(), min_jlong)); Node* ncmp = phase->transform(new CmpULNode(cmp1->in(1), ncmp2)); return new BoolNode(ncmp, _test._test); } else if (cmp2_op == Op_AddL && - !is_cloop_increment(cmp2) && - phase->type(cmp2->in(2)) == TypeLong::MIN) { + phase->type(cmp2->in(2)) == TypeLong::MIN && + !is_cloop_condition(this)) { Node* ncmp = phase->transform(new CmpULNode(cmp1->in(1), cmp2->in(1))); return new BoolNode(ncmp, _test._test); } diff --git a/test/hotspot/jtreg/compiler/c2/MinValueStrideCountedLoop.java b/test/hotspot/jtreg/compiler/c2/MinValueStrideCountedLoop.java index 7870e0ade6c..dcae2817883 100644 --- a/test/hotspot/jtreg/compiler/c2/MinValueStrideCountedLoop.java +++ b/test/hotspot/jtreg/compiler/c2/MinValueStrideCountedLoop.java @@ -31,17 +31,41 @@ package compiler.c2; * -XX:CompileCommand=compileonly,*MinValueStrideCountedLoop::test* * compiler.c2.MinValueStrideCountedLoop */ + +/* + * @test + * @bug 8316719 + * @summary Loop increment should not be transformed into unsigned comparison + * @requires vm.compiler2.enabled + * @run main/othervm -Xcomp -XX:-TieredCompilation -XX:-UseLoopPredicate + * -XX:CompileCommand=compileonly,*MinValueStrideCountedLoop::test* + * compiler.c2.MinValueStrideCountedLoop + */ public class MinValueStrideCountedLoop { static int limit = 0; static int res = 0; + static int[] array = new int[1]; + static boolean b; - static void test() { + static void test1() { for (int i = 0; i >= limit + -2147483647; i += -2147483648) { res += 42; } } + static int test2(int init, int limit) { + int res = 0; + int i = init; + do { + if (b) { } + res += array[i]; + i += -2147483648; + } while (i >= limit + -2147483647); + return res; + } + public static void main(String[] args) { - test(); + test1(); + test2(0, 0); } }