[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