Skip to content

Commit 6f644e0

Browse files
committed
8273277: C2: Move conditional negation into rc_predicate
Backport-of: 710f496456d642c3e98d230270598f0b2dc75aba
1 parent d1d0b08 commit 6f644e0

File tree

5 files changed

+84
-25
lines changed

5 files changed

+84
-25
lines changed

src/hotspot/share/opto/loopPredicate.cpp

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invari
816816
BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
817817
int scale, Node* offset,
818818
Node* init, Node* limit, jint stride,
819-
Node* range, bool upper, bool &overflow) {
819+
Node* range, bool upper, bool &overflow, bool negate) {
820820
jint con_limit = (limit != NULL && limit->is_Con()) ? limit->get_int() : 0;
821821
jint con_init = init->is_Con() ? init->get_int() : 0;
822822
jint con_offset = offset->is_Con() ? offset->get_int() : 0;
@@ -942,7 +942,7 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
942942
cmp = new CmpUNode(max_idx_expr, range);
943943
}
944944
register_new_node(cmp, ctrl);
945-
BoolNode* bol = new BoolNode(cmp, BoolTest::lt);
945+
BoolNode* bol = new BoolNode(cmp, negate ? BoolTest::ge : BoolTest::lt);
946946
register_new_node(bol, ctrl);
947947

948948
if (TraceLoopPredicate) {
@@ -1309,36 +1309,26 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree *loop, ProjNode*
13091309
}
13101310
// If predicate expressions may overflow in the integer range, longs are used.
13111311
bool overflow = false;
1312+
bool negate = (proj->_con != predicate_proj->_con);
13121313

13131314
// Test the lower bound
1314-
BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow);
1315-
// Negate test if necessary
1316-
bool negated = false;
1317-
if (proj->_con != predicate_proj->_con) {
1318-
lower_bound_bol = new BoolNode(lower_bound_bol->in(1), lower_bound_bol->_test.negate());
1319-
register_new_node(lower_bound_bol, ctrl);
1320-
negated = true;
1321-
}
1315+
BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow, negate);
1316+
13221317
ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, reason, overflow ? Op_If : iff->Opcode());
13231318
IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
13241319
_igvn.hash_delete(lower_bound_iff);
13251320
lower_bound_iff->set_req(1, lower_bound_bol);
1326-
if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx);
1321+
if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negate ? " negated" : "", lower_bound_iff->_idx);
13271322

13281323
// Test the upper bound
1329-
BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow);
1330-
negated = false;
1331-
if (proj->_con != predicate_proj->_con) {
1332-
upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate());
1333-
register_new_node(upper_bound_bol, ctrl);
1334-
negated = true;
1335-
}
1324+
BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow, negate);
1325+
13361326
ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, reason, overflow ? Op_If : iff->Opcode());
13371327
assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
13381328
IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
13391329
_igvn.hash_delete(upper_bound_iff);
13401330
upper_bound_iff->set_req(1, upper_bound_bol);
1341-
if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx);
1331+
if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negate ? " negated" : "", lower_bound_iff->_idx);
13421332

13431333
// Fall through into rest of the clean up code which will move
13441334
// any dependent nodes onto the upper bound test.
@@ -1384,10 +1374,10 @@ ProjNode* PhaseIdealLoop::insert_initial_skeleton_predicate(IfNode* iff, IdealLo
13841374
Node* rng, bool &overflow,
13851375
Deoptimization::DeoptReason reason) {
13861376
// First predicate for the initial value on first loop iteration
1387-
assert(proj->_con && predicate_proj->_con, "not a range check?");
13881377
Node* opaque_init = new OpaqueLoopInitNode(C, init);
13891378
register_new_node(opaque_init, upper_bound_proj);
1390-
BoolNode* bol = rc_predicate(loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng, (stride > 0) != (scale > 0), overflow);
1379+
bool negate = (proj->_con != predicate_proj->_con);
1380+
BoolNode* bol = rc_predicate(loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng, (stride > 0) != (scale > 0), overflow, negate);
13911381
Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1)); // This will go away once loop opts are over
13921382
C->add_skeleton_predicate_opaq(opaque_bol);
13931383
register_new_node(opaque_bol, upper_bound_proj);
@@ -1405,7 +1395,7 @@ ProjNode* PhaseIdealLoop::insert_initial_skeleton_predicate(IfNode* iff, IdealLo
14051395
register_new_node(max_value, new_proj);
14061396
max_value = new AddINode(opaque_init, max_value);
14071397
register_new_node(max_value, new_proj);
1408-
bol = rc_predicate(loop, new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0), overflow);
1398+
bol = rc_predicate(loop, new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0), overflow, negate);
14091399
opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
14101400
C->add_skeleton_predicate_opaq(opaque_bol);
14111401
register_new_node(opaque_bol, new_proj);

