FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());
// Create the new function body and insert it into the module.
- Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName());
+ Function *NF = Function::Create(NFTy, F->getLinkage(), F->getAddressSpace(),
+ F->getName());
NF->copyAttributesFrom(F);
// Patch the pointer to LLVM function in debug info descriptor.
unsigned NumArgs = Params.size();
// Create the new function body and insert it into the module...
- Function *NF = Function::Create(NFTy, Fn.getLinkage());
+ Function *NF = Function::Create(NFTy, Fn.getLinkage(), Fn.getAddressSpace());
NF->copyAttributesFrom(&Fn);
NF->setComdat(Fn.getComdat());
Fn.getParent()->getFunctionList().insert(Fn.getIterator(), NF);
return false;
// Create the new function body and insert it into the module...
- Function *NF = Function::Create(NFTy, F->getLinkage());
+ Function *NF = Function::Create(NFTy, F->getLinkage(), F->getAddressSpace());
NF->copyAttributesFrom(F);
NF->setComdat(F->getComdat());
NF->setAttributes(NewPAL);
llvm::Value *Declaration;
if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
+ CurI->getAddressSpace(),
CurI->getName(), &M);
} else {
if (GV.getValueType()->isFunctionTy())
NewGV =
Function::Create(cast<FunctionType>(GV.getValueType()),
- GlobalValue::ExternalLinkage, "", GV.getParent());
+ GlobalValue::ExternalLinkage, GV.getAddressSpace(),
+ "", GV.getParent());
else
NewGV =
new GlobalVariable(*GV.getParent(), GV.getValueType(),
if (F->isDSOLocal()) {
Function *RealF = Function::Create(F->getFunctionType(),
GlobalValue::ExternalLinkage,
+ F->getAddressSpace(),
Name + ".cfi", &M);
RealF->setVisibility(GlobalVariable::HiddenVisibility);
replaceDirectCalls(F, RealF);
if (F->isDeclarationForLinker() && !isDefinition) {
// Declaration of an external function.
FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
- Name + ".cfi_jt", &M);
+ F->getAddressSpace(), Name + ".cfi_jt", &M);
FDecl->setVisibility(GlobalValue::HiddenVisibility);
} else if (isDefinition) {
F->setName(Name + ".cfi");
F->setLinkage(GlobalValue::ExternalLinkage);
FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
- Name, &M);
+ F->getAddressSpace(), Name, &M);
FDecl->setVisibility(Visibility);
Visibility = GlobalValue::HiddenVisibility;
for (auto &U : F->uses()) {
if (auto *A = dyn_cast<GlobalAlias>(U.getUser())) {
Function *AliasDecl = Function::Create(
- F->getFunctionType(), GlobalValue::ExternalLinkage, "", &M);
+ F->getFunctionType(), GlobalValue::ExternalLinkage,
+ F->getAddressSpace(), "", &M);
AliasDecl->takeName(A);
A->replaceAllUsesWith(AliasDecl);
ToErase.push_back(A);
WeakInitializerFn = Function::Create(
FunctionType::get(Type::getVoidTy(M.getContext()),
/* IsVarArg */ false),
- GlobalValue::InternalLinkage, "__cfi_global_var_init", &M);
+ GlobalValue::InternalLinkage,
+ M.getDataLayout().getProgramAddressSpace(),
+ "__cfi_global_var_init", &M);
BasicBlock *BB =
BasicBlock::Create(M.getContext(), "entry", WeakInitializerFn);
ReturnInst::Create(M.getContext(), BB);
// placeholder first.
Function *PlaceholderFn =
Function::Create(cast<FunctionType>(F->getValueType()),
- GlobalValue::ExternalWeakLinkage, "", &M);
+ GlobalValue::ExternalWeakLinkage,
+ F->getAddressSpace(), "", &M);
replaceCfiUses(F, PlaceholderFn, IsDefinition);
Constant *Target = ConstantExpr::getSelect(
Function *JumpTableFn =
Function::Create(FunctionType::get(Type::getVoidTy(M.getContext()),
/* IsVarArg */ false),
- GlobalValue::PrivateLinkage, ".cfi.jumptable", &M);
+ GlobalValue::PrivateLinkage,
+ M.getDataLayout().getProgramAddressSpace(),
+ ".cfi.jumptable", &M);
ArrayType *JumpTableType =
ArrayType::get(getJumpTableEntryType(), Functions.size());
auto JumpTable =
if (!F)
F = Function::Create(
FunctionType::get(Type::getVoidTy(M.getContext()), false),
- GlobalVariable::ExternalLinkage, FunctionName, &M);
+ GlobalVariable::ExternalLinkage,
+ M.getDataLayout().getProgramAddressSpace(), FunctionName, &M);
// If the function is available_externally, remove its definition so
// that it is handled the same way as a declaration. Later we will try
GEntryBlock->getTerminator()->eraseFromParent();
BB = GEntryBlock;
} else {
- NewG = Function::Create(G->getFunctionType(), G->getLinkage(), "",
- G->getParent());
+ NewG = Function::Create(G->getFunctionType(), G->getLinkage(),
+ G->getAddressSpace(), "", G->getParent());
BB = BasicBlock::Create(F->getContext(), "", NewG);
}
}
// Make them both thunks to the same internal function.
- Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(), "",
- F->getParent());
+ Function *NewF = Function::Create(F->getFunctionType(), F->getLinkage(),
+ F->getAddressSpace(), "", F->getParent());
NewF->copyAttributesFrom(F);
NewF->takeName(F);
removeUsers(F);
continue;
Function *NewF =
- Function::Create(EmptyFT, GlobalValue::ExternalLinkage, "", &M);
+ Function::Create(EmptyFT, GlobalValue::ExternalLinkage,
+ F.getAddressSpace(), "", &M);
NewF->setVisibility(F.getVisibility());
NewF->takeName(&F);
F.replaceAllUsesWith(ConstantExpr::getBitCast(NewF, F.getType()));
Function *JT;
if (isa<MDString>(Slot.TypeID)) {
JT = Function::Create(FT, Function::ExternalLinkage,
+ M.getDataLayout().getProgramAddressSpace(),
getGlobalName(Slot, {}, "branch_funnel"), &M);
JT->setVisibility(GlobalValue::HiddenVisibility);
} else {
- JT = Function::Create(FT, Function::InternalLinkage, "branch_funnel", &M);
+ JT = Function::Create(FT, Function::InternalLinkage,
+ M.getDataLayout().getProgramAddressSpace(),
+ "branch_funnel", &M);
}
JT->addAttribute(1, Attribute::Nest);
--- /dev/null
+; RUN: opt < %s -argpromotion -S | FileCheck %s
+
+; ArgumentPromotion should preserve the default function address space
+; from the data layout.
+
+target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
+
+@g = common global i32 0, align 4
+
+define i32 @bar() {
+entry:
+ %call = call i32 @foo(i32* @g)
+; CHECK: %call = call addrspace(1) i32 @foo()
+ ret i32 %call
+}
+
+; CHECK: define internal i32 @foo() addrspace(1)
+define internal i32 @foo(i32*) {
+entry:
+ %retval = alloca i32, align 4
+ call void asm sideeffect "ldr r0, [r0] \0Abx lr \0A", ""()
+ unreachable
+}
+
--- /dev/null
+; RUN: opt -S -deadargelim %s | FileCheck %s
+
+; DeadArgumentElimination should respect the function address space
+; in the data layout.
+
+target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
+
+; CHECK: define internal i32 @foo() addrspace(1)
+define internal i32 @foo(i32 %x) #0 {
+ tail call void asm sideeffect inteldialect "mov eax, [esp + $$4]\0A\09ret", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+ unreachable
+}
+
+define i32 @f(i32 %x, i32 %y) {
+ ; CHECK: %r = call addrspace(1) i32 @foo()
+ %r = call i32 @foo(i32 %x)
+
+ ret i32 %r
+}
+
--- /dev/null
+; RUN: opt -S -mergefunc < %s | FileCheck %s
+
+; MergeFunctions should respect the default function address
+; space specified in the data layout.
+
+target datalayout = "e-P1-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+declare void @stuff()
+
+; CHECK-LABEL: @f0(
+define void @f0(i64 %p0) {
+entry:
+ call void @stuff()
+ call void @stuff()
+ call void @stuff()
+ ret void
+}
+
+; CHECK-LABEL: @f1(
+; CHECK: ptrtoint i64*
+; CHECK: tail call addrspace(1) void @f0(i64
+
+define void @f1(i64* %p0) {
+entry:
+ call void @stuff()
+ call void @stuff()
+ call void @stuff()
+ ret void
+}
+