xref: /aosp_15_r20/art/test/684-select-condition/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker public class Main {
18*795d594fSAndroid Build Coastguard Worker 
main(String args[])19*795d594fSAndroid Build Coastguard Worker   public static void main(String args[]) {
20*795d594fSAndroid Build Coastguard Worker     doFloatingPointTest("1", "1.0");
21*795d594fSAndroid Build Coastguard Worker     doFloatingPointTest("4", "2.0");
22*795d594fSAndroid Build Coastguard Worker     checkValue(String.valueOf(doIntegerTest1(4)), "0");
23*795d594fSAndroid Build Coastguard Worker     checkValue(String.valueOf(doIntegerTest2(4)), "4");
24*795d594fSAndroid Build Coastguard Worker 
25*795d594fSAndroid Build Coastguard Worker     // Another variant of the floating point test, but less brittle.
26*795d594fSAndroid Build Coastguard Worker     staticField = 1;
27*795d594fSAndroid Build Coastguard Worker     checkValue(String.valueOf($noinline$test()), "1.0");
28*795d594fSAndroid Build Coastguard Worker     staticField = 4;
29*795d594fSAndroid Build Coastguard Worker     checkValue(String.valueOf($noinline$test()), "2.0");
30*795d594fSAndroid Build Coastguard Worker   }
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker   // This code is a reduced version of the original reproducer. The arm
33*795d594fSAndroid Build Coastguard Worker   // code generator used to generate wrong code for it. Note that this
34*795d594fSAndroid Build Coastguard Worker   // test is very brittle and a simple change in it could cause the compiler
35*795d594fSAndroid Build Coastguard Worker   // to not trip.
doFloatingPointTest(String s, String expected)36*795d594fSAndroid Build Coastguard Worker   public static void doFloatingPointTest(String s, String expected) {
37*795d594fSAndroid Build Coastguard Worker     float a = (float)Integer.valueOf(s);
38*795d594fSAndroid Build Coastguard Worker     a = a < 2.0f ? a : 2.0f;
39*795d594fSAndroid Build Coastguard Worker     checkValue("" + a, expected);
40*795d594fSAndroid Build Coastguard Worker   }
41*795d594fSAndroid Build Coastguard Worker 
42*795d594fSAndroid Build Coastguard Worker   // The compiler used to trip on the two following methods. The test there
43*795d594fSAndroid Build Coastguard Worker   // is very brittle and requires not running constant folding after
44*795d594fSAndroid Build Coastguard Worker   // load/store elimination.
45*795d594fSAndroid Build Coastguard Worker   public static int doIntegerTest1(int param) {
46*795d594fSAndroid Build Coastguard Worker     Main main = new Main();
47*795d594fSAndroid Build Coastguard Worker     main.field = 0;
48*795d594fSAndroid Build Coastguard Worker     return (main.field == 0) ? 0 : param;
49*795d594fSAndroid Build Coastguard Worker   }
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker   public static int doIntegerTest2(int param) {
52*795d594fSAndroid Build Coastguard Worker     Main main = new Main();
53*795d594fSAndroid Build Coastguard Worker     main.field = 0;
54*795d594fSAndroid Build Coastguard Worker     return (main.field != 0) ? 0 : param;
55*795d594fSAndroid Build Coastguard Worker   }
56*795d594fSAndroid Build Coastguard Worker 
57*795d594fSAndroid Build Coastguard Worker   public static void checkValue(String actual, String expected) {
58*795d594fSAndroid Build Coastguard Worker     if (!expected.equals(actual)) {
59*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected " + expected + ", got " + actual);
60*795d594fSAndroid Build Coastguard Worker     }
61*795d594fSAndroid Build Coastguard Worker   }
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker   static void $noinline$nothing() {}
64*795d594fSAndroid Build Coastguard Worker   static int $noinline$getField() { return staticField; }
65*795d594fSAndroid Build Coastguard Worker 
66*795d594fSAndroid Build Coastguard Worker   static float $noinline$test() {
67*795d594fSAndroid Build Coastguard Worker     // The 2.0f shall be materialized for GreaterThanOrEqual at the beginning of the method;
68*795d594fSAndroid Build Coastguard Worker     // since the following call clobbers caller-saves, it is allocated to s16.
69*795d594fSAndroid Build Coastguard Worker     // r0(field) = InvokeStaticOrDirect[]
70*795d594fSAndroid Build Coastguard Worker     int one = $noinline$getField();
71*795d594fSAndroid Build Coastguard Worker     // s0(a_1) = TypeConversion[r0(one)]
72*795d594fSAndroid Build Coastguard Worker     float a = (float)one;
73*795d594fSAndroid Build Coastguard Worker     // s16(a_2) = Select[s0(a_1), C(2.0f), GreaterThanOrEqual[s0(a_1), s16(2.0f)]]
74*795d594fSAndroid Build Coastguard Worker     a = a < 2.0f ? a : 2.0f;
75*795d594fSAndroid Build Coastguard Worker     // The following call is added to clobber caller-saves, forcing the output of the Select
76*795d594fSAndroid Build Coastguard Worker     // to be allocated to s16.
77*795d594fSAndroid Build Coastguard Worker     $noinline$nothing();
78*795d594fSAndroid Build Coastguard Worker     return a;
79*795d594fSAndroid Build Coastguard Worker   }
80*795d594fSAndroid Build Coastguard Worker 
81*795d594fSAndroid Build Coastguard Worker   int field;
82*795d594fSAndroid Build Coastguard Worker   static int staticField;
83*795d594fSAndroid Build Coastguard Worker }
84