Skip to content

Commit 1827086

Browse files
authored
[SandboxIR] Add ExtractValueInst. (#106613)
1 parent 4ca817d commit 1827086

File tree

4 files changed

+194
-0
lines changed

4 files changed

+194
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
// |
7575
// +- ShuffleVectorInst
7676
// |
77+
// +- ExtractValueInst
78+
// |
7779
// +- InsertValueInst
7880
// |
7981
// +- StoreInst
@@ -120,6 +122,7 @@ class SelectInst;
120122
class ExtractElementInst;
121123
class InsertElementInst;
122124
class ShuffleVectorInst;
125+
class ExtractValueInst;
123126
class InsertValueInst;
124127
class BranchInst;
125128
class UnaryInstruction;
@@ -270,6 +273,7 @@ class Value {
270273
friend class ExtractElementInst; // For getting `Val`.
271274
friend class InsertElementInst; // For getting `Val`.
272275
friend class ShuffleVectorInst; // For getting `Val`.
276+
friend class ExtractValueInst; // For getting `Val`.
273277
friend class InsertValueInst; // For getting `Val`.
274278
friend class BranchInst; // For getting `Val`.
275279
friend class LoadInst; // For getting `Val`.
@@ -710,6 +714,7 @@ class Instruction : public sandboxir::User {
710714
friend class ExtractElementInst; // For getTopmostLLVMInstruction().
711715
friend class InsertElementInst; // For getTopmostLLVMInstruction().
712716
friend class ShuffleVectorInst; // For getTopmostLLVMInstruction().
717+
friend class ExtractValueInst; // For getTopmostLLVMInstruction().
713718
friend class InsertValueInst; // For getTopmostLLVMInstruction().
714719
friend class BranchInst; // For getTopmostLLVMInstruction().
715720
friend class LoadInst; // For getTopmostLLVMInstruction().
@@ -1621,6 +1626,65 @@ class UnaryInstruction
16211626
}
16221627
};
16231628

1629+
class ExtractValueInst : public UnaryInstruction {
1630+
/// Use Context::createExtractValueInst() instead.
1631+
ExtractValueInst(llvm::ExtractValueInst *EVI, Context &Ctx)
1632+
: UnaryInstruction(ClassID::ExtractValue, Opcode::ExtractValue, EVI,
1633+
Ctx) {}
1634+
friend Context; // for ExtractValueInst()
1635+
1636+
public:
1637+
static Value *create(Value *Agg, ArrayRef<unsigned> Idxs, BBIterator WhereIt,
1638+
BasicBlock *WhereBB, Context &Ctx,
1639+
const Twine &Name = "");
1640+
1641+
static bool classof(const Value *From) {
1642+
return From->getSubclassID() == ClassID::ExtractValue;
1643+
}
1644+
1645+
/// Returns the type of the element that would be extracted
1646+
/// with an extractvalue instruction with the specified parameters.
1647+
///
1648+
/// Null is returned if the indices are invalid for the specified type.
1649+
static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs) {
1650+
return llvm::ExtractValueInst::getIndexedType(Agg, Idxs);
1651+
}
1652+
1653+
using idx_iterator = llvm::ExtractValueInst::idx_iterator;
1654+
1655+
inline idx_iterator idx_begin() const {
1656+
return cast<llvm::ExtractValueInst>(Val)->idx_begin();
1657+
}
1658+
inline idx_iterator idx_end() const {
1659+
return cast<llvm::ExtractValueInst>(Val)->idx_end();
1660+
}
1661+
inline iterator_range<idx_iterator> indices() const {
1662+
return cast<llvm::ExtractValueInst>(Val)->indices();
1663+
}
1664+
1665+
Value *getAggregateOperand() {
1666+
return getOperand(getAggregateOperandIndex());
1667+
}
1668+
const Value *getAggregateOperand() const {
1669+
return getOperand(getAggregateOperandIndex());
1670+
}
1671+
static unsigned getAggregateOperandIndex() {
1672+
return llvm::ExtractValueInst::getAggregateOperandIndex();
1673+
}
1674+
1675+
ArrayRef<unsigned> getIndices() const {
1676+
return cast<llvm::ExtractValueInst>(Val)->getIndices();
1677+
}
1678+
1679+
unsigned getNumIndices() const {
1680+
return cast<llvm::ExtractValueInst>(Val)->getNumIndices();
1681+
}
1682+
1683+
unsigned hasIndices() const {
1684+
return cast<llvm::ExtractValueInst>(Val)->hasIndices();
1685+
}
1686+
};
1687+
16241688
class VAArgInst : public UnaryInstruction {
16251689
VAArgInst(llvm::VAArgInst *FI, Context &Ctx)
16261690
: UnaryInstruction(ClassID::VAArg, Opcode::VAArg, FI, Ctx) {}
@@ -3123,6 +3187,8 @@ class Context {
31233187
friend ExtractElementInst; // For createExtractElementInst()
31243188
ShuffleVectorInst *createShuffleVectorInst(llvm::ShuffleVectorInst *SVI);
31253189
friend ShuffleVectorInst; // For createShuffleVectorInst()
3190+
ExtractValueInst *createExtractValueInst(llvm::ExtractValueInst *IVI);
3191+
friend ExtractValueInst; // For createExtractValueInst()
31263192
InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
31273193
friend InsertValueInst; // For createInsertValueInst()
31283194
BranchInst *createBranchInst(llvm::BranchInst *I);

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ DEF_INSTR(VAArg, OP(VAArg), VAArgInst)
4747
DEF_INSTR(Freeze, OP(Freeze), FreezeInst)
4848
DEF_INSTR(Fence, OP(Fence), FenceInst)
4949
DEF_INSTR(ShuffleVector, OP(ShuffleVector), ShuffleVectorInst)
50+
DEF_INSTR(ExtractValue, OP(ExtractValue), ExtractValueInst)
5051
DEF_INSTR(InsertValue, OP(InsertValue), InsertValueInst)
5152
DEF_INSTR(Select, OP(Select), SelectInst)
5253
DEF_INSTR(Br, OP(Br), BranchInst)

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,6 +2145,21 @@ Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(
21452145
llvm::ShuffleVectorInst::convertShuffleMaskForBitcode(Mask, ResultTy));
21462146
}
21472147

2148+
Value *ExtractValueInst::create(Value *Agg, ArrayRef<unsigned> Idxs,
2149+
BBIterator WhereIt, BasicBlock *WhereBB,
2150+
Context &Ctx, const Twine &Name) {
2151+
auto &Builder = Ctx.getLLVMIRBuilder();
2152+
if (WhereIt != WhereBB->end())
2153+
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
2154+
else
2155+
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
2156+
llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name);
2157+
if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))
2158+
return Ctx.createExtractValueInst(NewExtractValueInst);
2159+
assert(isa<llvm::Constant>(NewV) && "Expected constant");
2160+
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
2161+
}
2162+
21482163
Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
21492164
BBIterator WhereIt, BasicBlock *WhereBB,
21502165
Context &Ctx, const Twine &Name) {
@@ -2320,6 +2335,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
23202335
new ShuffleVectorInst(LLVMIns, *this));
23212336
return It->second.get();
23222337
}
2338+
case llvm::Instruction::ExtractValue: {
2339+
auto *LLVMIns = cast<llvm::ExtractValueInst>(LLVMV);
2340+
It->second =
2341+
std::unique_ptr<ExtractValueInst>(new ExtractValueInst(LLVMIns, *this));
2342+
return It->second.get();
2343+
}
23232344
case llvm::Instruction::InsertValue: {
23242345
auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV);
23252346
It->second =
@@ -2548,6 +2569,12 @@ Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) {
25482569
return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
25492570
}
25502571

