Skip to content

Commit b40677c

Browse files
authored
[SandboxIR] Add InsertValueInst (#106273)
1 parent 40db261 commit b40677c

File tree

4 files changed

+200
-0
lines changed

4 files changed

+200
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@
7474
// |
7575
// +- ShuffleVectorInst
7676
// |
77+
// +- InsertValueInst
78+
// |
7779
// +- StoreInst
7880
// |
7981
// +- UnaryInstruction -+- LoadInst
@@ -118,6 +120,7 @@ class SelectInst;
118120
class ExtractElementInst;
119121
class InsertElementInst;
120122
class ShuffleVectorInst;
123+
class InsertValueInst;
121124
class BranchInst;
122125
class UnaryInstruction;
123126
class LoadInst;
@@ -267,6 +270,7 @@ class Value {
267270
friend class ExtractElementInst; // For getting `Val`.
268271
friend class InsertElementInst; // For getting `Val`.
269272
friend class ShuffleVectorInst; // For getting `Val`.
273+
friend class InsertValueInst; // For getting `Val`.
270274
friend class BranchInst; // For getting `Val`.
271275
friend class LoadInst; // For getting `Val`.
272276
friend class StoreInst; // For getting `Val`.
@@ -706,6 +710,7 @@ class Instruction : public sandboxir::User {
706710
friend class ExtractElementInst; // For getTopmostLLVMInstruction().
707711
friend class InsertElementInst; // For getTopmostLLVMInstruction().
708712
friend class ShuffleVectorInst; // For getTopmostLLVMInstruction().
713+
friend class InsertValueInst; // For getTopmostLLVMInstruction().
709714
friend class BranchInst; // For getTopmostLLVMInstruction().
710715
friend class LoadInst; // For getTopmostLLVMInstruction().
711716
friend class StoreInst; // For getTopmostLLVMInstruction().
@@ -1466,6 +1471,67 @@ class ShuffleVectorInst final
14661471
}
14671472
};
14681473

1474+
class InsertValueInst
1475+
: public SingleLLVMInstructionImpl<llvm::InsertValueInst> {
1476+
/// Use Context::createInsertValueInst(). Don't call the constructor directly.
1477+
InsertValueInst(llvm::InsertValueInst *IVI, Context &Ctx)
1478+
: SingleLLVMInstructionImpl(ClassID::InsertValue, Opcode::InsertValue,
1479+
IVI, Ctx) {}
1480+
friend Context; // for InsertValueInst()
1481+
1482+
public:
1483+
static Value *create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
1484+
BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
1485+
const Twine &Name = "");
1486+
1487+
static bool classof(const Value *From) {
1488+
return From->getSubclassID() == ClassID::InsertValue;
1489+
}
1490+
1491+
using idx_iterator = llvm::InsertValueInst::idx_iterator;
1492+
inline idx_iterator idx_begin() const {
1493+
return cast<llvm::InsertValueInst>(Val)->idx_begin();
1494+
}
1495+
inline idx_iterator idx_end() const {
1496+
return cast<llvm::InsertValueInst>(Val)->idx_end();
1497+
}
1498+
inline iterator_range<idx_iterator> indices() const {
1499+
return cast<llvm::InsertValueInst>(Val)->indices();
1500+
}
1501+
1502+
Value *getAggregateOperand() {
1503+
return getOperand(getAggregateOperandIndex());
1504+
}
1505+
const Value *getAggregateOperand() const {
1506+
return getOperand(getAggregateOperandIndex());
1507+
}
1508+
static unsigned getAggregateOperandIndex() {
1509+
return llvm::InsertValueInst::getAggregateOperandIndex();
1510+
}
1511+
1512+
Value *getInsertedValueOperand() {
1513+
return getOperand(getInsertedValueOperandIndex());
1514+
}
1515+
const Value *getInsertedValueOperand() const {
1516+
return getOperand(getInsertedValueOperandIndex());
1517+
}
1518+
static unsigned getInsertedValueOperandIndex() {
1519+
return llvm::InsertValueInst::getInsertedValueOperandIndex();
1520+
}
1521+
1522+
ArrayRef<unsigned> getIndices() const {
1523+
return cast<llvm::InsertValueInst>(Val)->getIndices();
1524+
}
1525+
1526+
unsigned getNumIndices() const {
1527+
return cast<llvm::InsertValueInst>(Val)->getNumIndices();
1528+
}
1529+
1530+
unsigned hasIndices() const {
1531+
return cast<llvm::InsertValueInst>(Val)->hasIndices();
1532+
}
1533+
};
1534+
14691535
class BranchInst : public SingleLLVMInstructionImpl<llvm::BranchInst> {
14701536
/// Use Context::createBranchInst(). Don't call the constructor directly.
14711537
BranchInst(llvm::BranchInst *BI, Context &Ctx)
@@ -3053,6 +3119,8 @@ class Context {
30533119
friend ExtractElementInst; // For createExtractElementInst()
30543120
ShuffleVectorInst *createShuffleVectorInst(llvm::ShuffleVectorInst *SVI);
30553121
friend ShuffleVectorInst; // For createShuffleVectorInst()
3122+
InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
3123+
friend InsertValueInst; // For createInsertValueInst()
30563124
BranchInst *createBranchInst(llvm::BranchInst *I);
30573125
friend BranchInst; // For createBranchInst()
30583126
LoadInst *createLoadInst(llvm::LoadInst *LI);

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(InsertValue, OP(InsertValue), InsertValueInst)
5051
DEF_INSTR(Select, OP(Select), SelectInst)
5152
DEF_INSTR(Br, OP(Br), BranchInst)
5253
DEF_INSTR(Load, OP(Load), LoadInst)

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 *InsertValueInst::create(Value *Agg, Value *Val, 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.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);
2157+
if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))
2158+
return Ctx.createInsertValueInst(NewInsertValueInst);
2159+
assert(isa<llvm::Constant>(NewV) && "Expected constant");
2160+
return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
2161+
}
2162+
21482163
#ifndef NDEBUG
21492164
void Constant::dumpOS(raw_ostream &OS) const {
21502165
dumpCommonPrefix(OS);
@@ -2305,6 +2320,12 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
23052320
new ShuffleVectorInst(LLVMIns, *this));
23062321
return It->second.get();
23072322
}
2323+
case llvm::Instruction::InsertValue: {
2324+
auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV);
2325+
It->second =
2326+
std::unique_ptr<InsertValueInst>(new InsertValueInst(LLVMIns, *this));
2327+
return It->second.get();
2328+
}
23082329
case llvm::Instruction::Br: {
23092330
auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
23102331
It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
@@ -2527,6 +2548,12 @@ Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) {
25272548
return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
25282549
}
25292550