src/hotspot/share/opto/loopTransform.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2555,7 +2555,7 @@ Node* PhaseIdealLoop::add_range_check_predicate(IdealLoopTree* loop, CountedLoop
25552555
Node* predicate_proj, int scale_con, Node* offset,
25562556
Node* limit, jint stride_con, Node* value) {
25572557
bool overflow = false;
2558-
BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, value, NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow);
2558+
BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, value, NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow, false);
25592559
Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
25602560
register_new_node(opaque_bol, predicate_proj);
25612561
IfNode* new_iff = NULL;

src/hotspot/share/opto/loopnode.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,8 @@ class PhaseIdealLoop : public PhaseTransform {
13031303
BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl,
13041304
int scale, Node* offset,
13051305
Node* init, Node* limit, jint stride,
1306-
Node* range, bool upper, bool &overflow);
1306+
Node* range, bool upper, bool &overflow,
1307+
bool negate);
13071308

13081309
// Implementation of the loop predication to promote checks outside the loop
13091310
bool loop_predication_impl(IdealLoopTree *loop);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
3+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation.
9+
*
10+
* This code is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* version 2 for more details (a copy is included in the LICENSE file that
14+
* accompanied this code).
15+
*
16+
* You should have received a copy of the GNU General Public License version
17+
* 2 along with this work; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19+
*
20+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21+
* or visit www.oracle.com if you need additional information or have any
22+
* questions.
23+
*/
24+
25+
/**
26+
* @test
27+
* @bug 8273277
28+
* @summary Skeleton predicates sometimes need to be negated
29+
* @run main compiler.loopopts.TestSkeletonPredicateNegation
30+
*
31+
*/
32+
33+
package compiler.loopopts;
34+
35+
public class TestSkeletonPredicateNegation {
36+
public static int in0 = 2;
37+
38+
public static void main(String[] args) {
39+
try {
40+
TestSkeletonPredicateNegation instance = new TestSkeletonPredicateNegation();
41+
for (int i = 0; i < 10000; ++i) {
42+
instance.mainTest(args);
43+
}
44+
} catch (Exception ex) {
45+
System.out.println(ex.getClass().getCanonicalName());
46+
} catch (OutOfMemoryError e) {
47+
System.out.println("OOM Error");
48+
}
49+
}
50+
51+
public void mainTest (String[] args){
52+
long loa11[] = new long[1987];
53+
54+
for (long lo14 : loa11) {
55+
TestSkeletonPredicateNegation.in0 = -128;
56+
for (int i18 = 0; i18 < 52; i18++) {
57+
try {
58+
loa11[TestSkeletonPredicateNegation.in0] %= 2275269548L;
59+
Math.ceil(1374905370.2785515599);
60+
} catch (Exception a_e) {
61+
TestSkeletonPredicateNegation.in0--;
62+
}
63+
}
64+
}
65+
}
66+
}

test/hotspot/jtreg/vmTestbase/jit/t/t105/t105.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@
2323

2424
/*
2525
* @test
26+
* @bug 8273277
2627
*
2728
* @summary converted from VM Testbase jit/t/t105.
2829
* VM Testbase keywords: [jit, quick]
2930
*
3031
* @library /vmTestbase
3132
* /test/lib
3233
* @run main/othervm -XX:-OmitStackTraceInFastThrow jit.t.t105.t105
34+
* @run main/othervm -XX:-OmitStackTraceInFastThrow -Xbatch -XX:Tier0BackedgeNotifyFreqLog=0 -XX:Tier2BackedgeNotifyFreqLog=0 -XX:Tier3BackedgeNotifyFreqLog=0 -XX:Tier2BackEdgeThreshold=1 -XX:Tier3BackEdgeThreshold=1 -XX:Tier4BackEdgeThreshold=1 jit.t.t105.t105
3335
*
34-
* This test must be run with ProfileTraps disabled to avoid preallocated
36+
* This test must be run with OmitStackTraceInFastThrow disabled to avoid preallocated
3537
* exceptions. They don't have the detailed message that this test relies on.
3638
*/
3739

0 commit comments

Comments
 (0)