[llvm] cf57fcf - [FileCheck, 1/4] NFC: Switch ExpressionValue to APInt

Thomas Preud'homme via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 4 13:39:26 PDT 2023


Author: Thomas Preud'homme
Date: 2023-07-04T21:39:20+01:00
New Revision: cf57fcfa0256df8d69638ab1462267413755ba86

URL: https://github.com/llvm/llvm-project/commit/cf57fcfa0256df8d69638ab1462267413755ba86
DIFF: https://github.com/llvm/llvm-project/commit/cf57fcfa0256df8d69638ab1462267413755ba86.diff

LOG: [FileCheck, 1/4] NFC: Switch ExpressionValue to APInt

Use APInt internally to store values represented by ExpressionValue.
This will allow to support any integer values in FileCheck numeric
expression in a subsequent commit.

Reviewed By: arichardson

Differential Revision: https://reviews.llvm.org/D154428

Added: 
    

Modified: 
    llvm/lib/FileCheck/FileCheck.cpp
    llvm/lib/FileCheck/FileCheckImpl.h

Removed: 
    


################################################################################
diff  --git a/llvm/lib/FileCheck/FileCheck.cpp b/llvm/lib/FileCheck/FileCheck.cpp
index f2ef46f12ef006..dd20bd3f071447 100644
--- a/llvm/lib/FileCheck/FileCheck.cpp
+++ b/llvm/lib/FileCheck/FileCheck.cpp
@@ -155,48 +155,25 @@ ExpressionFormat::valueFromStringRepr(StringRef StrVal,
   return ExpressionValue(UnsignedValue);
 }
 
-static int64_t getAsSigned(uint64_t UnsignedValue) {
-  // Use memcpy to reinterpret the bitpattern in Value since casting to
-  // signed is implementation-defined if the unsigned value is too big to be
-  // represented in the signed type and using an union violates type aliasing
-  // rules.
-  int64_t SignedValue;
-  memcpy(&SignedValue, &UnsignedValue, sizeof(SignedValue));
-  return SignedValue;
-}
-
 Expected<int64_t> ExpressionValue::getSignedValue() const {
-  if (Negative)
-    return getAsSigned(Value);
-
-  if (Value > (uint64_t)std::numeric_limits<int64_t>::max())
+  std::optional<int64_t> SignedValue = Value.trySExtValue();
+  if (!SignedValue)
     return make_error<OverflowError>();
-
-  // Value is in the representable range of int64_t so we can use cast.
-  return static_cast<int64_t>(Value);
+  return *SignedValue;
 }
 
 Expected<uint64_t> ExpressionValue::getUnsignedValue() const {
-  if (Negative)
+  std::optional<int64_t> UnsignedValue = Value.tryZExtValue();
+  if (!UnsignedValue)
     return make_error<OverflowError>();
 
-  return Value;
+  return *UnsignedValue;
 }
 
 ExpressionValue ExpressionValue::getAbsolute() const {
-  if (!Negative)
-    return *this;
-
-  int64_t SignedValue = getAsSigned(Value);
-  int64_t MaxInt64 = std::numeric_limits<int64_t>::max();
-  // Absolute value can be represented as int64_t.
-  if (SignedValue >= -MaxInt64)
-    return ExpressionValue(-getAsSigned(Value));
-
-  // -X == -(max int64_t + Rem), negate each component independently.
-  SignedValue += MaxInt64;
-  uint64_t RemainingValueAbsolute = -SignedValue;
-  return ExpressionValue(MaxInt64 + RemainingValueAbsolute);
+  unsigned bitwidth = Value.getBitWidth();
+  assert(!Value.isNegative() || Value.isSignedIntN(bitwidth - 1));
+  return ExpressionValue(Value.abs().getZExtValue());
 }
 
 Expected<ExpressionValue> llvm::operator+(const ExpressionValue &LeftOperand,

diff  --git a/llvm/lib/FileCheck/FileCheckImpl.h b/llvm/lib/FileCheck/FileCheckImpl.h
index 3a3f4ecdfb90b0..b67b70e1678f8e 100644
--- a/llvm/lib/FileCheck/FileCheckImpl.h
+++ b/llvm/lib/FileCheck/FileCheckImpl.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_LIB_FILECHECK_FILECHECKIMPL_H
 #define LLVM_LIB_FILECHECK_FILECHECKIMPL_H
 
+#include "llvm/ADT/APInt.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/FileCheck/FileCheck.h"
@@ -120,15 +121,15 @@ class OverflowError : public ErrorInfo<OverflowError> {
 /// Class representing a numeric value.
 class ExpressionValue {
 private:
-  uint64_t Value;
-  bool Negative;
+  APInt Value;
 
 public:
+  // Store signed and unsigned 64-bit integers in a signed 65-bit APInt.
   template <class T>
-  explicit ExpressionValue(T Val) : Value(Val), Negative(Val < 0) {}
+  explicit ExpressionValue(T Val) : Value(65, Val, /*isSigned=*/Val < 0) {}
 
   bool operator==(const ExpressionValue &Other) const {
-    return Value == Other.Value && isNegative() == Other.isNegative();
+    return Value == Other.Value;
   }
 
   bool operator!=(const ExpressionValue &Other) const {
@@ -136,10 +137,7 @@ class ExpressionValue {
   }
 
   /// Returns true if value is signed and negative, false otherwise.
-  bool isNegative() const {
-    assert((Value != 0 || !Negative) && "Unexpected negative zero!");
-    return Negative;
-  }
+  bool isNegative() const { return Value.isNegative(); }
 
   /// \returns the value as a signed integer or an error if the value is out of
   /// range.


        


More information about the llvm-commits mailing list