Skip to content

Commit c54fe36

Browse files
committed
Coro: Remove coro_end and coro_suspend_retcon in private unprocessed functions
We might emit functions that are private and never called. The coro split pass only processes functions that might be called. Remove intrinsics that we can't generate code for. rdar://84619859 Differential Revision: https://reviews.llvm.org/D114021
1 parent 0f38a40 commit c54fe36

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

llvm/lib/Transforms/Coroutines/CoroCleanup.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ static void lowerSubFn(IRBuilder<> &Builder, CoroSubFnInst *SubFn) {
5656
bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) {
5757
bool Changed = false;
5858

59+
bool IsPrivateAndUnprocessed =
60+
F.hasFnAttribute(CORO_PRESPLIT_ATTR) && F.hasLocalLinkage();
61+
5962
for (Instruction &I : llvm::make_early_inc_range(instructions(F))) {
6063
if (auto *II = dyn_cast<IntrinsicInst>(&I)) {
6164
switch (II->getIntrinsicID()) {
@@ -83,6 +86,13 @@ bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) {
8386
case Intrinsic::coro_subfn_addr:
8487
lowerSubFn(Builder, cast<CoroSubFnInst>(II));
8588
break;
89+
case Intrinsic::coro_end:
90+
case Intrinsic::coro_suspend_retcon:
91+
if (IsPrivateAndUnprocessed) {
92+
II->replaceAllUsesWith(UndefValue::get(II->getType()));
93+
} else
94+
continue;
95+
break;
8696
case Intrinsic::coro_async_size_replace:
8797
auto *Target = cast<ConstantStruct>(
8898
cast<GlobalVariable>(II->getArgOperand(0)->stripPointerCasts())
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; RUN: opt < %s -enable-coroutines -passes='default<O0>' -S | FileCheck %s
2+
3+
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
4+
target triple = "x86_64-apple-macosx10.12.0"
5+
6+
; CHECK: define internal { i8*, i32 } @f(i8* %buffer, i32* %array)
7+
; CHECK-NEXT: entry:
8+
; CHECK-NEXT: unreachable
9+
10+
define internal {i8*, i32} @f(i8* %buffer, i32* %array) {
11+
entry:
12+
%id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, i8* %buffer, i8* bitcast (void (i8*, i1)* @prototype to i8*), i8* bitcast (i8* (i32)* @allocate to i8*), i8* bitcast (void (i8*)* @deallocate to i8*))
13+
%hdl = call i8* @llvm.coro.begin(token %id, i8* null)
14+
%load = load i32, i32* %array
15+
%load.pos = icmp sgt i32 %load, 0
16+
br i1 %load.pos, label %pos, label %neg
17+
18+
pos:
19+
%unwind0 = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 %load)
20+
br i1 %unwind0, label %cleanup, label %pos.cont
21+
22+
pos.cont:
23+
store i32 0, i32* %array, align 4
24+
br label %cleanup
25+
26+
neg:
27+
%unwind1 = call i1 (...) @llvm.coro.suspend.retcon.i1(i32 0)
28+
br i1 %unwind1, label %cleanup, label %neg.cont
29+
30+
neg.cont:
31+
store i32 10, i32* %array, align 4
32+
br label %cleanup
33+
34+
cleanup:
35+
call i1 @llvm.coro.end(i8* %hdl, i1 0)
36+
unreachable
37+
}
38+
39+
declare token @llvm.coro.id.retcon.once(i32, i32, i8*, i8*, i8*, i8*)
40+
declare i8* @llvm.coro.begin(token, i8*)
41+
declare i1 @llvm.coro.suspend.retcon.i1(...)
42+
declare i1 @llvm.coro.end(i8*, i1)
43+
declare i8* @llvm.coro.prepare.retcon(i8*)
44+
45+
declare void @prototype(i8*, i1 zeroext)
46+
47+
declare noalias i8* @allocate(i32 %size)
48+
declare void @deallocate(i8* %ptr)

0 commit comments

Comments
 (0)