[llvm] [SandboxIR] OpaqueValue (PR #127699)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 18 13:41:42 PST 2025
https://github.com/vporpo created https://github.com/llvm/llvm-project/pull/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.
>From b8e2d0d1e16afae7331b0efc817c0fca44367186 Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Fri, 14 Feb 2025 15:20:48 -0800
Subject: [PATCH] [SandboxIR] OpaqueValue
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.
---
llvm/include/llvm/SandboxIR/Value.h | 23 ++++++++++++++++++++++
llvm/include/llvm/SandboxIR/Values.def | 1 +
llvm/lib/SandboxIR/BasicBlock.cpp | 6 ------
llvm/lib/SandboxIR/Context.cpp | 10 ++++++++++
llvm/unittests/SandboxIR/SandboxIRTest.cpp | 23 ++++++++++++++++++++++
5 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/llvm/include/llvm/SandboxIR/Value.h b/llvm/include/llvm/SandboxIR/Value.h
index 28e33ca0f2312..2e91b96bb22e6 100644
--- a/llvm/include/llvm/SandboxIR/Value.h
+++ b/llvm/include/llvm/SandboxIR/Value.h
@@ -9,6 +9,7 @@
#ifndef LLVM_SANDBOXIR_VALUE_H
#define LLVM_SANDBOXIR_VALUE_H
+#include "llvm/IR/Metadata.h"
#include "llvm/IR/Value.h"
#include "llvm/SandboxIR/Use.h"
@@ -282,6 +283,28 @@ class Value {
#endif
};
+class OpaqueValue : public Value {
+protected:
+ OpaqueValue(llvm::Value *V, Context &Ctx)
+ : Value(ClassID::OpaqueValue, V, Ctx) {}
+ friend class Context; // For constructor.
+
+public:
+ static bool classof(const Value *From) {
+ return From->getSubclassID() == ClassID::OpaqueValue;
+ }
+#ifndef NDEBUG
+ void verify() const override {
+ assert((isa<llvm::MetadataAsValue>(Val) || isa<llvm::InlineAsm>(Val)) &&
+ "Expected Metadata or InlineAssembly!");
+ }
+ void dumpOS(raw_ostream &OS) const override {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+ }
+#endif // NDEBUG
+};
+
} // namespace llvm::sandboxir
#endif // LLVM_SANDBOXIR_VALUE_H
diff --git a/llvm/include/llvm/SandboxIR/Values.def b/llvm/include/llvm/SandboxIR/Values.def
index 3d8ad6ce197f4..f5ead54a08e10 100644
--- a/llvm/include/llvm/SandboxIR/Values.def
+++ b/llvm/include/llvm/SandboxIR/Values.def
@@ -21,6 +21,7 @@
DEF_CONST(Function, Function)
DEF_VALUE(Argument, Argument)
+DEF_VALUE(OpaqueValue, OpaqueValue)
DEF_USER(User, User)
DEF_VALUE(Block, BasicBlock)
diff --git a/llvm/lib/SandboxIR/BasicBlock.cpp b/llvm/lib/SandboxIR/BasicBlock.cpp
index 983a5e8b8825e..b45c046402487 100644
--- a/llvm/lib/SandboxIR/BasicBlock.cpp
+++ b/llvm/lib/SandboxIR/BasicBlock.cpp
@@ -67,12 +67,6 @@ void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
// Skip instruction's label operands
if (isa<llvm::BasicBlock>(Op))
continue;
- // Skip metadata
- if (isa<llvm::MetadataAsValue>(Op))
- continue;
- // Skip asm
- if (isa<llvm::InlineAsm>(Op))
- continue;
Ctx.getOrCreateValue(Op);
}
}
diff --git a/llvm/lib/SandboxIR/Context.cpp b/llvm/lib/SandboxIR/Context.cpp
index 6a397b02d6bde..38ca60cfac3ec 100644
--- a/llvm/lib/SandboxIR/Context.cpp
+++ b/llvm/lib/SandboxIR/Context.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/SandboxIR/Context.h"
+#include "llvm/IR/InlineAsm.h"
#include "llvm/SandboxIR/Function.h"
#include "llvm/SandboxIR/Instruction.h"
#include "llvm/SandboxIR/Module.h"
@@ -169,6 +170,15 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
return SBBB;
return nullptr;
}
+ // TODO: Move these checks after more common Values, like after Instruction.
+ if (auto *MD = dyn_cast<llvm::MetadataAsValue>(LLVMV)) {
+ It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(MD, *this));
+ return It->second.get();
+ }
+ if (auto *Asm = dyn_cast<llvm::InlineAsm>(LLVMV)) {
+ It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(Asm, *this));
+ return It->second.get();
+ }
assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
index 2ad33659c609b..088264e0429fd 100644
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -6166,3 +6166,26 @@ define void @bar() {
// This should not crash, even though there is already a value for LLVMBar.
Ctx.createFunction(&LLVMBar);
}
+
+TEST_F(SandboxIRTest, OpaqueValue) {
+ parseIR(C, R"IR(
+declare void @bar(metadata)
+define void @foo() {
+ call void @bar(metadata !1)
+ call void asm "asm", ""()
+ ret void
+}
+!1 = !{}
+)IR");
+ Function &LLVMFoo = *M->getFunction("foo");
+ sandboxir::Context Ctx(C);
+ auto *F = Ctx.createFunction(&LLVMFoo);
+ auto *BB = &*F->begin();
+ auto It = BB->begin();
+ auto *Call = cast<sandboxir::CallInst>(&*It++);
+ auto *Op0 = Call->getOperand(0);
+ EXPECT_TRUE(isa<sandboxir::OpaqueValue>(Op0));
+ auto *Asm = cast<sandboxir::CallInst>(&*It++);
+ auto *AsmOp0 = Asm->getOperand(0);
+ EXPECT_TRUE(isa<sandboxir::OpaqueValue>(AsmOp0));
+}
More information about the llvm-commits
mailing list