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 Main {
18 
main(String[] args)19   public static void main(String[] args) {
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 
$opt$Rem(int a, int b)94   static int $opt$Rem(int a, int b) {
95     return a % b;
96   }
97 
$opt$RemZero(int a)98   static int $opt$RemZero(int a) {
99     return a % 0;
100   }
101 
102   // Modulo by literals != 0 should not generate checks.
$opt$RemConst(int a)103   static int $opt$RemConst(int a) {
104     return a % 4;
105   }
106 
$opt$RemConst(long a)107   static long $opt$RemConst(long a) {
108     return a % 4L;
109   }
110 
$opt$Rem(long a, long b)111   static long $opt$Rem(long a, long b) {
112     return a % b;
113   }
114 
$opt$RemZero(long a)115   static long $opt$RemZero(long a) {
116     return a % 0L;
117   }
118 
expectEquals(int expected, int result)119   public static void expectEquals(int expected, int result) {
120     if (expected != result) {
121       throw new Error("Expected: " + expected + ", found: " + result);
122     }
123   }
124 
expectEquals(long expected, long result)125   public static void expectEquals(long expected, long result) {
126     if (expected != result) {
127       throw new Error("Expected: " + expected + ", found: " + result);
128     }
129   }
130 
expectDivisionByZero(int value)131   public static void expectDivisionByZero(int value) {
132     try {
133       $opt$Rem(value, 0);
134       throw new Error("Expected RuntimeException when modulo by 0");
135     } catch (java.lang.RuntimeException e) {
136     }
137     try {
138       $opt$RemZero(value);
139       throw new Error("Expected RuntimeException when modulo by 0");
140     } catch (java.lang.RuntimeException e) {
141     }
142   }
143 
expectDivisionByZero(long value)144   public static void expectDivisionByZero(long value) {
145     try {
146       $opt$Rem(value, 0L);
147       throw new Error("Expected RuntimeException when modulo by 0");
148     } catch (java.lang.RuntimeException e) {
149     }
150     try {
151       $opt$RemZero(value);
152       throw new Error("Expected RuntimeException when modulo by 0");
153     } catch (java.lang.RuntimeException e) {
154     }
155   }
156 
157 }
158