[FileCheck, 2/4] NFC: Switch to APInt getter for ExpressionValue
authorThomas Preud'homme <thomas.preudhomme@arm.com>
Thu, 29 Jun 2023 21:44:24 +0000 (22:44 +0100)
committerThomas Preud'homme <thomas.preudhomme@arm.com>
Tue, 4 Jul 2023 20:42:11 +0000 (21:42 +0100)
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

llvm/lib/FileCheck/FileCheck.cpp
llvm/lib/FileCheck/FileCheckImpl.h
llvm/unittests/FileCheck/FileCheckTest.cpp

index dd20bd3..3e4514f 100644 (file)
@@ -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;
index b67b70e..10fe8d4 100644 (file)
@@ -128,28 +128,7 @@ public:
   template <class T>
   explicit ExpressionValue(T Val) : Value(65, Val, /*isSigned=*/Val < 0) {}
 
-  bool operator==(const ExpressionValue &Other) const {
-    return Value == Other.Value;
-  }
-
-  bool operator!=(const ExpressionValue &Other) const {
-    return !(*this == Other);
-  }
-
-  /// Returns true if value is signed and negative, false otherwise.
-  bool isNegative() const { return Value.isNegative(); }
-
-  /// \returns the value as a signed integer or an error if the value is out of
-  /// range.
-  Expected<int64_t> getSignedValue() const;
-
-  /// \returns the value as an unsigned integer or an error if the value is out
-  /// of range.
-  Expected<uint64_t> getUnsignedValue() const;
-
-  /// \returns an unsigned ExpressionValue instance whose value is the absolute
-  /// value to this object's value.
-  ExpressionValue getAbsolute() const;
+  APInt getAPIntValue() const { return Value; }
 };
 
 /// Performs operation and \returns its result or an error in case of failure,
index 142c428..767de75 100644 (file)
@@ -208,14 +208,13 @@ struct ExpressionFormatParameterisedFixture
     Expected<ExpressionValue> ResultValue = getValueFromStringReprFailure(Str);
     ASSERT_THAT_EXPECTED(ResultValue, Succeeded())
         << "Failed to get value from " << Str;
-    ASSERT_EQ(ResultValue->isNegative(), ExpectedVal < 0)
+    APInt ResValue = ResultValue->getAPIntValue();
+    ASSERT_EQ(ResValue.isNegative(), ExpectedVal < 0)
         << "Value for " << Str << " is not " << ExpectedVal;
-    if (ResultValue->isNegative())
-      EXPECT_EQ(cantFail(ResultValue->getSignedValue()),
-                static_cast<int64_t>(ExpectedVal));
+    if (ResValue.isNegative())
+      EXPECT_EQ(ResValue.getSExtValue(), static_cast<int64_t>(ExpectedVal));
     else
