Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.
/ lanai Public archive

Commit 4cfecce

Browse files
committedMar 4, 2021
8261730: C2 compilation fails with assert(store->find_edge(load) != -1) failed: missing precedence edge
Relax assertion in PhaseCFG::verify() to accept the case where a store is used to implement an implicit null check and a load is placed in the null block. Reviewed-by: thartmann, kvn
1 parent 7915a1f commit 4cfecce

File tree

4 files changed

+82
-2
lines changed

4 files changed

+82
-2
lines changed
 

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

+1
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ macro(Lock)
200200
macro(Loop)
201201
macro(LoopLimit)
202202
macro(Mach)
203+
macro(MachNullCheck)
203204
macro(MachProj)
204205
macro(MulAddS2I)
205206
macro(MaxI)

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

+18-1
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,24 @@ Block* PhaseCFG::insert_anti_dependences(Block* LCA, Node* load, bool verify) {
770770
// Add an anti-dep edge, and squeeze 'load' into the highest block.
771771
assert(store != load->find_exact_control(load->in(0)), "dependence cycle found");
772772
if (verify) {
773-
assert(store->find_edge(load) != -1, "missing precedence edge");
773+
#ifdef ASSERT
774+
// We expect an anti-dependence edge from 'load' to 'store', except when
775+
// implicit_null_check() has hoisted 'store' above its early block to
776+
// perform an implicit null check, and 'load' is placed in the null
777+
// block. In this case it is safe to ignore the anti-dependence, as the
778+
// null block is only reached if 'store' tries to write to null.
779+
Block* store_null_block = NULL;
780+
Node* store_null_check = store->find_out_with(Op_MachNullCheck);
781+
if (store_null_check != NULL) {
782+
Node* if_true = store_null_check->find_out_with(Op_IfTrue);
783+
assert(if_true != NULL, "null check without null projection");
784+
Node* null_block_region = if_true->find_out_with(Op_Region);
785+
assert(null_block_region != NULL, "null check without null region");
786+
store_null_block = get_block_for_node(null_block_region);
787+
}
788+
#endif
789+
assert(LCA == store_null_block || store->find_edge(load) != -1,
790+
"missing precedence edge");
774791
} else {
775792
store->add_prec(load);
776793
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -699,6 +699,7 @@ class MachNullCheckNode : public MachBranchNode {
699699
add_req(ctrl);
700700
add_req(memop);
701701
}
702+
virtual int Opcode() const;
702703
virtual uint size_of() const { return sizeof(*this); }
703704

704705
virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package compiler.uncommontrap;
25+
26+
/**
27+
* @test
28+
* @bug 8261730
29+
* @summary Test that no anti-dependence violation is reported between a store
30+
* used as an implicit null check and a load placed in the null block.
31+
* @run main/othervm -XX:-BackgroundCompilation
32+
* compiler.uncommontrap.TestNullCheckAntiDependence
33+
*/
34+
35+
public class TestNullCheckAntiDependence {
36+
37+
private static class MyInteger {
38+
int val;
39+
}
40+
41+
private static MyInteger foo = new MyInteger();
42+
private static MyInteger bar = new MyInteger();
43+
44+
static void setFooToZero() {
45+
for (int i = 0; i < 1; i++) {
46+
// This load is placed in the null block.
47+
foo.val = -bar.val;
48+
for (int k = 0; k < 10; k++) {
49+
// This store is hoisted and used as an implicit null check.
50+
foo.val = 0;
51+
}
52+
}
53+
}
54+
55+
public static void main(String[] args) {
56+
for (int i = 0; i < 10_000; i++) {
57+
setFooToZero();
58+
}
59+
}
60+
61+
}

0 commit comments

Comments
 (0)
This repository has been archived.