1 /*
2  * Copyright (c) 2016, Red Hat, 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  * @test
26  * @bug 8162338
27  * @summary intrinsify fused mac operations
28  * @run main/othervm -XX:-BackgroundCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestFMA
29  *
30  */
31 
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 import java.lang.reflect.Method;
35 import java.lang.reflect.Modifier;
36 
37 // Test all fused mac instructions that can be generated
38 public class TestFMA {
39 
40     @Test(args = {5.0F, 10.0F, 7.0F}, res = 57.0F)
test1(float a, float b, float c)41     static float test1(float a, float b, float c) {
42         return Math.fma(a, b, c);
43     }
44 
45     @Test(args = {5.0D, 10.0D, 7.0D}, res = 57.0D)
test2(double a, double b, double c)46     static double test2(double a, double b, double c) {
47         return Math.fma(a, b, c);
48     }
49 
50     @Test(args = {5.0F, 10.0F, 7.0F}, res = -43.0F)
test3(float a, float b, float c)51     static float test3(float a, float b, float c) {
52         return Math.fma(-a, b, c);
53     }
54 
55     @Test(args = {5.0D, 10.0D, 7.0D}, res = -43.0D)
test4(double a, double b, double c)56     static double test4(double a, double b, double c) {
57         return Math.fma(-a, b, c);
58     }
59 
60     @Test(args = {5.0F, 10.0F, 7.0F}, res = -43.0F)
test5(float a, float b, float c)61     static float test5(float a, float b, float c) {
62         return Math.fma(a, -b, c);
63     }
64 
65     @Test(args = {5.0D, 10.0D, 7.0D}, res = -43.0D)
test6(double a, double b, double c)66     static double test6(double a, double b, double c) {
67         return Math.fma(a, -b, c);
68     }
69 
70     @Test(args = {5.0F, 10.0F, 7.0F}, res = -57.0F)
test7(float a, float b, float c)71     static float test7(float a, float b, float c) {
72         return Math.fma(-a, b, -c);
73     }
74 
75     @Test(args = {5.0D, 10.0D, 7.0D}, res = -57.0D)
test8(double a, double b, double c)76     static double test8(double a, double b, double c) {
77         return Math.fma(-a, b, -c);
78     }
79 
80     @Test(args = {5.0F, 10.0F, 7.0F}, res = -57.0F)
test9(float a, float b, float c)81     static float test9(float a, float b, float c) {
82         return Math.fma(a, -b, -c);
83     }
84 
85     @Test(args = {5.0D, 10.0D, 7.0D}, res = -57.0D)
test10(double a, double b, double c)86     static double test10(double a, double b, double c) {
87         return Math.fma(a, -b, -c);
88     }
89 
90     @Test(args = {5.0F, 10.0F, 7.0F}, res = 43.0F)
test11(float a, float b, float c)91     static float test11(float a, float b, float c) {
92         return Math.fma(a, b, -c);
93     }
94 
95     @Test(args = {5.0D, 10.0D, 7.0D}, res = 43.0D)
test12(double a, double b, double c)96     static double test12(double a, double b, double c) {
97         return Math.fma(a, b, -c);
98     }
99 
main(String[] args)100     static public void main(String[] args) throws Exception {
101         TestFMA t = new TestFMA();
102         for (Method m : t.getClass().getDeclaredMethods()) {
103             if (m.getName().matches("test[0-9]+?")) {
104                 t.doTest(m);
105             }
106         }
107     }
108 
109     @Retention(RetentionPolicy.RUNTIME)
110     @interface Test {
args()111         double[] args();
res()112         double res();
113     }
114 
doTest(Method m)115     void doTest(Method m) throws Exception {
116         String name = m.getName();
117         System.out.println("Testing " + name);
118         Class retType = m.getReturnType();
119         Test test = m.getAnnotation(Test.class);
120         double[] args = test.args();
121         double expected = test.res();
122 
123         for (int i = 0; i < 20000; i++) {
124             if (retType == double.class) {
125                 Object res = m.invoke(null, (double)args[0], (double)args[1], (double)args[2]);
126                 if ((double)res != expected) {
127                     throw new RuntimeException(name + " failed : " + (double)res + " != " + expected);
128                 }
129             } else {
130                 Object res = m.invoke(null, (float)args[0], (float)args[1], (float)args[2]);
131                 if ((float)res != (float)expected) {
132                     throw new RuntimeException(name + " failed : " + (float)res + " != " + (float)expected);
133                 }
134             }
135         }
136     }
137 }
138