Skip to content

Commit f54e598

Browse files
committedMar 7, 2024
8327172: C2 SuperWord: data node in loop has no input in loop: replace assert with bailout
Reviewed-by: chagedorn, kvn
1 parent 4018341 commit f54e598

File tree

3 files changed

+102
-3
lines changed

3 files changed

+102
-3
lines changed
 

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

+10-3
Original file line numberDiff line numberDiff line change
@@ -2957,7 +2957,6 @@ VStatus VLoopBody::construct() {
29572957
return VStatus::make_failure(VLoopBody::FAILURE_NODE_NOT_ALLOWED);
29582958
}
29592959

2960-
#ifdef ASSERT
29612960
if (!n->is_CFG()) {
29622961
bool found = false;
29632962
for (uint j = 0; j < n->req(); j++) {
@@ -2967,9 +2966,17 @@ VStatus VLoopBody::construct() {
29672966
break;
29682967
}
29692968
}
2970-
assert(found, "every non-cfg node must have an input that is also inside the loop");
2971-
}
2969+
if (!found) {
2970+
// If all inputs to a data-node are outside the loop, the node itself should be outside the loop.
2971+
#ifndef PRODUCT
2972+
if (_vloop.is_trace_body()) {
2973+
tty->print_cr("VLoopBody::construct: fails because data node in loop has no input in loop:");
2974+
n->dump();
2975+
}
29722976
#endif
2977+
return VStatus::make_failure(VLoopBody::FAILURE_UNEXPECTED_CTRL);
2978+
}
2979+
}
29732980
}
29742981
}
29752982

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

+1
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ class VLoopMemorySlices : public StackObj {
324324
class VLoopBody : public StackObj {
325325
private:
326326
static constexpr char const* FAILURE_NODE_NOT_ALLOWED = "encontered unhandled node";
327+
static constexpr char const* FAILURE_UNEXPECTED_CTRL = "data node in loop has no input in loop";
327328

328329
const VLoop& _vloop;
329330

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright (c) 2024, 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.loopopts.superword;
25+
26+
/*
27+
* @test id=Vanilla
28+
* @bug 8327172
29+
* @summary Test bad loop ctrl: a node is in the loop, but has no input in the loop
30+
* @run main/othervm compiler.loopopts.superword.TestNoInputInLoop
31+
*/
32+
33+
/*
34+
* @test id=WithFlags
35+
* @bug 8327172
36+
* @summary Test bad loop ctrl: a node is in the loop, but has no input in the loop
37+
* @run main/othervm -Xbatch -XX:PerMethodTrapLimit=0
38+
* compiler.loopopts.superword.TestNoInputInLoop
39+
*/
40+
41+
/*
42+
* @test id=WithMoreFlags
43+
* @bug 8327172
44+
* @summary Test bad loop ctrl: a node is in the loop, but has no input in the loop
45+
* @run main/othervm -Xbatch -XX:PerMethodTrapLimit=0
46+
* -XX:CompileCommand=compileonly,compiler.loopopts.superword.TestNoInputInLoop::test*
47+
* compiler.loopopts.superword.TestNoInputInLoop
48+
*/
49+
50+
public class TestNoInputInLoop {
51+
static long lFld;
52+
static float fFld;
53+
static int iArr[] = new int[400];
54+
55+
public static void main(String[] strArr) {
56+
for (int i = 0; i < 100; i++) {
57+
test1();
58+
}
59+
for (int i = 0; i < 1_000; i++) {
60+
test2(0);
61+
}
62+
}
63+
64+
// It specifically reproduced with UseAVX=2
65+
// 1. PhaseIdealLoop::build_loop_early
66+
// We have a Store in a loop, with a Load after it.
67+
// Both have ctrl as the CountedLoopNode.
68+
// 2. split_if_with_blocks -> PhaseIdealLoop::try_move_store_before_loop
69+
// The Store is moved out of the loop, and its ctrl updated accordingly.
70+
// But the Load has its ctrl not updated, even though it has now no input in the loop.
71+
// 3. SuperWord (VLoopBody::construct)
72+
// We detect a data node in the loop that has no input in the loop.
73+
// This is not expected.
74+
75+
// OSR failure
76+
static void test1() {
77+
for (int i = 0; i < 200; i++) {
78+
fFld *= iArr[0] - lFld;
79+
iArr[1] = (int) lFld;
80+
for (int j = 0; j < 100_000; j++) {} // empty loop, trigger OSR
81+
}
82+
}
83+
84+
// Normal compilation
85+
static void test2(int start) {
86+
for (int i = start; i < 200; i++) {
87+
fFld *= iArr[0] - lFld;
88+
iArr[1] = (int) lFld;
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)
Please sign in to comment.