[llvm] [SandboxIR] Implement remaining ConstantInt functions (PR #106775)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 30 11:14:00 PDT 2024


https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/106775

None

>From f4588229806aed20ffa90448d4f21d7ca085290d Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Tue, 20 Aug 2024 08:49:03 -0700
Subject: [PATCH] [SandboxIR] Implement remaining ConstantInt functions

---
 llvm/include/llvm/SandboxIR/SandboxIR.h    | 158 ++++++++++++++++++-
 llvm/include/llvm/SandboxIR/Type.h         |  17 +++
 llvm/lib/SandboxIR/SandboxIR.cpp           |  61 ++++++++
 llvm/lib/SandboxIR/Type.cpp                |   5 +
 llvm/unittests/SandboxIR/SandboxIRTest.cpp | 168 ++++++++++++++++++++-
 llvm/unittests/SandboxIR/TypesTest.cpp     |  16 ++
 6 files changed, 419 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index 2ed7243fa612f4..2071f74e62e760 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -565,7 +565,7 @@ class Constant : public sandboxir::User {
 };
 
 class ConstantInt : public Constant {
-  ConstantInt(llvm::ConstantInt *C, sandboxir::Context &Ctx)
+  ConstantInt(llvm::ConstantInt *C, Context &Ctx)
       : Constant(ClassID::ConstantInt, C, Ctx) {}
   friend class Context; // For constructor.
 
@@ -574,11 +574,164 @@ class ConstantInt : public Constant {
   }
 
 public:
+  static ConstantInt *getTrue(Context &Ctx);
+  static ConstantInt *getFalse(Context &Ctx);
+  static ConstantInt *getBool(Context &Ctx, bool V);
+  static Constant *getTrue(Type *Ty);
+  static Constant *getFalse(Type *Ty);
+  static Constant *getBool(Type *Ty, bool V);
+
   /// If Ty is a vector type, return a Constant with a splat of the given
   /// value. Otherwise return a ConstantInt for the given value.
   static ConstantInt *get(Type *Ty, uint64_t V, bool IsSigned = false);
 
-  // TODO: Implement missing functions.
+  /// Return a ConstantInt with the specified integer value for the specified
+  /// type. If the type is wider than 64 bits, the value will be zero-extended
+  /// to fit the type, unless IsSigned is true, in which case the value will
+  /// be interpreted as a 64-bit signed integer and sign-extended to fit
+  /// the type.
+  /// Get a ConstantInt for a specific value.
+  static ConstantInt *get(IntegerType *Ty, uint64_t V, bool IsSigned = false);
+
+  /// Return a ConstantInt with the specified value for the specified type. The
+  /// value V will be canonicalized to a an unsigned APInt. Accessing it with
+  /// either getSExtValue() or getZExtValue() will yield a correctly sized and
+  /// signed value for the type Ty.
+  /// Get a ConstantInt for a specific signed value.
+  static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
+  static Constant *getSigned(Type *Ty, int64_t V);
+
+  /// Return a ConstantInt with the specified value and an implied Type. The
+  /// type is the integer type that corresponds to the bit width of the value.
+  static ConstantInt *get(Context &Ctx, const APInt &V);
+
+  /// Return a ConstantInt constructed from the string strStart with the given
+  /// radix.
+  static ConstantInt *get(IntegerType *Ty, StringRef Str, uint8_t Radix);
+
+  /// If Ty is a vector type, return a Constant with a splat of the given
+  /// value. Otherwise return a ConstantInt for the given value.
+  static Constant *get(Type *Ty, const APInt &V);
+
+  /// Return the constant as an APInt value reference. This allows clients to
+  /// obtain a full-precision copy of the value.
+  /// Return the constant's value.
+  inline const APInt &getValue() const {
+    return cast<llvm::ConstantInt>(Val)->getValue();
+  }
+
+  /// getBitWidth - Return the scalar bitwidth of this constant.
+  unsigned getBitWidth() const {
+    return cast<llvm::ConstantInt>(Val)->getBitWidth();
+  }
+  /// Return the constant as a 64-bit unsigned integer value after it
+  /// has been zero extended as appropriate for the type of this constant. Note
+  /// that this method can assert if the value does not fit in 64 bits.
+  /// Return the zero extended value.
+  inline uint64_t getZExtValue() const {
+    return cast<llvm::ConstantInt>(Val)->getZExtValue();
+  }
+
+  /// Return the constant as a 64-bit integer value after it has been sign
+  /// extended as appropriate for the type of this constant. Note that
+  /// this method can assert if the value does not fit in 64 bits.
+  /// Return the sign extended value.
+  inline int64_t getSExtValue() const {
+    return cast<llvm::ConstantInt>(Val)->getSExtValue();
+  }
+
+  /// Return the constant as an llvm::MaybeAlign.
+  /// Note that this method can assert if the value does not fit in 64 bits or
+  /// is not a power of two.
+  inline MaybeAlign getMaybeAlignValue() const {
+    return cast<llvm::ConstantInt>(Val)->getMaybeAlignValue();
+  }
+
+  /// Return the constant as an llvm::Align, interpreting `0` as `Align(1)`.
+  /// Note that this method can assert if the value does not fit in 64 bits or
+  /// is not a power of two.
+  inline Align getAlignValue() const {
+    return cast<llvm::ConstantInt>(Val)->getAlignValue();
+  }
+
+  /// A helper method that can be used to determine if the constant contained
+  /// within is equal to a constant.  This only works for very small values,
+  /// because this is all that can be represented with all types.
+  /// Determine if this constant's value is same as an unsigned char.
+  bool equalsInt(uint64_t V) const {
+    return cast<llvm::ConstantInt>(Val)->equalsInt(V);
+  }
+
+  /// Variant of the getType() method to always return an IntegerType, which
+  /// reduces the amount of casting needed in parts of the compiler.
+  IntegerType *getIntegerType() const;
+
+  /// This static method returns true if the type Ty is big enough to
+  /// represent the value V. This can be used to avoid having the get method
+  /// assert when V is larger than Ty can represent. Note that there are two
+  /// versions of this method, one for unsigned and one for signed integers.
+  /// Although ConstantInt canonicalizes everything to an unsigned integer,
+  /// the signed version avoids callers having to convert a signed quantity
+  /// to the appropriate unsigned type before calling the method.
+  /// @returns true if V is a valid value for type Ty
+  /// Determine if the value is in range for the given type.
+  static bool isValueValidForType(Type *Ty, uint64_t V);
+  static bool isValueValidForType(Type *Ty, int64_t V);
+
+  bool isNegative() const { return cast<llvm::ConstantInt>(Val)->isNegative(); }
+
+  /// This is just a convenience method to make client code smaller for a
+  /// common code. It also correctly performs the comparison without the
+  /// potential for an assertion from getZExtValue().
+  bool isZero() const { return cast<llvm::ConstantInt>(Val)->isZero(); }
+
+  /// This is just a convenience method to make client code smaller for a
+  /// common case. It also correctly performs the comparison without the
+  /// potential for an assertion from getZExtValue().
+  /// Determine if the value is one.
+  bool isOne() const { return cast<llvm::ConstantInt>(Val)->isOne(); }
+
+  /// This function will return true iff every bit in this constant is set
+  /// to true.
+  /// @returns true iff this constant's bits are all set to true.
+  /// Determine if the value is all ones.
+  bool isMinusOne() const { return cast<llvm::ConstantInt>(Val)->isMinusOne(); }
+
+  /// This function will return true iff this constant represents the largest
+  /// value that may be represented by the constant's type.
+  /// @returns true iff this is the largest value that may be represented
+  /// by this type.
+  /// Determine if the value is maximal.
+  bool isMaxValue(bool IsSigned) const {
+    return cast<llvm::ConstantInt>(Val)->isMaxValue(IsSigned);
+  }
+
+  /// This function will return true iff this constant represents the smallest
+  /// value that may be represented by this constant's type.
+  /// @returns true if this is the smallest value that may be represented by
+  /// this type.
+  /// Determine if the value is minimal.
+  bool isMinValue(bool IsSigned) const {
+    return cast<llvm::ConstantInt>(Val)->isMinValue(IsSigned);
+  }
+
+  /// This function will return true iff this constant represents a value with
+  /// active bits bigger than 64 bits or a value greater than the given uint64_t
+  /// value.
+  /// @returns true iff this constant is greater or equal to the given number.
+  /// Determine if the value is greater or equal to the given number.
+  bool uge(uint64_t Num) const {
+    return cast<llvm::ConstantInt>(Val)->uge(Num);
+  }
+
+  /// getLimitedValue - If the value is smaller than the specified limit,
+  /// return it, otherwise return the limit value.  This causes the value
+  /// to saturate to the limit.
+  /// @returns the min of the value of the constant and the specified value
+  /// Get the constant's value with a saturation limit
+  uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+    return cast<llvm::ConstantInt>(Val)->getLimitedValue(Limit);
+  }
 
   /// For isa/dyn_cast.
   static bool classof(const sandboxir::Value *From) {
@@ -3198,6 +3351,7 @@ class Context {
   LLVMContext &LLVMCtx;
   friend class Type;        // For LLVMCtx.
   friend class PointerType; // For LLVMCtx.
+  friend class IntegerType; // For LLVMCtx.
   Tracker IRTracker;
 
   /// Maps LLVM Value to the corresponding sandboxir::Value. Owns all
diff --git a/llvm/include/llvm/SandboxIR/Type.h b/llvm/include/llvm/SandboxIR/Type.h
index 89e787f5f5d4b2..938194c504477c 100644
--- a/llvm/include/llvm/SandboxIR/Type.h
+++ b/llvm/include/llvm/SandboxIR/Type.h
@@ -38,6 +38,7 @@ class Type {
   friend class VectorType;   // For LLVMTy.
   friend class PointerType;  // For LLVMTy.
   friend class FunctionType; // For LLVMTy.
+  friend class IntegerType;  // For LLVMTy.
   friend class Function;     // For LLVMTy.
   friend class CallBase;     // For LLVMTy.
   friend class ConstantInt;  // For LLVMTy.
@@ -295,6 +296,22 @@ class FunctionType : public Type {
   }
 };
 
+/// Class to represent integer types. Note that this class is also used to
+/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
+/// Int64Ty.
+/// Integer representation type
+class IntegerType : public Type {
+public:
+  static IntegerType *get(Context &C, unsigned NumBits);
+  // TODO: add missing functions
+  static bool classof(const Type *From) {
+    return isa<llvm::IntegerType>(From->LLVMTy);
+  }
+  operator llvm::IntegerType &() const {
+    return *cast<llvm::IntegerType>(LLVMTy);
+  }
+};
+
 } // namespace llvm::sandboxir
 
 #endif // LLVM_SANDBOXIR_TYPE_H
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 6bdc580f751d18..e814c4553bd4b4 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -2243,10 +2243,71 @@ void Constant::dumpOS(raw_ostream &OS) const {
 }
 #endif // NDEBUG
 
+ConstantInt *ConstantInt::getTrue(Context &Ctx) {
+  auto *LLVMC = llvm::ConstantInt::getTrue(Ctx.LLVMCtx);
+  return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::getFalse(Context &Ctx) {
+  auto *LLVMC = llvm::ConstantInt::getFalse(Ctx.LLVMCtx);
+  return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::getBool(Context &Ctx, bool V) {
+  auto *LLVMC = llvm::ConstantInt::getBool(Ctx.LLVMCtx, V);
+  return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
+}
+Constant *ConstantInt::getTrue(Type *Ty) {
+  auto *LLVMC = llvm::ConstantInt::getTrue(Ty->LLVMTy);
+  return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+Constant *ConstantInt::getFalse(Type *Ty) {
+  auto *LLVMC = llvm::ConstantInt::getFalse(Ty->LLVMTy);
+  return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+Constant *ConstantInt::getBool(Type *Ty, bool V) {
+  auto *LLVMC = llvm::ConstantInt::getBool(Ty->LLVMTy, V);
+  return Ty->getContext().getOrCreateConstant(LLVMC);
+}
 ConstantInt *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned) {
   auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
   return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
 }
+ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned) {
+  auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
+  return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {
+  auto *LLVMC =
+      llvm::ConstantInt::getSigned(cast<llvm::IntegerType>(Ty->LLVMTy), V);
+  return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {
+  auto *LLVMC = llvm::ConstantInt::getSigned(Ty->LLVMTy, V);
+  return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+ConstantInt *ConstantInt::get(Context &Ctx, const APInt &V) {
+  auto *LLVMC = llvm::ConstantInt::get(Ctx.LLVMCtx, V);
+  return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
+}
+ConstantInt *ConstantInt::get(IntegerType *Ty, StringRef Str, uint8_t Radix) {
+  auto *LLVMC =
+      llvm::ConstantInt::get(cast<llvm::IntegerType>(Ty->LLVMTy), Str, Radix);
+  return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
+}
+Constant *ConstantInt::get(Type *Ty, const APInt &V) {
+  auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V);
+  return Ty->getContext().getOrCreateConstant(LLVMC);
+}
+IntegerType *ConstantInt::getIntegerType() const {
+  auto *LLVMTy = cast<llvm::ConstantInt>(Val)->getIntegerType();
+  return cast<IntegerType>(Ctx.getType(LLVMTy));
+}
+
+bool ConstantInt::isValueValidForType(Type *Ty, uint64_t V) {
+  return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
+}
+bool ConstantInt::isValueValidForType(Type *Ty, int64_t V) {
+  return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
+}
 
 Constant *ConstantFP::get(Type *Ty, double V) {
   auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);
diff --git a/llvm/lib/SandboxIR/Type.cpp b/llvm/lib/SandboxIR/Type.cpp
index 6f850b82d2e996..eee69c5ec7c893 100644
--- a/llvm/lib/SandboxIR/Type.cpp
+++ b/llvm/lib/SandboxIR/Type.cpp
@@ -46,3 +46,8 @@ PointerType *PointerType::get(Context &Ctx, unsigned AddressSpace) {
   return cast<PointerType>(
       Ctx.getType(llvm::PointerType::get(Ctx.LLVMCtx, AddressSpace)));
 }
+
+IntegerType *IntegerType::get(Context &Ctx, unsigned NumBits) {
+  return cast<IntegerType>(
+      Ctx.getType(llvm::IntegerType::get(Ctx.LLVMCtx, NumBits)));
+}
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 01fe21eb5cfa43..2ec8eefd8c323c 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -112,6 +112,9 @@ define void @foo(i32 %v0) {
 }
 )IR");
   Function &LLVMF = *M->getFunction("foo");
+  auto *LLVMBB = &*LLVMF.begin();
+  auto *LLVMAdd0 = &*LLVMBB->begin();
+  auto *LLVMFortyTwo = cast<llvm::ConstantInt>(LLVMAdd0->getOperand(1));
   sandboxir::Context Ctx(C);
 
   auto &F = *Ctx.createFunction(&LLVMF);
@@ -124,10 +127,167 @@ define void @foo(i32 %v0) {
   auto *NewCI =
       sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
   EXPECT_EQ(NewCI, FortyTwo);
-  // Check new constant.
-  auto *FortyThree =
-      sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 43);
-  EXPECT_NE(FortyThree, FortyTwo);
+  {
+    // Check getTrue(Ctx).
+    auto *True = sandboxir::ConstantInt::getTrue(Ctx);
+    EXPECT_EQ(True, Ctx.getValue(llvm::ConstantInt::getTrue(C)));
+    // Check getFalse(Ctx).
+    auto *False = sandboxir::ConstantInt::getFalse(Ctx);
+    EXPECT_EQ(False, Ctx.getValue(llvm::ConstantInt::getFalse(C)));
+    // Check getBool(Ctx).
+    auto *Bool = sandboxir::ConstantInt::getBool(Ctx, true);
+    EXPECT_EQ(Bool, Ctx.getValue(llvm::ConstantInt::getBool(C, true)));
+  }
+  {
+    auto *Int1Ty = sandboxir::Type::getInt1Ty(Ctx);
+    auto *LLVMInt1Ty = llvm::Type::getInt1Ty(C);
+    // Check getTrue(Ty).
+    auto *True = sandboxir::ConstantInt::getTrue(Int1Ty);
+    EXPECT_EQ(True, Ctx.getValue(llvm::ConstantInt::getTrue(LLVMInt1Ty)));
+    // Check getFalse(Ty).
+    auto *False = sandboxir::ConstantInt::getFalse(Int1Ty);
+    EXPECT_EQ(False, Ctx.getValue(llvm::ConstantInt::getFalse(LLVMInt1Ty)));
+    // Check getBool(Ty).
+    auto *Bool = sandboxir::ConstantInt::getBool(Int1Ty, true);
+    EXPECT_EQ(Bool, Ctx.getValue(llvm::ConstantInt::getBool(LLVMInt1Ty, true)));
+  }
+
+  auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
+  auto *LLVMInt32Ty = llvm::Type::getInt32Ty(C);
+  {
+    // Check get(Type, V).
+    auto *FortyThree = sandboxir::ConstantInt::get(Int32Ty, 43);
+    auto *LLVMFortyThree = llvm::ConstantInt::get(LLVMInt32Ty, 43);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+  {
+    // Check get(Type, V, IsSigned).
+    auto *FortyThree =
+        sandboxir::ConstantInt::get(Int32Ty, 43, /*IsSigned=*/true);
+    auto *LLVMFortyThree =
+        llvm::ConstantInt::get(LLVMInt32Ty, 43, /*IsSigned=*/true);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+
+  {
+    // Check get(IntegerType, V).
+    auto *FortyThree =
+        sandboxir::ConstantInt::get(sandboxir::IntegerType::get(Ctx, 32), 43);
+    auto *LLVMFortyThree =
+        llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), 43);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+  {
+    // Check get(IntegerType, V, IsSigned).
+    auto *FortyThree = sandboxir::ConstantInt::get(
+        sandboxir::IntegerType::get(Ctx, 32), 43, /*IsSigned=*/true);
+    auto *LLVMFortyThree = llvm::ConstantInt::get(llvm::IntegerType::get(C, 32),
+                                                  43, /*IsSigned=*/true);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+
+  {
+    // Check getSigned(IntegerType, V).
+    auto *FortyThree = sandboxir::ConstantInt::getSigned(
+        sandboxir::IntegerType::get(Ctx, 32), 43);
+    auto *LLVMFortyThree =
+        llvm::ConstantInt::getSigned(llvm::IntegerType::get(C, 32), 43);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+  {
+    // Check getSigned(Type, V).
+    auto *FortyThree = sandboxir::ConstantInt::getSigned(Int32Ty, 43);
+    auto *LLVMFortyThree = llvm::ConstantInt::getSigned(LLVMInt32Ty, 43);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+  {
+    // Check get(Ctx, APInt).
+    APInt APInt43(32, 43);
+    auto *FortyThree = sandboxir::ConstantInt::get(Ctx, APInt43);
+    auto *LLVMFortyThree = llvm::ConstantInt::get(C, APInt43);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+  {
+    // Check get(Ty, Str, Radix).
+    StringRef Str("43");
+    uint8_t Radix(10);
+    auto *FortyThree = sandboxir::ConstantInt::get(
+        sandboxir::IntegerType::get(Ctx, 32), Str, Radix);
+    auto *LLVMFortyThree =
+        llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), Str, Radix);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+  {
+    // Check get(Ty, APInt).
+    APInt APInt43(32, 43);
+    auto *FortyThree = sandboxir::ConstantInt::get(Int32Ty, APInt43);
+    auto *LLVMFortyThree = llvm::ConstantInt::get(LLVMInt32Ty, APInt43);
+    EXPECT_NE(FortyThree, FortyTwo);
+    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
+  }
+  // Check getValue().
+  EXPECT_EQ(FortyTwo->getValue(), LLVMFortyTwo->getValue());
+  // Check getBitWidth().
+  EXPECT_EQ(FortyTwo->getBitWidth(), LLVMFortyTwo->getBitWidth());
+  // Check getZExtValue().
+  EXPECT_EQ(FortyTwo->getZExtValue(), LLVMFortyTwo->getZExtValue());
+  // Check getSExtValue().
+  EXPECT_EQ(FortyTwo->getSExtValue(), LLVMFortyTwo->getSExtValue());
+  // Check getMaybeAlignValue().
+  auto *SixtyFour =
+      cast<sandboxir::ConstantInt>(sandboxir::ConstantInt::get(Int32Ty, 64));
+  auto *LLVMSixtyFour =
+      cast<llvm::ConstantInt>(llvm::ConstantInt::get(LLVMInt32Ty, 64));
+  EXPECT_EQ(SixtyFour->getMaybeAlignValue(),
+            LLVMSixtyFour->getMaybeAlignValue());
+  // Check getAlignValue().
+  EXPECT_EQ(SixtyFour->getAlignValue(), LLVMSixtyFour->getAlignValue());
+  // Check equalsInt().
+  EXPECT_TRUE(FortyTwo->equalsInt(42));
+  EXPECT_FALSE(FortyTwo->equalsInt(43));
+  // Check getIntegerType().
+  EXPECT_EQ(FortyTwo->getIntegerType(), sandboxir::IntegerType::get(Ctx, 32));
+  // Check isValueValidForType().
+  EXPECT_TRUE(
+      sandboxir::ConstantInt::isValueValidForType(Int32Ty, (uint64_t)42));
+  EXPECT_TRUE(
+      sandboxir::ConstantInt::isValueValidForType(Int32Ty, (int64_t)42));
+  // Check isNegative().
+  EXPECT_FALSE(FortyTwo->isNegative());
+  EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, -42));
+  // Check isZero().
+  EXPECT_FALSE(FortyTwo->isZero());
+  EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, 0)->isZero());
+  // Check isOne().
+  EXPECT_FALSE(FortyTwo->isOne());
+  EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, 1)->isOne());
+  // Check isMinusOne().
+  EXPECT_FALSE(FortyTwo->isMinusOne());
+  EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, -1)->isMinusOne());
+  // Check isMaxValue().
+  EXPECT_FALSE(FortyTwo->isMaxValue(/*Signed=*/true));
+  EXPECT_TRUE(
+      sandboxir::ConstantInt::get(Int32Ty, std::numeric_limits<int32_t>::max())
+          ->isMaxValue(/*Signed=*/true));
+  // Check isMinValue().
+  EXPECT_FALSE(FortyTwo->isMinValue(/*Signed=*/true));
+  EXPECT_TRUE(
+      sandboxir::ConstantInt::get(Int32Ty, std::numeric_limits<int32_t>::min())
+          ->isMinValue(/*Signed=*/true));
+  // Check uge().
+  EXPECT_TRUE(FortyTwo->uge(41));
+  EXPECT_FALSE(FortyTwo->uge(43));
+  // Check getLimitedValue().
+  EXPECT_EQ(FortyTwo->getLimitedValue(40u), 40u);
+  EXPECT_EQ(FortyTwo->getLimitedValue(50u), 42u);
 }
 
 TEST_F(SandboxIRTest, ConstantFP) {
diff --git a/llvm/unittests/SandboxIR/TypesTest.cpp b/llvm/unittests/SandboxIR/TypesTest.cpp
index cd9e14dced7fe8..dcbf65a20b2fd7 100644
--- a/llvm/unittests/SandboxIR/TypesTest.cpp
+++ b/llvm/unittests/SandboxIR/TypesTest.cpp
@@ -251,3 +251,19 @@ define void @foo() {
   [[maybe_unused]] auto *FTy =
       cast<sandboxir::FunctionType>(F->getFunctionType());
 }
+
+TEST_F(SandboxTypeTest, IntegerType) {
+  parseIR(C, R"IR(
+define void @foo(i32 %v0) {
+  ret void
+}
+)IR");
+  llvm::Function *LLVMF = &*M->getFunction("foo");
+  sandboxir::Context Ctx(C);
+  auto *F = Ctx.createFunction(LLVMF);
+  // Check classof(), creation.
+  auto *Int32Ty = cast<sandboxir::IntegerType>(F->getArg(0)->getType());
+  // Check get().
+  auto *NewInt32Ty = sandboxir::IntegerType::get(Ctx, 32u);
+  EXPECT_EQ(NewInt32Ty, Int32Ty);
+}



More information about the llvm-commits mailing list