From 5449a1db40b75586c1daf70a14396295e7b3fe24 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Sun, 15 Jul 2012 00:23:36 +0000 Subject: [PATCH] Move IsSameValue from clang's ASTImporter to be methods on the APInt/APSInt classes. Part of rdar://11875995 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160223 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/APInt.h | 12 ++++++++++++ include/llvm/ADT/APSInt.h | 27 +++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 75c1d576a65..cacfb5d4c46 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -511,6 +511,18 @@ public: return getAllOnesValue(numBits).lshr(numBits - loBitsSet); } + /// \brief Determine if two APInts have the same value, after zero-extending + /// one of them (if needed!) to ensure that the bit-widths match. + static bool isSameValue(const APInt &I1, const APInt &I2) { + if (I1.getBitWidth() == I2.getBitWidth()) + return I1 == I2; + + if (I1.getBitWidth() > I2.getBitWidth()) + return I1 == I2.zext(I1.getBitWidth()); + + return I1.zext(I2.getBitWidth()) == I2; + } + /// \brief Overload to compute a hash_code for an APInt value. friend hash_code hash_value(const APInt &Arg); diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index 54a7b601d1f..807ca5e1927 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -250,6 +250,33 @@ public: : APInt::getSignedMinValue(numBits), Unsigned); } + /// \brief Determine if two APSInts have the same value, zero- or + /// sign-extending as needed. + static bool isSameValue(const APSInt &I1, const APSInt &I2) { + if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned()) + return I1 == I2; + + // Check for a bit-width mismatch. + if (I1.getBitWidth() > I2.getBitWidth()) + return isSameValue(I1, I2.extend(I1.getBitWidth())); + else if (I2.getBitWidth() > I1.getBitWidth()) + return isSameValue(I1.extend(I2.getBitWidth()), I2); + + // We have a signedness mismatch. Turn the signed value into an unsigned + // value. + if (I1.isSigned()) { + if (I1.isNegative()) + return false; + + return APSInt(I1, true) == I2; + } + + if (I2.isNegative()) + return false; + + return I1 == APSInt(I2, true); + } + /// Profile - Used to insert APSInt objects, or objects that contain APSInt /// objects, into FoldingSets. void Profile(FoldingSetNodeID& ID) const;