Skip to content

Commit 784a0f0

Browse files
committedJun 27, 2022
8288683: C2: And node gets wrong type due to not adding it back to the worklist in CCP
Reviewed-by: roland, thartmann
1 parent 7e13cdb commit 784a0f0

File tree

3 files changed

+110
-0
lines changed

3 files changed

+110
-0
lines changed
 

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

+18
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,24 @@ void PhaseCCP::analyze() {
18611861
}
18621862
}
18631863
}
1864+
push_and(worklist, n, m);
1865+
}
1866+
}
1867+
}
1868+
}
1869+
1870+
// AndI/L::Value() optimizes patterns similar to (v << 2) & 3 to zero if they are bitwise disjoint.
1871+
// Add the AndI/L nodes back to the worklist to re-apply Value() in case the shift value changed.
1872+
void PhaseCCP::push_and(Unique_Node_List& worklist, const Node* parent, const Node* use) const {
1873+
uint use_op = use->Opcode();
1874+
if ((use_op == Op_LShiftI || use_op == Op_LShiftL)
1875+
&& use->in(2) == parent) { // is shift value (right-hand side of LShift)
1876+
for (DUIterator_Fast imax, i = use->fast_outs(imax); i < imax; i++) {
1877+
Node* and_node = use->fast_out(i);
1878+
uint and_node_op = and_node->Opcode();
1879+
if ((and_node_op == Op_AndI || and_node_op == Op_AndL)
1880+
&& and_node->bottom_type() != type(and_node)) {
1881+
worklist.push(and_node);
18641882
}
18651883
}
18661884
}

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

+2
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,8 @@ class PhaseCCP : public PhaseIterGVN {
568568
// Non-recursive. Use analysis to transform single Node.
569569
virtual Node *transform_once( Node *n );
570570

571+
void push_and(Unique_Node_List& worklist, const Node* parent, const Node* use) const;
572+
571573
public:
572574
PhaseCCP( PhaseIterGVN *igvn ); // Compute conditional constants
573575
NOT_PRODUCT( ~PhaseCCP(); )
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) 2022, 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 8288683
27+
* @library /test/lib
28+
* @summary Test that And nodes are added to the CCP worklist if they have an LShift as input.
29+
* @run main/othervm -Xbatch compiler.c2.TestAndShiftZeroCCP
30+
*/
31+
package compiler.c2;
32+
33+
import jdk.test.lib.Asserts;
34+
35+
public class TestAndShiftZeroCCP {
36+
static int iFld = 0xfffff;
37+
38+
public static void main(String[] strArr) {
39+
for (int i = 0; i < 10000; i++) {
40+
Asserts.assertEQ(testAndI(), 224);
41+
Asserts.assertEQ(testAndL(), 224L);
42+
Asserts.assertEQ(testAndLConvI2L(), 224L);
43+
}
44+
}
45+
46+
static int testAndI() {
47+
int x = 10;
48+
int y = iFld;
49+
int z = 3;
50+
int q;
51+
for (int i = 62; i < 70; ++i) {
52+
q = y << i;
53+
for (int j = 0; j < 8; j++) {
54+
z += i;
55+
}
56+
z = q & 0xff;
57+
}
58+
return z;
59+
}
60+
61+
static long testAndL() {
62+
long x = 10;
63+
long y = iFld;
64+
long z = 3;
65+
long q;
66+
for (int i = 62; i < 70; ++i) {
67+
q = y << i;
68+
for (int j = 0; j < 8; j++) {
69+
z += i;
70+
}
71+
z = q & 0xff;
72+
}
73+
return z;
74+
}
75+
76+
static long testAndLConvI2L() {
77+
long x = 10;
78+
long y = iFld;
79+
long z = 3;
80+
long q;
81+
for (int i = 62; i < 70; ++i) {
82+
q = y << i;
83+
for (int j = 0; j < 8; j++) {
84+
z += i;
85+
}
86+
z = q & 0xff;
87+
}
88+
return z;
89+
}
90+
}

0 commit comments

Comments
 (0)
Please sign in to comment.