-      EXPECT_EQ(cantFail(ResultValue->getUnsignedValue()),
-                static_cast<uint64_t>(ExpectedVal));
+      EXPECT_EQ(ResValue.getZExtValue(), static_cast<uint64_t>(ExpectedVal));
   }
 
   void checkValueFromStringReprFailure(
@@ -400,16 +399,12 @@ static Expected<ExpressionValue> doValueOperation(binop_eval_t Operation,
 
 template <class T>
 static void expectValueEqual(ExpressionValue ActualValue, T ExpectedValue) {
-  EXPECT_EQ(ExpectedValue < 0, ActualValue.isNegative());
-  if (ExpectedValue < 0) {
-    Expected<int64_t> SignedActualValue = ActualValue.getSignedValue();
-    ASSERT_THAT_EXPECTED(SignedActualValue, Succeeded());
-    EXPECT_EQ(*SignedActualValue, static_cast<int64_t>(ExpectedValue));
-  } else {
-    Expected<uint64_t> UnsignedActualValue = ActualValue.getUnsignedValue();
-    ASSERT_THAT_EXPECTED(UnsignedActualValue, Succeeded());
-    EXPECT_EQ(*UnsignedActualValue, static_cast<uint64_t>(ExpectedValue));
-  }
+  APInt Value = ActualValue.getAPIntValue();
+  EXPECT_EQ(ExpectedValue < 0, Value.isNegative());
+  if (ExpectedValue < 0)
+    EXPECT_EQ(Value.getSExtValue(), static_cast<int64_t>(ExpectedValue));
+  else
+    EXPECT_EQ(Value.getZExtValue(), static_cast<uint64_t>(ExpectedValue));
 }
 
 template <class T1, class T2, class TR>
@@ -429,88 +424,6 @@ static void expectOperationValueResult(binop_eval_t Operation, T1 LeftValue,
       doValueOperation(Operation, LeftValue, RightValue).takeError());
 }
 
-TEST_F(FileCheckTest, ExpressionValueGetUnsigned) {
-  // Test positive value.
-  Expected<uint64_t> UnsignedValue = ExpressionValue(10).getUnsignedValue();
-  ASSERT_THAT_EXPECTED(UnsignedValue, Succeeded());
-  EXPECT_EQ(*UnsignedValue, 10U);
-
-  // Test 0.
-  UnsignedValue = ExpressionValue(0).getUnsignedValue();
-  ASSERT_THAT_EXPECTED(UnsignedValue, Succeeded());
-  EXPECT_EQ(*UnsignedValue, 0U);
-
-  // Test max positive value.
-  UnsignedValue = ExpressionValue(MaxUint64).getUnsignedValue();
-  ASSERT_THAT_EXPECTED(UnsignedValue, Succeeded());
-  EXPECT_EQ(*UnsignedValue, MaxUint64);
-
-  // Test failure with negative value.
-  expectError<OverflowError>(
-      "overflow error", ExpressionValue(-1).getUnsignedValue().takeError());
-
-  // Test failure with min negative value.
-  expectError<OverflowError>(
-      "overflow error",
-      ExpressionValue(MinInt64).getUnsignedValue().takeError());
-}
-
-TEST_F(FileCheckTest, ExpressionValueGetSigned) {
-  // Test positive value.
-  Expected<int64_t> SignedValue = ExpressionValue(10).getSignedValue();
-  ASSERT_THAT_EXPECTED(SignedValue, Succeeded());
-  EXPECT_EQ(*SignedValue, 10);
-
-  // Test 0.
-  SignedValue = ExpressionValue(0).getSignedValue();
-  ASSERT_THAT_EXPECTED(SignedValue, Succeeded());
-  EXPECT_EQ(*SignedValue, 0);
-
-  // Test max int64_t.
-  SignedValue = ExpressionValue(MaxInt64).getSignedValue();
-  ASSERT_THAT_EXPECTED(SignedValue, Succeeded());
-  EXPECT_EQ(*SignedValue, MaxInt64);
-
-  // Test failure with too big positive value.
-  expectError<OverflowError>(
-      "overflow error", ExpressionValue(static_cast<uint64_t>(MaxInt64) + 1)
-                            .getSignedValue()
-                            .takeError());
-
-  // Test failure with max uint64_t.
-  expectError<OverflowError>(
-      "overflow error",
-      ExpressionValue(MaxUint64).getSignedValue().takeError());
-
-  // Test negative value.
-  SignedValue = ExpressionValue(-10).getSignedValue();
-  ASSERT_THAT_EXPECTED(SignedValue, Succeeded());
-  EXPECT_EQ(*SignedValue, -10);
-
-  // Test min int64_t.
-  SignedValue = ExpressionValue(MinInt64).getSignedValue();
-  ASSERT_THAT_EXPECTED(SignedValue, Succeeded());
-  EXPECT_EQ(*SignedValue, MinInt64);
-}
-
-TEST_F(FileCheckTest, ExpressionValueAbsolute) {
-  // Test positive value.
-  expectValueEqual(ExpressionValue(10).getAbsolute(), 10);
-
-  // Test 0.
-  expectValueEqual(ExpressionValue(0).getAbsolute(), 0);
-
-  // Test max uint64_t.
-  expectValueEqual(ExpressionValue(MaxUint64).getAbsolute(), MaxUint64);
-
-  // Test negative value.
-  expectValueEqual(ExpressionValue(-10).getAbsolute(), 10);
-
-  // Test absence of overflow on min int64_t.
-  expectValueEqual(ExpressionValue(MinInt64).getAbsolute(),
-                   static_cast<uint64_t>(-(MinInt64 + 10)) + 10);
-}
-
 TEST_F(FileCheckTest, ExpressionValueAddition) {
   // Test both negative values.
   expectOperationValueResult(operator+, -10, -10, -20);
@@ -637,46 +550,6 @@ TEST_F(FileCheckTest, ExpressionValueDivision) {
   expectOperationValueResult(operator/, AbsoluteMaxInt64 + 2, -1);
 }
 
-TEST_F(FileCheckTest, ExpressionValueEquality) {
-  // Test negative and positive value.
-  EXPECT_FALSE(ExpressionValue(5) == ExpressionValue(-3));
-  EXPECT_TRUE(ExpressionValue(5) != ExpressionValue(-3));
-  EXPECT_FALSE(ExpressionValue(-2) == ExpressionValue(6));
-  EXPECT_TRUE(ExpressionValue(-2) != ExpressionValue(6));
-  EXPECT_FALSE(ExpressionValue(-7) == ExpressionValue(7));
-  EXPECT_TRUE(ExpressionValue(-7) != ExpressionValue(7));
-  EXPECT_FALSE(ExpressionValue(4) == ExpressionValue(-4));
-  EXPECT_TRUE(ExpressionValue(4) != ExpressionValue(-4));
-  EXPECT_FALSE(ExpressionValue(MaxUint64) == ExpressionValue(-1));
-  EXPECT_TRUE(ExpressionValue(MaxUint64) != ExpressionValue(-1));
-
-  // Test both negative values.
-  EXPECT_FALSE(ExpressionValue(-2) == ExpressionValue(-7));
-  EXPECT_TRUE(ExpressionValue(-2) != ExpressionValue(-7));
-  EXPECT_TRUE(ExpressionValue(-3) == ExpressionValue(-3));
-  EXPECT_FALSE(ExpressionValue(-3) != ExpressionValue(-3));
-  EXPECT_FALSE(ExpressionValue(MinInt64) == ExpressionValue(-1));
-  EXPECT_TRUE(ExpressionValue(MinInt64) != ExpressionValue(-1));
-  EXPECT_FALSE(ExpressionValue(MinInt64) == ExpressionValue(-0));
-  EXPECT_TRUE(ExpressionValue(MinInt64) != ExpressionValue(-0));
-
-  // Test both positive values.
-  EXPECT_FALSE(ExpressionValue(8) == ExpressionValue(9));
-  EXPECT_TRUE(ExpressionValue(8) != ExpressionValue(9));
-  EXPECT_TRUE(ExpressionValue(1) == ExpressionValue(1));
-  EXPECT_FALSE(ExpressionValue(1) != ExpressionValue(1));
-
-  // Check the signedness of zero doesn't affect equality.
-  EXPECT_TRUE(ExpressionValue(0) == ExpressionValue(0));
-  EXPECT_FALSE(ExpressionValue(0) != ExpressionValue(0));
-  EXPECT_TRUE(ExpressionValue(0) == ExpressionValue(-0));
-  EXPECT_FALSE(ExpressionValue(0) != ExpressionValue(-0));
-  EXPECT_TRUE(ExpressionValue(-0) == ExpressionValue(0));
-  EXPECT_FALSE(ExpressionValue(-0) != ExpressionValue(0));
-  EXPECT_TRUE(ExpressionValue(-0) == ExpressionValue(-0));
-  EXPECT_FALSE(ExpressionValue(-0) != ExpressionValue(-0));
-}
-
 TEST_F(FileCheckTest, Literal) {
   SourceMgr SM;
 
@@ -684,7 +557,7 @@ TEST_F(FileCheckTest, Literal) {
   ExpressionLiteral Ten(bufferize(SM, "10"), 10u);
   Expected<ExpressionValue> Value = Ten.eval();
   ASSERT_THAT_EXPECTED(Value, Succeeded());
-  EXPECT_EQ(10, cantFail(Value->getSignedValue()));
+  EXPECT_EQ(10, Value->getAPIntValue().getSExtValue());
   Expected<ExpressionFormat> ImplicitFormat = Ten.getImplicitFormat(SM);
   ASSERT_THAT_EXPECTED(ImplicitFormat, Succeeded());
   EXPECT_EQ(*ImplicitFormat, ExpressionFormat::Kind::NoFormat);
@@ -693,13 +566,13 @@ TEST_F(FileCheckTest, Literal) {
   ExpressionLiteral Min(bufferize(SM, std::to_string(MinInt64)), MinInt64);
   Value = Min.eval();
   ASSERT_TRUE(bool(Value));
-  EXPECT_EQ(MinInt64, cantFail(Value->getSignedValue()));
+  EXPECT_EQ(MinInt64, Value->getAPIntValue().getSExtValue());
 
   // Max value can be correctly represented.
   ExpressionLiteral Max(bufferize(SM, std::to_string(MaxUint64)), MaxUint64);
   Value = Max.eval();
   ASSERT_THAT_EXPECTED(Value, Succeeded());
-  EXPECT_EQ(MaxUint64, cantFail(Value->getUnsignedValue()));
+  EXPECT_EQ(MaxUint64, Value->getAPIntValue().getZExtValue());
 }
 
 TEST_F(FileCheckTest, Expression) {
@@ -748,11 +621,11 @@ TEST_F(FileCheckTest, NumericVariable) {
   FooVar.setValue(ExpressionValue(42u));
   std::optional<ExpressionValue> Value = FooVar.getValue();
   ASSERT_TRUE(Value);
-  EXPECT_EQ(42, cantFail(Value->getSignedValue()));
+  EXPECT_EQ(42, Value->getAPIntValue().getSExtValue());
   EXPECT_FALSE(FooVar.getStringValue());
   EvalResult = FooVarUse.eval();
   ASSERT_THAT_EXPECTED(EvalResult, Succeeded());
-  EXPECT_EQ(42, cantFail(EvalResult->getSignedValue()));
+  EXPECT_EQ(42, EvalResult->getAPIntValue().getSExtValue());
 
   // Defined variable with string: getValue, eval, and getStringValue return
   // value set.
@@ -760,14 +633,14 @@ TEST_F(FileCheckTest, NumericVariable) {
   FooVar.setValue(ExpressionValue(925u), StringValue);
   Value = FooVar.getValue();
   ASSERT_TRUE(Value);
-  EXPECT_EQ(925, cantFail(Value->getSignedValue()));
+  EXPECT_EQ(925, Value->getAPIntValue().getSExtValue());
   // getStringValue should return the same memory not just the same characters.
   EXPECT_EQ(StringValue.begin(), FooVar.getStringValue()->begin());
   EXPECT_EQ(StringValue.end(), FooVar.getStringValue()->end());
   EvalResult = FooVarUse.eval();
   ASSERT_THAT_EXPECTED(EvalResult, Succeeded());
-  EXPECT_EQ(925, cantFail(EvalResult->getSignedValue()));
-  EXPECT_EQ(925, cantFail(EvalResult->getSignedValue()));
+  EXPECT_EQ(925, EvalResult->getAPIntValue().getSExtValue());
+  EXPECT_EQ(925, EvalResult->getAPIntValue().getSExtValue());
 
   // Clearing variable: getValue and eval fail. Error returned by eval holds
   // the name of the cleared variable.
@@ -802,7 +675,7 @@ TEST_F(FileCheckTest, Binop) {
   // expected.
   Expected<ExpressionValue> Value = Binop.eval();
   ASSERT_THAT_EXPECTED(Value, Succeeded());
-  EXPECT_EQ(60, cantFail(Value->getSignedValue()));
+  EXPECT_EQ(60, Value->getAPIntValue().getSExtValue());
   Expected<ExpressionFormat> ImplicitFormat = Binop.getImplicitFormat(SM);
   ASSERT_THAT_EXPECTED(ImplicitFormat, Succeeded());
   EXPECT_EQ(*ImplicitFormat, ExpressionFormat::Kind::Unsigned);
@@ -1674,21 +1547,21 @@ TEST_F(FileCheckTest, FileCheckContext) {
   Expected<ExpressionValue> ExpressionVal =
       (*ExpressionPointer)->getAST()->eval();
   ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
-  EXPECT_EQ(cantFail(ExpressionVal->getSignedValue()), 18);
+  EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 18);
   ExpressionPointer = P.parseNumericSubstitutionBlock(
       LocalNumVar2Ref, DefinedNumericVariable,
       /*IsLegacyLineExpr=*/false, LineNumber, &Cxt, SM);
   ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded());
   ExpressionVal = (*ExpressionPointer)->getAST()->eval();
   ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
-  EXPECT_EQ(cantFail(ExpressionVal->getSignedValue()), 20);
+  EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 20);
   ExpressionPointer = P.parseNumericSubstitutionBlock(
       LocalNumVar3Ref, DefinedNumericVariable,
       /*IsLegacyLineExpr=*/false, LineNumber, &Cxt, SM);
   ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded());
   ExpressionVal = (*ExpressionPointer)->getAST()->eval();
   ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
-  EXPECT_EQ(cantFail(ExpressionVal->getSignedValue()), 12);
+  EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 12);
   ASSERT_THAT_EXPECTED(EmptyVar, Succeeded());
   EXPECT_EQ(*EmptyVar, "");
   expectUndefErrors({std::string(UnknownVarStr)}, UnknownVar.takeError());
@@ -1738,7 +1611,7 @@ TEST_F(FileCheckTest, FileCheckContext) {
   ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded());
   ExpressionVal = (*ExpressionPointer)->getAST()->eval();
   ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
-  EXPECT_EQ(cantFail(ExpressionVal->getSignedValue()), 36);
+  EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 36);
 
   // Clear local variables and check global variables remain defined.
   Cxt.clearLocalVars();
@@ -1750,7 +1623,7 @@ TEST_F(FileCheckTest, FileCheckContext) {
   ASSERT_THAT_EXPECTED(ExpressionPointer, Succeeded());
   ExpressionVal = (*ExpressionPointer)->getAST()->eval();
   ASSERT_THAT_EXPECTED(ExpressionVal, Succeeded());
-  EXPECT_EQ(cantFail(ExpressionVal->getSignedValue()), 36);
+  EXPECT_EQ(ExpressionVal->getAPIntValue().getSExtValue(), 36);
 }
 
 TEST_F(FileCheckTest, CapturedVarDiags) {