Skip to content

Commit

Permalink
JBR-3568 Backport JDK-8261812 to JBR11
Browse files Browse the repository at this point in the history
(cherry picked from commit 7b992c7)
  • Loading branch information
mkartashev authored and vprovodin committed Jul 2, 2021
1 parent 1f7adfe commit b534647
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 24 deletions.
24 changes: 24 additions & 0 deletions src/hotspot/share/opto/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4810,6 +4810,30 @@ bool Compile::randomized_select(int count) {
return (os::random() & RANDOMIZED_DOMAIN_MASK) < (RANDOMIZED_DOMAIN / count);
}

Node* Compile::narrow_value(BasicType bt, Node* value, const Type* type, PhaseGVN* phase, bool transform_res) {
if (type != NULL && phase->type(value)->higher_equal(type)) {
return value;
}
Node* result = NULL;
if (bt == T_BYTE) {
result = phase->transform(new LShiftINode(value, phase->intcon(24)));
result = new RShiftINode(result, phase->intcon(24));
} else if (bt == T_BOOLEAN) {
result = new AndINode(value, phase->intcon(0xFF));
} else if (bt == T_CHAR) {
result = new AndINode(value,phase->intcon(0xFFFF));
} else {
assert(bt == T_SHORT, "unexpected narrow type");
result = phase->transform(new LShiftINode(value, phase->intcon(16)));
result = new RShiftINode(result, phase->intcon(16));
}
if (transform_res) {
result = phase->transform(result);
}
return result;
}


CloneMap& Compile::clone_map() { return _clone_map; }
void Compile::set_clone_map(Dict* d) { _clone_map._dict = d; }

Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/opto/compile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,7 @@ class Compile : public Phase {
#ifdef ASSERT
bool _type_verify_symmetry;
#endif
static Node* narrow_value(BasicType bt, Node* value, const Type* type, PhaseGVN* phase, bool transform_res);
};

