Skip to content

Commit 48fa33a

Browse files
committed
8301489: C1: ShortLoopOptimizer might lift instructions before their inputs
Backport-of: 73d7aa1d2cb037fed69263a1990258866333664d
1 parent 89103c6 commit 48fa33a

File tree

2 files changed

+144
-1
lines changed

2 files changed

+144
-1
lines changed

src/hotspot/share/c1/c1_ValueMap.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,33 @@ LoopInvariantCodeMotion::LoopInvariantCodeMotion(ShortLoopOptimizer *slo, Global
359359
}
360360
}
361361

362+
class CheckInsertionPoint : public ValueVisitor {
363+
private:
364+
Value _insert;
365+
bool _valid = true;
366+
367+
void visit(Value* vp) {
368+
assert(*vp != nullptr, "value should not be null");
369+
if (_insert->dominator_depth() < (*vp)->dominator_depth()) {
370+
_valid = false;
371+
}
372+
}
373+
374+
public:
375+
bool is_valid() { return _valid; }
376+
CheckInsertionPoint(Value insert)
377+
: _insert(insert) {
378+
assert(insert != nullptr, "insertion point should not be null");
379+
}
380+
};
381+
382+
// Check that insertion point has higher dom depth than all inputs to cur
383+
static bool is_dominated_by_inputs(Instruction* insertion_point, Instruction* cur) {
384+
CheckInsertionPoint v(insertion_point);
385+
cur->input_values_do(&v);
386+
return v.is_valid();
387+
}
388+
362389
void LoopInvariantCodeMotion::process_block(BlockBegin* block) {
363390
TRACE_VALUE_NUMBERING(tty->print_cr("processing block B%d", block->block_id()));
364391

@@ -394,7 +421,7 @@ void LoopInvariantCodeMotion::process_block(BlockBegin* block) {
394421
cur_invariant = is_invariant(cvt->value());
395422
}
396423

397-
if (cur_invariant) {
424+
if (cur_invariant && is_dominated_by_inputs(_insertion_point, cur)) {
398425
// perform value numbering and mark instruction as loop-invariant
399426
_gvn->substitute(cur);
400427

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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 8301489
27+
* @summary ShortLoopOptimizer might lift instructions before their inputs
28+
* @requires vm.compiler1.enabled
29+
* @run main/othervm -Xcomp -XX:TieredStopAtLevel=1
30+
* -XX:CompileOnly=compiler.c1.Test8301489::*
31+
* compiler.c1.Test8301489
32+
*/
33+
34+
35+
package compiler.c1;
36+
37+
public class Test8301489 {
38+
static int c = 0;
39+
static int[] arr = {};
40+
41+
static void op2Test(int a, int b) {
42+
// Implicit edges created during dom calculation to exception handler
43+
if (a < 0) {
44+
b = 0;
45+
}
46+
// Create two branches into next loop header block
47+
try {
48+
int l = arr.length;
49+
for (int i = 0; i < l; i++) {
50+
int d = arr[i] + arr[i];
51+
}
52+
}
53+
// Exception handler as predecessor of the next loop header block
54+
catch (ArithmeticException e) {}
55+
56+
// op2(a, b) as candidate for hoisting: operands are loop invariant
57+
while (a + b < b) {}
58+
// op2(a, b) should not be hoisted above 'if (a < 0) {...}' block
59+
}
60+
61+
static void arrayLengthTest() {
62+
float [] newArr = new float[c];
63+
64+
try {
65+
for (float f : newArr) {}
66+
}
67+
catch (ArrayIndexOutOfBoundsException e) {}
68+
69+
while (54321 < newArr.length) {
70+
newArr[c] = 123.45f;
71+
}
72+
}
73+
74+
static void negateTest(int a) {
75+
if (a <= 111) {
76+
a = -111;
77+
}
78+
79+
int f = 0;
80+
try {
81+
int l = arr.length;
82+
f--;
83+
}
84+
catch (NegativeArraySizeException e) {}
85+
86+
while (-a < f) {
87+
f--;
88+
}
89+
}
90+
91+
static void convertTest(int a) {
92+
if (c == 0) {
93+
a = 0;
94+
}
95+
96+
long tgt = 10;
97+
98+
try {
99+
String s = String.valueOf(c);
100+
}
101+
catch (NumberFormatException e) {}
102+
103+
while ((long)a != tgt) {
104+
tgt--;
105+
}
106+
}
107+
108+
public static void main(String[] args) {
109+
for (int i = 0; i < 3; i++) {
110+
op2Test(12, 34);
111+
arrayLengthTest();
112+
negateTest(-778);
113+
convertTest(4812);
114+
}
115+
}
116+
}

0 commit comments

Comments
 (0)