Index: lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- lib/Transforms/Coroutines/CoroSplit.cpp +++ lib/Transforms/Coroutines/CoroSplit.cpp @@ -250,8 +250,7 @@ auto *FnTy = cast(FnPtrTy->getElementType()); Function *NewF = - Function::Create(FnTy, GlobalValue::LinkageTypes::InternalLinkage, - F.getName() + Suffix, M); + Function::Create(FnTy, F.getLinkage(), F.getName() + Suffix, M); NewF->addParamAttr(0, Attribute::NonNull); NewF->addParamAttr(0, Attribute::NoAlias); Index: test/Transforms/Coroutines/coro-debug.ll =================================================================== --- test/Transforms/Coroutines/coro-debug.ll +++ test/Transforms/Coroutines/coro-debug.ll @@ -127,9 +127,9 @@ !24 = !DILocation(line: 62, column: 3, scope: !6) ; CHECK: define i8* @f(i32 %x) #0 !dbg ![[ORIG:[0-9]+]] -; CHECK: define internal fastcc void @f.resume(%f.Frame* %FramePtr) #0 !dbg ![[RESUME:[0-9]+]] -; CHECK: define internal fastcc void @f.destroy(%f.Frame* %FramePtr) #0 !dbg ![[DESTROY:[0-9]+]] -; CHECK: define internal fastcc void @f.cleanup(%f.Frame* %FramePtr) #0 !dbg ![[CLEANUP:[0-9]+]] +; CHECK: define dso_local fastcc void @f.resume(%f.Frame* %FramePtr) #0 !dbg ![[RESUME:[0-9]+]] +; CHECK: define dso_local fastcc void @f.destroy(%f.Frame* %FramePtr) #0 !dbg ![[DESTROY:[0-9]+]] +; CHECK: define dso_local fastcc void @f.cleanup(%f.Frame* %FramePtr) #0 !dbg ![[CLEANUP:[0-9]+]] ; CHECK: ![[ORIG]] = distinct !DISubprogram(name: "f", linkageName: "flink" ; CHECK: !DILocalVariable(name: "x", arg: 1, scope: ![[ORIG]] Index: test/Transforms/Coroutines/coro-eh-aware-edge-split.ll =================================================================== --- test/Transforms/Coroutines/coro-eh-aware-edge-split.ll +++ test/Transforms/Coroutines/coro-eh-aware-edge-split.ll @@ -4,7 +4,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" -; CHECK-LABEL: define internal fastcc void @f.resume( +; CHECK-LABEL: define dso_local fastcc void @f.resume( define void @f(i1 %cond) "coroutine.presplit"="1" personality i32 0 { entry: %id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null) @@ -72,7 +72,7 @@ unreachable } -; CHECK-LABEL: define internal fastcc void @g.resume( +; CHECK-LABEL: define dso_local fastcc void @g.resume( define void @g(i1 %cond, i32 %x, i32 %y) "coroutine.presplit"="1" personality i32 0 { entry: %id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null) @@ -134,7 +134,7 @@ unreachable } -; CHECK-LABEL: define internal fastcc void @h.resume( +; CHECK-LABEL: define dso_local fastcc void @h.resume( define void @h(i1 %cond, i32 %x, i32 %y) "coroutine.presplit"="1" personality i32 0 { entry: %id = call token @llvm.coro.id(i32 16, i8* null, i8* null, i8* null) Index: test/Transforms/Coroutines/coro-split-eh.ll =================================================================== --- test/Transforms/Coroutines/coro-split-eh.ll +++ test/Transforms/Coroutines/coro-split-eh.ll @@ -102,7 +102,7 @@ ; VERIFY Resume Parts ; Verify that resume function does not contains both print calls appearing after coro.end -; CHECK-LABEL: define internal fastcc void @f.resume +; CHECK-LABEL: define dso_local fastcc void @f.resume ; CHECK: invoke void @print(i32 1) ; CHECK: to label %CoroEnd unwind label %lpad @@ -116,7 +116,7 @@ ; CHECK-NEXT: resume { i8*, i32 } %lpval ; Verify that resume function does not contains both print calls appearing after coro.end -; CHECK-LABEL: define internal fastcc void @f2.resume +; CHECK-LABEL: define dso_local fastcc void @f2.resume ; CHECK: invoke void @print(i32 1) ; CHECK: to label %CoroEnd unwind label %lpad Index: test/Transforms/Coroutines/coro-split-hidden.ll =================================================================== --- /dev/null +++ test/Transforms/Coroutines/coro-split-hidden.ll @@ -0,0 +1,81 @@ +; Tests that coro-split can convert functions with hidden visibility. +; These may be generated by a frontend such as Clang, when inlining with +; '-fvisibility-inlines-hidden'. +; RUN: opt < %s -coro-split -S | FileCheck %s + +define hidden i8* @f() "coroutine.presplit"="1" { +entry: + %id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) + %need.alloc = call i1 @llvm.coro.alloc(token %id) + br i1 %need.alloc, label %dyn.alloc, label %begin + +dyn.alloc: + %size = call i32 @llvm.coro.size.i32() + %alloc = call i8* @malloc(i32 %size) + br label %begin + +begin: + %phi = phi i8* [ null, %entry ], [ %alloc, %dyn.alloc ] + %hdl = call i8* @llvm.coro.begin(token %id, i8* %phi) + call void @print(i32 0) + %0 = call i8 @llvm.coro.suspend(token none, i1 false) + switch i8 %0, label %suspend [i8 0, label %resume + i8 1, label %cleanup] +resume: + call void @print(i32 1) + br label %cleanup + +cleanup: + %mem = call i8* @llvm.coro.free(token %id, i8* %hdl) + call void @free(i8* %mem) + br label %suspend +suspend: + call i1 @llvm.coro.end(i8* %hdl, i1 0) + ret i8* %hdl +} + +; CHECK-LABEL: hidden{{.*}}@f( +; CHECK: call i8* @malloc +; CHECK: @llvm.coro.begin(token %id, i8* %phi) +; CHECK: store void (%f.Frame*)* @f.resume, void (%f.Frame*)** %resume.addr +; CHECK: %[[SEL:.+]] = select i1 %need.alloc, void (%f.Frame*)* @f.destroy, void (%f.Frame*)* @f.cleanup +; CHECK: store void (%f.Frame*)* %[[SEL]], void (%f.Frame*)** %destroy.addr +; CHECK: call void @print(i32 0) +; CHECK-NOT: call void @print(i32 1) +; CHECK-NOT: call void @free( +; CHECK: ret i8* %hdl + +; CHECK-LABEL: hidden{{.*}}@f.resume( +; CHECK-NOT: call i8* @malloc +; CHECK-NOT: call void @print(i32 0) +; CHECK: call void @print(i32 1) +; CHECK-NOT: call void @print(i32 0) +; CHECK: call void @free( +; CHECK: ret void + +; CHECK-LABEL: hidden{{.*}}@f.destroy( +; CHECK-NOT: call i8* @malloc +; CHECK-NOT: call void @print( +; CHECK: call void @free( +; CHECK: ret void + +; CHECK-LABEL: hidden{{.*}}@f.cleanup( +; CHECK-NOT: call i8* @malloc +; CHECK-NOT: call void @print( +; CHECK-NOT: call void @free( +; CHECK: ret void + +declare i8* @llvm.coro.free(token, i8*) +declare i32 @llvm.coro.size.i32() +declare i8 @llvm.coro.suspend(token, i1) +declare void @llvm.coro.resume(i8*) +declare void @llvm.coro.destroy(i8*) + +declare token @llvm.coro.id(i32, i8*, i8*, i8*) +declare i1 @llvm.coro.alloc(token) +declare i8* @llvm.coro.begin(token, i8*) +declare i1 @llvm.coro.end(i8*, i1) + +declare noalias i8* @malloc(i32) +declare void @print(i32) +declare void @free(i8*)