#endif // SHARE_VM_OPTO_COMPILE_HPP
9 changes: 5 additions & 4 deletions src/hotspot/share/opto/macro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,16 +462,17 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
if (val == mem) {
values.at_put(j, mem);
} else if (val->is_Store()) {
#if INCLUDE_SHENANDOAHGC
Node* n = val->in(MemNode::ValueIn);
#if INCLUDE_SHENANDOAHGC
if (UseShenandoahGC) {
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
n = bs->step_over_gc_barrier(n);
}
values.at_put(j, n);
#else
values.at_put(j, val->in(MemNode::ValueIn));
#endif
if (is_subword_type(ft)) {
n = Compile::narrow_value(ft, n, phi_type, &_igvn, true);
}
values.at_put(j, n);
} else if(val->is_Proj() && val->in(0) == alloc) {
values.at_put(j, _igvn.zerocon(ft));
} else if (val->is_Phi()) {
Expand Down
38 changes: 25 additions & 13 deletions src/hotspot/share/opto/memnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1995,12 +1995,14 @@ uint LoadNode::match_edge(uint idx) const {
// with the value stored truncated to a byte. If no truncation is
// needed, the replacement is done in LoadNode::Identity().
//
Node *LoadBNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* LoadBNode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* mem = in(MemNode::Memory);
Node* value = can_see_stored_value(mem,phase);
if( value && !phase->type(value)->higher_equal( _type ) ) {
Node *result = phase->transform( new LShiftINode(value, phase->intcon(24)) );
return new RShiftINode(result, phase->intcon(24));
if (value != NULL) {
Node* narrow = Compile::narrow_value(T_BYTE, value, _type, phase, false);
if (narrow != value) {
return narrow;
}
}
// Identity call will handle the case where truncation is not needed.
return LoadNode::Ideal(phase, can_reshape);
Expand Down Expand Up @@ -2030,8 +2032,12 @@ const Type* LoadBNode::Value(PhaseGVN* phase) const {
Node* LoadUBNode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* mem = in(MemNode::Memory);
Node* value = can_see_stored_value(mem, phase);
if (value && !phase->type(value)->higher_equal(_type))
return new AndINode(value, phase->intcon(0xFF));
if (value != NULL) {
Node* narrow = Compile::narrow_value(T_BOOLEAN, value, _type, phase, false);
if (narrow != value) {
return narrow;
}
}
// Identity call will handle the case where truncation is not needed.
return LoadNode::Ideal(phase, can_reshape);
}
Expand All @@ -2057,11 +2063,15 @@ const Type* LoadUBNode::Value(PhaseGVN* phase) const {
// with the value stored truncated to a char. If no truncation is
// needed, the replacement is done in LoadNode::Identity().
//
Node *LoadUSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* LoadUSNode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* mem = in(MemNode::Memory);
Node* value = can_see_stored_value(mem,phase);
if( value && !phase->type(value)->higher_equal( _type ) )
return new AndINode(value,phase->intcon(0xFFFF));
if (value != NULL) {
Node* narrow = Compile::narrow_value(T_CHAR, value, _type, phase, false);
if (narrow != value) {
return narrow;
}
}
// Identity call will handle the case where truncation is not needed.
return LoadNode::Ideal(phase, can_reshape);
}
Expand All @@ -2087,12 +2097,14 @@ const Type* LoadUSNode::Value(PhaseGVN* phase) const {
// with the value stored truncated to a short. If no truncation is
// needed, the replacement is done in LoadNode::Identity().
//
Node *LoadSNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node* LoadSNode::Ideal(PhaseGVN* phase, bool can_reshape) {
Node* mem = in(MemNode::Memory);
Node* value = can_see_stored_value(mem,phase);
if( value && !phase->type(value)->higher_equal( _type ) ) {
Node *result = phase->transform( new LShiftINode(value, phase->intcon(16)) );
return new RShiftINode(result, phase->intcon(16));
if (value != NULL) {
Node* narrow = Compile::narrow_value(T_SHORT, value, _type, phase, false);
if (narrow != value) {
return narrow;
}
}
// Identity call will handle the case where truncation is not needed.
return LoadNode::Ideal(phase, can_reshape);
Expand Down
13 changes: 6 additions & 7 deletions src/hotspot/share/opto/parse2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2618,19 +2618,18 @@ void Parse::do_one_bytecode() {
case Bytecodes::_i2b:
// Sign extend
a = pop();
a = _gvn.transform( new LShiftINode(a,_gvn.intcon(24)) );
a = _gvn.transform( new RShiftINode(a,_gvn.intcon(24)) );
push( a );
a = Compile::narrow_value(T_BYTE, a, NULL, &_gvn, true);
push(a);
break;
case Bytecodes::_i2s:
a = pop();
a = _gvn.transform( new LShiftINode(a,_gvn.intcon(16)) );
a = _gvn.transform( new RShiftINode(a,_gvn.intcon(16)) );
push( a );
a = Compile::narrow_value(T_SHORT, a, NULL, &_gvn, true);
push(a);
break;
case Bytecodes::_i2c:
a = pop();
push( _gvn.transform( new AndINode(a,_gvn.intcon(0xFFFF)) ) );
a = Compile::narrow_value(T_CHAR, a, NULL, &_gvn, true);
push(a);
break;

case Bytecodes::_i2f:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright (c) 2021, Red Hat, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/**
* @test
* @bug 8261812
* @summary C2 compilation fails with assert(!had_error) failed: bad dominance
*
* @run main/othervm -XX:-BackgroundCompilation TestValAtSafepointOverflowsInt
*
*/

public class TestValAtSafepointOverflowsInt {
private static volatile int volatileField;

public static void main(String[] args) {
for (int i = 0; i < 20_000; i++) {
testByte(true, false);
testByte(false, false);
testShort(true, false);
testShort(false, false);
testChar(true, false);
testChar(false, false);
}
testByte(true, true);
testShort(true, true);
testChar(true, true);
}

private static Object testByte(boolean flag, boolean flag2) {
int i;
// loop to delay constant folding
for (i = 0; i < 9; i++) {
}
C obj = new C();
if (flag) {
obj.byteField = (byte)(1 << i);
} else {
obj.byteField = (byte)(1 << (i+1));
}
// Phi for byte here for uncommon trap in never taken path below
// Phi inputs don't fit in a byte. Phi transfomed to top.
if (flag2) {
return obj;
}
return null;
}

private static Object testShort(boolean flag, boolean flag2) {
int i;
for (i = 0; i < 17; i++) {
}
C obj = new C();
if (flag) {
obj.shortField = (short)(1 << i);
} else {
obj.shortField = (short)(1 << (i+1));
}
if (flag2) {
return obj;
}
return null;
}

private static Object testChar(boolean flag, boolean flag2) {
int i;
for (i = 0; i < 17; i++) {
}
C obj = new C();
if (flag) {
obj.charField = (char)(1 << i);
} else {
obj.charField = (char)(1 << (i+1));
}
if (flag2) {
return obj;
}
return null;
}


static class C {
byte byteField;
short shortField;
char charField;
}

}

0 comments on commit b534647

Please sign in to comment.