1 //===- FunctionTest.cpp - Function unit tests -----------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "llvm/IR/Function.h" 10 #include "llvm/IR/Module.h" 11 #include "gtest/gtest.h" 12 using namespace llvm; 13 14 namespace { 15 16 TEST(FunctionTest, hasLazyArguments) { 17 LLVMContext C; 18 19 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)}; 20 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false); 21 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()); 26 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()); 32 33 // The argument list should be populated at first access. 34 (void)F->arg_begin(); 35 EXPECT_FALSE(F->hasLazyArguments()); 36 37 // Checking that getArg gets the arguments from F1 in the correct order. 38 unsigned i = 0; 39 for (Argument &A : F->args()) { 40 EXPECT_EQ(&A, F->getArg(i)); 41 ++i; 42 } 43 EXPECT_FALSE(F->hasLazyArguments()); 44 } 45 46 TEST(FunctionTest, stealArgumentListFrom) { 47 LLVMContext C; 48 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()); 57 58 // Steal arguments before they've been accessed. Nothing should change; both 59 // functions should still have lazy arguments. 60 // 61 // steal(empty); drop (empty) 62 F1->stealArgumentListFrom(*F2); 63 EXPECT_TRUE(F1->hasLazyArguments()); 64 EXPECT_TRUE(F2->hasLazyArguments()); 65 66 // Save arguments from F1 for later assertions. F1 won't have lazy arguments 67 // anymore. 68 SmallVector<Argument *, 4> Args; 69 for (Argument &A : F1->args()) 70 Args.push_back(&A); 71 EXPECT_EQ(2u, Args.size()); 72 EXPECT_FALSE(F1->hasLazyArguments()); 73 74 // Steal arguments from F1 to F2. F1's arguments should be lazy again. 75 // 76 // steal(real); drop (empty) 77 F2->stealArgumentListFrom(*F1); 78 EXPECT_TRUE(F1->hasLazyArguments()); 79 EXPECT_FALSE(F2->hasLazyArguments()); 80 unsigned I = 0; 81 for (Argument &A : F2->args()) { 82 EXPECT_EQ(Args[I], &A); 83 I++; 84 } 85 EXPECT_EQ(2u, I); 86 87 // Check that arguments in F1 don't have pointer equality with the saved ones. 88 // This also instantiates F1's arguments. 89 I = 0; 90 for (Argument &A : F1->args()) { 91 EXPECT_NE(Args[I], &A); 92 I++; 93 } 94 EXPECT_EQ(2u, I); 95 EXPECT_FALSE(F1->hasLazyArguments()); 96 EXPECT_FALSE(F2->hasLazyArguments()); 97 98 // Steal back from F2. F2's arguments should be lazy again. 99 // 100 // steal(real); drop (real) 101 F1->stealArgumentListFrom(*F2); 102 EXPECT_FALSE(F1->hasLazyArguments()); 103 EXPECT_TRUE(F2->hasLazyArguments()); 104 I = 0; 105 for (Argument &A : F1->args()) { 106 EXPECT_EQ(Args[I], &A); 107 I++; 108 } 109 EXPECT_EQ(2u, I); 110 111 // Steal from F2 a second time. Now both functions should have lazy 112 // arguments. 113 // 114 // steal(empty); drop (real) 115 F1->stealArgumentListFrom(*F2); 116 EXPECT_TRUE(F1->hasLazyArguments()); 117 EXPECT_TRUE(F2->hasLazyArguments()); 118 } 119 120 // Test setting and removing section information 121 TEST(FunctionTest, setSection) { 122 LLVMContext C; 123 Module M("test", C); 124 125 llvm::Function *F = 126 Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C), false), 127 llvm::GlobalValue::ExternalLinkage, "F", &M); 128 129 F->setSection(".text.test"); 130 EXPECT_TRUE(F->getSection() == ".text.test"); 131 EXPECT_TRUE(F->hasSection()); 132 F->setSection(""); 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()); 138 } 139 140 TEST(FunctionTest, GetPointerAlignment) { 141 LLVMContext Context; 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(Align(1), 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"))); 153 154 Func->setAlignment(Align(4)); 155 156 EXPECT_EQ(Align(1), 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"))); 163 } 164 165 } // end namespace 166