[llvm] [SandboxIR] Implement ConstantDataArray functions (PR #134729)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 7 13:58:00 PDT 2025
https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/134729
Mirrors LLVM IR.
>From ae0c9d3eaf72ba7c583748fc138ec676d01316cd Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Mon, 17 Mar 2025 10:12:52 -0700
Subject: [PATCH] [SandboxIR] Implement ConstantDataArray functions
Mirrors LLVM IR.
---
llvm/include/llvm/SandboxIR/Constant.h | 67 +++++++++++++++++++++-
llvm/include/llvm/SandboxIR/Type.h | 1 +
llvm/include/llvm/SandboxIR/Value.h | 1 +
llvm/lib/SandboxIR/Type.cpp | 3 +
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 50 +++++++++++++++-
5 files changed, 119 insertions(+), 3 deletions(-)
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 7d90168c06576..4acd9260e5c19 100644
--- a/llvm/include/llvm/SandboxIR/Type.h
+++ b/llvm/include/llvm/SandboxIR/Type.h
@@ -277,6 +277,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..3d9afd631ed10 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,43 @@ 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);
+ EXPECT_EQ(
+ sandboxir::ConstantDataArray::getFP(F16Ty, Elts16),
+ cast<sandboxir::ConstantDataArray>(Ctx.getValue(
+ llvm::ConstantDataArray::getFP(llvm::Type::getHalfTy(C), Elts16))));
+ EXPECT_EQ(
+ sandboxir::ConstantDataArray::getFP(F32Ty, Elts32),
+ cast<sandboxir::ConstantDataArray>(Ctx.getValue(
+ llvm::ConstantDataArray::getFP(llvm::Type::getFloatTy(C), Elts32))));
+ EXPECT_EQ(
+ sandboxir::ConstantDataArray::getFP(F64Ty, Elts64),
+ 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