1 /*
   2  * Copyright 2010 Google, Inc.  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 /*
  26  * @test
  27  * @bug 6921969
  28  * @summary Tests shorter long multiply sequences when the high 32 bits of long operands are known to be zero on x86_32
  29  * @run main/othervm -Xbatch -XX:-Inline
  30  *    -XX:CompileCommand=compileonly,compiler.c2.TestMultiplyLongHiZero::testNormal
  31  *    -XX:CompileCommand=compileonly,compiler.c2.TestMultiplyLongHiZero::testLeftOptimized
  32  *    -XX:CompileCommand=compileonly,compiler.c2.TestMultiplyLongHiZero::testRightOptimized
  33  *    -XX:CompileCommand=compileonly,compiler.c2.TestMultiplyLongHiZero::testOptimized
  34  *    -XX:CompileCommand=compileonly,compiler.c2.TestMultiplyLongHiZero::testLeftOptimized_LoadUI2L
  35  *    -XX:CompileCommand=compileonly,compiler.c2.TestMultiplyLongHiZero::testRightOptimized_LoadUI2L
  36  *    -XX:CompileCommand=compileonly,compiler.c2.TestMultiplyLongHiZero::testOptimized_LoadUI2L
  37  *    compiler.c2.TestMultiplyLongHiZero
  38  */
  39 
  40 package compiler.c2;
  41 
  42 // This test must run without any command line arguments.
  43 public class TestMultiplyLongHiZero {
  44 
  45   private static void check(long leftFactor, long rightFactor, long optimizedProduct, long constantProduct) {
  46     long normalProduct = leftFactor * rightFactor; // unaffected by the new optimization
  47     if (optimizedProduct != constantProduct || normalProduct != constantProduct) {
  48       throw new RuntimeException("Not all three products are equal: " +
  49                                  Long.toHexString(normalProduct) + ", " +
  50                                  Long.toHexString(optimizedProduct) + ", " +
  51                                  Long.toHexString(constantProduct));
  52     }
  53   }
  54 
  55   private static int initInt(String[] args, int v) {
  56     if (args.length > 0) {
  57       try {
  58         return Integer.valueOf(args[0]);
  59       } catch (NumberFormatException e) { }
  60     }
  61     return v;
  62   }
  63 
  64   private static final long mask32 = 0x00000000FFFFFFFFL;
  65 
  66   private static void testNormal(int leftFactor, int rightFactor, long constantProduct) {
  67     check((long) leftFactor,
  68           (long) rightFactor,
  69           (long) leftFactor * (long) rightFactor, // unaffected by the new optimization
  70           constantProduct);
  71   }
  72 
  73   private static void testLeftOptimized(int leftFactor, int rightFactor, long constantProduct) {
  74     check((leftFactor & mask32),
  75           (long) rightFactor,
  76           (leftFactor & mask32) * (long) rightFactor, // left factor optimized
  77           constantProduct);
  78   }
  79 
  80   private static void testRightOptimized(int leftFactor, int rightFactor, long constantProduct) {
  81     check((long) leftFactor,
  82           (rightFactor & mask32),
  83           (long) leftFactor * (rightFactor & mask32), // right factor optimized
  84           constantProduct);
  85   }
  86 
  87   private static void testOptimized(int leftFactor, int rightFactor, long constantProduct) {
  88     check((leftFactor & mask32),
  89           (rightFactor & mask32),
  90           (leftFactor & mask32) * (rightFactor & mask32), // both factors optimized
  91           constantProduct);
  92   }
  93 
  94   private static void testLeftOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors) {
  95     check((leftFactor & mask32),
  96           (long) rightFactor,
  97           (factors[0] & mask32) * (long) rightFactor, // left factor optimized
  98           constantProduct);
  99   }
 100 
 101   private static void testRightOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors) {
 102     check((long) leftFactor,
 103           (rightFactor & mask32),
 104           (long) leftFactor * (factors[1] & mask32), // right factor optimized
 105           constantProduct);
 106   }
 107 
 108   private static void testOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors) {
 109     check((leftFactor & mask32),
 110           (rightFactor & mask32),
 111           (factors[0] & mask32) * (factors[1] & mask32), // both factors optimized
 112           constantProduct);
 113   }
 114 
 115   private static void test(int leftFactor, int rightFactor,
 116                            long normalConstantProduct,
 117                            long leftOptimizedConstantProduct,
 118                            long rightOptimizedConstantProduct,
 119                            long optimizedConstantProduct) {
 120     int[] factors = new int[2];
 121     factors[0] = leftFactor;
 122     factors[1] = rightFactor;
 123     testNormal(leftFactor, rightFactor, normalConstantProduct);
 124     testLeftOptimized(leftFactor, rightFactor, leftOptimizedConstantProduct);
 125     testRightOptimized(leftFactor, rightFactor, rightOptimizedConstantProduct);
 126     testOptimized(leftFactor, rightFactor, optimizedConstantProduct);
 127     testLeftOptimized_LoadUI2L(leftFactor, rightFactor, leftOptimizedConstantProduct, factors);
 128     testRightOptimized_LoadUI2L(leftFactor, rightFactor, rightOptimizedConstantProduct, factors);
 129     testOptimized_LoadUI2L(leftFactor, rightFactor, optimizedConstantProduct, factors);
 130   }
 131 
 132   public static void main(String[] args) {
 133     for (int i = 0; i < 100000; ++i) { // Trigger compilation
 134       int i0 = initInt(args, 1);
 135       int i1 = initInt(args, 3);
 136       int i2 = initInt(args, -1);
 137       int i3 = initInt(args, 0x7FFFFFFF);
 138       test(i0, i1, 3L, 3L, 3L, 3L);
 139       test(i0, i2, -1L, -1L, 0xFFFFFFFFL, 0xFFFFFFFFL);
 140       test(i0, i3, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL, 0x7FFFFFFFL);
 141       test(i1, i2, -3L, -3L, 0x2FFFFFFFDL, 0x2FFFFFFFDL);
 142       test(i1, i3, 0x17FFFFFFDL, 0x17FFFFFFDL, 0x17FFFFFFDL, 0x17FFFFFFDL);
 143       test(i2, i3, 0xFFFFFFFF80000001L, 0x7FFFFFFE80000001L,
 144            0xFFFFFFFF80000001L, 0x7FFFFFFE80000001L);
 145     }
 146   }
 147 }