llvm.org GIT mirror llvm / 97ec768
ADT: Add int64_t interoperability to APSInt Add some API to `APSInt` to make it easier to compare with `int64_t`. - `APSInt::compareValues(APSInt, APSInt)` returns 1, -1 or 0 for greater, lesser, or equal, doing the right thing for mismatched "has-sign" and bitwidths. This is just like `isSameValue()` (and is now the implementation of it). - `APSInt::get(int64_t)` gets a signed `APSInt`. - `operator<(int64_t)`, etc., are implemented trivially via `get()` and `compareValues()`. - Also added `APSInt::getUnsigned(uint64_t)` to make it easier to test `compareValues()`. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@228239 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 5 years ago
2 changed file(s) with 156 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
6161 }
6262 using APInt::toString;
6363
64 /// \brief Get the correctly-extended \c int64_t value.
65 int64_t getExtValue() const {
66 assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
67 return isSigned() ? getSExtValue() : getZExtValue();
68 }
69
6470 APSInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(uint32_t width) const {
6571 return APSInt(APInt::trunc(width), IsUnsigned);
6672 }
132138 assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
133139 return eq(RHS);
134140 }
135 inline bool operator==(int64_t RHS) const {
136 return isSameValue(*this, APSInt(APInt(64, RHS), true));
137 }
138141 inline bool operator!=(const APSInt& RHS) const {
139142 return !((*this) == RHS);
140143 }
141 inline bool operator!=(int64_t RHS) const {
142 return !((*this) == RHS);
144
145 bool operator==(int64_t RHS) const {
146 return compareValues(*this, get(RHS)) == 0;
147 }
148 bool operator!=(int64_t RHS) const {
149 return compareValues(*this, get(RHS)) != 0;
150 }
151 bool operator<=(int64_t RHS) const {
152 return compareValues(*this, get(RHS)) <= 0;
153 }
154 bool operator>=(int64_t RHS) const {
155 return compareValues(*this, get(RHS)) >= 0;
156 }
157 bool operator<(int64_t RHS) const {
158 return compareValues(*this, get(RHS)) < 0;
159 }
160 bool operator>(int64_t RHS) const {
161 return compareValues(*this, get(RHS)) > 0;
143162 }
144163
145164 // The remaining operators just wrap the logic of APInt, but retain the
259278 /// \brief Determine if two APSInts have the same value, zero- or
260279 /// sign-extending as needed.
261280 static bool isSameValue(const APSInt &I1, const APSInt &I2) {
281 return !compareValues(I1, I2);
282 }
283
284 /// \brief Compare underlying values of two numbers.
285 static int compareValues(const APSInt &I1, const APSInt &I2) {
262286 if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
263 return I1 == I2;
287 return I1 == I2 ? 0 : I1 > I2 ? 1 : -1;
264288
265289 // Check for a bit-width mismatch.
266290 if (I1.getBitWidth() > I2.getBitWidth())
267 return isSameValue(I1, I2.extend(I1.getBitWidth()));
291 return compareValues(I1, I2.extend(I1.getBitWidth()));
268292 else if (I2.getBitWidth() > I1.getBitWidth())
269 return isSameValue(I1.extend(I2.getBitWidth()), I2);
270
271 assert(I1.isSigned() != I2.isSigned());
293 return compareValues(I1.extend(I2.getBitWidth()), I2);
272294
273295 // We have a signedness mismatch. Check for negative values and do an
274 // unsigned compare if signs match.
275 if ((I1.isSigned() && I1.isNegative()) ||
276 (!I1.isSigned() && I2.isNegative()))
277 return false;
278
279 return I1.eq(I2);
280 }
296 // unsigned compare if both are positive.
297 if (I1.isSigned()) {
298 assert(!I2.isSigned() && "Expected signed mismatch");
299 if (I1.isNegative())
300 return -1;
301 } else {
302 assert(I2.isSigned() && "Expected signed mismatch");
303 if (I2.isNegative())
304 return 1;
305 }
306
307 return I1.eq(I2) ? 0 : I1.ugt(I2) ? 1 : -1;
308 }
309
310 static APSInt get(int64_t X) { return APSInt(APInt(64, X), false); }
311 static APSInt getUnsigned(uint64_t X) { return APSInt(APInt(64, X), true); }
281312
282313 /// Profile - Used to insert APSInt objects, or objects that contain APSInt
283314 /// objects, into FoldingSets.
284315 void Profile(FoldingSetNodeID& ID) const;
285316 };
286317
287 inline bool operator==(int64_t V1, const APSInt& V2) {
288 return V2 == V1;
289 }
290 inline bool operator!=(int64_t V1, const APSInt& V2) {
291 return V2 != V1;
292 }
318 inline bool operator==(int64_t V1, const APSInt &V2) { return V2 == V1; }
319 inline bool operator!=(int64_t V1, const APSInt &V2) { return V2 != V1; }
320 inline bool operator<=(int64_t V1, const APSInt &V2) { return V2 >= V1; }
321 inline bool operator>=(int64_t V1, const APSInt &V2) { return V2 <= V1; }
322 inline bool operator<(int64_t V1, const APSInt &V2) { return V2 > V1; }
323 inline bool operator>(int64_t V1, const APSInt &V2) { return V2 < V1; }
293324
294325 inline raw_ostream &operator<<(raw_ostream &OS, const APSInt &I) {
295326 I.print(OS, I.isSigned());
4040 EXPECT_EQ(Bits, A.getRawData()); // Verify that "Wide" was really moved.
4141 }
4242
43 TEST(APSIntTest, get) {
44 EXPECT_TRUE(APSInt::get(7).isSigned());
45 EXPECT_EQ(64u, APSInt::get(7).getBitWidth());
46 EXPECT_EQ(7u, APSInt::get(7).getZExtValue());
47 EXPECT_EQ(7, APSInt::get(7).getSExtValue());
48 EXPECT_TRUE(APSInt::get(-7).isSigned());
49 EXPECT_EQ(64u, APSInt::get(-7).getBitWidth());
50 EXPECT_EQ(-7, APSInt::get(-7).getSExtValue());
51 EXPECT_EQ(UINT64_C(0) - 7, APSInt::get(-7).getZExtValue());
4352 }
53
54 TEST(APSIntTest, getUnsigned) {
55 EXPECT_TRUE(APSInt::getUnsigned(7).isUnsigned());
56 EXPECT_EQ(64u, APSInt::getUnsigned(7).getBitWidth());
57 EXPECT_EQ(7u, APSInt::getUnsigned(7).getZExtValue());
58 EXPECT_EQ(7, APSInt::getUnsigned(7).getSExtValue());
59 EXPECT_TRUE(APSInt::getUnsigned(-7).isUnsigned());
60 EXPECT_EQ(64u, APSInt::getUnsigned(-7).getBitWidth());
61 EXPECT_EQ(-7, APSInt::getUnsigned(-7).getSExtValue());
62 EXPECT_EQ(UINT64_C(0) - 7, APSInt::getUnsigned(-7).getZExtValue());
63 }
64
65 TEST(APSIntTest, getExtValue) {
66 EXPECT_TRUE(APSInt(APInt(3, 7), true).isUnsigned());
67 EXPECT_TRUE(APSInt(APInt(3, 7), false).isSigned());
68 EXPECT_TRUE(APSInt(APInt(4, 7), true).isUnsigned());
69 EXPECT_TRUE(APSInt(APInt(4, 7), false).isSigned());
70 EXPECT_TRUE(APSInt(APInt(4, -7), true).isUnsigned());
71 EXPECT_TRUE(APSInt(APInt(4, -7), false).isSigned());
72 EXPECT_EQ(7, APSInt(APInt(3, 7), true).getExtValue());
73 EXPECT_EQ(-1, APSInt(APInt(3, 7), false).getExtValue());
74 EXPECT_EQ(7, APSInt(APInt(4, 7), true).getExtValue());
75 EXPECT_EQ(7, APSInt(APInt(4, 7), false).getExtValue());
76 EXPECT_EQ(9, APSInt(APInt(4, -7), true).getExtValue());
77 EXPECT_EQ(-7, APSInt(APInt(4, -7), false).getExtValue());
78 }
79
80 TEST(APSIntTest, compareValues) {
81 auto U = [](uint64_t V) { return APSInt::getUnsigned(V); };
82 auto S = [](int64_t V) { return APSInt::get(V); };
83
84 // Bit-width matches and is-signed.
85 EXPECT_TRUE(APSInt::compareValues(S(7), S(8)) < 0);
86 EXPECT_TRUE(APSInt::compareValues(S(8), S(7)) > 0);
87 EXPECT_TRUE(APSInt::compareValues(S(7), S(7)) == 0);
88 EXPECT_TRUE(APSInt::compareValues(S(-7), S(8)) < 0);
89 EXPECT_TRUE(APSInt::compareValues(S(8), S(-7)) > 0);
90 EXPECT_TRUE(APSInt::compareValues(S(-7), S(-7)) == 0);
91 EXPECT_TRUE(APSInt::compareValues(S(-7), S(-8)) > 0);
92 EXPECT_TRUE(APSInt::compareValues(S(-8), S(-7)) < 0);
93 EXPECT_TRUE(APSInt::compareValues(S(-7), S(-7)) == 0);
94
95 // Bit-width matches and not is-signed.
96 EXPECT_TRUE(APSInt::compareValues(U(7), U(8)) < 0);
97 EXPECT_TRUE(APSInt::compareValues(U(8), U(7)) > 0);
98 EXPECT_TRUE(APSInt::compareValues(U(7), U(7)) == 0);
99
100 // Bit-width matches and mixed signs.
101 EXPECT_TRUE(APSInt::compareValues(U(7), S(8)) < 0);
102 EXPECT_TRUE(APSInt::compareValues(U(8), S(7)) > 0);
103 EXPECT_TRUE(APSInt::compareValues(U(7), S(7)) == 0);
104 EXPECT_TRUE(APSInt::compareValues(U(8), S(-7)) > 0);
105
106 // Bit-width mismatch and is-signed.
107 EXPECT_TRUE(APSInt::compareValues(S(7).trunc(32), S(8)) < 0);
108 EXPECT_TRUE(APSInt::compareValues(S(8).trunc(32), S(7)) > 0);
109 EXPECT_TRUE(APSInt::compareValues(S(7).trunc(32), S(7)) == 0);
110 EXPECT_TRUE(APSInt::compareValues(S(-7).trunc(32), S(8)) < 0);
111 EXPECT_TRUE(APSInt::compareValues(S(8).trunc(32), S(-7)) > 0);
112 EXPECT_TRUE(APSInt::compareValues(S(-7).trunc(32), S(-7)) == 0);
113 EXPECT_TRUE(APSInt::compareValues(S(-7).trunc(32), S(-8)) > 0);
114 EXPECT_TRUE(APSInt::compareValues(S(-8).trunc(32), S(-7)) < 0);
115 EXPECT_TRUE(APSInt::compareValues(S(-7).trunc(32), S(-7)) == 0);
116 EXPECT_TRUE(APSInt::compareValues(S(7), S(8).trunc(32)) < 0);
117 EXPECT_TRUE(APSInt::compareValues(S(8), S(7).trunc(32)) > 0);
118 EXPECT_TRUE(APSInt::compareValues(S(7), S(7).trunc(32)) == 0);
119 EXPECT_TRUE(APSInt::compareValues(S(-7), S(8).trunc(32)) < 0);
120 EXPECT_TRUE(APSInt::compareValues(S(8), S(-7).trunc(32)) > 0);
121 EXPECT_TRUE(APSInt::compareValues(S(-7), S(-7).trunc(32)) == 0);
122 EXPECT_TRUE(APSInt::compareValues(S(-7), S(-8).trunc(32)) > 0);
123 EXPECT_TRUE(APSInt::compareValues(S(-8), S(-7).trunc(32)) < 0);
124 EXPECT_TRUE(APSInt::compareValues(S(-7), S(-7).trunc(32)) == 0);
125
126 // Bit-width mismatch and not is-signed.
127 EXPECT_TRUE(APSInt::compareValues(U(7), U(8).trunc(32)) < 0);
128 EXPECT_TRUE(APSInt::compareValues(U(8), U(7).trunc(32)) > 0);
129 EXPECT_TRUE(APSInt::compareValues(U(7), U(7).trunc(32)) == 0);
130 EXPECT_TRUE(APSInt::compareValues(U(7).trunc(32), U(8)) < 0);
131 EXPECT_TRUE(APSInt::compareValues(U(8).trunc(32), U(7)) > 0);
132 EXPECT_TRUE(APSInt::compareValues(U(7).trunc(32), U(7)) == 0);
133
134 // Bit-width mismatch and mixed signs.
135 EXPECT_TRUE(APSInt::compareValues(U(7).trunc(32), S(8)) < 0);
136 EXPECT_TRUE(APSInt::compareValues(U(8).trunc(32), S(7)) > 0);
137 EXPECT_TRUE(APSInt::compareValues(U(7).trunc(32), S(7)) == 0);
138 EXPECT_TRUE(APSInt::compareValues(U(8).trunc(32), S(-7)) > 0);
139 EXPECT_TRUE(APSInt::compareValues(U(7), S(8).trunc(32)) < 0);
140 EXPECT_TRUE(APSInt::compareValues(U(8), S(7).trunc(32)) > 0);
141 EXPECT_TRUE(APSInt::compareValues(U(7), S(7).trunc(32)) == 0);
142 EXPECT_TRUE(APSInt::compareValues(U(8), S(-7).trunc(32)) > 0);
143 }
144
145 }