8229016: C2 scalarization crashes with assert(node->Opcode() == Op_CastP2X) failed: ConvP2XNode required
Detect array copy to self to avoid emitting another load to the to-be-removed allocation. Reviewed-by: kvn
This commit is contained in:
parent
c64f70be82
commit
ac2ea95788
@ -348,6 +348,7 @@ Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset,
|
||||
}
|
||||
Node* res = NULL;
|
||||
if (ac->is_clonebasic()) {
|
||||
assert(ac->in(ArrayCopyNode::Src) != ac->in(ArrayCopyNode::Dest), "clone source equals destination");
|
||||
Node* base = ac->in(ArrayCopyNode::Src)->in(AddPNode::Base);
|
||||
Node* adr = _igvn.transform(new AddPNode(base, base, MakeConX(offset)));
|
||||
const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset);
|
||||
@ -355,7 +356,7 @@ Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset,
|
||||
} else {
|
||||
if (ac->modifies(offset, offset, &_igvn, true)) {
|
||||
assert(ac->in(ArrayCopyNode::Dest) == alloc->result_cast(), "arraycopy destination should be allocation's result");
|
||||
uint shift = exact_log2(type2aelembytes(bt));
|
||||
uint shift = exact_log2(type2aelembytes(bt));
|
||||
Node* diff = _igvn.transform(new SubINode(ac->in(ArrayCopyNode::SrcPos), ac->in(ArrayCopyNode::DestPos)));
|
||||
#ifdef _LP64
|
||||
diff = _igvn.transform(new ConvI2LNode(diff));
|
||||
@ -366,6 +367,10 @@ Node* PhaseMacroExpand::make_arraycopy_load(ArrayCopyNode* ac, intptr_t offset,
|
||||
Node* base = ac->in(ArrayCopyNode::Src);
|
||||
Node* adr = _igvn.transform(new AddPNode(base, base, off));
|
||||
const TypePtr* adr_type = _igvn.type(base)->is_ptr()->add_offset(offset);
|
||||
if (ac->in(ArrayCopyNode::Src) == ac->in(ArrayCopyNode::Dest)) {
|
||||
// Don't emit a new load from src if src == dst but try to get the value from memory instead
|
||||
return value_from_mem(ac->in(TypeFunc::Memory), ctl, ft, ftype, adr_type->isa_oopptr(), alloc);
|
||||
}
|
||||
res = LoadNode::make(_igvn, ctl, mem, adr, adr_type, type, bt, MemNode::unordered, LoadNode::UnknownControl);
|
||||
}
|
||||
}
|
||||
@ -497,7 +502,6 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, Node *sfpt_ctl, BasicType
|
||||
Arena *a = Thread::current()->resource_area();
|
||||
VectorSet visited(a);
|
||||
|
||||
|
||||
bool done = sfpt_mem == alloc_mem;
|
||||
Node *mem = sfpt_mem;
|
||||
while (!done) {
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. 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 8229016
|
||||
* @summary Test correct elimination of array allocation with arraycopy to itself.
|
||||
* @library /test/lib
|
||||
* @run main/othervm -Xbatch -XX:CompileCommand=compileonly,compiler.escapeAnalysis.TestSelfArrayCopy::test
|
||||
* compiler.escapeAnalysis.TestSelfArrayCopy
|
||||
*/
|
||||
|
||||
package compiler.escapeAnalysis;
|
||||
|
||||
import jdk.test.lib.Utils;
|
||||
|
||||
public class TestSelfArrayCopy {
|
||||
private static boolean b = false;
|
||||
private static final int rI1 = Utils.getRandomInstance().nextInt();
|
||||
private static final int rI2 = Utils.getRandomInstance().nextInt();
|
||||
|
||||
private static int test() {
|
||||
// Non-escaping allocation
|
||||
Integer[] array = {rI1, rI2};
|
||||
// Arraycopy with src == dst
|
||||
System.arraycopy(array, 0, array, 0, array.length - 1);
|
||||
if (b) {
|
||||
// Uncommon trap
|
||||
System.out.println(array[0]);
|
||||
}
|
||||
return array[0] + array[1];
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int expected = rI1 + rI2;
|
||||
// Trigger compilation
|
||||
for (int i = 0; i < 20_000; ++i) {
|
||||
int result = test();
|
||||
if (result != expected) {
|
||||
throw new RuntimeException("Incorrect result: " + result + " != " + expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user