1 /*
   2  * Copyright (c) 2015, 2019, 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.debug.DebugContext;
  28 import org.graalvm.compiler.nodes.StructuredGraph;
  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.nodes.spi.CoreProviders;
  33 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
  34 import org.junit.Ignore;
  35 import org.junit.Test;
  36 
  37 import jdk.vm.ci.meta.ResolvedJavaMethod;
  38 
  39 public class ConditionalEliminationTest13 extends ConditionalEliminationTestBase {
  40 
  41     @Override
  42     protected InlineInvokePlugin.InlineInfo bytecodeParserShouldInlineInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args) {
  43         return InlineInvokePlugin.InlineInfo.createStandardInlineInfo(method);
  44     }
  45 
  46     public static void referenceSnippet1(int a) {
  47         if (Integer.compareUnsigned(a, a + 1) < 0) {
  48             sink1 = 0;
  49         } else {
  50             sink0 = -1;
  51         }
  52     }
  53 
  54     public static void testSnippet1(int a) {
  55         if (Integer.compareUnsigned(a, a + 1) < 0 || a == 0) {
  56             sink1 = 0;
  57         } else {
  58             sink0 = -1;
  59         }
  60     }
  61 
  62     public static void referenceSnippet2(int a) {
  63         if (0 < a) {
  64             sink1 = 0;
  65         }
  66         sink0 = -1;
  67     }
  68 
  69     public static void testSnippet2(int a) {
  70         if (0 < a) {
  71             if (a == -1) {
  72                 sink2 = -2;
  73             }
  74             sink1 = 0;
  75         }
  76         sink0 = -1;
  77     }
  78 
  79     public static void testSnippet3(int a) {
  80         if (0 < a) {
  81             if (a == 1) {
  82                 sink2 = -2;
  83             }
  84             sink1 = 0;
  85         }
  86         sink0 = -1;
  87     }
  88 
  89     @SuppressWarnings("unused")
  90     public static void referenceSnippet4(int a) {
  91         sink1 = 0;
  92     }
  93 
  94     public static void testSnippet4(int a) {
  95         if (Integer.compareUnsigned(a - 1, a) < 0 || a == 0) {
  96             sink1 = 0;
  97         } else {
  98             sink0 = -1;
  99         }
 100     }
 101 
 102     public static void testSnippet5(int a) {
 103         if (a < 0) {
 104             if (a == -1) {
 105                 sink2 = -2;
 106             }
 107             sink1 = 0;
 108         }
 109         sink0 = -1;
 110     }
 111 
 112     public static void referenceSnippet6(int a) {
 113         if (a < 0) {
 114             sink1 = 0;
 115         }
 116         sink0 = -1;
 117     }
 118 
 119     public static void testSnippet6(int a) {
 120         if (a < 0) {
 121             if (a == 0) {
 122                 sink2 = -2;
 123             }
 124             sink1 = 0;
 125         }
 126         sink0 = -1;
 127     }
 128 
 129     public static void testSnippet7(int a) {
 130         if (0 < a) {
 131             if (a == 0) {
 132                 sink2 = -2;
 133             }
 134             sink1 = 0;
 135         }
 136         sink0 = -1;
 137     }
 138 
 139     public static void testSnippet8(int a) {
 140         if (Integer.compareUnsigned(a, a + 1) < 0 || a == 0xffff_ffff) {
 141             sink1 = 0;
 142         } else {
 143             sink0 = -1;
 144         }
 145     }
 146 
 147     public static void referenceSnippet9(int a) {
 148         if (Integer.compareUnsigned(a - 1, a) < 0) {
 149             sink1 = 0;
 150         } else {
 151             sink0 = -1;
 152         }
 153     }
 154 
 155     public static void testSnippet9(int a) {
 156         if (Integer.compareUnsigned(a - 1, a) < 0 || a == 0xffff_ffff) {
 157             sink1 = 0;
 158         } else {
 159             sink0 = -1;
 160         }
 161     }
 162 
 163     private static int either(int a, int b) {
 164         return (sink0 + sink1 + sink2) == 0 ? a : b;
 165     }
 166 
 167     public static void testSnippet10(int a) {
 168         if (Integer.compareUnsigned(a, a + either(1, 2)) < 0 || a == 0xffff_ffff || a == 0xffff_fffe) {
 169             sink1 = 0;
 170         } else {
 171             sink0 = -1;
 172         }
 173     }
 174 
 175     public static void referenceSnippet11(int a) {
 176         if (Integer.compareUnsigned(a, Integer.MAX_VALUE + 1) > 0) {
 177             sink1 = 0;
 178         }
 179         sink0 = -1;
 180     }
 181 
 182     public static void testSnippet11(int a) {
 183         if (Integer.compareUnsigned(a, Integer.MAX_VALUE + 1) > 0) {
 184             if (Integer.compareUnsigned(a, 42) <= 0) {
 185                 sink2 = -2;
 186             }
 187             sink1 = 0;
 188         }
 189         sink0 = -1;
 190     }
 191 
 192     public static void referenceSnippet12(int a) {
 193         if (Integer.compareUnsigned(a, 0xffff_ffff) >= 0) {
 194             sink1 = 0;
 195         } else {
 196             sink0 = -1;
 197         }
 198     }
 199 
 200     public static void testSnippet12(int a) {
 201         if (Integer.compareUnsigned(a, 0xffff_ffff) >= 0 && a == 0xffff_ffff) {
 202             sink1 = 0;
 203         } else {
 204             sink0 = -1;
 205         }
 206     }
 207 
 208     public static void testSnippet13(int a) {
 209         int x = either(0, 1);
 210         if (a <= a + x) {
 211             if (a == Integer.MAX_VALUE) {
 212                 sink2 = -2;
 213             }
 214             sink1 = 0;
 215         } else {
 216             sink0 = -1;
 217         }
 218     }
 219 
 220     public static void referenceSnippet14(int a) {
 221         int x = either(0, 1);
 222         if (a < a + x) {
 223             sink1 = 0;
 224         } else {
 225             sink0 = -1;
 226         }
 227     }
 228 
 229     public static void testSnippet14(int a) {
 230         int x = either(0, 1);
 231         if (a < a + x) {
 232             if (a == Integer.MAX_VALUE) {
 233                 sink2 = -2;
 234             }
 235             sink1 = 0;
 236         } else {
 237             sink0 = -1;
 238         }
 239     }
 240 
 241     @Test
 242     public void test1() {
 243         testConditionalElimination("testSnippet1", "referenceSnippet1");
 244     }
 245 
 246     @Test
 247     public void test2() {
 248         testConditionalElimination("testSnippet2", "referenceSnippet2");
 249     }
 250 
 251     @Test
 252     public void test3() {
 253         testConditionalElimination("testSnippet3", "testSnippet3");
 254     }
 255 
 256     @Test
 257     public void test4() {
 258         testConditionalElimination("testSnippet4", "referenceSnippet4");
 259     }
 260 
 261     @Test
 262     public void test5() {
 263         testConditionalElimination("testSnippet5", "testSnippet5");
 264     }
 265 
 266     @Test
 267     public void test6() {
 268         testConditionalElimination("testSnippet6", "referenceSnippet6");
 269     }
 270 
 271     @Test
 272     public void test7() {
 273         testConditionalElimination("testSnippet7", "referenceSnippet2");
 274     }
 275 
 276     @Test
 277     public void test8() {
 278         testConditionalElimination("testSnippet8", "referenceSnippet4");
 279     }
 280 
 281     @Test
 282     public void test9() {
 283         testConditionalElimination("testSnippet9", "referenceSnippet9");
 284     }
 285 
 286     @Ignore("Need better unsigned stamps for this conditional elimination to work.")
 287     @Test
 288     public void test10() {
 289         testConditionalElimination("testSnippet10", "referenceSnippet4");
 290     }
 291 
 292     @Test
 293     public void test11() {
 294         testConditionalElimination("testSnippet11", "referenceSnippet11");
 295     }
 296 
 297     @Test
 298     public void test12() {
 299         testConditionalElimination("testSnippet12", "referenceSnippet12");
 300     }
 301 
 302     @Test
 303     public void test13() {
 304         testConditionalElimination("testSnippet13", "testSnippet13");
 305     }
 306 
 307     @Test
 308     public void test14() {
 309         testConditionalElimination("testSnippet14", "referenceSnippet14");
 310     }
 311 
 312     @Override
 313     protected void prepareGraph(StructuredGraph graph, CanonicalizerPhase canonicalizer, CoreProviders context, boolean applyLowering) {
 314         super.prepareGraph(graph, canonicalizer, context, applyLowering);
 315         graph.clearAllStateAfter();
 316         graph.setGuardsStage(StructuredGraph.GuardsStage.AFTER_FSA);
 317         DebugContext debug = graph.getDebug();
 318         debug.dump(DebugContext.BASIC_LEVEL, graph, "After preparation");
 319         canonicalizer.apply(graph, context);
 320     }
 321 }