Skip to content

Commit ff81f9f

Browse files
authored
[SandboxIR] Implement VAArgInst (#106247)
This patch implements sandboxir::VAArgInst mirroring llvm::VAArgInst.
1 parent abd69b3 commit ff81f9f

File tree

4 files changed

+86
-0
lines changed

4 files changed

+86
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class ConstantInt;
111111
class Context;
112112
class Function;
113113
class Instruction;
114+
class VAArgInst;
114115
class FreezeInst;
115116
class FenceInst;
116117
class SelectInst;
@@ -255,6 +256,7 @@ class Value {
255256
friend class Context; // For getting `Val`.
256257
friend class User; // For getting `Val`.
257258
friend class Use; // For getting `Val`.
259+
friend class VAArgInst; // For getting `Val`.
258260
friend class FreezeInst; // For getting `Val`.
259261
friend class FenceInst; // For getting `Val`.
260262
friend class SelectInst; // For getting `Val`.
@@ -688,6 +690,7 @@ class Instruction : public sandboxir::User {
688690
/// A SandboxIR Instruction may map to multiple LLVM IR Instruction. This
689691
/// returns its topmost LLVM IR instruction.
690692
llvm::Instruction *getTopmostLLVMInstruction() const;
693+
friend class VAArgInst; // For getTopmostLLVMInstruction().
691694
friend class FreezeInst; // For getTopmostLLVMInstruction().
692695
friend class FenceInst; // For getTopmostLLVMInstruction().
693696
friend class SelectInst; // For getTopmostLLVMInstruction().
@@ -1543,6 +1546,27 @@ class UnaryInstruction
15431546
}
15441547
};
15451548

1549+
class VAArgInst : public UnaryInstruction {
1550+
VAArgInst(llvm::VAArgInst *FI, Context &Ctx)
1551+
: UnaryInstruction(ClassID::VAArg, Opcode::VAArg, FI, Ctx) {}
1552+
friend Context; // For constructor;
1553+
1554+
public:
1555+
static VAArgInst *create(Value *List, Type *Ty, BBIterator WhereIt,
1556+
BasicBlock *WhereBB, Context &Ctx,
1557+
const Twine &Name = "");
1558+
Value *getPointerOperand();
1559+
const Value *getPointerOperand() const {
1560+
return const_cast<VAArgInst *>(this)->getPointerOperand();
1561+
}
1562+
static unsigned getPointerOperandIndex() {
1563+
return llvm::VAArgInst::getPointerOperandIndex();
1564+
}
1565+
static bool classof(const Value *From) {
1566+
return From->getSubclassID() == ClassID::VAArg;
1567+
}
1568+
};
1569+
15461570
class FreezeInst : public UnaryInstruction {
15471571
FreezeInst(llvm::FreezeInst *FI, Context &Ctx)
15481572
: UnaryInstruction(ClassID::Freeze, Opcode::Freeze, FI, Ctx) {}
@@ -3006,6 +3030,8 @@ class Context {
30063030
IRBuilder<ConstantFolder> LLVMIRBuilder;
30073031
auto &getLLVMIRBuilder() { return LLVMIRBuilder; }
30083032

3033+
VAArgInst *createVAArgInst(llvm::VAArgInst *SI);
3034+
friend VAArgInst; // For createVAArgInst()
30093035
FreezeInst *createFreezeInst(llvm::FreezeInst *SI);
30103036
friend FreezeInst; // For createFreezeInst()
30113037
FenceInst *createFenceInst(llvm::FenceInst *SI);

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ DEF_USER(ConstantInt, ConstantInt)
3737
DEF_INSTR(Opaque, OP(Opaque), OpaqueInst)
3838
DEF_INSTR(ExtractElement, OP(ExtractElement), ExtractElementInst)
3939
DEF_INSTR(InsertElement, OP(InsertElement), InsertElementInst)
40+
DEF_INSTR(VAArg, OP(VAArg), VAArgInst)
4041
DEF_INSTR(Freeze, OP(Freeze), FreezeInst)
4142
DEF_INSTR(Fence, OP(Fence), FenceInst)
4243
DEF_INSTR(ShuffleVector, OP(ShuffleVector), ShuffleVectorInst)

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,22 @@ void Instruction::dumpOS(raw_ostream &OS) const {
575575
}
576576
#endif // NDEBUG
577577

578+
VAArgInst *VAArgInst::create(Value *List, Type *Ty, BBIterator WhereIt,
579+
BasicBlock *WhereBB, Context &Ctx,
580+
const Twine &Name) {
581+
auto &Builder = Ctx.getLLVMIRBuilder();
582+
if (WhereIt != WhereBB->end())
583+
Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
584+
else
585+
Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
586+
auto *LLVMI = cast<llvm::VAArgInst>(Builder.CreateVAArg(List->Val, Ty, Name));
587+
return Ctx.createVAArgInst(LLVMI);
588+
}
589+
590+
Value *VAArgInst::getPointerOperand() {
591+
return Ctx.getValue(cast<llvm::VAArgInst>(Val)->getPointerOperand());
592+
}
593+
578594
FreezeInst *FreezeInst::create(Value *V, BBIterator WhereIt,
579595
BasicBlock *WhereBB, Context &Ctx,
580596
const Twine &Name) {
@@ -2251,6 +2267,11 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
22512267
assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
22522268

22532269
switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
2270+
case llvm::Instruction::VAArg: {
2271+
auto *LLVMVAArg = cast<llvm::VAArgInst>(LLVMV);
2272+
It->second = std::unique_ptr<VAArgInst>(new VAArgInst(LLVMVAArg, *this));
2273+
return It->second.get();
2274+
}
22542275
case llvm::Instruction::Freeze: {
22552276
auto *LLVMFreeze = cast<llvm::FreezeInst>(LLVMV);
22562277
It->second = std::unique_ptr<FreezeInst>(new FreezeInst(LLVMFreeze, *this));
@@ -2465,6 +2486,11 @@ BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
24652486
return BB;
24662487
}
24672488

2489+
VAArgInst *Context::createVAArgInst(llvm::VAArgInst *SI) {
2490+
auto NewPtr = std::unique_ptr<VAArgInst>(new VAArgInst(SI, *this));
2491+
return cast<VAArgInst>(registerValue(std::move(NewPtr)));
2492+
}
2493+
24682494
FreezeInst *Context::createFreezeInst(llvm::FreezeInst *SI) {
24692495
auto NewPtr = std::unique_ptr<FreezeInst>(new FreezeInst(SI, *this));
24702496
return cast<FreezeInst>(registerValue(std::move(NewPtr)));

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,39 @@ define void @foo(i8 %v1) {
580580
EXPECT_EQ(I0->getNextNode(), Ret);
581581
}
582582

583+
TEST_F(SandboxIRTest, VAArgInst) {
584+
parseIR(C, R"IR(
585+
define void @foo(ptr %va) {
586+
%va_arg = va_arg ptr %va, i32
587+
ret void
588+
}
589+
)IR");
590+
llvm::Function *LLVMF = &*M->getFunction("foo");
591+
592+
sandboxir::Context Ctx(C);
593+
sandboxir::Function *F = Ctx.createFunction(LLVMF);
594+
auto *Arg = F->getArg(0);
595+
auto *BB = &*F->begin();
596+
auto It = BB->begin();
597+
auto *VA = cast<sandboxir::VAArgInst>(&*It++);
598+
auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
599+
600+
// Check getPointerOperand().
601+
EXPECT_EQ(VA->getPointerOperand(), Arg);
602+
// Check getPOinterOperandIndex().
603+
EXPECT_EQ(sandboxir::VAArgInst::getPointerOperandIndex(),
604+
llvm::VAArgInst::getPointerOperandIndex());
605+
// Check create().
606+
auto *NewVATy = Type::getInt8Ty(C);
607+
auto *NewVA = sandboxir::VAArgInst::create(Arg, NewVATy, Ret->getIterator(),
608+
Ret->getParent(), Ctx, "NewVA");
609+
EXPECT_EQ(NewVA->getNextNode(), Ret);
610+
EXPECT_EQ(NewVA->getType(), NewVATy);
611+
#ifndef NDEBUG
612+
EXPECT_EQ(NewVA->getName(), "NewVA");
613+
#endif // NDEBUG
614+
}
615+
583616
TEST_F(SandboxIRTest, FreezeInst) {
584617
parseIR(C, R"IR(
585618
define void @foo(i8 %arg) {

0 commit comments

Comments
 (0)