Index: llvm/lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUCtorDtorLowering.cpp @@ -56,16 +56,17 @@ ConstantArray *GA = dyn_cast(GV->getInitializer()); if (!GA || GA->getNumOperands() == 0) return false; + Function *InitOrFiniKernel = createInitOrFiniKernelFunction(M, IsCtor); IRBuilder<> IRB(InitOrFiniKernel->getEntryBlock().getTerminator()); + + FunctionType *ConstructorTy = InitOrFiniKernel->getFunctionType(); + for (Value *V : GA->operands()) { auto *CS = cast(V); - if (Function *F = dyn_cast(CS->getOperand(1))) { - FunctionCallee Ctor = - M.getOrInsertFunction(F->getName(), IRB.getVoidTy()); - IRB.CreateCall(Ctor); - } + IRB.CreateCall(ConstructorTy, CS->getOperand(1)); } + appendToUsed(M, {InitOrFiniKernel}); return true; } Index: llvm/test/CodeGen/AMDGPU/lower-ctor-dtor-constexpr-alias.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AMDGPU/lower-ctor-dtor-constexpr-alias.ll @@ -0,0 +1,53 @@ +; RUN: opt -S -mtriple=amdgcn-- -amdgpu-lower-ctor-dtor %s | FileCheck %s + +; Make sure we emit code for constructor entries that aren't direct +; function calls. + +; Check a constructor that's an alias, and an integer literal. +@llvm.global_ctors = appending addrspace(1) global [2 x { i32, ptr, ptr }] [ + { i32, ptr, ptr } { i32 1, ptr @foo.alias, i8* null }, + { i32, ptr, ptr } { i32 1, ptr inttoptr (i64 4096 to ptr), i8* null } +] + +; Check a constantexpr addrspacecast +@llvm.global_dtors = appending addrspace(1) global [1 x { i32, ptr, ptr }] [ + { i32, ptr, ptr } { i32 1, ptr addrspacecast (ptr addrspace(1) @bar to ptr), i8* null } +] + +@foo.alias = hidden alias void (), ptr @foo + +;. +; CHECK: @llvm.global_ctors = appending addrspace(1) global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @foo.alias, ptr null }, { i32, ptr, ptr } { i32 1, ptr inttoptr (i64 4096 to ptr), ptr null }] +; CHECK: @llvm.global_dtors = appending addrspace(1) global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr addrspacecast (ptr addrspace(1) @bar to ptr), ptr null }] +; CHECK: @llvm.used = appending global [2 x ptr] [ptr @amdgcn.device.init, ptr @amdgcn.device.fini], section "llvm.metadata" +; CHECK: @foo.alias = hidden alias void (), ptr @foo +;. +define void @foo() { +; CHECK-LABEL: @foo( +; CHECK-NEXT: ret void +; + ret void +} + +define void @bar() addrspace(1) { +; CHECK-LABEL: @bar( +; CHECK-NEXT: ret void +; + ret void +} + +; CHECK: define amdgpu_kernel void @amdgcn.device.init() #[[ATTR0:[0-9]+]] { +; CHECK-NEXT: call void @foo.alias() +; CHECK-NEXT: call void inttoptr (i64 4096 to ptr)() +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +; CHECK: define amdgpu_kernel void @amdgcn.device.fini() #[[ATTR1:[0-9]+]] { +; CHECK-NEXT: call void addrspacecast (ptr addrspace(1) @bar to ptr)() +; CHECK-NEXT: ret void +; CHECK-NEXT: } + +;. +; CHECK: attributes #[[ATTR0]] = { "device-init" } +; CHECK: attributes #[[ATTR1]] = { "device-fini" } +;.