diff options
author | Thomas Preud'homme <thomas.preudhomme@arm.com> | 2023-06-29 22:44:24 +0100 |
---|---|---|
committer | Thomas Preud'homme <thomas.preudhomme@arm.com> | 2023-07-04 21:42:11 +0100 |
commit | fc0d1c05a04b7b3fbb8805de53d695f0deeac57c (patch) | |
tree | 2c399e6d546a0a167cd7291a5175aad7c0065ef7 /llvm/lib/FileCheck/FileCheck.cpp | |
parent | cf57fcfa0256df8d69638ab1462267413755ba86 (diff) | |
download | llvm-fc0d1c05a04b7b3fbb8805de53d695f0deeac57c.zip llvm-fc0d1c05a04b7b3fbb8805de53d695f0deeac57c.tar.gz llvm-fc0d1c05a04b7b3fbb8805de53d695f0deeac57c.tar.bz2 |
[FileCheck, 2/4] NFC: Switch to APInt getter for ExpressionValue
Use an APInt getter as the only interface to getting the value out of an
ExpressionValue. This paves the way to switch ExpressionValue to handle
any integer without causing too big of a patch.
Reviewed By: arichardson
Differential Revision: https://reviews.llvm.org/D154429
Diffstat (limited to 'llvm/lib/FileCheck/FileCheck.cpp')
-rw-r--r-- | llvm/lib/FileCheck/FileCheck.cpp | 230 |
1 files changed, 66 insertions, 164 deletions
diff --git a/llvm/lib/FileCheck/FileCheck.cpp b/llvm/lib/FileCheck/FileCheck.cpp index dd20bd3..3e4514f 100644 --- a/llvm/lib/FileCheck/FileCheck.cpp +++ b/llvm/lib/FileCheck/FileCheck.cpp @@ -79,38 +79,42 @@ Expected<std::string> ExpressionFormat::getWildcardRegex() const { Expected<std::string> ExpressionFormat::getMatchingString(ExpressionValue IntegerValue) const { - uint64_t AbsoluteValue; - StringRef SignPrefix = IntegerValue.isNegative() ? "-" : ""; - + APInt IntValue = IntegerValue.getAPIntValue(); + // Error out for values that cannot be represented by the appropriate 64-bit + // integer (e.g. int64_t for a signed format) to keep the getter of + // ExpressionValue as an APInt an NFC. if (Value == Kind::Signed) { - Expected<int64_t> SignedValue = IntegerValue.getSignedValue(); - if (!SignedValue) - return SignedValue.takeError(); - if (*SignedValue < 0) - AbsoluteValue = cantFail(IntegerValue.getAbsolute().getUnsignedValue()); - else - AbsoluteValue = *SignedValue; + if (!IntValue.isSignedIntN(64)) + return make_error<OverflowError>(); } else { - Expected<uint64_t> UnsignedValue = IntegerValue.getUnsignedValue(); - if (!UnsignedValue) - return UnsignedValue.takeError(); - AbsoluteValue = *UnsignedValue; + if (!IntValue.isIntN(64)) + return make_error<OverflowError>(); } - std::string AbsoluteValueStr; + unsigned Radix; + bool UpperCase = false; + SmallString<8> AbsoluteValueStr; + StringRef SignPrefix = IntValue.isNegative() ? "-" : ""; switch (Value) { case Kind::Unsigned: case Kind::Signed: - AbsoluteValueStr = utostr(AbsoluteValue); + Radix = 10; break; case Kind::HexUpper: + UpperCase = true; + Radix = 16; + break; case Kind::HexLower: - AbsoluteValueStr = utohexstr(AbsoluteValue, Value == Kind::HexLower); + Radix = 16; + UpperCase = false; break; default: return createStringError(std::errc::invalid_argument, "trying to match value with invalid format"); } + IntValue.abs().toString(AbsoluteValueStr, Radix, /*Signed=*/false, + /*formatAsCLiteral=*/false, + /*UpperCase=*/UpperCase); StringRef AlternateFormPrefix = AlternateForm ? StringRef("0x") : StringRef(); @@ -155,183 +159,81 @@ ExpressionFormat::valueFromStringRepr(StringRef StrVal, return ExpressionValue(UnsignedValue); } -Expected<int64_t> ExpressionValue::getSignedValue() const { - std::optional<int64_t> SignedValue = Value.trySExtValue(); - if (!SignedValue) - return make_error<OverflowError>(); - return *SignedValue; -} - -Expected<uint64_t> ExpressionValue::getUnsignedValue() const { - std::optional<int64_t> UnsignedValue = Value.tryZExtValue(); - if (!UnsignedValue) - return make_error<OverflowError>(); - - return *UnsignedValue; -} - -ExpressionValue ExpressionValue::getAbsolute() const { - unsigned bitwidth = Value.getBitWidth(); - assert(!Value.isNegative() || Value.isSignedIntN(bitwidth - 1)); - return ExpressionValue(Value.abs().getZExtValue()); -} - Expected<ExpressionValue> llvm::operator+(const ExpressionValue &LeftOperand, const ExpressionValue &RightOperand) { - if (LeftOperand.isNegative() && RightOperand.isNegative()) { - int64_t LeftValue = cantFail(LeftOperand.getSignedValue()); - int64_t RightValue = cantFail(RightOperand.getSignedValue()); - std::optional<int64_t> Result = checkedAdd<int64_t>(LeftValue, RightValue); - if (!Result) - return make_error<OverflowError>(); - - return ExpressionValue(*Result); - } - - // (-A) + B == B - A. - if (LeftOperand.isNegative()) - return RightOperand - LeftOperand.getAbsolute(); - - // A + (-B) == A - B. - if (RightOperand.isNegative()) - return LeftOperand - RightOperand.getAbsolute(); - - // Both values are positive at this point. - uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); - uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); - std::optional<uint64_t> Result = - checkedAddUnsigned<uint64_t>(LeftValue, RightValue); - if (!Result) + bool Overflow; + APInt Result = LeftOperand.getAPIntValue().sadd_ov( + RightOperand.getAPIntValue(), Overflow); + if (Overflow || + (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1))) return make_error<OverflowError>(); - return ExpressionValue(*Result); + if (Result.isNegative()) + return ExpressionValue(Result.getSExtValue()); + else + return ExpressionValue(Result.getZExtValue()); } Expected<ExpressionValue> llvm::operator-(const ExpressionValue &LeftOperand, const ExpressionValue &RightOperand) { - // Result will be negative and thus might underflow. - if (LeftOperand.isNegative() && !RightOperand.isNegative()) { - int64_t LeftValue = cantFail(LeftOperand.getSignedValue()); - uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); - // Result <= -1 - (max int64_t) which overflows on 1- and 2-complement. - if (RightValue > (uint64_t)std::numeric_limits<int64_t>::max()) - return make_error<OverflowError>(); - std::optional<int64_t> Result = - checkedSub(LeftValue, static_cast<int64_t>(RightValue)); - if (!Result) - return make_error<OverflowError>(); - - return ExpressionValue(*Result); - } - - // (-A) - (-B) == B - A. - if (LeftOperand.isNegative()) - return RightOperand.getAbsolute() - LeftOperand.getAbsolute(); - - // A - (-B) == A + B. - if (RightOperand.isNegative()) - return LeftOperand + RightOperand.getAbsolute(); - - // Both values are positive at this point. - uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); - uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); - if (LeftValue >= RightValue) - return ExpressionValue(LeftValue - RightValue); - else { - uint64_t AbsoluteDifference = RightValue - LeftValue; - uint64_t MaxInt64 = std::numeric_limits<int64_t>::max(); - // Value might underflow. - if (AbsoluteDifference > MaxInt64) { - AbsoluteDifference -= MaxInt64; - int64_t Result = -MaxInt64; - int64_t MinInt64 = std::numeric_limits<int64_t>::min(); - // Underflow, tested by: - // abs(Result + (max int64_t)) > abs((min int64_t) + (max int64_t)) - if (AbsoluteDifference > static_cast<uint64_t>(-(MinInt64 - Result))) - return make_error<OverflowError>(); - Result -= static_cast<int64_t>(AbsoluteDifference); - return ExpressionValue(Result); - } + bool Overflow; + APInt Result = LeftOperand.getAPIntValue().ssub_ov( + RightOperand.getAPIntValue(), Overflow); + if (Overflow || + (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1))) + return make_error<OverflowError>(); - return ExpressionValue(-static_cast<int64_t>(AbsoluteDifference)); - } + if (Result.isNegative()) + return ExpressionValue(Result.getSExtValue()); + else + return ExpressionValue(Result.getZExtValue()); } Expected<ExpressionValue> llvm::operator*(const ExpressionValue &LeftOperand, const ExpressionValue &RightOperand) { - // -A * -B == A * B - if (LeftOperand.isNegative() && RightOperand.isNegative()) - return LeftOperand.getAbsolute() * RightOperand.getAbsolute(); - - // A * -B == -B * A - if (RightOperand.isNegative()) - return RightOperand * LeftOperand; - - assert(!RightOperand.isNegative() && "Unexpected negative operand!"); - - // Result will be negative and can underflow. - if (LeftOperand.isNegative()) { - auto Result = LeftOperand.getAbsolute() * RightOperand.getAbsolute(); - if (!Result) - return Result; - - return ExpressionValue(0) - *Result; - } - - // Result will be positive and can overflow. - uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); - uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); - std::optional<uint64_t> Result = - checkedMulUnsigned<uint64_t>(LeftValue, RightValue); - if (!Result) + bool Overflow; + APInt Result = LeftOperand.getAPIntValue().smul_ov( + RightOperand.getAPIntValue(), Overflow); + if (Overflow || + (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1))) return make_error<OverflowError>(); - return ExpressionValue(*Result); + if (Result.isNegative()) + return ExpressionValue(Result.getSExtValue()); + else + return ExpressionValue(Result.getZExtValue()); } Expected<ExpressionValue> llvm::operator/(const ExpressionValue &LeftOperand, const ExpressionValue &RightOperand) { - // -A / -B == A / B - if (LeftOperand.isNegative() && RightOperand.isNegative()) - return LeftOperand.getAbsolute() / RightOperand.getAbsolute(); - - // Check for divide by zero. - if (RightOperand == ExpressionValue(0)) + // Check for division by zero. + if (RightOperand.getAPIntValue().isZero()) return make_error<OverflowError>(); - // Result will be negative and can underflow. - if (LeftOperand.isNegative() || RightOperand.isNegative()) - return ExpressionValue(0) - - cantFail(LeftOperand.getAbsolute() / RightOperand.getAbsolute()); + bool Overflow; + APInt Result = LeftOperand.getAPIntValue().sdiv_ov( + RightOperand.getAPIntValue(), Overflow); + if (Overflow || + (Result.isNegative() && !Result.isSignedIntN(Result.getBitWidth() - 1))) + return make_error<OverflowError>(); - uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); - uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); - return ExpressionValue(LeftValue / RightValue); + if (Result.isNegative()) + return ExpressionValue(Result.getSExtValue()); + else + return ExpressionValue(Result.getZExtValue()); } Expected<ExpressionValue> llvm::max(const ExpressionValue &LeftOperand, const ExpressionValue &RightOperand) { - if (LeftOperand.isNegative() && RightOperand.isNegative()) { - int64_t LeftValue = cantFail(LeftOperand.getSignedValue()); - int64_t RightValue = cantFail(RightOperand.getSignedValue()); - return ExpressionValue(std::max(LeftValue, RightValue)); - } - - if (!LeftOperand.isNegative() && !RightOperand.isNegative()) { - uint64_t LeftValue = cantFail(LeftOperand.getUnsignedValue()); - uint64_t RightValue = cantFail(RightOperand.getUnsignedValue()); - return ExpressionValue(std::max(LeftValue, RightValue)); - } - - if (LeftOperand.isNegative()) - return RightOperand; - - return LeftOperand; + return LeftOperand.getAPIntValue().slt(RightOperand.getAPIntValue()) + ? RightOperand + : LeftOperand; } Expected<ExpressionValue> llvm::min(const ExpressionValue &LeftOperand, const ExpressionValue &RightOperand) { - if (cantFail(max(LeftOperand, RightOperand)) == LeftOperand) + if (cantFail(max(LeftOperand, RightOperand)).getAPIntValue() == + LeftOperand.getAPIntValue()) return RightOperand; return LeftOperand; |