[llvm] 1827086 - [SandboxIR] Add ExtractValueInst. (#106613)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 29 14:25:38 PDT 2024
Author: Jorge Gorbe Moya
Date: 2024-08-29T14:25:34-07:00
New Revision: 182708680bbe34b579a09b2dbc3215b519b2473f
URL: https://github.com/llvm/llvm-project/commit/182708680bbe34b579a09b2dbc3215b519b2473f
DIFF: https://github.com/llvm/llvm-project/commit/182708680bbe34b579a09b2dbc3215b519b2473f.diff
LOG: [SandboxIR] Add ExtractValueInst. (#106613)
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 14210ae35c0082..d4c2efca4ecfa0 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -74,6 +74,8 @@
// |
// +- ShuffleVectorInst
// |
+// +- ExtractValueInst
+// |
// +- InsertValueInst
// |
// +- StoreInst
@@ -120,6 +122,7 @@ class SelectInst;
class ExtractElementInst;
class InsertElementInst;
class ShuffleVectorInst;
+class ExtractValueInst;
class InsertValueInst;
class BranchInst;
class UnaryInstruction;
@@ -270,6 +273,7 @@ class Value {
friend class ExtractElementInst; // For getting `Val`.
friend class InsertElementInst; // For getting `Val`.
friend class ShuffleVectorInst; // For getting `Val`.
+ friend class ExtractValueInst; // For getting `Val`.
friend class InsertValueInst; // For getting `Val`.
friend class BranchInst; // For getting `Val`.
friend class LoadInst; // For getting `Val`.
@@ -710,6 +714,7 @@ class Instruction : public sandboxir::User {
friend class ExtractElementInst; // For getTopmostLLVMInstruction().
friend class InsertElementInst; // For getTopmostLLVMInstruction().
friend class ShuffleVectorInst; // For getTopmostLLVMInstruction().
+ friend class ExtractValueInst; // For getTopmostLLVMInstruction().
friend class InsertValueInst; // For getTopmostLLVMInstruction().
friend class BranchInst; // For getTopmostLLVMInstruction().
friend class LoadInst; // For getTopmostLLVMInstruction().
@@ -1621,6 +1626,65 @@ class UnaryInstruction
}
};
+class ExtractValueInst : public UnaryInstruction {
+ /// Use Context::createExtractValueInst() instead.
+ ExtractValueInst(llvm::ExtractValueInst *EVI, Context &Ctx)
+ : UnaryInstruction(ClassID::ExtractValue, Opcode::ExtractValue, EVI,
+ Ctx) {}
+ friend Context; // for ExtractValueInst()
+
+public:
+ static Value *create(Value *Agg, ArrayRef<unsigned> Idxs, BBIterator WhereIt,
+ BasicBlock *WhereBB, Context &Ctx,
+ const Twine &Name = "");
+
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::ExtractValue;
+ }
+
+ /// Returns the type of the element that would be extracted
+ /// with an extractvalue instruction with the specified parameters.
+ ///
+ /// Null is returned if the indices are invalid for the specified type.
+ static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs) {
+ return llvm::ExtractValueInst::getIndexedType(Agg, Idxs);
+ }
+
+ using idx_iterator = llvm::ExtractValueInst::idx_iterator;
+
+ inline idx_iterator idx_begin() const {
+ return cast<llvm::ExtractValueInst>(Val)->idx_begin();
+ }
+ inline idx_iterator idx_end() const {
+ return cast<llvm::ExtractValueInst>(Val)->idx_end();
+ }
+ inline iterator_range<idx_iterator> indices() const {
+ return cast<llvm::ExtractValueInst>(Val)->indices();
+ }
+
+ Value *getAggregateOperand() {
+ return getOperand(getAggregateOperandIndex());
+ }
+ const Value *getAggregateOperand() const {
+ return getOperand(getAggregateOperandIndex());
+ }
+ static unsigned getAggregateOperandIndex() {
+ return llvm::ExtractValueInst::getAggregateOperandIndex();
+ }
+
+ ArrayRef<unsigned> getIndices() const {
+ return cast<llvm::ExtractValueInst>(Val)->getIndices();
+ }
+
+ unsigned getNumIndices() const {
+ return cast<llvm::ExtractValueInst>(Val)->getNumIndices();
+ }
+
+ unsigned hasIndices() const {
+ return cast<llvm::ExtractValueInst>(Val)->hasIndices();
+ }
+};
+
class VAArgInst : public UnaryInstruction {
VAArgInst(llvm::VAArgInst *FI, Context &Ctx)
: UnaryInstruction(ClassID::VAArg, Opcode::VAArg, FI, Ctx) {}
@@ -3123,6 +3187,8 @@ class Context {
friend ExtractElementInst; // For createExtractElementInst()
ShuffleVectorInst *createShuffleVectorInst(llvm::ShuffleVectorInst *SVI);
friend ShuffleVectorInst; // For createShuffleVectorInst()
+ ExtractValueInst *createExtractValueInst(llvm::ExtractValueInst *IVI);
+ friend ExtractValueInst; // For createExtractValueInst()
InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
friend InsertValueInst; // For createInsertValueInst()
BranchInst *createBranchInst(llvm::BranchInst *I);
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
index 49b03ad6760d37..d29fc3b5e95871 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(ExtractValue, OP(ExtractValue), ExtractValueInst)
DEF_INSTR(InsertValue, OP(InsertValue), InsertValueInst)
DEF_INSTR(Select, OP(Select), SelectInst)
DEF_INSTR(Br, OP(Br), BranchInst)
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 86198b7b83d0e2..b5786cdafd6307 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 *ExtractValueInst::create(Value *Agg, 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.CreateExtractValue(Agg->Val, Idxs, Name);
+ if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))
+ return Ctx.createExtractValueInst(NewExtractValueInst);
+ assert(isa<llvm::Constant>(NewV) && "Expected constant");
+ return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
+}
+
Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
BBIterator WhereIt, BasicBlock *WhereBB,
Context &Ctx, const Twine &Name) {
@@ -2320,6 +2335,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
new ShuffleVectorInst(LLVMIns, *this));
return It->second.get();
}
+ case llvm::Instruction::ExtractValue: {
+ auto *LLVMIns = cast<llvm::ExtractValueInst>(LLVMV);
+ It->second =
+ std::unique_ptr<ExtractValueInst>(new ExtractValueInst(LLVMIns, *this));
+ return It->second.get();
+ }
case llvm::Instruction::InsertValue: {
auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV);
It->second =
@@ -2548,6 +2569,12 @@ Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) {
return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
}
+ExtractValueInst *Context::createExtractValueInst(llvm::ExtractValueInst *EVI) {
+ auto NewPtr =
+ std::unique_ptr<ExtractValueInst>(new ExtractValueInst(EVI, *this));
+ return cast<ExtractValueInst>(registerValue(std::move(NewPtr)));
+}
+
InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) {
auto NewPtr =
std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 31519074e1b908..8bf4b24c48ee0d 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -1261,6 +1261,106 @@ define void @foo(<2 x i8> %v1, <2 x i8> %v2) {
}
}
+TEST_F(SandboxIRTest, ExtractValueInst) {
+ parseIR(C, R"IR(
+define void @foo({i32, float} %agg) {
+ %ext_simple = extractvalue {i32, float} %agg, 0
+ %ext_nested = extractvalue {float, {i32}} undef, 1, 0
+ %const1 = extractvalue {i32, float} {i32 0, float 99.0}, 0
+ ret void
+}
+)IR");
+ Function &LLVMF = *M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ auto &F = *Ctx.createFunction(&LLVMF);
+ auto *ArgAgg = F.getArg(0);
+ auto *BB = &*F.begin();
+ auto It = BB->begin();
+ auto *ExtSimple = cast<sandboxir::ExtractValueInst>(&*It++);
+ auto *ExtNested = cast<sandboxir::ExtractValueInst>(&*It++);
+ auto *Const1 = cast<sandboxir::ExtractValueInst>(&*It++);
+ auto *Ret = &*It++;
+
+ EXPECT_EQ(ExtSimple->getOperand(0), ArgAgg);
+
+ // create before instruction
+ auto *NewExtBeforeRet =
+ cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
+ ArgAgg, ArrayRef<unsigned>({0}), Ret->getIterator(), Ret->getParent(),
+ Ctx, "NewExtBeforeRet"));
+ EXPECT_EQ(NewExtBeforeRet->getNextNode(), Ret);
+#ifndef NDEBUG
+ EXPECT_EQ(NewExtBeforeRet->getName(), "NewExtBeforeRet");
+#endif // NDEBUG
+
+ // create at end of BB
+ auto *NewExtAtEnd =
+ cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
+ ArgAgg, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx, "NewExtAtEnd"));
+ EXPECT_EQ(NewExtAtEnd->getPrevNode(), Ret);
+#ifndef NDEBUG
+ EXPECT_EQ(NewExtAtEnd->getName(), "NewExtAtEnd");
+#endif // NDEBUG
+
+ // Test the path that creates a folded constant.
+ auto *ShouldBeConstant = sandboxir::ExtractValueInst::create(
+ Const1->getOperand(0), ArrayRef<unsigned>({0}), BB->end(), BB, Ctx);
+ EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
+
+ auto *Zero = sandboxir::ConstantInt::get(Type::getInt32Ty(C), 0, Ctx);
+ EXPECT_EQ(ShouldBeConstant, Zero);
+
+ // getIndexedType
+ Type *AggType = ExtNested->getAggregateOperand()->getType();
+ EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
+ AggType, ArrayRef<unsigned>({1, 0})),
+ llvm::ExtractValueInst::getIndexedType(AggType,
+ ArrayRef<unsigned>({1, 0})));
+
+ EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
+ AggType, ArrayRef<unsigned>({2})),
+ nullptr);
+
+ // idx_begin / idx_end
+ {
+ SmallVector<int, 2> IndicesSimple(ExtSimple->idx_begin(),
+ ExtSimple->idx_end());
+ EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
+
+ SmallVector<int, 2> IndicesNested(ExtNested->idx_begin(),
+ ExtNested->idx_end());
+ EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
+ }
+
+ // indices
+ {
+ SmallVector<int, 2> IndicesSimple(ExtSimple->indices());
+ EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
+
+ SmallVector<int, 2> IndicesNested(ExtNested->indices());
+ EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
+ }
+
+ // getAggregateOperand
+ EXPECT_EQ(ExtSimple->getAggregateOperand(), ArgAgg);
+ const auto *ConstExtSimple = ExtSimple;
+ EXPECT_EQ(ConstExtSimple->getAggregateOperand(), ArgAgg);
+
+ // getAggregateOperandIndex
+ EXPECT_EQ(sandboxir::ExtractValueInst::getAggregateOperandIndex(),
+ llvm::ExtractValueInst::getAggregateOperandIndex());
+
+ // getIndices
+ EXPECT_EQ(ExtSimple->getIndices().size(), 1u);
+ EXPECT_EQ(ExtSimple->getIndices()[0], 0u);
+
+ // getNumIndices
+ EXPECT_EQ(ExtSimple->getNumIndices(), 1u);
+
+ // hasIndices
+ EXPECT_EQ(ExtSimple->hasIndices(), true);
+}
+
TEST_F(SandboxIRTest, InsertValueInst) {
parseIR(C, R"IR(
define void @foo({i32, float} %agg, i32 %i) {
More information about the llvm-commits
mailing list