Skip to content

Commit 1987f93

Browse files
authored
[SandboxIR] OpaqueValue (#127699)
This patch implements a new subclass of the Value class used for Sandbox IR Values that we don't support, like metadata or inline asm. The goal is to never have null sandboxir::Value objects, because this is not the expected behavior.
1 parent 4a411eb commit 1987f93

File tree

5 files changed

+57
-6
lines changed

5 files changed

+57
-6
lines changed

llvm/include/llvm/SandboxIR/Value.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_SANDBOXIR_VALUE_H
1010
#define LLVM_SANDBOXIR_VALUE_H
1111

12+
#include "llvm/IR/Metadata.h"
1213
#include "llvm/IR/Value.h"
1314
#include "llvm/SandboxIR/Use.h"
1415

@@ -282,6 +283,28 @@ class Value {
282283
#endif
283284
};
284285

286+
class OpaqueValue : public Value {
287+
protected:
288+
OpaqueValue(llvm::Value *V, Context &Ctx)
289+
: Value(ClassID::OpaqueValue, V, Ctx) {}
290+
friend class Context; // For constructor.
291+
292+
public:
293+
static bool classof(const Value *From) {
294+
return From->getSubclassID() == ClassID::OpaqueValue;
295+
}
296+
#ifndef NDEBUG
297+
void verify() const override {
298+
assert((isa<llvm::MetadataAsValue>(Val) || isa<llvm::InlineAsm>(Val)) &&
299+
"Expected Metadata or InlineAssembly!");
300+
}
301+
void dumpOS(raw_ostream &OS) const override {
302+
dumpCommonPrefix(OS);
303+
dumpCommonSuffix(OS);
304+
}
305+
#endif // NDEBUG
306+
};
307+
285308
} // namespace llvm::sandboxir
286309

287310
#endif // LLVM_SANDBOXIR_VALUE_H

llvm/include/llvm/SandboxIR/Values.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
DEF_CONST(Function, Function)
2323
DEF_VALUE(Argument, Argument)
24+
DEF_VALUE(OpaqueValue, OpaqueValue)
2425

2526
DEF_USER(User, User)
2627
DEF_VALUE(Block, BasicBlock)

llvm/lib/SandboxIR/BasicBlock.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,6 @@ void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
6767
// Skip instruction's label operands
6868
if (isa<llvm::BasicBlock>(Op))
6969
continue;
70-
// Skip metadata
71-
if (isa<llvm::MetadataAsValue>(Op))
72-
continue;
73-
// Skip asm
74-
if (isa<llvm::InlineAsm>(Op))
75-
continue;
7670
Ctx.getOrCreateValue(Op);
7771
}
7872
}

llvm/lib/SandboxIR/Context.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "llvm/SandboxIR/Context.h"
10+
#include "llvm/IR/InlineAsm.h"
1011
#include "llvm/SandboxIR/Function.h"
1112
#include "llvm/SandboxIR/Instruction.h"
1213
#include "llvm/SandboxIR/Module.h"
@@ -169,6 +170,15 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
169170
return SBBB;
170171
return nullptr;
171172
}
173+
// TODO: Move these checks after more common Values, like after Instruction.
174+
if (auto *MD = dyn_cast<llvm::MetadataAsValue>(LLVMV)) {
175+
It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(MD, *this));
176+
return It->second.get();
177+
}
178+
if (auto *Asm = dyn_cast<llvm::InlineAsm>(LLVMV)) {
179+
It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(Asm, *this));
180+
return It->second.get();
181+
}
172182
assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
173183

174184
switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6166,3 +6166,26 @@ define void @bar() {
61666166
// This should not crash, even though there is already a value for LLVMBar.
61676167
Ctx.createFunction(&LLVMBar);
61686168
}
6169+
6170+
TEST_F(SandboxIRTest, OpaqueValue) {
6171+
parseIR(C, R"IR(
6172+
declare void @bar(metadata)
6173+
define void @foo() {
6174+
call void @bar(metadata !1)
6175+
call void asm "asm", ""()
6176+
ret void
6177+
}
6178+
!1 = !{}
6179+
)IR");
6180+
Function &LLVMFoo = *M->getFunction("foo");
6181+
sandboxir::Context Ctx(C);
6182+
auto *F = Ctx.createFunction(&LLVMFoo);
6183+
auto *BB = &*F->begin();
6184+
auto It = BB->begin();
6185+
auto *Call = cast<sandboxir::CallInst>(&*It++);
6186+
auto *Op0 = Call->getOperand(0);
6187+
EXPECT_TRUE(isa<sandboxir::OpaqueValue>(Op0));
6188+
auto *Asm = cast<sandboxir::CallInst>(&*It++);
6189+
auto *AsmOp0 = Asm->getOperand(0);
6190+
EXPECT_TRUE(isa<sandboxir::OpaqueValue>(AsmOp0));
6191+
}

0 commit comments

Comments
 (0)