xref: /aosp_15_r20/art/runtime/interpreter/safe_math_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "safe_math.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <limits>
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker #include "gtest/gtest.h"
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
24*795d594fSAndroid Build Coastguard Worker namespace interpreter {
25*795d594fSAndroid Build Coastguard Worker 
TEST(SafeMath,Add)26*795d594fSAndroid Build Coastguard Worker TEST(SafeMath, Add) {
27*795d594fSAndroid Build Coastguard Worker   // Adding 1 overflows 0x7ff... to 0x800... aka max and min.
28*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::max(), 1),
29*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int32_t>::min());
30*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::max(), 1),
31*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int64_t>::min());
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker   // Vanilla arithmetic should work too.
34*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::max() - 1, 1),
35*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int32_t>::max());
36*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::max() - 1, 1),
37*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int64_t>::max());
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(std::numeric_limits<int32_t>::min() + 1, -1),
40*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int32_t>::min());
41*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(std::numeric_limits<int64_t>::min() + 1, -1),
42*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int64_t>::min());
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int32_t(-1), -1), -2);
45*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int64_t(-1), -1), -2);
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int32_t(1), 1), 2);
48*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int64_t(1), 1), 2);
49*795d594fSAndroid Build Coastguard Worker 
50*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int32_t(-1), 1), 0);
51*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int64_t(-1), 1), 0);
52*795d594fSAndroid Build Coastguard Worker 
53*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int32_t(1), -1), 0);
54*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int64_t(1), -1), 0);
55*795d594fSAndroid Build Coastguard Worker 
56*795d594fSAndroid Build Coastguard Worker   // Test sign extension of smaller operand sizes.
57*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int32_t(1), int8_t(-1)), 0);
58*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int64_t(1), int8_t(-1)), 0);
59*795d594fSAndroid Build Coastguard Worker }
60*795d594fSAndroid Build Coastguard Worker 
TEST(SafeMath,Sub)61*795d594fSAndroid Build Coastguard Worker TEST(SafeMath, Sub) {
62*795d594fSAndroid Build Coastguard Worker   // Subtracting 1 underflows 0x800... to 0x7ff... aka min and max.
63*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::min(), 1),
64*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int32_t>::max());
65*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::min(), 1),
66*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int64_t>::max());
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker   // Vanilla arithmetic should work too.
69*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::max() - 1, -1),
70*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int32_t>::max());
71*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::max() - 1, -1),
72*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int64_t>::max());
73*795d594fSAndroid Build Coastguard Worker 
74*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(std::numeric_limits<int32_t>::min() + 1, 1),
75*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int32_t>::min());
76*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(std::numeric_limits<int64_t>::min() + 1, 1),
77*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int64_t>::min());
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(int32_t(-1), -1), 0);
80*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(int64_t(-1), -1), 0);
81*795d594fSAndroid Build Coastguard Worker 
82*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(int32_t(1), 1), 0);
83*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(int64_t(1), 1), 0);
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(int32_t(-1), 1), -2);
86*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(int64_t(-1), 1), -2);
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(int32_t(1), -1), 2);
89*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeSub(int64_t(1), -1), 2);
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   // Test sign extension of smaller operand sizes.
92*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int32_t(1), int8_t(-1)), 0);
93*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeAdd(int64_t(1), int8_t(-1)), 0);
94*795d594fSAndroid Build Coastguard Worker }
95*795d594fSAndroid Build Coastguard Worker 
TEST(SafeMath,Mul)96*795d594fSAndroid Build Coastguard Worker TEST(SafeMath, Mul) {
97*795d594fSAndroid Build Coastguard Worker   // Multiplying by 2 overflows 0x7ff...f to 0xfff...e aka max and -2.
98*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::max(), 2),
99*795d594fSAndroid Build Coastguard Worker             -2);
100*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::max(), 2),
101*795d594fSAndroid Build Coastguard Worker             -2);
102*795d594fSAndroid Build Coastguard Worker 
103*795d594fSAndroid Build Coastguard Worker   // Vanilla arithmetic should work too.
104*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::max() / 2, 2),
105*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int32_t>::max() - 1);  // -1 as LSB is lost by division.
106*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::max() / 2, 2),
107*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int64_t>::max() - 1);  // -1 as LSB is lost by division.
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(std::numeric_limits<int32_t>::min() / 2, 2),
110*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int32_t>::min());
111*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(std::numeric_limits<int64_t>::min() / 2, 2),
112*795d594fSAndroid Build Coastguard Worker             std::numeric_limits<int64_t>::min());
113*795d594fSAndroid Build Coastguard Worker 
114*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int32_t(-1), -1), 1);
115*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int64_t(-1), -1), 1);
116*795d594fSAndroid Build Coastguard Worker 
117*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int32_t(1), 1), 1);
118*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int64_t(1), 1), 1);
119*795d594fSAndroid Build Coastguard Worker 
120*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int32_t(-1), 1), -1);
121*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int64_t(-1), 1), -1);
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int32_t(1), -1), -1);
124*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int64_t(1), -1), -1);
125*795d594fSAndroid Build Coastguard Worker 
126*795d594fSAndroid Build Coastguard Worker   // Test sign extension of smaller operand sizes.
127*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int32_t(1), int8_t(-1)), -1);
128*795d594fSAndroid Build Coastguard Worker   EXPECT_EQ(SafeMul(int64_t(1), int8_t(-1)), -1);
129*795d594fSAndroid Build Coastguard Worker }
130*795d594fSAndroid Build Coastguard Worker 
131*795d594fSAndroid Build Coastguard Worker }  // namespace interpreter
132*795d594fSAndroid Build Coastguard Worker }  // namespace art
133