[llvm] b40677c - [SandboxIR] Add InsertValueInst (#106273)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 28 10:11:27 PDT 2024
Author: Jorge Gorbe Moya
Date: 2024-08-28T10:11:23-07:00
New Revision: b40677ccf871c5e514aa824d187350f9279c6c1c
URL: https://github.com/llvm/llvm-project/commit/b40677ccf871c5e514aa824d187350f9279c6c1c
DIFF: https://github.com/llvm/llvm-project/commit/b40677ccf871c5e514aa824d187350f9279c6c1c.diff
LOG: [SandboxIR] Add InsertValueInst (#106273)
Added:
Modified:
llvm/include/llvm/SandboxIR/SandboxIR.h
llvm/include/llvm/SandboxIR/SandboxIRValues.def
llvm/lib/SandboxIR/SandboxIR.cpp
llvm/unittests/SandboxIR/SandboxIRTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index b7bdf9acd2ef45..9818a8bcbc2cb4 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -74,6 +74,8 @@
// |
// +- ShuffleVectorInst
// |
+// +- InsertValueInst
+// |
// +- StoreInst
// |
// +- UnaryInstruction -+- LoadInst
@@ -118,6 +120,7 @@ class SelectInst;
class ExtractElementInst;
class InsertElementInst;
class ShuffleVectorInst;
+class InsertValueInst;
class BranchInst;
class UnaryInstruction;
class LoadInst;
@@ -267,6 +270,7 @@ class Value {
friend class ExtractElementInst; // For getting `Val`.
friend class InsertElementInst; // For getting `Val`.
friend class ShuffleVectorInst; // For getting `Val`.
+ friend class InsertValueInst; // For getting `Val`.
friend class BranchInst; // For getting `Val`.
friend class LoadInst; // For getting `Val`.
friend class StoreInst; // For getting `Val`.
@@ -706,6 +710,7 @@ class Instruction : public sandboxir::User {
friend class ExtractElementInst; // For getTopmostLLVMInstruction().
friend class InsertElementInst; // For getTopmostLLVMInstruction().
friend class ShuffleVectorInst; // For getTopmostLLVMInstruction().
+ friend class InsertValueInst; // For getTopmostLLVMInstruction().
friend class BranchInst; // For getTopmostLLVMInstruction().
friend class LoadInst; // For getTopmostLLVMInstruction().
friend class StoreInst; // For getTopmostLLVMInstruction().
@@ -1466,6 +1471,67 @@ class ShuffleVectorInst final
}
};
+class InsertValueInst
+ : public SingleLLVMInstructionImpl<llvm::InsertValueInst> {
+ /// Use Context::createInsertValueInst(). Don't call the constructor directly.
+ InsertValueInst(llvm::InsertValueInst *IVI, Context &Ctx)
+ : SingleLLVMInstructionImpl(ClassID::InsertValue, Opcode::InsertValue,
+ IVI, Ctx) {}
+ friend Context; // for InsertValueInst()
+
+public:
+ static Value *create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
+ BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
+ const Twine &Name = "");
+
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::InsertValue;
+ }
+
+ using idx_iterator = llvm::InsertValueInst::idx_iterator;
+ inline idx_iterator idx_begin() const {
+ return cast<llvm::InsertValueInst>(Val)->idx_begin();
+ }
+ inline idx_iterator idx_end() const {
+ return cast<llvm::InsertValueInst>(Val)->idx_end();
+ }
+ inline iterator_range<idx_iterator> indices() const {
+ return cast<llvm::InsertValueInst>(Val)->indices();
+ }
+
+ Value *getAggregateOperand() {
+ return getOperand(getAggregateOperandIndex());
+ }
+ const Value *getAggregateOperand() const {
+ return getOperand(getAggregateOperandIndex());
+ }
+ static unsigned getAggregateOperandIndex() {
+ return llvm::InsertValueInst::getAggregateOperandIndex();
+ }
+
+ Value *getInsertedValueOperand() {
+ return getOperand(getInsertedValueOperandIndex());
+ }
+ const Value *getInsertedValueOperand() const {
+ return getOperand(getInsertedValueOperandIndex());
+ }
+ static unsigned getInsertedValueOperandIndex() {
+ return llvm::InsertValueInst::getInsertedValueOperandIndex();
+ }
+
+ ArrayRef<unsigned> getIndices() const {
+ return cast<llvm::InsertValueInst>(Val)->getIndices();
+ }
+
+ unsigned getNumIndices() const {
+ return cast<llvm::InsertValueInst>(Val)->getNumIndices();
+ }
+
+ unsigned hasIndices() const {
+ return cast<llvm::InsertValueInst>(Val)->hasIndices();
+ }
+};
+
class BranchInst : public SingleLLVMInstructionImpl<llvm::BranchInst> {
/// Use Context::createBranchInst(). Don't call the constructor directly.
BranchInst(llvm::BranchInst *BI, Context &Ctx)
@@ -3053,6 +3119,8 @@ class Context {
friend ExtractElementInst; // For createExtractElementInst()
ShuffleVectorInst *createShuffleVectorInst(llvm::ShuffleVectorInst *SVI);
friend ShuffleVectorInst; // For createShuffleVectorInst()
+ InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
+ friend InsertValueInst; // For createInsertValueInst()
BranchInst *createBranchInst(llvm::BranchInst *I);
friend BranchInst; // For createBranchInst()
LoadInst *createLoadInst(llvm::LoadInst *LI);
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index 00c1a6333c8ec4..49b03ad6760d37 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIRValues.def
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -47,6 +47,7 @@ DEF_INSTR(VAArg, OP(VAArg), VAArgInst)
DEF_INSTR(Freeze, OP(Freeze), FreezeInst)
DEF_INSTR(Fence, OP(Fence), FenceInst)
DEF_INSTR(ShuffleVector, OP(ShuffleVector), ShuffleVectorInst)
+DEF_INSTR(InsertValue, OP(InsertValue), InsertValueInst)
DEF_INSTR(Select, OP(Select), SelectInst)
DEF_INSTR(Br, OP(Br), BranchInst)
DEF_INSTR(Load, OP(Load), LoadInst)
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index b75424909f0835..86198b7b83d0e2 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -2145,6 +2145,21 @@ Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(
llvm::ShuffleVectorInst::convertShuffleMaskForBitcode(Mask, ResultTy));
}
+Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
+ BBIterator WhereIt, BasicBlock *WhereBB,
+ Context &Ctx, const Twine &Name) {
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ if (WhereIt != WhereBB->end())
+ Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
+ else
+ Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
+ llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);
+ if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))
+ return Ctx.createInsertValueInst(NewInsertValueInst);
+ assert(isa<llvm::Constant>(NewV) && "Expected constant");
+ return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
+}
+
#ifndef NDEBUG
void Constant::dumpOS(raw_ostream &OS) const {
dumpCommonPrefix(OS);
@@ -2305,6 +2320,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
new ShuffleVectorInst(LLVMIns, *this));
return It->second.get();
}
+ case llvm::Instruction::InsertValue: {
+ auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV);
+ It->second =
+ std::unique_ptr<InsertValueInst>(new InsertValueInst(LLVMIns, *this));
+ return It->second.get();
+ }
case llvm::Instruction::Br: {
auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
@@ -2527,6 +2548,12 @@ Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) {
return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
}
+InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) {
+ auto NewPtr =
+ std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));
+ return cast<InsertValueInst>(registerValue(std::move(NewPtr)));
+}
+
BranchInst *Context::createBranchInst(llvm::BranchInst *BI) {
auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
return cast<BranchInst>(registerValue(std::move(NewPtr)));
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index bc3fddf9e163dc..016024750baf21 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -1261,6 +1261,110 @@ define void @foo(<2 x i8> %v1, <2 x i8> %v2) {
}
}
+TEST_F(SandboxIRTest, InsertValueInst) {
+ parseIR(C, R"IR(
+define void @foo({i32, float} %agg, i32 %i) {
+ %ins_simple = insertvalue {i32, float} %agg, i32 %i, 0
+ %ins_nested = insertvalue {float, {i32}} undef, i32 %i, 1, 0
+ %const1 = insertvalue {i32, float} {i32 99, float 99.0}, i32 %i, 0
+ %const2 = insertvalue {i32, float} {i32 0, float 99.0}, i32 %i, 0
+ ret void
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ auto &F = *Ctx.createFunction(&LLVMF);
+ auto *ArgAgg = F.getArg(0);
+ auto *ArgInt = F.getArg(1);
+ auto *BB = &*F.begin();
+ auto It = BB->begin();
+ auto *InsSimple = cast<sandboxir::InsertValueInst>(&*It++);
+ auto *InsNested = cast<sandboxir::InsertValueInst>(&*It++);
+ // These "const" instructions are helpers to create constant struct operands.
+ // TODO: Remove them once sandboxir::ConstantStruct gets added.
+ auto *Const1 = cast<sandboxir::InsertValueInst>(&*It++);
+ auto *Const2 = cast<sandboxir::InsertValueInst>(&*It++);
+ auto *Ret = &*It++;
+
+ EXPECT_EQ(InsSimple->getOperand(0), ArgAgg);
+ EXPECT_EQ(InsSimple->getOperand(1), ArgInt);
+
+ // create before instruction
+ auto *NewInsBeforeRet =
+ cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
+ ArgAgg, ArgInt, ArrayRef<unsigned>({0}), Ret->getIterator(),
+ Ret->getParent(), Ctx, "NewInsBeforeRet"));
+ EXPECT_EQ(NewInsBeforeRet->getNextNode(), Ret);
+#ifndef NDEBUG
+ EXPECT_EQ(NewInsBeforeRet->getName(), "NewInsBeforeRet");
+#endif // NDEBUG
+
+ // create at end of BB
+ auto *NewInsAtEnd =
+ cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
+ ArgAgg, ArgInt, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx,
+ "NewInsAtEnd"));
+ EXPECT_EQ(NewInsAtEnd->getPrevNode(), Ret);
+#ifndef NDEBUG
+ EXPECT_EQ(NewInsAtEnd->getName(), "NewInsAtEnd");
+#endif // NDEBUG
+
+ // Test the path that creates a folded constant.
+ auto *Zero = sandboxir::ConstantInt::get(Type::getInt32Ty(C), 0, Ctx);
+ auto *ShouldBeConstant = sandboxir::InsertValueInst::create(
+ Const1->getOperand(0), Zero, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx);
+ auto *ExpectedConstant = Const2->getOperand(0);
+ EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
+ EXPECT_EQ(ShouldBeConstant, ExpectedConstant);
+
+ // idx_begin / idx_end
+ {
+ SmallVector<int, 2> IndicesSimple(InsSimple->idx_begin(),
+ InsSimple->idx_end());
+ EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
+
+ SmallVector<int, 2> IndicesNested(InsNested->idx_begin(),
+ InsNested->idx_end());
+ EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
+ }
+
+ // indices
+ {
+ SmallVector<int, 2> IndicesSimple(InsSimple->indices());
+ EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
+
+ SmallVector<int, 2> IndicesNested(InsNested->indices());
+ EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
+ }
+
+ // getAggregateOperand
+ EXPECT_EQ(InsSimple->getAggregateOperand(), ArgAgg);
+ const auto *ConstInsSimple = InsSimple;
+ EXPECT_EQ(ConstInsSimple->getAggregateOperand(), ArgAgg);
+
+ // getAggregateOperandIndex
+ EXPECT_EQ(sandboxir::InsertValueInst::getAggregateOperandIndex(),
+ llvm::InsertValueInst::getAggregateOperandIndex());
+
+ // getInsertedValueOperand
+ EXPECT_EQ(InsSimple->getInsertedValueOperand(), ArgInt);
+ EXPECT_EQ(ConstInsSimple->getInsertedValueOperand(), ArgInt);
+
+ // getInsertedValueOperandIndex
+ EXPECT_EQ(sandboxir::InsertValueInst::getInsertedValueOperandIndex(),
+ llvm::InsertValueInst::getInsertedValueOperandIndex());
+
+ // getIndices
+ EXPECT_EQ(InsSimple->getIndices().size(), 1u);
+ EXPECT_EQ(InsSimple->getIndices()[0], 0u);
+
+ // getNumIndices
+ EXPECT_EQ(InsSimple->getNumIndices(), 1u);
+
+ // hasIndices
+ EXPECT_EQ(InsSimple->hasIndices(), true);
+}
+
TEST_F(SandboxIRTest, BranchInst) {
parseIR(C, R"IR(
define void @foo(i1 %cond0, i1 %cond2) {
More information about the llvm-commits
mailing list