1 /*
2  * Copyright (c) 2012, 2018, 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 package org.graalvm.compiler.core.test;
26 
27 import org.graalvm.compiler.nodes.StructuredGraph;
28 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
29 import org.graalvm.compiler.nodes.ValueNode;
30 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
31 import org.graalvm.compiler.nodes.graphbuilderconf.InlineInvokePlugin;
32 import org.graalvm.compiler.phases.OptimisticOptimizations;
33 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
34 import org.graalvm.compiler.phases.common.FrameStateAssignmentPhase;
35 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
36 import org.graalvm.compiler.phases.tiers.MidTierContext;
37 import org.graalvm.compiler.phases.tiers.PhaseContext;
38 import org.junit.Ignore;
39 import org.junit.Test;
40 
41 import jdk.vm.ci.meta.ResolvedJavaMethod;
42 
43 public class CompareCanonicalizerTest3 extends GraalCompilerTest {
44 
45     @SuppressWarnings("unused") private static int sink0;
46     @SuppressWarnings("unused") private static int sink1;
47 
48     @Ignore("Subword input cannot be trusted.")
49     @Test
test00()50     public void test00() {
51         assertCanonicallyEqual("integerTestCanonicalization00", "referenceSnippet00");
52     }
53 
integerTestCanonicalization00(char a)54     public static void integerTestCanonicalization00(char a) {
55         if (a - 1 < a) {
56             sink1 = 0;
57         } else {
58             sink0 = -1;
59         }
60     }
61 
62     @SuppressWarnings("unused")
referenceSnippet00(char a)63     public static void referenceSnippet00(char a) {
64         sink1 = 0;
65     }
66 
67     @Ignore("Needs better stamp support for unsigned ranges")
68     @Test
test01()69     public void test01() {
70         assertCanonicallyEqual("integerTestCanonicalization01", "referenceSnippet01");
71     }
72 
integerTestCanonicalization01(char a)73     public static void integerTestCanonicalization01(char a) {
74         if (Integer.compareUnsigned(a - 1, a) < 0) {
75             sink1 = 0;
76         } else {
77             sink0 = -1;
78         }
79     }
80 
referenceSnippet01(char a)81     public static void referenceSnippet01(char a) {
82         if (a != 0) {
83             sink1 = 0;
84         } else {
85             sink0 = -1;
86         }
87     }
88 
89     @Ignore("Needs better stamp support for unsigned ranges")
90     @Test
test1()91     public void test1() {
92         assertCanonicallyEqual("integerTestCanonicalization1", "referenceSnippet1");
93     }
94 
integerTestCanonicalization1(char[] a)95     public static void integerTestCanonicalization1(char[] a) {
96         int len = a.length;
97         if (Integer.compareUnsigned(len - 2, len) < 0) {
98             sink1 = 0;
99         } else {
100             sink0 = -1;
101         }
102     }
103 
referenceSnippet1(char[] a)104     public static void referenceSnippet1(char[] a) {
105         int len = a.length;
106         if (Integer.compareUnsigned(len, 2) >= 0) {
107             sink1 = 0;
108         } else {
109             sink0 = -1;
110         }
111     }
112 
113     @Test
test2()114     public void test2() {
115         assertCanonicallyEqual("integerTestCanonicalization2", "referenceSnippet2");
116     }
117 
integerTestCanonicalization2(int a)118     public static void integerTestCanonicalization2(int a) {
119         if (a - 1 < a) {
120             sink1 = 0;
121         } else {
122             sink0 = -1;
123         }
124     }
125 
referenceSnippet2(int a)126     public static void referenceSnippet2(int a) {
127         if (a != Integer.MIN_VALUE) {
128             sink1 = 0;
129         } else {
130             sink0 = -1;
131         }
132     }
133 
134     @Test
test3()135     public void test3() {
136         assertCanonicallyEqual("integerTestCanonicalization3", "referenceSnippet3");
137     }
138 
integerTestCanonicalization3(int a)139     public static void integerTestCanonicalization3(int a) {
140         if (a - 2 < a) {
141             sink1 = 0;
142         } else {
143             sink0 = -1;
144         }
145     }
146 
referenceSnippet3(int a)147     public static void referenceSnippet3(int a) {
148         if (a >= Integer.MIN_VALUE + 2) {
149             sink1 = 0;
150         } else {
151             sink0 = -1;
152         }
153     }
154 
155     @Test
test4()156     public void test4() {
157         assertCanonicallyEqual("integerTestCanonicalization4", "referenceSnippet4");
158     }
159 
integerTestCanonicalization4(int a)160     public static void integerTestCanonicalization4(int a) {
161         if (a + 1 < a) {
162             sink1 = 0;
163         } else {
164             sink0 = -1;
165         }
166     }
167 
referenceSnippet4(int a)168     public static void referenceSnippet4(int a) {
169         if (a == Integer.MAX_VALUE) {
170             sink1 = 0;
171         } else {
172             sink0 = -1;
173         }
174     }
175 
176     @Test
test5()177     public void test5() {
178         assertCanonicallyEqual("integerTestCanonicalization5", "referenceSnippet5");
179     }
180 
integerTestCanonicalization5(int a)181     public static void integerTestCanonicalization5(int a) {
182         if (a + 2 < a) {
183             sink1 = 0;
184         } else {
185             sink0 = -1;
186         }
187     }
188 
referenceSnippet5(int a)189     public static void referenceSnippet5(int a) {
190         if (a > Integer.MAX_VALUE - 2) {
191             sink1 = 0;
192         } else {
193             sink0 = -1;
194         }
195     }
196 
197     @Test
test6()198     public void test6() {
199         assertCanonicallyEqual("integerTestCanonicalization6", "referenceSnippet6");
200     }
201 
integerTestCanonicalization6(int a)202     public static void integerTestCanonicalization6(int a) {
203         if (a < a + 1) {
204             sink1 = 0;
205         } else {
206             sink0 = -1;
207         }
208     }
209 
referenceSnippet6(int a)210     public static void referenceSnippet6(int a) {
211         if (a != Integer.MAX_VALUE) {
212             sink1 = 0;
213         } else {
214             sink0 = -1;
215         }
216     }
217 
218     @Test
test7()219     public void test7() {
220         assertCanonicallyEqual("integerTestCanonicalization7", "referenceSnippet7");
221     }
222 
integerTestCanonicalization7(int a)223     public static void integerTestCanonicalization7(int a) {
224         if (a < a + 2) {
225             sink1 = 0;
226         } else {
227             sink0 = -1;
228         }
229     }
230 
referenceSnippet7(int a)231     public static void referenceSnippet7(int a) {
232         if (a <= Integer.MAX_VALUE - 2) {
233             sink1 = 0;
234         } else {
235             sink0 = -1;
236         }
237     }
238 
assertCanonicallyEqual(String snippet, String reference)239     protected void assertCanonicallyEqual(String snippet, String reference) {
240         StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
241         PhaseContext context = new PhaseContext(getProviders());
242         CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
243 
244         canonicalizer.apply(graph, context);
245         new GuardLoweringPhase().apply(graph, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo()));
246         new FrameStateAssignmentPhase().apply(graph);
247         canonicalizer.apply(graph, context);
248 
249         StructuredGraph referenceGraph = parseEager(reference, AllowAssumptions.YES);
250         canonicalizer.apply(referenceGraph, context);
251         new GuardLoweringPhase().apply(referenceGraph, new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo()));
252         new FrameStateAssignmentPhase().apply(referenceGraph);
253         canonicalizer.apply(referenceGraph, context);
254 
255         canonicalizer.apply(referenceGraph, context);
256         assertEquals(referenceGraph, graph, true, true);
257     }
258 
259     @Override
bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args)260     protected InlineInvokePlugin.InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
261         return InlineInvokePlugin.InlineInfo.createStandardInlineInfo(method);
262     }
263 }
264