1 /*
2  * Copyright (C) 2014 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 // Note that $opt$ is a marker for the optimizing compiler to test
18 // it does compile the method, and that $noinline$ is a marker to
19 // test that it does not inline it.
20 public class Main {
21 
assertEquals(int expected, int result)22   public static void assertEquals(int expected, int result) {
23     if (expected != result) {
24       throw new Error("Expected: " + expected + ", found: " + result);
25     }
26   }
27 
assertEquals(long expected, long result)28   public static void assertEquals(long expected, long result) {
29     if (expected != result) {
30       throw new Error("Expected: " + expected + ", found: " + result);
31     }
32   }
33 
assertEquals(float expected, float result)34   public static void assertEquals(float expected, float result) {
35     if (expected != result) {
36       throw new Error("Expected: " + expected + ", found: " + result);
37     }
38   }
39 
assertEquals(String expected, float result)40   public static void assertEquals(String expected, float result) {
41     if (!expected.equals(new Float(result).toString())) {
42       throw new Error("Expected: " + expected + ", found: " + result);
43     }
44   }
45 
assertEquals(double expected, double result)46   public static void assertEquals(double expected, double result) {
47     if (expected != result) {
48       throw new Error("Expected: " + expected + ", found: " + result);
49     }
50   }
51 
assertEquals(String expected, double result)52   public static void assertEquals(String expected, double result) {
53     if (!expected.equals(new Double(result).toString())) {
54       throw new Error("Expected: " + expected + ", found: " + result);
55     }
56   }
57 
assertIsNaN(float result)58   public static void assertIsNaN(float result) {
59     if (!Float.isNaN(result)) {
60       throw new Error("Expected NaN: " + result);
61     }
62   }
63 
assertIsNaN(double result)64   public static void assertIsNaN(double result) {
65     if (!Double.isNaN(result)) {
66       throw new Error("Expected NaN: " + result);
67     }
68   }
69 
main(String[] args)70   public static void main(String[] args) {
71     negInt();
72     $opt$noinline$InplaceNegOneInt(1);
73 
74     negLong();
75     $opt$noinline$InplaceNegOneLong(1L);
76 
77     negFloat();
78     negDouble();
79   }
80 
negInt()81   private static void negInt() {
82     assertEquals(-1, $opt$noinline$NegInt(1));
83     assertEquals(1, $opt$noinline$NegInt(-1));
84     assertEquals(0, $opt$noinline$NegInt(0));
85     assertEquals(51, $opt$noinline$NegInt(-51));
86     assertEquals(-51, $opt$noinline$NegInt(51));
87     assertEquals(2147483647, $opt$noinline$NegInt(-2147483647));  // -(2^31 - 1)
88     assertEquals(-2147483647, $opt$noinline$NegInt(2147483647));  // 2^31 - 1
89     // From the Java 7 SE Edition specification:
90     // http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.15.4
91     //
92     //   For integer values, negation is the same as subtraction from
93     //   zero.  The Java programming language uses two's-complement
94     //   representation for integers, and the range of two's-complement
95     //   values is not symmetric, so negation of the maximum negative
96     //   int or long results in that same maximum negative number.
97     //   Overflow occurs in this case, but no exception is thrown.
98     //   For all integer values x, -x equals (~x)+1.''
99     assertEquals(-2147483648, $opt$noinline$NegInt(-2147483648)); // -(2^31)
100   }
101 
negLong()102   private static void negLong() {
103     assertEquals(-1L, $opt$noinline$NegLong(1L));
104     assertEquals(1L, $opt$noinline$NegLong(-1L));
105     assertEquals(0L, $opt$noinline$NegLong(0L));
106     assertEquals(51L, $opt$noinline$NegLong(-51L));
107     assertEquals(-51L, $opt$noinline$NegLong(51L));
108 
109     assertEquals(2147483647L, $opt$noinline$NegLong(-2147483647L));  // -(2^31 - 1)
110     assertEquals(-2147483647L, $opt$noinline$NegLong(2147483647L));  // (2^31 - 1)
111     assertEquals(2147483648L, $opt$noinline$NegLong(-2147483648L));  // -(2^31)
112     assertEquals(-2147483648L, $opt$noinline$NegLong(2147483648L));  // 2^31
113 
114     assertEquals(9223372036854775807L, $opt$noinline$NegLong(-9223372036854775807L));  // -(2^63 - 1)
115     assertEquals(-9223372036854775807L, $opt$noinline$NegLong(9223372036854775807L));  // 2^63 - 1
116     // See remark regarding the negation of the maximum negative
117     // (long) value in negInt().
118     assertEquals(-9223372036854775808L, $opt$noinline$NegLong(-9223372036854775808L)); // -(2^63)
119   }
120 
negFloat()121   private static void negFloat() {
122      assertEquals("-0.0", $opt$noinline$NegFloat(0F));
123      assertEquals("0.0", $opt$noinline$NegFloat(-0F));
124      assertEquals(-1F, $opt$noinline$NegFloat(1F));
125      assertEquals(1F, $opt$noinline$NegFloat(-1F));
126      assertEquals(51F, $opt$noinline$NegFloat(-51F));
127      assertEquals(-51F, $opt$noinline$NegFloat(51F));
128 
129      assertEquals(-0.1F, $opt$noinline$NegFloat(0.1F));
130      assertEquals(0.1F, $opt$noinline$NegFloat(-0.1F));
131      assertEquals(343597.38362F, $opt$noinline$NegFloat(-343597.38362F));
132      assertEquals(-343597.38362F, $opt$noinline$NegFloat(343597.38362F));
133 
134      assertEquals(-Float.MIN_NORMAL, $opt$noinline$NegFloat(Float.MIN_NORMAL));
135      assertEquals(Float.MIN_NORMAL, $opt$noinline$NegFloat(-Float.MIN_NORMAL));
136      assertEquals(-Float.MIN_VALUE, $opt$noinline$NegFloat(Float.MIN_VALUE));
137      assertEquals(Float.MIN_VALUE, $opt$noinline$NegFloat(-Float.MIN_VALUE));
138      assertEquals(-Float.MAX_VALUE, $opt$noinline$NegFloat(Float.MAX_VALUE));
139      assertEquals(Float.MAX_VALUE, $opt$noinline$NegFloat(-Float.MAX_VALUE));
140 
141      assertEquals(Float.NEGATIVE_INFINITY, $opt$noinline$NegFloat(Float.POSITIVE_INFINITY));
142      assertEquals(Float.POSITIVE_INFINITY, $opt$noinline$NegFloat(Float.NEGATIVE_INFINITY));
143      assertIsNaN($opt$noinline$NegFloat(Float.NaN));
144   }
145 
negDouble()146   private static void negDouble() {
147      assertEquals("-0.0", $opt$noinline$NegDouble(0D));
148      assertEquals("0.0", $opt$noinline$NegDouble(-0D));
149      assertEquals(-1D, $opt$noinline$NegDouble(1D));
150      assertEquals(1D, $opt$noinline$NegDouble(-1D));
151      assertEquals(51D, $opt$noinline$NegDouble(-51D));
152      assertEquals(-51D, $opt$noinline$NegDouble(51D));
153 
154      assertEquals(-0.1D, $opt$noinline$NegDouble(0.1D));
155      assertEquals(0.1D, $opt$noinline$NegDouble(-0.1D));
156      assertEquals(343597.38362D, $opt$noinline$NegDouble(-343597.38362D));
157      assertEquals(-343597.38362D, $opt$noinline$NegDouble(343597.38362D));
158 
159      assertEquals(-Double.MIN_NORMAL, $opt$noinline$NegDouble(Double.MIN_NORMAL));
160      assertEquals(Double.MIN_NORMAL, $opt$noinline$NegDouble(-Double.MIN_NORMAL));
161      assertEquals(-Double.MIN_VALUE, $opt$noinline$NegDouble(Double.MIN_VALUE));
162      assertEquals(Double.MIN_VALUE, $opt$noinline$NegDouble(-Double.MIN_VALUE));
163      assertEquals(-Double.MAX_VALUE, $opt$noinline$NegDouble(Double.MAX_VALUE));
164      assertEquals(Double.MAX_VALUE, $opt$noinline$NegDouble(-Double.MAX_VALUE));
165 
166      assertEquals(Double.NEGATIVE_INFINITY, $opt$noinline$NegDouble(Double.POSITIVE_INFINITY));
167      assertEquals(Double.POSITIVE_INFINITY, $opt$noinline$NegDouble(Double.NEGATIVE_INFINITY));
168      assertIsNaN($opt$noinline$NegDouble(Double.NaN));
169   }
170 
171 
172   static boolean doThrow = false;
173 
$opt$noinline$InplaceNegOneInt(int a)174   private static void $opt$noinline$InplaceNegOneInt(int a) {
175     if (doThrow) {
176       // Try defeating inlining.
177       throw new Error();
178     }
179     a = -a;
180     assertEquals(-1, a);
181   }
182 
$opt$noinline$InplaceNegOneLong(long a)183   private static void $opt$noinline$InplaceNegOneLong(long a) {
184     if (doThrow) {
185       // Try defeating inlining.
186       throw new Error();
187     }
188     a = -a;
189     assertEquals(-1L, a);
190   }
191 
$opt$noinline$NegInt(int a)192   private static int $opt$noinline$NegInt(int a){
193     if (doThrow) {
194       // Try defeating inlining.
195       throw new Error();
196     }
197     return -a;
198   }
199 
$opt$noinline$NegLong(long a)200   private static long $opt$noinline$NegLong(long a){
201     if (doThrow) {
202       // Try defeating inlining.
203       throw new Error();
204     }
205     return -a;
206   }
207 
$opt$noinline$NegFloat(float a)208   private static float $opt$noinline$NegFloat(float a){
209     if (doThrow) {
210       // Try defeating inlining.
211       throw new Error();
212     }
213     return -a;
214   }
215 
$opt$noinline$NegDouble(double a)216   private static double $opt$noinline$NegDouble(double a){
217     if (doThrow) {
218       // Try defeating inlining.
219       throw new Error();
220     }
221     return -a;
222   }
223 }
224