148 lines · cpp
1//===----- AbstractCallSiteTest.cpp - AbstractCallSite Unittests ----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/IR/AbstractCallSite.h"10#include "llvm/AsmParser/Parser.h"11#include "llvm/IR/Argument.h"12#include "llvm/IR/Function.h"13#include "llvm/IR/Module.h"14#include "llvm/Support/SourceMgr.h"15#include "gtest/gtest.h"16 17using namespace llvm;18 19static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {20 SMDiagnostic Err;21 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);22 if (!Mod)23 Err.print("AbstractCallSiteTests", errs());24 return Mod;25}26 27TEST(AbstractCallSite, CallbackCall) {28 LLVMContext C;29 30 const char *IR =31 "define void @callback(i8* %X, i32* %A) {\n"32 " ret void\n"33 "}\n"34 "define void @foo(i32* %A) {\n"35 " call void (i32, void (i8*, ...)*, ...) @broker(i32 1, void (i8*, ...)* bitcast (void (i8*, i32*)* @callback to void (i8*, ...)*), i32* %A)\n"36 " ret void\n"37 "}\n"38 "declare !callback !0 void @broker(i32, void (i8*, ...)*, ...)\n"39 "!0 = !{!1}\n"40 "!1 = !{i64 1, i64 -1, i1 true}";41 42 std::unique_ptr<Module> M = parseIR(C, IR);43 ASSERT_TRUE(M);44 45 Function *Callback = M->getFunction("callback");46 ASSERT_NE(Callback, nullptr);47 48 const Use *CallbackUse = Callback->getSingleUndroppableUse();49 ASSERT_NE(CallbackUse, nullptr);50 51 AbstractCallSite ACS(CallbackUse);52 EXPECT_TRUE(ACS);53 EXPECT_TRUE(ACS.isCallbackCall());54 EXPECT_TRUE(ACS.isCallee(CallbackUse));55 EXPECT_EQ(ACS.getCalleeUseForCallback(), *CallbackUse);56 EXPECT_EQ(ACS.getCalledFunction(), Callback);57 58 // The callback metadata {CallbackNo, Arg0No, ..., isVarArg} = {1, -1, true}59 EXPECT_EQ(ACS.getCallArgOperandNoForCallee(), 1);60 // Though the callback metadata only specifies ONE unfixed argument No, the61 // callback callee is vararg, hence the third arg is also considered as62 // another arg for the callback.63 EXPECT_EQ(ACS.getNumArgOperands(), 2u);64 Argument *Param0 = Callback->getArg(0), *Param1 = Callback->getArg(1);65 ASSERT_TRUE(Param0 && Param1);66 EXPECT_EQ(ACS.getCallArgOperandNo(*Param0), -1);67 EXPECT_EQ(ACS.getCallArgOperandNo(*Param1), 2);68}69 70TEST(AbstractCallSite, DirectCall) {71 LLVMContext C;72 73 const char *IR = "declare void @bar(i32 %x, i32 %y)\n"74 "define void @foo() {\n"75 " call void @bar(i32 1, i32 2)\n"76 " ret void\n"77 "}\n";78 79 std::unique_ptr<Module> M = parseIR(C, IR);80 ASSERT_TRUE(M);81 82 Function *Callee = M->getFunction("bar");83 ASSERT_NE(Callee, nullptr);84 85 const Use *DirectCallUse = Callee->getSingleUndroppableUse();86 ASSERT_NE(DirectCallUse, nullptr);87 88 AbstractCallSite ACS(DirectCallUse);89 EXPECT_TRUE(ACS);90 EXPECT_TRUE(ACS.isDirectCall());91 EXPECT_TRUE(ACS.isCallee(DirectCallUse));92 EXPECT_EQ(ACS.getCalledFunction(), Callee);93 EXPECT_EQ(ACS.getNumArgOperands(), 2u);94 Argument *ArgX = Callee->getArg(0);95 ASSERT_NE(ArgX, nullptr);96 Value *CAO1 = ACS.getCallArgOperand(*ArgX);97 Value *CAO2 = ACS.getCallArgOperand(0);98 ASSERT_NE(CAO2, nullptr);99 // The two call arg operands should be the same object, since they are both100 // the first argument of the call.101 EXPECT_EQ(CAO2, CAO1);102 103 ConstantInt *FirstArgInt = dyn_cast<ConstantInt>(CAO2);104 ASSERT_NE(FirstArgInt, nullptr);105 EXPECT_EQ(FirstArgInt->getZExtValue(), 1ull);106 107 EXPECT_EQ(ACS.getCallArgOperandNo(*ArgX), 0);108 EXPECT_EQ(ACS.getCallArgOperandNo(0), 0);109 EXPECT_EQ(ACS.getCallArgOperandNo(1), 1);110}111 112TEST(AbstractCallSite, IndirectCall) {113 LLVMContext C;114 115 const char *IR = "define void @foo(ptr %0) {\n"116 " call void %0(i32 1, i32 2)\n"117 " ret void\n"118 "}\n";119 120 std::unique_ptr<Module> M = parseIR(C, IR);121 ASSERT_TRUE(M);122 123 Function *Fun = M->getFunction("foo");124 ASSERT_NE(Fun, nullptr);125 126 Argument *ArgAsCallee = Fun->getArg(0);127 ASSERT_NE(ArgAsCallee, nullptr);128 129 const Use *IndCallUse = ArgAsCallee->getSingleUndroppableUse();130 ASSERT_NE(IndCallUse, nullptr);131 132 AbstractCallSite ACS(IndCallUse);133 EXPECT_TRUE(ACS);134 EXPECT_TRUE(ACS.isIndirectCall());135 EXPECT_TRUE(ACS.isCallee(IndCallUse));136 EXPECT_EQ(ACS.getCalledFunction(), nullptr);137 EXPECT_EQ(ACS.getCalledOperand(), ArgAsCallee);138 EXPECT_EQ(ACS.getNumArgOperands(), 2u);139 Value *CalledOperand = ACS.getCallArgOperand(0);140 ASSERT_NE(CalledOperand, nullptr);141 ConstantInt *FirstArgInt = dyn_cast<ConstantInt>(CalledOperand);142 ASSERT_NE(FirstArgInt, nullptr);143 EXPECT_EQ(FirstArgInt->getZExtValue(), 1ull);144 145 EXPECT_EQ(ACS.getCallArgOperandNo(0), 0);146 EXPECT_EQ(ACS.getCallArgOperandNo(1), 1);147}148