-
Notifications
You must be signed in to change notification settings - Fork 16k
[APInt] Extend isSameValue to also do signed-compares #178854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Similar to isSameValue, it checks if two APInts have the same signed value.
|
@llvm/pr-subscribers-llvm-adt Author: Ramkumar Ramachandra (artagnon) ChangesSimilar to isSameValue, it checks if two APInts have the same signed value. Full diff: https://github.com/llvm/llvm-project/pull/178854.diff 2 Files Affected:
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index 9193b5f8994e0..2676cb67005b0 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -561,6 +561,18 @@ class [[nodiscard]] APInt {
return I1.zext(I2.getBitWidth()) == I2;
}
+ /// Determine if two APInts have the same value, after sign-extending
+ /// one of them (if needed!) to ensure that the bit-widths match.
+ static bool isSameSignedValue(const APInt &I1, const APInt &I2) {
+ if (I1.getBitWidth() == I2.getBitWidth())
+ return I1 == I2;
+
+ if (I1.getBitWidth() > I2.getBitWidth())
+ return I1 == I2.sext(I1.getBitWidth());
+
+ return I1.sext(I2.getBitWidth()) == I2;
+ }
+
/// Overload to compute a hash_code for an APInt value.
LLVM_ABI friend hash_code hash_value(const APInt &Arg);
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index 271d17cb29905..be5db038c904d 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -14,7 +14,6 @@
#include "llvm/Support/Alignment.h"
#include "gtest/gtest.h"
#include <array>
-#include <climits>
#include <limits>
#include <optional>
@@ -29,6 +28,28 @@ TEST(APIntTest, ValueInit) {
EXPECT_TRUE(!Zero.sext(64));
}
+TEST(APIntTest, IsSameValueAndIsSameSignedValue) {
+ APInt One8(8, 1, /*isSigned=*/false);
+ APInt Three4(4, 3, /*isSigned=*/false);
+ EXPECT_FALSE(APInt::isSameValue(One8, Three4));
+ EXPECT_FALSE(APInt::isSameSignedValue(One8, Three4));
+
+ APInt Two8(8, 2, /*isSigned=*/false);
+ APInt Two4(4, 2, /*isSigned=*/false);
+ EXPECT_TRUE(APInt::isSameValue(Two8, Two4));
+ EXPECT_TRUE(APInt::isSameSignedValue(Two8, Two4));
+
+ APInt Seven8(8, 7, /*isSigned=*/false);
+ APInt Seven3(3, 7, /*isSigned=*/false);
+ EXPECT_TRUE(APInt::isSameValue(Seven8, Seven3));
+ EXPECT_FALSE(APInt::isSameSignedValue(Seven8, Seven3));
+
+ APInt Ones8 = APInt::getAllOnes(8);
+ APInt Ones4 = APInt::getAllOnes(4);
+ EXPECT_FALSE(APInt::isSameValue(Ones8, Ones4));
+ EXPECT_TRUE(APInt::isSameSignedValue(Ones8, Ones4));
+}
+
// Test that 0^5 == 0
TEST(APIntTest, PowZeroTo5) {
APInt Zero = APInt::getZero(32);
|
dtcxzyw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where will it be used?
Here: #172372 |
kuhar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered adding an extra flag to isSameValue, say signedCompare = false, so that we don't introduce too many functions? The implementation is identical in both cases modulo the extension used.
dtcxzyw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Introduce a SignedCompare parameter of isSameValue to use sext instead of zext.