1bdfc9846SDuncan P. N. Exon Smith //===- FunctionTest.cpp - Function unit tests -----------------------------===//
2bdfc9846SDuncan P. N. Exon Smith //
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
6bdfc9846SDuncan P. N. Exon Smith //
7bdfc9846SDuncan P. N. Exon Smith //===----------------------------------------------------------------------===//
8bdfc9846SDuncan P. N. Exon Smith
9bdfc9846SDuncan P. N. Exon Smith #include "llvm/IR/Function.h"
105e1e5918SKeno Fischer #include "llvm/IR/Module.h"
11bdfc9846SDuncan P. N. Exon Smith #include "gtest/gtest.h"
12bdfc9846SDuncan P. N. Exon Smith using namespace llvm;
13bdfc9846SDuncan P. N. Exon Smith
14bdfc9846SDuncan P. N. Exon Smith namespace {
15bdfc9846SDuncan P. N. Exon Smith
TEST(FunctionTest,hasLazyArguments)16bdfc9846SDuncan P. N. Exon Smith TEST(FunctionTest, hasLazyArguments) {
17bdfc9846SDuncan P. N. Exon Smith LLVMContext C;
18bdfc9846SDuncan P. N. Exon Smith
19bdfc9846SDuncan P. N. Exon Smith Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
20bdfc9846SDuncan P. N. Exon Smith FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
21bdfc9846SDuncan P. N. Exon Smith
22bdfc9846SDuncan P. N. Exon Smith // Functions start out with lazy arguments.
23bdfc9846SDuncan P. N. Exon Smith std::unique_ptr<Function> F(
24bdfc9846SDuncan P. N. Exon Smith Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
25bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F->hasLazyArguments());
26bdfc9846SDuncan P. N. Exon Smith
27bdfc9846SDuncan P. N. Exon Smith // Checking for empty or size shouldn't force arguments to be instantiated.
28bdfc9846SDuncan P. N. Exon Smith EXPECT_FALSE(F->arg_empty());
29bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F->hasLazyArguments());
30bdfc9846SDuncan P. N. Exon Smith EXPECT_EQ(2u, F->arg_size());
31bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F->hasLazyArguments());
32bdfc9846SDuncan P. N. Exon Smith
33bdfc9846SDuncan P. N. Exon Smith // The argument list should be populated at first access.
34bdfc9846SDuncan P. N. Exon Smith (void)F->arg_begin();
35bdfc9846SDuncan P. N. Exon Smith EXPECT_FALSE(F->hasLazyArguments());
3601dcdcddSTeresa Johnson
3701dcdcddSTeresa Johnson // Checking that getArg gets the arguments from F1 in the correct order.
3801dcdcddSTeresa Johnson unsigned i = 0;
3901dcdcddSTeresa Johnson for (Argument &A : F->args()) {
4001dcdcddSTeresa Johnson EXPECT_EQ(&A, F->getArg(i));
4101dcdcddSTeresa Johnson ++i;
4201dcdcddSTeresa Johnson }
4301dcdcddSTeresa Johnson EXPECT_FALSE(F->hasLazyArguments());
44bdfc9846SDuncan P. N. Exon Smith }
45bdfc9846SDuncan P. N. Exon Smith
TEST(FunctionTest,stealArgumentListFrom)46bdfc9846SDuncan P. N. Exon Smith TEST(FunctionTest, stealArgumentListFrom) {
47bdfc9846SDuncan P. N. Exon Smith LLVMContext C;
48bdfc9846SDuncan P. N. Exon Smith
49bdfc9846SDuncan P. N. Exon Smith Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
50bdfc9846SDuncan P. N. Exon Smith FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
51bdfc9846SDuncan P. N. Exon Smith std::unique_ptr<Function> F1(
52bdfc9846SDuncan P. N. Exon Smith Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
53bdfc9846SDuncan P. N. Exon Smith std::unique_ptr<Function> F2(
54bdfc9846SDuncan P. N. Exon Smith Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
55bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F1->hasLazyArguments());
56bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F2->hasLazyArguments());
57bdfc9846SDuncan P. N. Exon Smith
58bdfc9846SDuncan P. N. Exon Smith // Steal arguments before they've been accessed. Nothing should change; both
59bdfc9846SDuncan P. N. Exon Smith // functions should still have lazy arguments.
60bdfc9846SDuncan P. N. Exon Smith //
61bdfc9846SDuncan P. N. Exon Smith // steal(empty); drop (empty)
62bdfc9846SDuncan P. N. Exon Smith F1->stealArgumentListFrom(*F2);
63bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F1->hasLazyArguments());
64bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F2->hasLazyArguments());
65bdfc9846SDuncan P. N. Exon Smith
66bdfc9846SDuncan P. N. Exon Smith // Save arguments from F1 for later assertions. F1 won't have lazy arguments
67bdfc9846SDuncan P. N. Exon Smith // anymore.
68bdfc9846SDuncan P. N. Exon Smith SmallVector<Argument *, 4> Args;
69bdfc9846SDuncan P. N. Exon Smith for (Argument &A : F1->args())
70bdfc9846SDuncan P. N. Exon Smith Args.push_back(&A);
71bdfc9846SDuncan P. N. Exon Smith EXPECT_EQ(2u, Args.size());
72bdfc9846SDuncan P. N. Exon Smith EXPECT_FALSE(F1->hasLazyArguments());
73bdfc9846SDuncan P. N. Exon Smith
74bdfc9846SDuncan P. N. Exon Smith // Steal arguments from F1 to F2. F1's arguments should be lazy again.
75bdfc9846SDuncan P. N. Exon Smith //
76bdfc9846SDuncan P. N. Exon Smith // steal(real); drop (empty)
77bdfc9846SDuncan P. N. Exon Smith F2->stealArgumentListFrom(*F1);
78bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F1->hasLazyArguments());
79bdfc9846SDuncan P. N. Exon Smith EXPECT_FALSE(F2->hasLazyArguments());
80bdfc9846SDuncan P. N. Exon Smith unsigned I = 0;
81ab4622cbSJustin Lebar for (Argument &A : F2->args()) {
82ab4622cbSJustin Lebar EXPECT_EQ(Args[I], &A);
83ab4622cbSJustin Lebar I++;
84ab4622cbSJustin Lebar }
85bdfc9846SDuncan P. N. Exon Smith EXPECT_EQ(2u, I);
86bdfc9846SDuncan P. N. Exon Smith
87bdfc9846SDuncan P. N. Exon Smith // Check that arguments in F1 don't have pointer equality with the saved ones.
88bdfc9846SDuncan P. N. Exon Smith // This also instantiates F1's arguments.
89bdfc9846SDuncan P. N. Exon Smith I = 0;
90ab4622cbSJustin Lebar for (Argument &A : F1->args()) {
91ab4622cbSJustin Lebar EXPECT_NE(Args[I], &A);
92ab4622cbSJustin Lebar I++;
93ab4622cbSJustin Lebar }
94bdfc9846SDuncan P. N. Exon Smith EXPECT_EQ(2u, I);
95bdfc9846SDuncan P. N. Exon Smith EXPECT_FALSE(F1->hasLazyArguments());
96bdfc9846SDuncan P. N. Exon Smith EXPECT_FALSE(F2->hasLazyArguments());
97bdfc9846SDuncan P. N. Exon Smith
98bdfc9846SDuncan P. N. Exon Smith // Steal back from F2. F2's arguments should be lazy again.
99bdfc9846SDuncan P. N. Exon Smith //
100bdfc9846SDuncan P. N. Exon Smith // steal(real); drop (real)
101bdfc9846SDuncan P. N. Exon Smith F1->stealArgumentListFrom(*F2);
102bdfc9846SDuncan P. N. Exon Smith EXPECT_FALSE(F1->hasLazyArguments());
103bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F2->hasLazyArguments());
104bdfc9846SDuncan P. N. Exon Smith I = 0;
105ab4622cbSJustin Lebar for (Argument &A : F1->args()) {
106ab4622cbSJustin Lebar EXPECT_EQ(Args[I], &A);
107ab4622cbSJustin Lebar I++;
108ab4622cbSJustin Lebar }
109bdfc9846SDuncan P. N. Exon Smith EXPECT_EQ(2u, I);
110bdfc9846SDuncan P. N. Exon Smith
111bdfc9846SDuncan P. N. Exon Smith // Steal from F2 a second time. Now both functions should have lazy
112bdfc9846SDuncan P. N. Exon Smith // arguments.
113bdfc9846SDuncan P. N. Exon Smith //
114bdfc9846SDuncan P. N. Exon Smith // steal(empty); drop (real)
115bdfc9846SDuncan P. N. Exon Smith F1->stealArgumentListFrom(*F2);
116bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F1->hasLazyArguments());
117bdfc9846SDuncan P. N. Exon Smith EXPECT_TRUE(F2->hasLazyArguments());
118bdfc9846SDuncan P. N. Exon Smith }
119bdfc9846SDuncan P. N. Exon Smith
1205e1e5918SKeno Fischer // Test setting and removing section information
TEST(FunctionTest,setSection)1215e1e5918SKeno Fischer TEST(FunctionTest, setSection) {
1225e1e5918SKeno Fischer LLVMContext C;
1235e1e5918SKeno Fischer Module M("test", C);
1245e1e5918SKeno Fischer
1255e1e5918SKeno Fischer llvm::Function *F =
1265e1e5918SKeno Fischer Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C), false),
1275e1e5918SKeno Fischer llvm::GlobalValue::ExternalLinkage, "F", &M);
1285e1e5918SKeno Fischer
1295e1e5918SKeno Fischer F->setSection(".text.test");
1305e1e5918SKeno Fischer EXPECT_TRUE(F->getSection() == ".text.test");
1315e1e5918SKeno Fischer EXPECT_TRUE(F->hasSection());
1325e1e5918SKeno Fischer F->setSection("");
1335e1e5918SKeno Fischer EXPECT_FALSE(F->hasSection());
1345e1e5918SKeno Fischer F->setSection(".text.test");
1355e1e5918SKeno Fischer F->setSection(".text.test2");
1365e1e5918SKeno Fischer EXPECT_TRUE(F->getSection() == ".text.test2");
1375e1e5918SKeno Fischer EXPECT_TRUE(F->hasSection());
1385e1e5918SKeno Fischer }
1395e1e5918SKeno Fischer
TEST(FunctionTest,GetPointerAlignment)140308e82ecSMichael Platings TEST(FunctionTest, GetPointerAlignment) {
141308e82ecSMichael Platings LLVMContext Context;
142308e82ecSMichael Platings Type *VoidType(Type::getVoidTy(Context));
143308e82ecSMichael Platings FunctionType *FuncType(FunctionType::get(VoidType, false));
144308e82ecSMichael Platings std::unique_ptr<Function> Func(Function::Create(
145308e82ecSMichael Platings FuncType, GlobalValue::ExternalLinkage));
146*f26bdb53SEli Friedman EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("")));
147bae629b9SGuillaume Chatelet EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fi8")));
148bae629b9SGuillaume Chatelet EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fn8")));
149bae629b9SGuillaume Chatelet EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fi16")));
150bae629b9SGuillaume Chatelet EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fn16")));
151bae629b9SGuillaume Chatelet EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fi32")));
152bae629b9SGuillaume Chatelet EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn32")));
153308e82ecSMichael Platings
1540e62011dSGuillaume Chatelet Func->setAlignment(Align(4));
155308e82ecSMichael Platings
156*f26bdb53SEli Friedman EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("")));
157bae629b9SGuillaume Chatelet EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fi8")));
158bae629b9SGuillaume Chatelet EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn8")));
159bae629b9SGuillaume Chatelet EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fi16")));
160bae629b9SGuillaume Chatelet EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn16")));
161bae629b9SGuillaume Chatelet EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fi32")));
162bae629b9SGuillaume Chatelet EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn32")));
163308e82ecSMichael Platings }
164308e82ecSMichael Platings
165bdfc9846SDuncan P. N. Exon Smith } // end namespace
166