Skip to content

Commit 526dba1

Browse files
committedJun 28, 2023
8310130: C2: assert(false) failed: scalar_input is neither phi nor a matchin reduction
Reviewed-by: kvn, chagedorn
1 parent 48e61c1 commit 526dba1

File tree

3 files changed

+145
-4
lines changed

3 files changed

+145
-4
lines changed
 

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -4224,7 +4224,8 @@ void PhaseIdealLoop::move_unordered_reduction_out_of_loop(IdealLoopTree* loop) {
42244224
if (use != phi && ctrl_or_self(use) == cl) {
42254225
DEBUG_ONLY( current->dump(-1); )
42264226
assert(false, "reduction has use inside loop");
4227-
break; // Chain traversal fails.
4227+
// Should not be allowed by SuperWord::mark_reductions
4228+
return; // bail out of optimization
42284229
}
42294230
}
42304231
} else {
@@ -4245,8 +4246,9 @@ void PhaseIdealLoop::move_unordered_reduction_out_of_loop(IdealLoopTree* loop) {
42454246
current = nullptr;
42464247
break; // Success.
42474248
} else {
4248-
DEBUG_ONLY( current->dump(1); )
4249-
assert(false, "scalar_input is neither phi nor a matchin reduction");
4249+
// scalar_input is neither phi nor a matching reduction
4250+
// Can for example be scalar reduction when we have
4251+
// partial vectorization.
42504252
break; // Chain traversal fails.
42514253
}
42524254
}

‎test/hotspot/jtreg/compiler/loopopts/superword/TestUnorderedReduction.java

+43-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public static void main(String[] args) {
4343
"-XX:MaxVectorSize=16");
4444
}
4545

46-
@Run(test = {"test1", "test2"})
46+
@Run(test = {"test1", "test2", "test3"})
4747
@Warmup(0)
4848
public void runTests() throws Exception {
4949
int[] data = new int[RANGE];
@@ -64,6 +64,14 @@ public void runTests() throws Exception {
6464
throw new RuntimeException("Wrong result test2: " + r1 + " != " + r2);
6565
}
6666
}
67+
68+
for (int i = 0; i < ITER; i++) {
69+
int r1 = test3(data, i);
70+
int r2 = ref3(data, i);
71+
if (r1 != r2) {
72+
throw new RuntimeException("Wrong result test3: " + r1 + " != " + r2);
73+
}
74+
}
6775
}
6876

6977
@Test
@@ -140,6 +148,40 @@ static int ref2(int[] data, int sum) {
140148
return sum;
141149
}
142150

151+
@Test
152+
@IR(counts = {IRNode.LOAD_VECTOR, "> 0",
153+
IRNode.MUL_VI, "> 0",
154+
IRNode.ADD_VI, "= 0", // reduction not moved out of loop
155+
IRNode.ADD_REDUCTION_VI, "> 0",},
156+
applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"})
157+
static int test3(int[] data, int sum) {
158+
for (int i = 0; i < RANGE; i+=8) {
159+
// Partial vectorization of reduction chain -> cannot move out of loop
160+
sum += 11 * data[i+0]; // vec 1
161+
sum += 13 & data[i+1]; // ---------- breaks vec 1 -> scalar reductions
162+
sum += 11 * data[i+2];
163+
sum += 11 * data[i+3];
164+
sum += 11 * data[i+4]; // vec 2 -> vectorizes -> vector reduction
165+
sum += 11 * data[i+5];
166+
sum += 11 * data[i+6];
167+
sum += 11 * data[i+7];
168+
}
169+
return sum;
170+
}
171+
172+
static int ref3(int[] data, int sum) {
173+
for (int i = 0; i < RANGE; i+=8) {
174+
sum += 11 * data[i+0];
175+
sum += 13 & data[i+1];
176+
sum += 11 * data[i+2];
177+
sum += 11 * data[i+3];
178+
sum += 11 * data[i+4];
179+
sum += 11 * data[i+5];
180+
sum += 11 * data[i+6];
181+
sum += 11 * data[i+7];
182+
}
183+
return sum;
184+
}
143185

144186
static void init(int[] data) {
145187
for (int i = 0; i < RANGE; i++) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright (c) 2023, 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+
/**
25+
* @test
26+
* @bug JDK-8310130
27+
* @summary Special test cases for PhaseIdealLoop::move_unordered_reduction_out_of_loop
28+
* Here a case with partial vectorization of the reduction.
29+
* @requires vm.bits == "64"
30+
* @library /test/lib /
31+
* @run driver compiler.loopopts.superword.TestUnorderedReductionPartialVectorization
32+
*/
33+
34+
package compiler.loopopts.superword;
35+
36+
import compiler.lib.ir_framework.*;
37+
38+
public class TestUnorderedReductionPartialVectorization {
39+
static final int RANGE = 1024;
40+
static final int ITER = 10;
41+
42+
public static void main(String[] args) {
43+
TestFramework.run();
44+
}
45+
46+
@Run(test = {"test1"})
47+
@Warmup(0)
48+
public void runTests() throws Exception {
49+
int[] data = new int[RANGE];
50+
51+
init(data);
52+
for (int i = 0; i < ITER; i++) {
53+
long r1 = test1(data, i);
54+
long r2 = ref1(data, i);
55+
if (r1 != r2) {
56+
throw new RuntimeException("Wrong result test1: " + r1 + " != " + r2);
57+
}
58+
}
59+
}
60+
61+
@Test
62+
@IR(counts = {IRNode.LOAD_VECTOR, "> 0",
63+
IRNode.OR_REDUCTION_V, "> 0",},
64+
applyIfCPUFeatureOr = {"avx2", "true"})
65+
static long test1(int[] data, long sum) {
66+
for (int i = 0; i < data.length; i++) {
67+
// Mixing int and long ops means we only end up allowing half of the int
68+
// loads in one pack, and we have two int packs. The first pack has one
69+
// of the pairs missing because of the store, which creates a dependency.
70+
// The first pack is rejected and left as scalar, the second pack succeeds
71+
// with vectorization. That means we have a mixed scalar/vector reduction
72+
// chain. This way it is possible that a vector-reduction has a scalar
73+
// reduction as input, which is neigher a phi nor a vector reduction.
74+
// In such a case, we must bail out of the optimization in
75+
// PhaseIdealLoop::move_unordered_reduction_out_of_loop
76+
int v = data[i]; // int read
77+
data[0] = 0; // ruin the first pack
78+
sum |= v; // long reduction
79+
}
80+
return sum;
81+
}
82+
83+
static long ref1(int[] data, long sum) {
84+
for (int i = 0; i < data.length; i++) {
85+
int v = data[i];
86+
data[0] = 0;
87+
sum |= v;
88+
}
89+
return sum;
90+
}
91+
92+
static void init(int[] data) {
93+
for (int i = 0; i < RANGE; i++) {
94+
data[i] = i + 1;
95+
}
96+
}
97+
}

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Jun 28, 2023

@openjdk-notifier[bot]
Please sign in to comment.