1dc4260dbSLang Hames //===- LazyEmittingLayerTest.cpp - Unit tests for the lazy emitting layer -===//
2dc4260dbSLang Hames //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6dc4260dbSLang Hames //
7dc4260dbSLang Hames //===----------------------------------------------------------------------===//
8dc4260dbSLang Hames
99a67b073SChandler Carruth #include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
10dc4260dbSLang Hames #include "OrcTestCommon.h"
11dc4260dbSLang Hames #include "llvm/ADT/SmallVector.h"
12dc4260dbSLang Hames #include "gtest/gtest.h"
13dc4260dbSLang Hames
14dc4260dbSLang Hames using namespace llvm;
15dc4260dbSLang Hames
16dc4260dbSLang Hames namespace {
17dc4260dbSLang Hames
TEST(IndirectionUtilsTest,MakeStub)18dc4260dbSLang Hames TEST(IndirectionUtilsTest, MakeStub) {
1903b42e41SMehdi Amini LLVMContext Context;
2003b42e41SMehdi Amini ModuleBuilder MB(Context, "x86_64-apple-macosx10.10", "");
21a7f183afSNikita Popov StructType *ArgTy = getDummyStructTy(Context);
22a7f183afSNikita Popov Type *ArgPtrTy = PointerType::getUnqual(ArgTy);
23c0044118SJames Y Knight FunctionType *FTy = FunctionType::get(
24a7f183afSNikita Popov Type::getVoidTy(Context), {ArgPtrTy, ArgPtrTy}, false);
25c0044118SJames Y Knight Function *F = MB.createFunctionDecl(FTy, "");
26a0b45f4bSReid Kleckner AttributeSet FnAttrs = AttributeSet::get(
27*d2cc6c2dSSerge Guelton Context, AttrBuilder(Context).addAttribute(Attribute::NoUnwind));
28a0b45f4bSReid Kleckner AttributeSet RetAttrs; // None
29a0b45f4bSReid Kleckner AttributeSet ArgAttrs[2] = {
30*d2cc6c2dSSerge Guelton AttributeSet::get(Context, AttrBuilder(Context).addStructRetAttr(ArgTy)),
31*d2cc6c2dSSerge Guelton AttributeSet::get(Context, AttrBuilder(Context).addByValAttr(ArgTy)),
32a0b45f4bSReid Kleckner };
33a0b45f4bSReid Kleckner F->setAttributes(AttributeList::get(Context, FnAttrs, RetAttrs, ArgAttrs));
34dc4260dbSLang Hames
35dc4260dbSLang Hames auto ImplPtr = orc::createImplPointer(*F->getType(), *MB.getModule(), "", nullptr);
36dc4260dbSLang Hames orc::makeStub(*F, *ImplPtr);
37dc4260dbSLang Hames
38dc4260dbSLang Hames auto II = F->getEntryBlock().begin();
39dc4260dbSLang Hames EXPECT_TRUE(isa<LoadInst>(*II)) << "First instruction of stub should be a load.";
40dc4260dbSLang Hames auto *Call = dyn_cast<CallInst>(std::next(II));
41dc4260dbSLang Hames EXPECT_TRUE(Call != nullptr) << "Second instruction of stub should be a call.";
42dc4260dbSLang Hames EXPECT_TRUE(Call->isTailCall()) << "Indirect call from stub should be tail call.";
43dc4260dbSLang Hames EXPECT_TRUE(Call->hasStructRetAttr())
44dc4260dbSLang Hames << "makeStub should propagate sret attr on 1st argument.";
45fb502d2fSReid Kleckner EXPECT_TRUE(Call->paramHasAttr(1U, Attribute::ByVal))
46dc4260dbSLang Hames << "makeStub should propagate byval attr on 2nd argument.";
47dc4260dbSLang Hames }
48dc4260dbSLang Hames
49dc4260dbSLang Hames }
50