Skip to content

Commit ca713e4

Browse files
committed
[AbstractCallSite] Handle Indirect Calls Properly
1 parent b0b4a8e commit ca713e4

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

llvm/include/llvm/IR/AbstractCallSite.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class AbstractCallSite {
137137

138138
/// Return true if @p U is the use that defines the callee of this ACS.
139139
bool isCallee(const Use *U) const {
140-
if (isDirectCall())
140+
if (!isCallbackCall())
141141
return CB->isCallee(U);
142142

143143
assert(!CI.ParameterEncoding.empty() &&
@@ -154,7 +154,7 @@ class AbstractCallSite {
154154

155155
/// Return the number of parameters of the callee.
156156
unsigned getNumArgOperands() const {
157-
if (isDirectCall())
157+
if (!isCallbackCall())
158158
return CB->arg_size();
159159
// Subtract 1 for the callee encoding.
160160
return CI.ParameterEncoding.size() - 1;
@@ -169,7 +169,7 @@ class AbstractCallSite {
169169
/// Return the operand index of the underlying instruction associated with
170170
/// the function parameter number @p ArgNo or -1 if there is none.
171171
int getCallArgOperandNo(unsigned ArgNo) const {
172-
if (isDirectCall())
172+
if (!isCallbackCall())
173173
return ArgNo;
174174
// Add 1 for the callee encoding.
175175
return CI.ParameterEncoding[ArgNo + 1];
@@ -183,7 +183,7 @@ class AbstractCallSite {
183183
/// Return the operand of the underlying instruction associated with the
184184
/// function parameter number @p ArgNo or nullptr if there is none.
185185
Value *getCallArgOperand(unsigned ArgNo) const {
186-
if (isDirectCall())
186+
if (!isCallbackCall())
187187
return CB->getArgOperand(ArgNo);
188188
// Add 1 for the callee encoding.
189189
return CI.ParameterEncoding[ArgNo + 1] >= 0
@@ -210,7 +210,7 @@ class AbstractCallSite {
210210

211211
/// Return the pointer to function that is being called.
212212
Value *getCalledOperand() const {
213-
if (isDirectCall())
213+
if (!isCallbackCall())
214214
return CB->getCalledOperand();
215215
return CB->getArgOperand(getCallArgOperandNoForCallee());
216216
}

llvm/unittests/IR/AbstractCallSiteTest.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,56 @@ TEST(AbstractCallSite, CallbackCall) {
5353
EXPECT_TRUE(ACS.isCallee(CallbackUse));
5454
EXPECT_EQ(ACS.getCalledFunction(), Callback);
5555
}
56+
57+
TEST(AbstractCallSite, DirectCall) {
58+
LLVMContext C;
59+
60+
const char *IR = "declare void @bar()\n"
61+
"define void @foo() {\n"
62+
" call void @bar()\n"
63+
" ret void\n"
64+
"}\n";
65+
66+
std::unique_ptr<Module> M = parseIR(C, IR);
67+
ASSERT_TRUE(M);
68+
69+
Function *Callee = M->getFunction("bar");
70+
ASSERT_NE(Callee, nullptr);
71+
72+
const Use *DirectCallUse = Callee->getSingleUndroppableUse();
73+
ASSERT_NE(DirectCallUse, nullptr);
74+
75+
AbstractCallSite ACS(DirectCallUse);
76+
EXPECT_TRUE(ACS);
77+
EXPECT_TRUE(ACS.isDirectCall());
78+
EXPECT_TRUE(ACS.isCallee(DirectCallUse));
79+
EXPECT_EQ(ACS.getCalledFunction(), Callee);
80+
}
81+
82+
TEST(AbstractCallSite, IndirectCall) {
83+
LLVMContext C;
84+
85+
const char *IR = "define void @foo(ptr %0) {\n"
86+
" call void %0()\n"
87+
" ret void\n"
88+
"}\n";
89+
90+
std::unique_ptr<Module> M = parseIR(C, IR);
91+
ASSERT_TRUE(M);
92+
93+
Function *Fun = M->getFunction("foo");
94+
ASSERT_NE(Fun, nullptr);
95+
96+
Argument *ArgAsCallee = Fun->getArg(0);
97+
ASSERT_NE(ArgAsCallee, nullptr);
98+
99+
const Use *IndCallUse = ArgAsCallee->getSingleUndroppableUse();
100+
ASSERT_NE(IndCallUse, nullptr);
101+
102+
AbstractCallSite ACS(IndCallUse);
103+
EXPECT_TRUE(ACS);
104+
EXPECT_TRUE(ACS.isIndirectCall());
105+
EXPECT_TRUE(ACS.isCallee(IndCallUse));
106+
EXPECT_EQ(ACS.getCalledFunction(), nullptr);
107+
EXPECT_EQ(ACS.getCalledOperand(), ArgAsCallee);
108+
}

0 commit comments

Comments
 (0)