2572+
ExtractValueInst *Context::createExtractValueInst(llvm::ExtractValueInst *EVI) {
2573+
auto NewPtr =
2574+
std::unique_ptr<ExtractValueInst>(new ExtractValueInst(EVI, *this));
2575+
return cast<ExtractValueInst>(registerValue(std::move(NewPtr)));
2576+
}
2577+
25512578
InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) {
25522579
auto NewPtr =
25532580
std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,106 @@ define void @foo(<2 x i8> %v1, <2 x i8> %v2) {
12611261
}
12621262
}
12631263

1264+
TEST_F(SandboxIRTest, ExtractValueInst) {
1265+
parseIR(C, R"IR(
1266+
define void @foo({i32, float} %agg) {
1267+
%ext_simple = extractvalue {i32, float} %agg, 0
1268+
%ext_nested = extractvalue {float, {i32}} undef, 1, 0
1269+
%const1 = extractvalue {i32, float} {i32 0, float 99.0}, 0
1270+
ret void
1271+
}
1272+
)IR");
1273+
Function &LLVMF = *M->getFunction("foo");
1274+
sandboxir::Context Ctx(C);
1275+
auto &F = *Ctx.createFunction(&LLVMF);
1276+
auto *ArgAgg = F.getArg(0);
1277+
auto *BB = &*F.begin();
1278+
auto It = BB->begin();
1279+
auto *ExtSimple = cast<sandboxir::ExtractValueInst>(&*It++);
1280+
auto *ExtNested = cast<sandboxir::ExtractValueInst>(&*It++);
1281+
auto *Const1 = cast<sandboxir::ExtractValueInst>(&*It++);
1282+
auto *Ret = &*It++;
1283+
1284+
EXPECT_EQ(ExtSimple->getOperand(0), ArgAgg);
1285+
1286+
// create before instruction
1287+
auto *NewExtBeforeRet =
1288+
cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
1289+
ArgAgg, ArrayRef<unsigned>({0}), Ret->getIterator(), Ret->getParent(),
1290+
Ctx, "NewExtBeforeRet"));
1291+
EXPECT_EQ(NewExtBeforeRet->getNextNode(), Ret);
1292+
#ifndef NDEBUG
1293+
EXPECT_EQ(NewExtBeforeRet->getName(), "NewExtBeforeRet");
1294+
#endif // NDEBUG
1295+
1296+
// create at end of BB
1297+
auto *NewExtAtEnd =
1298+
cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
1299+
ArgAgg, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx, "NewExtAtEnd"));
1300+
EXPECT_EQ(NewExtAtEnd->getPrevNode(), Ret);
1301+
#ifndef NDEBUG
1302+
EXPECT_EQ(NewExtAtEnd->getName(), "NewExtAtEnd");
1303+
#endif // NDEBUG
1304+
1305+
// Test the path that creates a folded constant.
1306+
auto *ShouldBeConstant = sandboxir::ExtractValueInst::create(
1307+
Const1->getOperand(0), ArrayRef<unsigned>({0}), BB->end(), BB, Ctx);
1308+
EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
1309+
1310+
auto *Zero = sandboxir::ConstantInt::get(Type::getInt32Ty(C), 0, Ctx);
1311+
EXPECT_EQ(ShouldBeConstant, Zero);
1312+
1313+
// getIndexedType
1314+
Type *AggType = ExtNested->getAggregateOperand()->getType();
1315+
EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
1316+
AggType, ArrayRef<unsigned>({1, 0})),
1317+
llvm::ExtractValueInst::getIndexedType(AggType,
1318+
ArrayRef<unsigned>({1, 0})));
1319+
1320+
EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
1321+
AggType, ArrayRef<unsigned>({2})),
1322+
nullptr);
1323+
1324+
// idx_begin / idx_end
1325+
{
1326+
SmallVector<int, 2> IndicesSimple(ExtSimple->idx_begin(),
1327+
ExtSimple->idx_end());
1328+
EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
1329+
1330+
SmallVector<int, 2> IndicesNested(ExtNested->idx_begin(),
1331+
ExtNested->idx_end());
1332+
EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
1333+
}
1334+
1335+
// indices
1336+
{
1337+
SmallVector<int, 2> IndicesSimple(ExtSimple->indices());
1338+
EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
1339+
1340+
SmallVector<int, 2> IndicesNested(ExtNested->indices());
1341+
EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
1342+
}
1343+
1344+
// getAggregateOperand
1345+
EXPECT_EQ(ExtSimple->getAggregateOperand(), ArgAgg);
1346+
const auto *ConstExtSimple = ExtSimple;
1347+
EXPECT_EQ(ConstExtSimple->getAggregateOperand(), ArgAgg);
1348+
1349+
// getAggregateOperandIndex
1350+
EXPECT_EQ(sandboxir::ExtractValueInst::getAggregateOperandIndex(),
1351+
llvm::ExtractValueInst::getAggregateOperandIndex());
1352+
1353+
// getIndices
1354+
EXPECT_EQ(ExtSimple->getIndices().size(), 1u);
1355+
EXPECT_EQ(ExtSimple->getIndices()[0], 0u);
1356+
1357+
// getNumIndices
1358+
EXPECT_EQ(ExtSimple->getNumIndices(), 1u);
1359+
1360+
// hasIndices
1361+
EXPECT_EQ(ExtSimple->hasIndices(), true);
1362+
}
1363+
12641364
TEST_F(SandboxIRTest, InsertValueInst) {
12651365
parseIR(C, R"IR(
12661366
define void @foo({i32, float} %agg, i32 %i) {

0 commit comments

Comments
 (0)