1 //===- FunctionTest.cpp - Function unit tests -----------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/Function.h"
10 #include "llvm/IR/Module.h"
11 #include "gtest/gtest.h"
16 TEST(FunctionTest
, hasLazyArguments
) {
19 Type
*ArgTypes
[] = {Type::getInt8Ty(C
), Type::getInt32Ty(C
)};
20 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), ArgTypes
, false);
22 // Functions start out with lazy arguments.
23 std::unique_ptr
<Function
> F(
24 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F"));
25 EXPECT_TRUE(F
->hasLazyArguments());
27 // Checking for empty or size shouldn't force arguments to be instantiated.
28 EXPECT_FALSE(F
->arg_empty());
29 EXPECT_TRUE(F
->hasLazyArguments());
30 EXPECT_EQ(2u, F
->arg_size());
31 EXPECT_TRUE(F
->hasLazyArguments());
33 // The argument list should be populated at first access.
35 EXPECT_FALSE(F
->hasLazyArguments());
37 // Checking that getArg gets the arguments from F1 in the correct order.
39 for (Argument
&A
: F
->args()) {
40 EXPECT_EQ(&A
, F
->getArg(i
));
43 EXPECT_FALSE(F
->hasLazyArguments());
46 TEST(FunctionTest
, stealArgumentListFrom
) {
49 Type
*ArgTypes
[] = {Type::getInt8Ty(C
), Type::getInt32Ty(C
)};
50 FunctionType
*FTy
= FunctionType::get(Type::getVoidTy(C
), ArgTypes
, false);
51 std::unique_ptr
<Function
> F1(
52 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F1"));
53 std::unique_ptr
<Function
> F2(
54 Function::Create(FTy
, GlobalValue::ExternalLinkage
, "F1"));
55 EXPECT_TRUE(F1
->hasLazyArguments());
56 EXPECT_TRUE(F2
->hasLazyArguments());
58 // Steal arguments before they've been accessed. Nothing should change; both
59 // functions should still have lazy arguments.
61 // steal(empty); drop (empty)
62 F1
->stealArgumentListFrom(*F2
);
63 EXPECT_TRUE(F1
->hasLazyArguments());
64 EXPECT_TRUE(F2
->hasLazyArguments());
66 // Save arguments from F1 for later assertions. F1 won't have lazy arguments
68 SmallVector
<Argument
*, 4> Args
;
69 for (Argument
&A
: F1
->args())
71 EXPECT_EQ(2u, Args
.size());
72 EXPECT_FALSE(F1
->hasLazyArguments());
74 // Steal arguments from F1 to F2. F1's arguments should be lazy again.
76 // steal(real); drop (empty)
77 F2
->stealArgumentListFrom(*F1
);
78 EXPECT_TRUE(F1
->hasLazyArguments());
79 EXPECT_FALSE(F2
->hasLazyArguments());
81 for (Argument
&A
: F2
->args()) {
82 EXPECT_EQ(Args
[I
], &A
);
87 // Check that arguments in F1 don't have pointer equality with the saved ones.
88 // This also instantiates F1's arguments.
90 for (Argument
&A
: F1
->args()) {
91 EXPECT_NE(Args
[I
], &A
);
95 EXPECT_FALSE(F1
->hasLazyArguments());
96 EXPECT_FALSE(F2
->hasLazyArguments());
98 // Steal back from F2. F2's arguments should be lazy again.
100 // steal(real); drop (real)
101 F1
->stealArgumentListFrom(*F2
);
102 EXPECT_FALSE(F1
->hasLazyArguments());
103 EXPECT_TRUE(F2
->hasLazyArguments());
105 for (Argument
&A
: F1
->args()) {
106 EXPECT_EQ(Args
[I
], &A
);
111 // Steal from F2 a second time. Now both functions should have lazy
114 // steal(empty); drop (real)
115 F1
->stealArgumentListFrom(*F2
);
116 EXPECT_TRUE(F1
->hasLazyArguments());
117 EXPECT_TRUE(F2
->hasLazyArguments());
120 // Test setting and removing section information
121 TEST(FunctionTest
, setSection
) {
126 Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C
), false),
127 llvm::GlobalValue::ExternalLinkage
, "F", &M
);
129 F
->setSection(".text.test");
130 EXPECT_TRUE(F
->getSection() == ".text.test");
131 EXPECT_TRUE(F
->hasSection());
133 EXPECT_FALSE(F
->hasSection());
134 F
->setSection(".text.test");
135 F
->setSection(".text.test2");
136 EXPECT_TRUE(F
->getSection() == ".text.test2");
137 EXPECT_TRUE(F
->hasSection());
140 TEST(FunctionTest
, GetPointerAlignment
) {
142 Type
*VoidType(Type::getVoidTy(Context
));
143 FunctionType
*FuncType(FunctionType::get(VoidType
, false));
144 std::unique_ptr
<Function
> Func(Function::Create(
145 FuncType
, GlobalValue::ExternalLinkage
));
146 EXPECT_EQ(MaybeAlign(), Func
->getPointerAlignment(DataLayout("")));
147 EXPECT_EQ(Align(1), Func
->getPointerAlignment(DataLayout("Fi8")));
148 EXPECT_EQ(Align(1), Func
->getPointerAlignment(DataLayout("Fn8")));
149 EXPECT_EQ(Align(2), Func
->getPointerAlignment(DataLayout("Fi16")));
150 EXPECT_EQ(Align(2), Func
->getPointerAlignment(DataLayout("Fn16")));
151 EXPECT_EQ(Align(4), Func
->getPointerAlignment(DataLayout("Fi32")));
152 EXPECT_EQ(Align(4), Func
->getPointerAlignment(DataLayout("Fn32")));
154 Func
->setAlignment(Align(4));
156 EXPECT_EQ(MaybeAlign(), Func
->getPointerAlignment(DataLayout("")));
157 EXPECT_EQ(Align(1), Func
->getPointerAlignment(DataLayout("Fi8")));
158 EXPECT_EQ(Align(4), Func
->getPointerAlignment(DataLayout("Fn8")));
159 EXPECT_EQ(Align(2), Func
->getPointerAlignment(DataLayout("Fi16")));
160 EXPECT_EQ(Align(4), Func
->getPointerAlignment(DataLayout("Fn16")));
161 EXPECT_EQ(Align(4), Func
->getPointerAlignment(DataLayout("Fi32")));
162 EXPECT_EQ(Align(4), Func
->getPointerAlignment(DataLayout("Fn32")));