1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import java.util.Arrays;
18
19// Modified from a fuzz test.
20public class Main {
21
22  private interface X {
23    int x();
24  }
25
26  private class A {
27    public int a() {
28      return (+ (Math.multiplyExact(mI, mI)));
29    }
30  }
31
32  private class B extends A implements X {
33    public int a() {
34      return super.a() + ((int) (Math.max(364746077.0f, ((float) mD))));
35    }
36    public int x() {
37      return (mI >> (mI++));
38    }
39  }
40
41  private static class C implements X {
42    public static int s() {
43      return 671468641;
44    }
45    public int c() {
46      return -383762838;
47    }
48    public int x() {
49      return -138813312;
50    }
51  }
52
53  private A mA  = new B();
54  private B mB  = new B();
55  private X mBX = new B();
56  private C mC  = new C();
57  private X mCX = new C();
58
59  private boolean mZ = false;
60  private int     mI = 0;
61  private long    mJ = 0;
62  private float   mF = 0;
63  private double  mD = 0;
64
65  private boolean[] mArray = new boolean[576];
66
67  private Main() {
68    boolean a = false;
69    for (int i0 = 0; i0 < 576; i0++) {
70      mArray[i0] = a;
71      a = !a;
72    }
73  }
74
75  /// CHECK-START: float Main.testMethod() load_store_elimination (before)
76  /// CHECK-DAG: Deoptimize
77  /// CHECK-DAG: Deoptimize
78  /// CHECK-DAG: NewInstance
79  /// CHECK-DAG: ConstructorFence
80  /// CHECK-DAG: NewInstance
81  /// CHECK-DAG: ConstructorFence
82  /// CHECK-DAG: NewInstance
83  /// CHECK-DAG: ConstructorFence
84  /// CHECK-DAG: NewInstance
85  /// CHECK-DAG: ConstructorFence
86  /// CHECK-DAG: NewInstance
87  /// CHECK-DAG: ConstructorFence
88  /// CHECK-DAG: NewInstance
89  /// CHECK-DAG: ConstructorFence
90  /// CHECK-DAG: NewInstance
91  /// CHECK-DAG: ConstructorFence
92  /// CHECK-DAG: NewInstance
93  /// CHECK-DAG: ConstructorFence
94  /// CHECK-DAG: NewInstance
95  /// CHECK-DAG: ConstructorFence
96  /// CHECK-DAG: NewInstance
97  /// CHECK-DAG: ConstructorFence
98  /// CHECK-DAG: NewInstance
99  /// CHECK-DAG: ConstructorFence
100  /// CHECK-DAG: NewInstance
101  /// CHECK-DAG: NewInstance
102  /// CHECK-DAG: NewInstance
103  /// CHECK-NOT: NewInstance
104
105  /// CHECK-START: float Main.testMethod() load_store_elimination (after)
106  /// CHECK-DAG: Deoptimize
107  /// CHECK-DAG: Deoptimize
108  /// CHECK-NOT: NewInstance
109  /// CHECK-NOT: ConstructorFence
110
111  private float testMethod() {
112    {
113      // Each of the "new" statements here will initialize an object with final fields,
114      // which after inlining will also retain a constructor fence.
115      //
116      // After LSE we remove the 'new-instance' and the associated constructor fence.
117      int lI0 = (-1456058746 << mI);
118      mD = ((double)(int)(double) mD);
119      for (int i0 = 56 - 1; i0 >= 0; i0--) {
120        mArray[i0] &= (Boolean.logicalOr(((true ? ((boolean) new Boolean((mZ))) : mZ) || mArray[i0]), (mZ)));
121        mF *= (mF * mF);
122        if ((mZ ^ true)) {
123          mF *= ((float)(int)(float) 267827331.0f);
124          mZ ^= ((false & ((boolean) new Boolean(false))) | mZ);
125          for (int i1 = 576 - 1; i1 >= 0; i1--) {
126            mZ &= ((mArray[279]) | ((boolean) new Boolean(true)));
127            mD -= (--mD);
128            for (int i2 = 56 - 1; i2 >= 0; i2--) {
129              mF /= (mF - mF);
130              mI = (Math.min(((int) new Integer(mI)), (766538816 * (++mI))));
131              mF += (mZ ? (mB.a()) : ((! mZ) ? -752042357.0f : (++mF)));
132              mJ |= ((long) new Long((-2084191070L + (mJ | mJ))));
133              lI0 |= ((int) new Integer(((int) new Integer(mI))));
134              if (((boolean) new Boolean(false))) {
135                mZ &= (mZ);
136                mF *= (mF--);
137                mD = (Double.POSITIVE_INFINITY);
138                mF += ((float)(int)(float) (-2026938813.0f * 638401585.0f));
139                mJ = (--mJ);
140                for (int i3 = 56 - 1; i3 >= 0; i3--) {
141                  mI &= (- mI);
142                  mD = (--mD);
143                  mArray[426] = (mZ || false);
144                  mF -= (((this instanceof Main) ? mF : mF) + 976981405.0f);
145                  mZ &= ((mZ) & (this instanceof Main));
146                }
147                mZ ^= (Float.isFinite(-1975953895.0f));
148              } else {
149                mJ /= ((long) (Math.nextDown(-1519600008.0f)));
150                mJ <<= (Math.round(1237681786.0));
151              }
152            }
153            mArray[i0] &= (false || ((1256071300.0f != -353296391.0f) ? false : (mZ ^ mArray[i0])));
154            mF *= (+ ((float) mD));
155            for (int i2 = 0; i2 < 576; i2++) {
156              mD *= ((double) lI0);
157              lI0 = (lI0 & (Integer.MIN_VALUE));
158              mF -= (--mF);
159            }
160            if ((this instanceof Main)) {
161              mZ ^= ((boolean) new Boolean(true));
162            } else {
163              {
164                int lI1 = (mZ ? (--lI0) : 1099574344);
165                mJ >>= (Math.incrementExact(mJ));
166                mJ = (~ -2103354070L);
167              }
168            }
169          }
170        } else {
171          mJ *= (- ((long) new Long(479832084L)));
172          mJ %= (Long.MAX_VALUE);
173          mD /= (--mD);
174          if ((mI > ((mBX.x()) << mI))) {
175            {
176              long lJ0 = (mJ--);
177              mI >>>= (mBX.x());
178            }
179            mF = (+ 505094603.0f);
180            mD *= (((boolean) new Boolean((! false))) ? mD : 1808773781.0);
181            mI *= (Integer.MIN_VALUE);
182            for (int i1 = 576 - 1; i1 >= 0; i1--) {
183              if (((boolean) new Boolean(false))) {
184                mD += ((double)(float)(double) -1051436901.0);
185              } else {
186                mF -= ((float)(int)(float) (Float.min(mF, (mF--))));
187              }
188              for (int i2 = 0; i2 < 576; i2++) {
189                mJ -= ((long) new Long(-1968644857L));
190                mJ ^= (+ (mC.s()));
191              }
192            }
193          } else {
194            mF -= ((- mF) + -2145489966.0f);
195          }
196          mD -= (mD++);
197          mD = (949112777.0 * 1209996119.0);
198        }
199        mZ &= (Boolean.logicalAnd(true, ((mZ) & (((boolean) new Boolean(true)) && true))));
200      }
201    }
202    return ((float) 964977619L);
203  }
204
205  public static void main(String[] args) {
206    System.out.println("Start....");
207    Main t = new Main();
208    float r = 1883600237.0f;
209    try {
210      r = t.testMethod();
211    } catch (Exception e) {
212      // Arithmetic, null pointer, index out of bounds, etc.
213      System.out.println("An exception was caught.");
214    }
215    System.out.println("r  = " + r);
216    System.out.println("mZ = " + t.mZ);
217    System.out.println("mI = " + t.mI);
218    System.out.println("mJ = " + t.mJ);
219    System.out.println("mF = " + t.mF);
220    System.out.println("mD = " + t.mD);
221    System.out.println("Done....");
222  }
223}
224
225