Skip to content

Commit 74c0ab6

Browse files
authored
[SandboxIR] Implement NoCFIValue (#109046)
This patch implements sandboxir::NoCFIValue mirroring llvm::NoCFIValue.
1 parent 104b249 commit 74c0ab6

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

llvm/include/llvm/SandboxIR/SandboxIR.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class GlobalObject;
133133
class GlobalIFunc;
134134
class GlobalVariable;
135135
class GlobalAlias;
136+
class NoCFIValue;
136137
class Context;
137138
class Function;
138139
class Instruction;
@@ -340,6 +341,7 @@ class Value {
340341
friend class GlobalIFunc; // For `Val`.
341342
friend class GlobalVariable; // For `Val`.
342343
friend class GlobalAlias; // For `Val`.
344+
friend class NoCFIValue; // For `Val`.
343345

344346
/// All values point to the context.
345347
Context &Ctx;
@@ -1564,6 +1566,43 @@ class GlobalAlias final
15641566
}
15651567
};
15661568

1569+
class NoCFIValue final : public Constant {
1570+
NoCFIValue(llvm::NoCFIValue *C, Context &Ctx)
1571+
: Constant(ClassID::NoCFIValue, C, Ctx) {}
1572+
friend class Context; // For constructor.
1573+
1574+
Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
1575+
return getOperandUseDefault(OpIdx, Verify);
1576+
}
1577+
1578+
public:
1579+
/// Return a NoCFIValue for the specified function.
1580+
static NoCFIValue *get(GlobalValue *GV);
1581+
1582+
GlobalValue *getGlobalValue() const;
1583+
1584+
/// NoCFIValue is always a pointer.
1585+
PointerType *getType() const;
1586+
/// For isa/dyn_cast.
1587+
static bool classof(const sandboxir::Value *From) {
1588+
return From->getSubclassID() == ClassID::NoCFIValue;
1589+
}
1590+
1591+
unsigned getUseOperandNo(const Use &Use) const final {
1592+
return getUseOperandNoDefault(Use);
1593+
}
1594+
1595+
#ifndef NDEBUG
1596+
void verify() const override {
1597+
assert(isa<llvm::NoCFIValue>(Val) && "Expected a NoCFIValue!");
1598+
}
1599+
void dumpOS(raw_ostream &OS) const override {
1600+
dumpCommonPrefix(OS);
1601+
dumpCommonSuffix(OS);
1602+
}
1603+
#endif
1604+
};
1605+
15671606
class BlockAddress final : public Constant {
15681607
BlockAddress(llvm::BlockAddress *C, Context &Ctx)
15691608
: Constant(ClassID::BlockAddress, C, Ctx) {}

llvm/include/llvm/SandboxIR/SandboxIRValues.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ DEF_CONST(GlobalVariable, GlobalVariable)
3838
DEF_CONST(GlobalIFunc, GlobalIFunc)
3939
DEF_CONST(GlobalAlias, GlobalAlias)
4040
DEF_CONST(BlockAddress, BlockAddress)
41+
DEF_CONST(NoCFIValue, NoCFIValue)
4142
DEF_CONST(DSOLocalEquivalent, DSOLocalEquivalent)
4243
DEF_CONST(ConstantTokenNone, ConstantTokenNone)
4344

llvm/lib/SandboxIR/SandboxIR.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,6 +2626,20 @@ void GlobalValue::setVisibility(VisibilityTypes V) {
26262626
cast<llvm::GlobalValue>(Val)->setVisibility(V);
26272627
}
26282628

2629+
NoCFIValue *NoCFIValue::get(GlobalValue *GV) {
2630+
auto *LLVMC = llvm::NoCFIValue::get(cast<llvm::GlobalValue>(GV->Val));
2631+
return cast<NoCFIValue>(GV->getContext().getOrCreateConstant(LLVMC));
2632+
}
2633+
2634+
GlobalValue *NoCFIValue::getGlobalValue() const {
2635+
auto *LLVMC = cast<llvm::NoCFIValue>(Val)->getGlobalValue();
2636+
return cast<GlobalValue>(Ctx.getOrCreateConstant(LLVMC));
2637+
}
2638+
2639+
PointerType *NoCFIValue::getType() const {
2640+
return cast<PointerType>(Ctx.getType(cast<llvm::NoCFIValue>(Val)->getType()));
2641+
}
2642+
26292643
BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
26302644
auto *LLVMC = llvm::BlockAddress::get(cast<llvm::Function>(F->Val),
26312645
cast<llvm::BasicBlock>(BB->Val));
@@ -2832,6 +2846,10 @@ Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
28322846
It->second = std::unique_ptr<GlobalAlias>(
28332847
new GlobalAlias(cast<llvm::GlobalAlias>(C), *this));
28342848
break;
2849+
case llvm::Value::NoCFIValueVal:
2850+
It->second = std::unique_ptr<NoCFIValue>(
2851+
new NoCFIValue(cast<llvm::NoCFIValue>(C), *this));
2852+
break;
28352853
default:
28362854
It->second = std::unique_ptr<Constant>(new Constant(C, *this));
28372855
break;

llvm/unittests/SandboxIR/SandboxIRTest.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,31 @@ define void @foo() {
11171117
Ctx.getValue(LLVMAlias0->getAliaseeObject()));
11181118
}
11191119

1120+
TEST_F(SandboxIRTest, NoCFIValue) {
1121+
parseIR(C, R"IR(
1122+
define void @foo() {
1123+
call void no_cfi @foo()
1124+
ret void
1125+
}
1126+
)IR");
1127+
Function &LLVMF = *M->getFunction("foo");
1128+
sandboxir::Context Ctx(C);
1129+
1130+
auto &F = *Ctx.createFunction(&LLVMF);
1131+
auto *BB = &*F.begin();
1132+
auto It = BB->begin();
1133+
auto *Call = cast<sandboxir::CallInst>(&*It++);
1134+
// Check classof(), creation.
1135+
auto *NoCFI = cast<sandboxir::NoCFIValue>(Call->getCalledOperand());
1136+
// Check get().
1137+
auto *NewNoCFI = sandboxir::NoCFIValue::get(&F);
1138+
EXPECT_EQ(NewNoCFI, NoCFI);
1139+
// Check getGlobalValue().
1140+
EXPECT_EQ(NoCFI->getGlobalValue(), &F);
1141+
// Check getType().
1142+
EXPECT_EQ(NoCFI->getType(), F.getType());
1143+
}
1144+
11201145
TEST_F(SandboxIRTest, BlockAddress) {
11211146
parseIR(C, R"IR(
11221147
define void @foo(ptr %ptr) {

0 commit comments

Comments
 (0)