1 /*
  2  * Copyright (c) 2020, 2021, 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 package compiler.c2;
 25 
 26 import jdk.test.lib.process.OutputAnalyzer;
 27 import jdk.test.lib.process.ProcessTools;
 28 
 29 /*
 30  * @test
 31  * @bug 8247408
 32  * @summary C2 should convert ((var&16) == 16) to ((var&16) != 0) for power-of-two constants
 33  * @library /test/lib /
 34  *
 35  * @requires vm.flagless
 36  * @requires os.arch=="aarch64" | os.arch=="amd64" | os.arch == "ppc64le"
 37  * @requires vm.debug == true & vm.compiler2.enabled
 38  *
 39  * @run driver compiler.c2.TestBit
 40  */
 41 public class TestBit {
 42 
 43     static void runTest(String testName) throws Exception {
 44         String className = TestBit.class.getName();
 45         String[] procArgs = {
 46             "-Xbatch",
 47             "-XX:-TieredCompilation",
 48             "-XX:+PrintOptoAssembly",
 49             "-XX:CompileCommand=compileonly," + className + "::tst*",
 50             className, testName};
 51 
 52         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(procArgs);
 53         OutputAnalyzer output = new OutputAnalyzer(pb.start());
 54 
 55         String expectedTestBitInstruction =
 56             "ppc64le".equals(System.getProperty("os.arch")) ? "ANDI" :
 57             "aarch64".equals(System.getProperty("os.arch")) ? "tb"   :
 58             "amd64".equals(System.getProperty("os.arch"))   ? "test" : null;
 59 
 60         if (expectedTestBitInstruction != null) {
 61             output.shouldContain(expectedTestBitInstruction);
 62         } else {
 63             System.err.println("unexpected os.arch");
 64         }
 65     }
 66 
 67     static final int ITER = 100000; // ~ Tier4CompileThreshold + compilation time
 68 
 69     // dummy volatile variable
 70     public static volatile long c = 0;
 71 
 72     // C2 is expected to generate test bit instruction on the test
 73     static void tstBitLong(long value) {
 74         if (1L == (1L & value)) {
 75             c++;
 76         } else {
 77             c--;
 78         }
 79     }
 80 
 81     // C2 is expected to generate test bit instruction on the test
 82     static void tstBitInt(int value) {
 83         if (1 == (1 & value)) {
 84             c++;
 85         } else {
 86             c--;
 87         }
 88     }
 89 
 90     public static void main(String[] args) throws Exception {
 91         if (args.length == 0) {
 92             // Fork VMs to check their debug compiler output
 93             runTest("tstBitLong");
 94             runTest("tstBitInt");
 95         }
 96         if (args.length > 0) {
 97             // We are in a forked VM to execute the named test
 98             String testName = args[0];
 99             switch (testName) {
100             case "tstBitLong":
101                 for (int i = 0; i < ITER; i++) {
102                     tstBitLong(i % 2);
103                 }
104                 break;
105             case "tstBitInt":
106                 for (int i = 0; i < ITER; i++) {
107                     tstBitInt(i % 2);
108                 }
109                 break;
110             default:
111                 throw new RuntimeException("unexpected test name " + testName);
112             }
113         }
114     }
115 }