[llvm] a0b2a95 - [SandboxIR] Implement ConstantDataArray functions (#134729)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 17 14:03:52 PDT 2025
Author: vporpo
Date: 2025-04-17T14:03:49-07:00
New Revision: a0b2a952266a22ed096a7670e33a611c145e3866
URL: https://github.com/llvm/llvm-project/commit/a0b2a952266a22ed096a7670e33a611c145e3866
DIFF: https://github.com/llvm/llvm-project/commit/a0b2a952266a22ed096a7670e33a611c145e3866.diff
LOG: [SandboxIR] Implement ConstantDataArray functions (#134729)
Mirrors LLVM IR.
Added:
Modified:
llvm/include/llvm/SandboxIR/Constant.h
llvm/include/llvm/SandboxIR/Type.h
llvm/include/llvm/SandboxIR/Value.h
llvm/lib/SandboxIR/Type.cpp
llvm/unittests/SandboxIR/SandboxIRTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/Constant.h b/llvm/include/llvm/SandboxIR/Constant.h
index ddd90291c509b..fa00b29dbd803 100644
--- a/llvm/include/llvm/SandboxIR/Constant.h
+++ b/llvm/include/llvm/SandboxIR/Constant.h
@@ -591,7 +591,72 @@ class ConstantDataArray final : public ConstantDataSequential {
friend class Context;
public:
- // TODO: Add missing functions.
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::ConstantDataArray;
+ }
+ /// get() constructor - Return a constant with array type with an element
+ /// count and element type matching the ArrayRef passed in. Note that this
+ /// can return a ConstantAggregateZero object.
+ template <typename ElementTy>
+ static Constant *get(Context &Ctx, ArrayRef<ElementTy> Elts) {
+ auto *NewLLVMC = llvm::ConstantDataArray::get(Ctx.LLVMCtx, Elts);
+ return Ctx.getOrCreateConstant(NewLLVMC);
+ }
+
+ /// get() constructor - ArrayTy needs to be compatible with
+ /// ArrayRef<ElementTy>.
+ template <typename ArrayTy>
+ static Constant *get(Context &Ctx, ArrayTy &Elts) {
+ return ConstantDataArray::get(Ctx, ArrayRef(Elts));
+ }
+
+ /// getRaw() constructor - Return a constant with array type with an element
+ /// count and element type matching the NumElements and ElementTy parameters
+ /// passed in. Note that this can return a ConstantAggregateZero object.
+ /// ElementTy must be one of i8/i16/i32/i64/half/bfloat/float/double. Data is
+ /// the buffer containing the elements. Be careful to make sure Data uses the
+ /// right endianness, the buffer will be used as-is.
+ static Constant *getRaw(StringRef Data, uint64_t NumElements,
+ Type *ElementTy) {
+ auto *LLVMC =
+ llvm::ConstantDataArray::getRaw(Data, NumElements, ElementTy->LLVMTy);
+ return ElementTy->getContext().getOrCreateConstant(LLVMC);
+ }
+ /// getFP() constructors - Return a constant of array type with a float
+ /// element type taken from argument `ElementType', and count taken from
+ /// argument `Elts'. The amount of bits of the contained type must match the
+ /// number of bits of the type contained in the passed in ArrayRef.
+ /// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
+ /// that this can return a ConstantAggregateZero object.
+ static Constant *getFP(Type *ElementType, ArrayRef<uint16_t> Elts) {
+ auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
+ return ElementType->getContext().getOrCreateConstant(LLVMC);
+ }
+ static Constant *getFP(Type *ElementType, ArrayRef<uint32_t> Elts) {
+ auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
+ return ElementType->getContext().getOrCreateConstant(LLVMC);
+ }
+ static Constant *getFP(Type *ElementType, ArrayRef<uint64_t> Elts) {
+ auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
+ return ElementType->getContext().getOrCreateConstant(LLVMC);
+ }
+ /// This method constructs a CDS and initializes it with a text string.
+ /// The default behavior (AddNull==true) causes a null terminator to
+ /// be placed at the end of the array (increasing the length of the string by
+ /// one more than the StringRef would normally indicate. Pass AddNull=false
+ /// to disable this behavior.
+ static Constant *getString(Context &Ctx, StringRef Initializer,
+ bool AddNull = true) {
+ auto *LLVMC =
+ llvm::ConstantDataArray::getString(Ctx.LLVMCtx, Initializer, AddNull);
+ return Ctx.getOrCreateConstant(LLVMC);
+ }
+
+ /// Specialize the getType() method to always return an ArrayType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ inline ArrayType *getType() const {
+ return cast<ArrayType>(Value::getType());
+ }
};
/// A vector constant whose element type is a simple 1/2/4/8-byte integer or
diff --git a/llvm/include/llvm/SandboxIR/Type.h b/llvm/include/llvm/SandboxIR/Type.h
index 46032ba1084ff..f90ae096443b5 100644
--- a/llvm/include/llvm/SandboxIR/Type.h
+++ b/llvm/include/llvm/SandboxIR/Type.h
@@ -275,6 +275,7 @@ class Type {
static Type *getInt1Ty(Context &Ctx);
static Type *getDoubleTy(Context &Ctx);
static Type *getFloatTy(Context &Ctx);
+ static Type *getHalfTy(Context &Ctx);
// TODO: missing get*
/// Get the address space of this pointer or pointer vector type.
diff --git a/llvm/include/llvm/SandboxIR/Value.h b/llvm/include/llvm/SandboxIR/Value.h
index 508978709f96c..d45aa4059de69 100644
--- a/llvm/include/llvm/SandboxIR/Value.h
+++ b/llvm/include/llvm/SandboxIR/Value.h
@@ -170,6 +170,7 @@ class Value {
// expose metadata in sandboxir.
friend class Region;
friend class ScoreBoard; // Needs access to `Val` for the instruction cost.
+ friend class ConstantDataArray; // For `Val`
/// All values point to the context.
Context &Ctx;
diff --git a/llvm/lib/SandboxIR/Type.cpp b/llvm/lib/SandboxIR/Type.cpp
index 51128bf307e9f..dfb54df0c9ce8 100644
--- a/llvm/lib/SandboxIR/Type.cpp
+++ b/llvm/lib/SandboxIR/Type.cpp
@@ -36,6 +36,9 @@ Type *Type::getDoubleTy(Context &Ctx) {
Type *Type::getFloatTy(Context &Ctx) {
return Ctx.getType(llvm::Type::getFloatTy(Ctx.LLVMCtx));
}
+Type *Type::getHalfTy(Context &Ctx) {
+ return Ctx.getType(llvm::Type::getHalfTy(Ctx.LLVMCtx));
+}
#ifndef NDEBUG
void Type::dumpOS(raw_ostream &OS) { LLVMTy->print(OS); }
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 690e9a521c168..8cce659596a4d 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -298,9 +298,10 @@ define void @foo(i32 %v0) {
TEST_F(SandboxIRTest, ConstantFP) {
parseIR(C, R"IR(
-define void @foo(float %v0, double %v1) {
+define void @foo(float %v0, double %v1, half %v2) {
%fadd0 = fadd float %v0, 42.0
%fadd1 = fadd double %v1, 43.0
+ %fadd2 = fadd half %v2, 44.0
ret void
}
)IR");
@@ -312,12 +313,16 @@ define void @foo(float %v0, double %v1) {
auto It = BB.begin();
auto *FAdd0 = cast<sandboxir::BinaryOperator>(&*It++);
auto *FAdd1 = cast<sandboxir::BinaryOperator>(&*It++);
+ auto *FAdd2 = cast<sandboxir::BinaryOperator>(&*It++);
auto *FortyTwo = cast<sandboxir::ConstantFP>(FAdd0->getOperand(1));
[[maybe_unused]] auto *FortyThree =
cast<sandboxir::ConstantFP>(FAdd1->getOperand(1));
auto *FloatTy = sandboxir::Type::getFloatTy(Ctx);
auto *DoubleTy = sandboxir::Type::getDoubleTy(Ctx);
+ auto *HalfTy = sandboxir::Type::getHalfTy(Ctx);
+ EXPECT_EQ(HalfTy, Ctx.getType(llvm::Type::getHalfTy(C)));
+ EXPECT_EQ(FAdd2->getType(), HalfTy);
auto *LLVMFloatTy = Type::getFloatTy(C);
auto *LLVMDoubleTy = Type::getDoubleTy(C);
// Check that creating an identical constant gives us the same object.
@@ -616,6 +621,7 @@ define void @foo() {
%farray = extractvalue [2 x float] [float 0.0, float 1.0], 0
%fvector = extractelement <2 x double> <double 0.0, double 1.0>, i32 0
%string = extractvalue [6 x i8] [i8 72, i8 69, i8 76, i8 76, i8 79, i8 0], 0
+ %stringNoNull = extractvalue [5 x i8] [i8 72, i8 69, i8 76, i8 76, i8 79], 0
ret void
}
)IR");
@@ -630,16 +636,19 @@ define void @foo() {
auto *I2 = &*It++;
auto *I3 = &*It++;
auto *I4 = &*It++;
+ auto *I5 = &*It++;
auto *Array = cast<sandboxir::ConstantDataArray>(I0->getOperand(0));
EXPECT_TRUE(isa<sandboxir::ConstantDataSequential>(Array));
auto *Vector = cast<sandboxir::ConstantDataVector>(I1->getOperand(0));
EXPECT_TRUE(isa<sandboxir::ConstantDataVector>(Vector));
auto *FArray = cast<sandboxir::ConstantDataArray>(I2->getOperand(0));
EXPECT_TRUE(isa<sandboxir::ConstantDataSequential>(FArray));
- auto *FVector = cast<sandboxir::ConstantDataArray>(I3->getOperand(0));
+ auto *FVector = cast<sandboxir::ConstantDataVector>(I3->getOperand(0));
EXPECT_TRUE(isa<sandboxir::ConstantDataVector>(FVector));
auto *String = cast<sandboxir::ConstantDataArray>(I4->getOperand(0));
EXPECT_TRUE(isa<sandboxir::ConstantDataArray>(String));
+ auto *StringNoNull = cast<sandboxir::ConstantDataArray>(I5->getOperand(0));
+ EXPECT_TRUE(isa<sandboxir::ConstantDataArray>(StringNoNull));
auto *Zero8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0);
auto *One8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 1);
@@ -706,6 +715,44 @@ define void @foo() {
EXPECT_EQ(String->getAsCString(), "HELLO");
// Check getRawDataValues().
EXPECT_EQ(String->getRawDataValues(), HelloWithNull);
+
+ // Check ConstantDataArray member functions
+ // ----------------------------------------
+ // Check get<ElementTy>().
+ EXPECT_EQ(sandboxir::ConstantDataArray::get<char>(Ctx, {0, 1}), Array);
+ // Check get<ArrayTy>().
+ SmallVector<char> Elmts({0, 1});
+ EXPECT_EQ(sandboxir::ConstantDataArray::get<SmallVector<char>>(Ctx, Elmts),
+ Array);
+ // Check getRaw().
+ EXPECT_EQ(sandboxir::ConstantDataArray::getRaw(StringRef("HELLO"), 5,
+ Zero8->getType()),
+ StringNoNull);
+ // Check getFP().
+ SmallVector<uint16_t> Elts16({42, 43});
+ SmallVector<uint32_t> Elts32({42, 43});
+ SmallVector<uint64_t> Elts64({42, 43});
+ auto *F16Ty = sandboxir::Type::getHalfTy(Ctx);
+ auto *F32Ty = sandboxir::Type::getFloatTy(Ctx);
+ auto *F64Ty = sandboxir::Type::getDoubleTy(Ctx);
+
+ auto *CDA16 = sandboxir::ConstantDataArray::getFP(F16Ty, Elts16);
+ EXPECT_EQ(CDA16, cast<sandboxir::ConstantDataArray>(
+ Ctx.getValue(llvm::ConstantDataArray::getFP(
+ llvm::Type::getHalfTy(C), Elts16))));
+ auto *CDA32 = sandboxir::ConstantDataArray::getFP(F32Ty, Elts32);
+ EXPECT_EQ(CDA32, cast<sandboxir::ConstantDataArray>(
+ Ctx.getValue(llvm::ConstantDataArray::getFP(
+ llvm::Type::getFloatTy(C), Elts32))));
+ auto *CDA64 = sandboxir::ConstantDataArray::getFP(F64Ty, Elts64);
+ EXPECT_EQ(CDA64, cast<sandboxir::ConstantDataArray>(
+ Ctx.getValue(llvm::ConstantDataArray::getFP(
+ llvm::Type::getDoubleTy(C), Elts64))));
+ // Check getString().
+ EXPECT_EQ(sandboxir::ConstantDataArray::getString(Ctx, "HELLO"), String);
+ EXPECT_EQ(sandboxir::ConstantDataArray::getString(Ctx, "HELLO",
+ /*AddNull=*/false),
+ StringNoNull);
}
TEST_F(SandboxIRTest, ConstantPointerNull) {
More information about the llvm-commits
mailing list