Skip to content

Commit 710f496

Browse files
author
Nils Eliasson
committedNov 12, 2021
8273277: C2: Move conditional negation into rc_predicate
Reviewed-by: thartmann, chagedorn, kvn
1 parent 6b833db commit 710f496

File tree

5 files changed

+84
-25
lines changed

5 files changed

+84
-25
lines changed
 

‎src/hotspot/share/opto/loopPredicate.cpp

+12-22
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ bool IdealLoopTree::is_range_check_if(IfNode *iff, PhaseIdealLoop *phase, Invari
802802
BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
803803
int scale, Node* offset,
804804
Node* init, Node* limit, jint stride,
805-
Node* range, bool upper, bool &overflow) {
805+
Node* range, bool upper, bool &overflow, bool negate) {
806806
jint con_limit = (limit != NULL && limit->is_Con()) ? limit->get_int() : 0;
807807
jint con_init = init->is_Con() ? init->get_int() : 0;
808808
jint con_offset = offset->is_Con() ? offset->get_int() : 0;
@@ -928,7 +928,7 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
928928
cmp = new CmpUNode(max_idx_expr, range);
929929
}
930930
register_new_node(cmp, ctrl);
931-
BoolNode* bol = new BoolNode(cmp, BoolTest::lt);
931+
BoolNode* bol = new BoolNode(cmp, negate ? BoolTest::ge : BoolTest::lt);
932932
register_new_node(bol, ctrl);
933933

934934
if (TraceLoopPredicate) {
@@ -1295,36 +1295,26 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree *loop, ProjNode*
12951295
}
12961296
// If predicate expressions may overflow in the integer range, longs are used.
12971297
bool overflow = false;
1298+
bool negate = (proj->_con != predicate_proj->_con);
12981299

12991300
// Test the lower bound
1300-
BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow);
1301-
// Negate test if necessary
1302-
bool negated = false;
1303-
if (proj->_con != predicate_proj->_con) {
1304-
lower_bound_bol = new BoolNode(lower_bound_bol->in(1), lower_bound_bol->_test.negate());
1305-
register_new_node(lower_bound_bol, ctrl);
1306-
negated = true;
1307-
}
1301+
BoolNode* lower_bound_bol = rc_predicate(loop, ctrl, scale, offset, init, limit, stride, rng, false, overflow, negate);
1302+
13081303
ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, reason, overflow ? Op_If : iff->Opcode());
13091304
IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If();
13101305
_igvn.hash_delete(lower_bound_iff);
13111306
lower_bound_iff->set_req(1, lower_bound_bol);
1312-
if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx);
1307+
if (TraceLoopPredicate) tty->print_cr("lower bound check if: %s %d ", negate ? " negated" : "", lower_bound_iff->_idx);
13131308

13141309
// Test the upper bound
1315-
BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow);
1316-
negated = false;
1317-
if (proj->_con != predicate_proj->_con) {
1318-
upper_bound_bol = new BoolNode(upper_bound_bol->in(1), upper_bound_bol->_test.negate());
1319-
register_new_node(upper_bound_bol, ctrl);
1320-
negated = true;
1321-
}
1310+
BoolNode* upper_bound_bol = rc_predicate(loop, lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow, negate);
1311+
13221312
ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, reason, overflow ? Op_If : iff->Opcode());
13231313
assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
13241314
IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If();
13251315
_igvn.hash_delete(upper_bound_iff);
13261316
upper_bound_iff->set_req(1, upper_bound_bol);
1327-
if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negated ? " negated" : "", lower_bound_iff->_idx);
1317+
if (TraceLoopPredicate) tty->print_cr("upper bound check if: %s %d ", negate ? " negated" : "", lower_bound_iff->_idx);
13281318

13291319
// Fall through into rest of the clean up code which will move
13301320
// any dependent nodes onto the upper bound test.
@@ -1370,10 +1360,10 @@ ProjNode* PhaseIdealLoop::insert_initial_skeleton_predicate(IfNode* iff, IdealLo
13701360
Node* rng, bool &overflow,
13711361
Deoptimization::DeoptReason reason) {
13721362
// First predicate for the initial value on first loop iteration
1373-
assert(proj->_con && predicate_proj->_con, "not a range check?");
13741363
Node* opaque_init = new OpaqueLoopInitNode(C, init);
13751364
register_new_node(opaque_init, upper_bound_proj);
1376-
BoolNode* bol = rc_predicate(loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng, (stride > 0) != (scale > 0), overflow);
1365+
bool negate = (proj->_con != predicate_proj->_con);
1366+
BoolNode* bol = rc_predicate(loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng, (stride > 0) != (scale > 0), overflow, negate);
13771367
Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1)); // This will go away once loop opts are over
13781368
C->add_skeleton_predicate_opaq(opaque_bol);
13791369
register_new_node(opaque_bol, upper_bound_proj);
@@ -1391,7 +1381,7 @@ ProjNode* PhaseIdealLoop::insert_initial_skeleton_predicate(IfNode* iff, IdealLo
13911381
register_new_node(max_value, new_proj);
13921382
max_value = new AddINode(opaque_init, max_value);
13931383
register_new_node(max_value, new_proj);
1394-
bol = rc_predicate(loop, new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0), overflow);
1384+
bol = rc_predicate(loop, new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0) != (scale > 0), overflow, negate);
13951385
opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
13961386
C->add_skeleton_predicate_opaq(opaque_bol);
13971387
register_new_node(opaque_bol, new_proj);

‎src/hotspot/share/opto/loopTransform.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2589,7 +2589,7 @@ Node* PhaseIdealLoop::add_range_check_predicate(IdealLoopTree* loop, CountedLoop
25892589
Node* predicate_proj, int scale_con, Node* offset,
25902590
Node* limit, jint stride_con, Node* value) {
25912591
bool overflow = false;
2592-
BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, value, NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow);
2592+
BoolNode* bol = rc_predicate(loop, predicate_proj, scale_con, offset, value, NULL, stride_con, limit, (stride_con > 0) != (scale_con > 0), overflow, false);
25932593
Node* opaque_bol = new Opaque4Node(C, bol, _igvn.intcon(1));
25942594
register_new_node(opaque_bol, predicate_proj);
25952595
IfNode* new_iff = NULL;

‎src/hotspot/share/opto/loopnode.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,8 @@ class PhaseIdealLoop : public PhaseTransform {
13161316
BoolNode* rc_predicate(IdealLoopTree *loop, Node* ctrl,
13171317
int scale, Node* offset,
13181318
Node* init, Node* limit, jint stride,
1319-
Node* range, bool upper, bool &overflow);
1319+
Node* range, bool upper, bool &overflow,
1320+
bool negate);
13201321

13211322
// Implementation of the loop predication to promote checks outside the loop
13221323
bool loop_predication_impl(IdealLoopTree *loop);
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

+3-1
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)