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 public class RemTest {
18 
main()19   public static void main() {
20     remInt();
21     remLong();
22   }
23 
remInt()24   private static void remInt() {
25     expectEquals(2, $opt$RemConst(6));
26     expectEquals(2, $opt$Rem(6, 4));
27     expectEquals(2, $opt$Rem(6, -4));
28     expectEquals(0, $opt$Rem(6, 3));
29     expectEquals(0, $opt$Rem(6, -3));
30     expectEquals(0, $opt$Rem(6, 1));
31     expectEquals(0, $opt$Rem(6, -1));
32     expectEquals(-1, $opt$Rem(-7, 3));
33     expectEquals(-1, $opt$Rem(-7, -3));
34     expectEquals(0, $opt$Rem(6, 6));
35     expectEquals(0, $opt$Rem(-6, -6));
36     expectEquals(7, $opt$Rem(7, 9));
37     expectEquals(7, $opt$Rem(7, -9));
38     expectEquals(-7, $opt$Rem(-7, 9));
39     expectEquals(-7, $opt$Rem(-7, -9));
40 
41     expectEquals(0, $opt$Rem(Integer.MAX_VALUE, 1));
42     expectEquals(0, $opt$Rem(Integer.MAX_VALUE, -1));
43     expectEquals(0, $opt$Rem(Integer.MIN_VALUE, 1));
44     expectEquals(0, $opt$Rem(Integer.MIN_VALUE, -1)); // no overflow
45     expectEquals(-1, $opt$Rem(Integer.MIN_VALUE, Integer.MAX_VALUE));
46     expectEquals(Integer.MAX_VALUE, $opt$Rem(Integer.MAX_VALUE, Integer.MIN_VALUE));
47 
48     expectEquals(0, $opt$Rem(0, 7));
49     expectEquals(0, $opt$Rem(0, Integer.MAX_VALUE));
50     expectEquals(0, $opt$Rem(0, Integer.MIN_VALUE));
51 
52     expectDivisionByZero(0);
53     expectDivisionByZero(1);
54     expectDivisionByZero(5);
55     expectDivisionByZero(Integer.MAX_VALUE);
56     expectDivisionByZero(Integer.MIN_VALUE);
57   }
58 
remLong()59   private static void remLong() {
60     expectEquals(2L, $opt$RemConst(6L));
61     expectEquals(2L, $opt$Rem(6L, 4L));
62     expectEquals(2L, $opt$Rem(6L, -4L));
63     expectEquals(0L, $opt$Rem(6L, 3L));
64     expectEquals(0L, $opt$Rem(6L, -3L));
65     expectEquals(0L, $opt$Rem(6L, 1L));
66     expectEquals(0L, $opt$Rem(6L, -1L));
67     expectEquals(-1L, $opt$Rem(-7L, 3L));
68     expectEquals(-1L, $opt$Rem(-7L, -3L));
69     expectEquals(0L, $opt$Rem(6L, 6L));
70     expectEquals(0L, $opt$Rem(-6L, -6L));
71     expectEquals(7L, $opt$Rem(7L, 9L));
72     expectEquals(7L, $opt$Rem(7L, -9L));
73     expectEquals(-7L, $opt$Rem(-7L, 9L));
74     expectEquals(-7L, $opt$Rem(-7L, -9L));
75 
76     expectEquals(0L, $opt$Rem(Long.MAX_VALUE, 1L));
77     expectEquals(0L, $opt$Rem(Long.MAX_VALUE, -1L));
78     expectEquals(0L, $opt$Rem(Long.MIN_VALUE, 1L));
79     expectEquals(0L, $opt$Rem(Long.MIN_VALUE, -1L)); // no overflow
80     expectEquals(-1L, $opt$Rem(Long.MIN_VALUE, Long.MAX_VALUE));
81     expectEquals(Long.MAX_VALUE, $opt$Rem(Long.MAX_VALUE, Long.MIN_VALUE));
82 
83     expectEquals(0L, $opt$Rem(0L, 7L));
84     expectEquals(0L, $opt$Rem(0L, Long.MAX_VALUE));
85     expectEquals(0L, $opt$Rem(0L, Long.MIN_VALUE));
86 
87     expectDivisionByZero(0L);
88     expectDivisionByZero(1L);
89     expectDivisionByZero(5L);
90     expectDivisionByZero(Long.MAX_VALUE);
91     expectDivisionByZero(Long.MIN_VALUE);
92 
93     expectEquals(0, $noinline$RemLoaded1(0));
94     expectEquals(0, $noinline$RemLoaded1(1));
95     expectEquals(0, $noinline$RemLoaded1(-1));
96     expectEquals(0, $noinline$RemLoaded1(12345));
97     expectEquals(0, $noinline$RemLoaded1(Integer.MAX_VALUE));
98     expectEquals(0, $noinline$RemLoaded1(Integer.MIN_VALUE));
99 
100     expectEquals(0, $noinline$RemLoadedN1(0));
101     expectEquals(0, $noinline$RemLoadedN1(1));
102     expectEquals(0, $noinline$RemLoadedN1(-1));
103     expectEquals(0, $noinline$RemLoadedN1(12345));
104     expectEquals(0, $noinline$RemLoadedN1(Integer.MAX_VALUE));
105     expectEquals(0, $noinline$RemLoadedN1(Integer.MIN_VALUE));
106 
107     expectEquals(0L, $noinline$RemLoaded1(0L));
108     expectEquals(0L, $noinline$RemLoaded1(1L));
109     expectEquals(0L, $noinline$RemLoaded1(-1L));
110     expectEquals(0L, $noinline$RemLoaded1(12345L));
111     expectEquals(0L, $noinline$RemLoaded1(Long.MAX_VALUE));
112     expectEquals(0L, $noinline$RemLoaded1(Long.MIN_VALUE));
113 
114     expectEquals(0L, $noinline$RemLoadedN1(0L));
115     expectEquals(0L, $noinline$RemLoadedN1(1L));
116     expectEquals(0L, $noinline$RemLoadedN1(-1L));
117     expectEquals(0L, $noinline$RemLoadedN1(12345L));
118     expectEquals(0L, $noinline$RemLoadedN1(Long.MAX_VALUE));
119     expectEquals(0L, $noinline$RemLoadedN1(Long.MIN_VALUE));
120   }
121 
$opt$Rem(int a, int b)122   static int $opt$Rem(int a, int b) {
123     return a % b;
124   }
125 
$opt$RemZero(int a)126   static int $opt$RemZero(int a) {
127     return a % 0;
128   }
129 
$noinline$RemLoaded1(int a)130   static int $noinline$RemLoaded1(int a) {
131     int[] v = {25, 1};
132     return a % v[1];
133   }
134 
$noinline$RemLoadedN1(int a)135   static int $noinline$RemLoadedN1(int a) {
136     int [] v = {25, -1};
137     return a % v[1];
138   }
139 
$noinline$RemLoaded1(long a)140   static long $noinline$RemLoaded1(long a) {
141     long[] v = {25, 1};
142     return a % v[1];
143   }
144 
$noinline$RemLoadedN1(long a)145   static long $noinline$RemLoadedN1(long a) {
146     long [] v = {25, -1};
147     return a % v[1];
148   }
149 
150   // Modulo by literals != 0 should not generate checks.
$opt$RemConst(int a)151   static int $opt$RemConst(int a) {
152     return a % 4;
153   }
154 
$opt$RemConst(long a)155   static long $opt$RemConst(long a) {
156     return a % 4L;
157   }
158 
$opt$Rem(long a, long b)159   static long $opt$Rem(long a, long b) {
160     return a % b;
161   }
162 
$opt$RemZero(long a)163   static long $opt$RemZero(long a) {
164     return a % 0L;
165   }
166 
expectEquals(int expected, int result)167   public static void expectEquals(int expected, int result) {
168     if (expected != result) {
169       throw new Error("Expected: " + expected + ", found: " + result);
170     }
171   }
172 
expectEquals(long expected, long result)173   public static void expectEquals(long expected, long result) {
174     if (expected != result) {
175       throw new Error("Expected: " + expected + ", found: " + result);
176     }
177   }
178 
expectDivisionByZero(int value)179   public static void expectDivisionByZero(int value) {
180     try {
181       $opt$Rem(value, 0);
182       throw new Error("Expected RuntimeException when modulo by 0");
183     } catch (java.lang.RuntimeException e) {
184     }
185     try {
186       $opt$RemZero(value);
187       throw new Error("Expected RuntimeException when modulo by 0");
188     } catch (java.lang.RuntimeException e) {
189     }
190   }
191 
expectDivisionByZero(long value)192   public static void expectDivisionByZero(long value) {
193     try {
194       $opt$Rem(value, 0L);
195       throw new Error("Expected RuntimeException when modulo by 0");
196     } catch (java.lang.RuntimeException e) {
197     }
198     try {
199       $opt$RemZero(value);
200       throw new Error("Expected RuntimeException when modulo by 0");
201     } catch (java.lang.RuntimeException e) {
202     }
203   }
204 
205 }
206