RFR: 8286182: C2: crash with SIGFPE when executing compiled code
Martin Doerr
mdoerr at openjdk.java.net
Wed May 18 12:40:58 UTC 2022
On Mon, 16 May 2022 12:36:43 GMT, Martin Doerr <mdoerr at openjdk.org> wrote:
> The bug is not assigned to me, but I have seen that the C2 code which checks for div by 0 is not aware of the new nodes from [JDK-8284742](https://bugs.openjdk.java.net/browse/JDK-8284742).
> This fixes the VM to pass the reproducer. I'm not sure if more opcode checks are required to get added.
While evaluation is ongoing I have thought a bit about making the div node dependent on a single check which avoids all SIGFPE cases:
diff --git a/src/hotspot/share/opto/parse3.cpp b/src/hotspot/share/opto/parse3.cpp
index 7e0f854436b..9d4226571ae 100644
--- a/src/hotspot/share/opto/parse3.cpp
+++ b/src/hotspot/share/opto/parse3.cpp
@@ -484,26 +484,30 @@ void Parse::do_divmod_fixup() {
return;
}
- // The generated graph is equivalent to (in2 == -1) ? -in1 : (in1 / in2)
- // we need to have a separate branch for in2 == -1 due to the special
- // case of min_jint / -1
- Node* cmp = _gvn.transform(CmpNode::make(in2, _gvn.integercon(-1, bt), bt));
- Node* bol = Bool(cmp, BoolTest::eq);
- IfNode* iff = create_and_map_if(control(), bol, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
+ // Check if in2 < -1 or > 1 by one CmpUNode (in2 + 1 >u 1). Reason:
+ // Div node will have to get pinned, but we can only pin to one region.
+ Node* inc = _gvn.transform(AddNode::make(in2, _gvn.integercon(1, bt), bt));
+ Node* cmp = _gvn.transform(CmpUNode::make(inc, _gvn.integercon(1, bt), bt));
+
+ Node* bol = Bool(cmp, BoolTest::gt);
+ IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
Node* iff_true = IfTrue(iff);
Node* iff_false = IfFalse(iff);
+
+ Node* res_slow = generate_division(_gvn, iff_true, in1, in2, bc);
+
Node* res_fast = (bc == Bytecodes::_idiv || bc == Bytecodes::_ldiv)
? _gvn.transform(SubNode::make(_gvn.zerocon(bt), in1, bt))
: _gvn.zerocon(bt);
- Node* res_slow = generate_division(_gvn, iff_false, in1, in2, bc);
+
Node* merge = new RegionNode(3);
merge->init_req(1, iff_true);
merge->init_req(2, iff_false);
record_for_igvn(merge);
set_control(_gvn.transform(merge));
Node* res = new PhiNode(merge, Type::get_const_basic_type(bt));
- res->init_req(1, res_fast);
- res->init_req(2, res_slow);
+ res->init_req(1, res_slow);
+ res->init_req(2, res_fast);
res = _gvn.transform(res);
push_result(*this, res, bt);
}
This effectively disables implicit div by 0 checks, but I believe they could get repaired. Are there any opinions about this idea?
-------------
PR: https://git.openjdk.java.net/jdk/pull/8726
More information about the hotspot-compiler-dev
mailing list