2551+
InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) {
2552+
auto NewPtr =
2553+
std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));
2554+
return cast<InsertValueInst>(registerValue(std::move(NewPtr)));
2555+
}
2556+
25302557
BranchInst *Context::createBranchInst(llvm::BranchInst *BI) {
25312558
auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
25322559
return cast<BranchInst>(registerValue(std::move(NewPtr)));

llvm/unittests/SandboxIR/SandboxIRTest.cpp

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

1264+
TEST_F(SandboxIRTest, InsertValueInst) {
1265+
parseIR(C, R"IR(
1266+
define void @foo({i32, float} %agg, i32 %i) {
1267+
%ins_simple = insertvalue {i32, float} %agg, i32 %i, 0
1268+
%ins_nested = insertvalue {float, {i32}} undef, i32 %i, 1, 0
1269+
%const1 = insertvalue {i32, float} {i32 99, float 99.0}, i32 %i, 0
1270+
%const2 = insertvalue {i32, float} {i32 0, float 99.0}, i32 %i, 0
1271+
ret void
1272+
}
1273+
)IR");
1274+
Function &LLVMF = *M->getFunction("foo");
1275+
sandboxir::Context Ctx(C);
1276+
auto &F = *Ctx.createFunction(&LLVMF);
1277+
auto *ArgAgg = F.getArg(0);
1278+
auto *ArgInt = F.getArg(1);
1279+
auto *BB = &*F.begin();
1280+
auto It = BB->begin();
1281+
auto *InsSimple = cast<sandboxir::InsertValueInst>(&*It++);
1282+
auto *InsNested = cast<sandboxir::InsertValueInst>(&*It++);
1283+
// These "const" instructions are helpers to create constant struct operands.
1284+
// TODO: Remove them once sandboxir::ConstantStruct gets added.
1285+
auto *Const1 = cast<sandboxir::InsertValueInst>(&*It++);
1286+
auto *Const2 = cast<sandboxir::InsertValueInst>(&*It++);
1287+
auto *Ret = &*It++;
1288+
1289+
EXPECT_EQ(InsSimple->getOperand(0), ArgAgg);
1290+
EXPECT_EQ(InsSimple->getOperand(1), ArgInt);
1291+
1292+
// create before instruction
1293+
auto *NewInsBeforeRet =
1294+
cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
1295+
ArgAgg, ArgInt, ArrayRef<unsigned>({0}), Ret->getIterator(),
1296+
Ret->getParent(), Ctx, "NewInsBeforeRet"));
1297+
EXPECT_EQ(NewInsBeforeRet->getNextNode(), Ret);
1298+
#ifndef NDEBUG
1299+
EXPECT_EQ(NewInsBeforeRet->getName(), "NewInsBeforeRet");
1300+
#endif // NDEBUG
1301+
1302+
// create at end of BB
1303+
auto *NewInsAtEnd =
1304+
cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
1305+
ArgAgg, ArgInt, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx,
1306+
"NewInsAtEnd"));
1307+
EXPECT_EQ(NewInsAtEnd->getPrevNode(), Ret);
1308+
#ifndef NDEBUG
1309+
EXPECT_EQ(NewInsAtEnd->getName(), "NewInsAtEnd");
1310+
#endif // NDEBUG
1311+
1312+
// Test the path that creates a folded constant.
1313+
auto *Zero = sandboxir::ConstantInt::get(Type::getInt32Ty(C), 0, Ctx);
1314+
auto *ShouldBeConstant = sandboxir::InsertValueInst::create(
1315+
Const1->getOperand(0), Zero, ArrayRef<unsigned>({0}), BB->end(), BB, Ctx);
1316+
auto *ExpectedConstant = Const2->getOperand(0);
1317+
EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
1318+
EXPECT_EQ(ShouldBeConstant, ExpectedConstant);
1319+
1320+
// idx_begin / idx_end
1321+
{
1322+
SmallVector<int, 2> IndicesSimple(InsSimple->idx_begin(),
1323+
InsSimple->idx_end());
1324+
EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
1325+
1326+
SmallVector<int, 2> IndicesNested(InsNested->idx_begin(),
1327+
InsNested->idx_end());
1328+
EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
1329+
}
1330+
1331+
// indices
1332+
{
1333+
SmallVector<int, 2> IndicesSimple(InsSimple->indices());
1334+
EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
1335+
1336+
SmallVector<int, 2> IndicesNested(InsNested->indices());
1337+
EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
1338+
}
1339+
1340+
// getAggregateOperand
1341+
EXPECT_EQ(InsSimple->getAggregateOperand(), ArgAgg);
1342+
const auto *ConstInsSimple = InsSimple;
1343+
EXPECT_EQ(ConstInsSimple->getAggregateOperand(), ArgAgg);
1344+
1345+
// getAggregateOperandIndex
1346+
EXPECT_EQ(sandboxir::InsertValueInst::getAggregateOperandIndex(),
1347+
llvm::InsertValueInst::getAggregateOperandIndex());
1348+
1349+
// getInsertedValueOperand
1350+
EXPECT_EQ(InsSimple->getInsertedValueOperand(), ArgInt);
1351+
EXPECT_EQ(ConstInsSimple->getInsertedValueOperand(), ArgInt);
1352+
1353+
// getInsertedValueOperandIndex
1354+
EXPECT_EQ(sandboxir::InsertValueInst::getInsertedValueOperandIndex(),
1355+
llvm::InsertValueInst::getInsertedValueOperandIndex());
1356+
1357+
// getIndices
1358+
EXPECT_EQ(InsSimple->getIndices().size(), 1u);
1359+
EXPECT_EQ(InsSimple->getIndices()[0], 0u);
1360+
1361+
// getNumIndices
1362+
EXPECT_EQ(InsSimple->getNumIndices(), 1u);
1363+
1364+
// hasIndices
1365+
EXPECT_EQ(InsSimple->hasIndices(), true);
1366+
}
1367+
12641368
TEST_F(SandboxIRTest, BranchInst) {
12651369
parseIR(C, R"IR(
12661370
define void @foo(i1 %cond0, i1 %cond2) {

0 commit comments

Comments
 (0)