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 
check(long leftFactor, long rightFactor, long optimizedProduct, long constantProduct)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 
initInt(String[] args, int v)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 
testNormal(int leftFactor, int rightFactor, long constantProduct)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 
testLeftOptimized(int leftFactor, int rightFactor, long constantProduct)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 
testRightOptimized(int leftFactor, int rightFactor, long constantProduct)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 
testOptimized(int leftFactor, int rightFactor, long constantProduct)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 
testLeftOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors)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 
testRightOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors)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 
testOptimized_LoadUI2L(int leftFactor, int rightFactor, long constantProduct, int[] factors)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 
test(int leftFactor, int rightFactor, long normalConstantProduct, long leftOptimizedConstantProduct, long rightOptimizedConstantProduct, long optimizedConstantProduct)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 
main(String[] args)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 }
148