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 17 import java.util.Arrays; 18 19 // Modified from a fuzz test. 20 public 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