mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-16 13:25:34 +00:00
8235452: Strip mined loop verification fails with assert(is_OuterStripMinedLoop()) failed: invalid node class
Do not try to verify strip mining if the strip mined loop is malformed. Reviewed-by: roland, vlivanov
This commit is contained in:
parent
f6d50463f6
commit
642d2ddcbc
@ -1388,9 +1388,8 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
|
||||
// an early loop exit. Try them with profile data.
|
||||
while (if_proj_list.size() > 0) {
|
||||
Node* proj = if_proj_list.pop();
|
||||
float f = pf.to(proj);
|
||||
if (proj->as_Proj()->is_uncommon_trap_if_pattern(Deoptimization::Reason_none) &&
|
||||
f * loop_trip_cnt >= 1) {
|
||||
pf.to(proj) * loop_trip_cnt >= 1) {
|
||||
hoisted = loop_predication_impl_helper(loop, proj->as_Proj(), profile_predicate_proj, cl, zero, invar, Deoptimization::Reason_profile_predicate) | hoisted;
|
||||
}
|
||||
}
|
||||
|
||||
@ -944,8 +944,11 @@ Node *LoopNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
return RegionNode::Ideal(phase, can_reshape);
|
||||
}
|
||||
|
||||
void LoopNode::verify_strip_mined(int expect_skeleton) const {
|
||||
#ifdef ASSERT
|
||||
void LoopNode::verify_strip_mined(int expect_skeleton) const {
|
||||
if (!is_valid_counted_loop()) {
|
||||
return; // Skip malformed counted loop
|
||||
}
|
||||
const OuterStripMinedLoopNode* outer = NULL;
|
||||
const CountedLoopNode* inner = NULL;
|
||||
if (is_strip_mined()) {
|
||||
@ -955,6 +958,7 @@ void LoopNode::verify_strip_mined(int expect_skeleton) const {
|
||||
} else if (is_OuterStripMinedLoop()) {
|
||||
outer = this->as_OuterStripMinedLoop();
|
||||
inner = outer->unique_ctrl_out()->as_CountedLoop();
|
||||
assert(inner->is_valid_counted_loop(), "OuterStripMinedLoop should have been removed");
|
||||
assert(!is_strip_mined(), "outer loop shouldn't be marked strip mined");
|
||||
}
|
||||
if (inner != NULL || outer != NULL) {
|
||||
@ -1024,8 +1028,8 @@ void LoopNode::verify_strip_mined(int expect_skeleton) const {
|
||||
assert(sfpt->outcnt() == 1, "no data node");
|
||||
assert(outer_tail->outcnt() == 1 || !has_skeleton, "no data node");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
//------------------------------Ideal------------------------------------------
|
||||
|
||||
@ -152,7 +152,7 @@ public:
|
||||
virtual void dump_spec(outputStream *st) const;
|
||||
#endif
|
||||
|
||||
void verify_strip_mined(int expect_skeleton) const;
|
||||
void verify_strip_mined(int expect_skeleton) const NOT_DEBUG_RETURN;
|
||||
virtual LoopNode* skip_strip_mined(int expect_skeleton = 1) { return this; }
|
||||
virtual IfTrueNode* outer_loop_tail() const { ShouldNotReachHere(); return NULL; }
|
||||
virtual OuterStripMinedLoopEndNode* outer_loop_end() const { ShouldNotReachHere(); return NULL; }
|
||||
|
||||
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 8235452
|
||||
* @library /test/lib /
|
||||
* @summary Test loop strip mining verification with dying outer loop.
|
||||
* @run main/othervm -Xbatch -XX:-TieredCompilation
|
||||
* compiler.loopstripmining.TestDeadOuterStripMinedLoop
|
||||
*/
|
||||
|
||||
package compiler.loopstripmining;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
public class TestDeadOuterStripMinedLoop {
|
||||
|
||||
public static int test(boolean b) {
|
||||
int res = 5000;
|
||||
for (int i = 0; i < 42; i++) {
|
||||
if (!b) {
|
||||
break;
|
||||
}
|
||||
// Strip mined loop
|
||||
while (--res > 0) {
|
||||
if (res < 1) {
|
||||
throw new RuntimeException("Should not reach here!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
After parsing:
|
||||
Loop:
|
||||
res--;
|
||||
if (res <= 0) {
|
||||
goto End;
|
||||
}
|
||||
if (res < 1) { <- Treated as loop exit check (res <= 0)
|
||||
UncommonTrap();
|
||||
}
|
||||
goto Loop;
|
||||
End:
|
||||
|
||||
Loop opts convert this into:
|
||||
// Outer strip mined loop
|
||||
do {
|
||||
// Strip mined loop
|
||||
do {
|
||||
res--;
|
||||
if (res <= 0) {
|
||||
goto End;
|
||||
}
|
||||
} while (res > 0); <- Always false due to above res <= 0 check
|
||||
Safepoint()
|
||||
} while (false);
|
||||
UncommonTrap();
|
||||
End:
|
||||
|
||||
The safepoint path dies, because the exit condition of the strip mined loop is always false:
|
||||
// Strip mined loop
|
||||
do {
|
||||
res--;
|
||||
if (res <= 0) {
|
||||
goto End;
|
||||
}
|
||||
} while (true);
|
||||
End:
|
||||
*/
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
Asserts.assertEQ(test(true), -41);
|
||||
}
|
||||
Asserts.assertEQ(test(false), 5000);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user