1 /*
  2  * Copyright (c) 2024, 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 /*
 25  * @test
 26  * @summary Smoke test for code reflection with binary operations.
 27  * @build BinopTest
 28  * @build CodeReflectionTester
 29  * @run main CodeReflectionTester BinopTest
 30  */
 31 
 32 import java.lang.runtime.CodeReflection;
 33 
 34 public class BinopTest {
 35 
 36     @CodeReflection
 37     @IR("""
 38             func @"test" (%0 : BinopTest)int -> {
 39                 %1 : int = constant @"5";
 40                 %2 : int = constant @"2";
 41                 %3 : int = constant @"4";
 42                 %4 : int = mul %2 %3;
 43                 %5 : int = add %1 %4;
 44                 %6 : int = constant @"3";
 45                 %7 : int = sub %5 %6;
 46                 return %7;
 47             };
 48             """)
 49     int test() {
 50         return 5 + 2 * 4 - 3;
 51     }
 52 
 53     @CodeReflection
 54     @IR("""
 55             func @"test2" (%0 : BinopTest)int -> {
 56                 %1 : int = constant @"1";
 57                 %2 : int = constant @"2";
 58                 %3 : int = constant @"3";
 59                 %4 : int = constant @"4";
 60                 %5 : int = add %3 %4;
 61                 %6 : int = add %2 %5;
 62                 %7 : int = add %1 %6;
 63                 return %7;
 64             };
 65             """)
 66     int test2() {
 67         return 1 + (2 + (3 + 4));
 68     }
 69 
 70     @CodeReflection
 71     @IR("""
 72             func @"test3" (%0 : BinopTest)int -> {
 73                 %1 : int = constant @"1";
 74                 %2 : int = constant @"2";
 75                 %3 : int = add %1 %2;
 76                 %4 : int = constant @"3";
 77                 %5 : int = add %3 %4;
 78                 %6 : int = constant @"4";
 79                 %7 : int = add %5 %6;
 80                 return %7;
 81             };
 82             """)
 83     int test3() {
 84         return ((1 + 2) + 3) + 4;
 85     }
 86 
 87     @CodeReflection
 88     @IR("""
 89             func @"test4" (%0 : BinopTest, %1 : int)int -> {
 90                 %2 : Var<int> = var %1 @"i";
 91                 %3 : int = var.load %2;
 92                 %4 : int = constant @"1";
 93                 %5 : int = add %3 %4;
 94                 var.store %2 %5;
 95                 %6 : int = var.load %2;
 96                 %7 : int = constant @"1";
 97                 %8 : int = mul %6 %7;
 98                 var.store %2 %8;
 99                 %9 : int = add %5 %8;
100                 %10 : int = var.load %2;
101                 %11 : int = constant @"1";
102                 %12 : int = div %10 %11;
103                 var.store %2 %12;
104                 %13 : int = add %9 %12;
105                 %14 : int = var.load %2;
106                 %15 : int = constant @"1";
107                 %16 : int = sub %14 %15;
108                 var.store %2 %16;
109                 %17 : int = add %13 %16;
110                 %18 : int = var.load %2;
111                 %19 : int = constant @"1";
112                 %20 : int = mod %18 %19;
113                 var.store %2 %20;
114                 %21 : int = add %17 %20;
115                 return %21;
116             };
117             """)
118     int test4(int i) {
119         return (i += 1) + (i *= 1) + (i /= 1) + (i -= 1) + (i %= 1);
120     }
121 
122     @CodeReflection
123     @IR("""
124             func @"test5" (%0 : BinopTest, %1 : int)boolean -> {
125                 %2 : Var<int> = var %1 @"i";
126                 %3 : int = var.load %2;
127                 %4 : int = constant @"0";
128                 %5 : boolean = eq %3 %4;
129                 %6 : boolean = not %5;
130                 return %6;
131             };
132             """)
133     boolean test5(int i) {
134         return !(i == 0);
135     }
136 
137     @CodeReflection
138     @IR("""
139             func @"test6" (%0 : BinopTest)int -> {
140                 %1 : int = constant @"5";
141                 %2 : int = constant @"2";
142                 %3 : int = mod %1 %2;
143                 return %3;
144             };
145             """)
146     int test6() {
147         return 5 % 2;
148     }
149 
150     @CodeReflection
151     @IR("""
152             func @"test7" (%0 : BinopTest, %1 : double)void -> {
153                 %2 : Var<double> = var %1 @"d";
154                 %3 : double = var.load %2;
155                 %4 : int = constant @"1";
156                 %5 : double = conv %4;
157                 %6 : double = add %3 %5;
158                 var.store %2 %6;
159                 %7 : long = constant @"1";
160                 %8 : double = conv %7;
161                 %9 : double = var.load %2;
162                 %10 : double = add %8 %9;
163                 var.store %2 %10;
164                 %11 : double = var.load %2;
165                 %12 : long = constant @"1";
166                 %13 : double = conv %12;
167                 %14 : double = sub %11 %13;
168                 var.store %2 %14;
169                 %15 : int = constant @"1";
170                 %16 : double = conv %15;
171                 %17 : double = var.load %2;
172                 %18 : double = sub %16 %17;
173                 var.store %2 %18;
174                 %19 : double = var.load %2;
175                 %20 : int = constant @"1";
176                 %21 : double = conv %20;
177                 %22 : double = mul %19 %21;
178                 var.store %2 %22;
179                 %23 : long = constant @"1";
180                 %24 : double = conv %23;
181                 %25 : double = var.load %2;
182                 %26 : double = mul %24 %25;
183                 var.store %2 %26;
184                 %27 : double = var.load %2;
185                 %28 : long = constant @"1";
186                 %29 : double = conv %28;
187                 %30 : double = div %27 %29;
188                 var.store %2 %30;
189                 %31 : int = constant @"1";
190                 %32 : double = conv %31;
191                 %33 : double = var.load %2;
192                 %34 : double = div %32 %33;
193                 var.store %2 %34;
194                 %35 : double = var.load %2;
195                 %36 : int = constant @"1";
196                 %37 : double = conv %36;
197                 %38 : double = mod %35 %37;
198                 var.store %2 %38;
199                 %39 : long = constant @"1";
200                 %40 : double = conv %39;
201                 %41 : double = var.load %2;
202                 %42 : double = mod %40 %41;
203                 var.store %2 %42;
204                 %43 : int = constant @"-1";
205                 %44 : double = conv %43;
206                 var.store %2 %44;
207                 return;
208             };
209             """)
210     void test7(double d) {
211         d = d + 1;
212         d = 1L + d;
213 
214         d = d - 1L;
215         d = 1 - d;
216 
217         d = d * 1;
218         d = 1L * d;
219 
220         d = d / 1L;
221         d = 1 / d;
222 
223         d = d % 1;
224         d = 1L % d;
225 
226         d = -1;
227     }
228 
229     @CodeReflection
230     @IR("""
231             func @"test8" (%0 : BinopTest, %1 : double)void -> {
232                 %2 : Var<double> = var %1 @"d";
233                 %3 : double = var.load %2;
234                 %4 : int = constant @"1";
235                 %5 : double = conv %4;
236                 %6 : double = add %3 %5;
237                 var.store %2 %6;
238                 %7 : double = var.load %2;
239                 %8 : long = constant @"1";
240                 %9 : double = conv %8;
241                 %10 : double = sub %7 %9;
242                 var.store %2 %10;
243                 %11 : double = var.load %2;
244                 %12 : int = constant @"1";
245                 %13 : double = conv %12;
246                 %14 : double = mul %11 %13;
247                 var.store %2 %14;
248                 %15 : double = var.load %2;
249                 %16 : long = constant @"1";
250                 %17 : double = conv %16;
251                 %18 : double = div %15 %17;
252                 var.store %2 %18;
253                 %19 : double = var.load %2;
254                 %20 : int = constant @"1";
255                 %21 : double = conv %20;
256                 %22 : double = mod %19 %21;
257                 var.store %2 %22;
258                 return;
259             };
260             """)
261     void test8(double d) {
262         d += 1;
263 
264         d -= 1L;
265 
266         d *= 1;
267 
268         d /= 1L;
269 
270         d %= 1;
271     }
272 
273     @CodeReflection
274     @IR("""
275             func @"test9" (%0 : BinopTest, %1 : byte, %2 : byte, %3 : short)void -> {
276                 %4 : Var<byte> = var %1 @"a";
277                 %5 : Var<byte> = var %2 @"b";
278                 %6 : Var<short> = var %3 @"s";
279                 %7 : byte = var.load %4;
280                 %8 : byte = var.load %5;
281                 %9 : byte = add %7 %8;
282                 var.store %4 %9;
283                 %10 : byte = var.load %4;
284                 %11 : short = var.load %6;
285                 %12 : byte = conv %11;
286                 %13 : byte = div %10 %12;
287                 var.store %4 %13;
288                 %14 : byte = var.load %4;
289                 %15 : double = constant @"3.5";
290                 %16 : byte = conv %15;
291                 %17 : byte = mul %14 %16;
292                 var.store %4 %17;
293                 %18 : byte = var.load %4;
294                 %19 : byte = var.load %5;
295                 %20 : byte = lshl %18 %19;
296                 var.store %4 %20;
297                 %21 : byte = var.load %4;
298                 %22 : int = constant @"1";
299                 %23 : byte = conv %22;
300                 %24 : byte = ashr %21 %23;
301                 var.store %4 %24;
302                 %25 : byte = var.load %4;
303                 %26 : long = constant @"1";
304                 %27 : byte = conv %26;
305                 %28 : byte = ashr %25 %27;
306                 var.store %4 %28;
307                 return;
308             };
309             """)
310     void test9(byte a, byte b, short s) {
311         a += b;
312 
313         a /= s;
314 
315         a *= 3.5d;
316 
317         a <<= b;
318 
319         a >>= 1;
320 
321         a >>= 1L;
322     }
323 }