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" | os.arch == "riscv64"
 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" :
 59             "riscv64".equals(System.getProperty("os.arch")) ? "andi" : null;
 60 
 61         if (expectedTestBitInstruction != null) {
 62             output.shouldContain(expectedTestBitInstruction);
 63         } else {
 64             System.err.println("unexpected os.arch");
 65         }
 66     }
 67 
 68     static final int ITER = 100000; // ~ Tier4CompileThreshold + compilation time
 69 
 70     // dummy volatile variable
 71     public static volatile long c = 0;
 72 
 73     // C2 is expected to generate test bit instruction on the test
 74     static void tstBitLong(long value) {
 75         if (1L == (1L & value)) {
 76             c++;
 77         } else {
 78             c--;
 79         }
 80     }
 81 
 82     // C2 is expected to generate test bit instruction on the test
 83     static void tstBitInt(int value) {
 84         if (1 == (1 & value)) {
 85             c++;
 86         } else {
 87             c--;
 88         }
 89     }
 90 
 91     public static void main(String[] args) throws Exception {
 92         if (args.length == 0) {
 93             // Fork VMs to check their debug compiler output
 94             runTest("tstBitLong");
 95             runTest("tstBitInt");
 96         }
 97         if (args.length > 0) {
 98             // We are in a forked VM to execute the named test
 99             String testName = args[0];
100             switch (testName) {
101             case "tstBitLong":
102                 for (int i = 0; i < ITER; i++) {
103                     tstBitLong(i % 2);
104                 }
105                 break;
106             case "tstBitInt":
107                 for (int i = 0; i < ITER; i++) {
108                     tstBitInt(i % 2);
109                 }
110                 break;
111             default:
112                 throw new RuntimeException("unexpected test name " + testName);
113             }
114         }
115     }
116 }