Skip to content

Commit d227a7f

Browse files
committed
[InlineFunction] Fix logic to update PHI nodes in an exceptional block
when inlining tasks at an invoke instruction. Addresses issue llvm#73.
1 parent c13a32f commit d227a7f

File tree

2 files changed

+111
-5
lines changed

2 files changed

+111
-5
lines changed

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -658,9 +658,11 @@ static void HandleInlinedTasksHelper(
658658
// Promote any calls in the block to invokes.
659659
if (BasicBlock *NewBB = HandleCallsInBlockInlinedThroughInvoke(
660660
BB, UnwindEdge)) {
661-
// Update any PHI nodes in the exceptional block to indicate that there
662-
// is now a new entry in them.
663-
Invoke.addIncomingPHIValuesFor(NewBB);
661+
// If this is the topmost invocation of HandleInlinedTasksHelper, update
662+
// any PHI nodes in the exceptional block to indicate that there is now a
663+
// new entry in them.
664+
if (nullptr == ParentWorklist)
665+
Invoke.addIncomingPHIValuesFor(NewBB);
664666
BlocksToProcess.insert(
665667
cast<InvokeInst>(NewBB->getTerminator())->getNormalDest());
666668
}
@@ -697,7 +699,7 @@ static void HandleInlinedTasksHelper(
697699
continue;
698700
}
699701

700-
// Process a detach instruction specially. In particular, process th
702+
// Process a detach instruction specially. In particular, process the
701703
// spawned task recursively.
702704
if (DetachInst *DI = dyn_cast<DetachInst>(BB->getTerminator())) {
703705
if (!DI->hasUnwindDest()) {
@@ -714,8 +716,13 @@ static void HandleInlinedTasksHelper(
714716
// If the new unwind edge is not used, remove it.
715717
if (pred_empty(SubTaskUnwindEdge))
716718
SubTaskUnwindEdge->eraseFromParent();
717-
else
719+
else {
718720
DetachesToReplace.push_back(DI);
721+
// Update PHI nodes in the exceptional block to indicate that
722+
// SubTaskUnwindEdge is a new entry in them. This should only have an
723+
// effect for the topmost call to HandleInlinedTasksHelper.
724+
Invoke.addIncomingPHIValuesFor(SubTaskUnwindEdge);
725+
}
719726

720727
} else if (Visited.insert(DI->getUnwindDest()).second) {
721728
// If the detach-unwind isn't dead, add it to the worklist.
@@ -745,6 +752,11 @@ static void HandleInlinedTasksHelper(
745752
// Replace detaches that now require unwind destinations.
746753
while (!DetachesToReplace.empty()) {
747754
DetachInst *DI = DetachesToReplace.pop_back_val();
755+
// If this is the topmost invocation of HandleInlinedTasksHelper, update any
756+
// PHI nodes in the exceptional block to indicate that there is now a new
757+
// entry in them.
758+
if (nullptr == ParentWorklist)
759+
Invoke.addIncomingPHIValuesFor(DI->getParent());
748760
ReplaceInstWithInst(DI, DetachInst::Create(
749761
DI->getDetached(), DI->getContinue(), UnwindEdge,
750762
DI->getSyncRegion()));
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
; RUN: opt < %s -inline -S -o - | FileCheck %s
2+
; RUN: opt < %s -passes='inline' -S -o - | FileCheck %s
3+
4+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5+
target triple = "x86_64-unknown-linux-gnu"
6+
7+
$_ZN5outerC2ERKS_ = comdat any
8+
9+
$_ZNSt5arrayI5outerLm2EED2Ev = comdat any
10+
11+
define dso_local void @main() local_unnamed_addr #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
12+
entry:
13+
invoke void @_ZN5outerC2ERKS_()
14+
to label %invoke.cont unwind label %lpad
15+
16+
invoke.cont: ; preds = %entry
17+
invoke void @_ZN5outerC2ERKS_()
18+
to label %invoke.cont1 unwind label %lpad
19+
20+
invoke.cont1: ; preds = %invoke.cont
21+
ret void
22+
23+
lpad: ; preds = %entry, %invoke.cont
24+
%arrayinit.endOfInit.0.idx = phi i64 [ 1, %invoke.cont ], [ 0, %entry ]
25+
%0 = landingpad { i8*, i32 }
26+
cleanup
27+
resume { i8*, i32 } %0
28+
}
29+
30+
; CHECK: define {{.*}}void @main()
31+
; CHECK: entry:
32+
; CHECK: detach within %{{.*}}, label %[[PFOR_BODY_1:.+]], label %{{.*}} unwind label %lpad
33+
34+
; CHECK: [[PFOR_BODY_1]]:
35+
; CHECK-NEXT: invoke void @_Znwm()
36+
; CHECK-NEXT: to label %{{.*}} unwind label %[[LPAD1:.+]]
37+
38+
; CHECK: [[LPAD1]]:
39+
; CHECK: invoke void @llvm.detached.rethrow.sl_p0i8i32s(token %{{.*}},
40+
; CHECK-NEXT: to label %{{.*}} unwind label %lpad
41+
42+
; CHECK: invoke.cont:
43+
; CHECK: detach within %{{.*}}, label %[[PFOR_BODY_2:.+]], label %{{.*}} unwind label %lpad
44+
45+
; CHECK: [[PFOR_BODY_2]]:
46+
; CHECK-NEXT: invoke void @_Znwm()
47+
; CHECK-NEXT: to label %{{.*}} unwind label %[[LPAD2:.+]]
48+
49+
; CHECK: [[LPAD2]]:
50+
; CHECK: invoke void @llvm.detached.rethrow.sl_p0i8i32s(token %{{.*}},
51+
; CHECK-NEXT: to label %{{.*}} unwind label %lpad
52+
53+
; CHECK: lpad:
54+
; CHECK-NEXT: %arrayinit.endOfInit.0.idx = phi i64 [ 0, %[[LPAD1]] ], [ 0, %entry ], [ 1, %[[LPAD2]] ], [ 1, %invoke.cont ]
55+
56+
define dso_local void @_ZN5outerC2ERKS_() unnamed_addr #1 comdat align 2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
57+
entry:
58+
%syncreg = call token @llvm.syncregion.start()
59+
br label %pfor.cond
60+
61+
pfor.cond: ; preds = %entry
62+
detach within %syncreg, label %pfor.body.entry, label %pfor.inc
63+
64+
pfor.body.entry: ; preds = %pfor.cond
65+
br label %pfor.body
66+
67+
pfor.body: ; preds = %pfor.body.entry
68+
call void @_Znwm() #3
69+
unreachable
70+
71+
pfor.inc: ; preds = %pfor.cond
72+
unreachable
73+
}
74+
75+
declare dso_local i32 @__gxx_personality_v0(...)
76+
77+
define dso_local void @_ZNSt5arrayI5outerLm2EED2Ev() unnamed_addr #1 comdat align 2 {
78+
entry:
79+
ret void
80+
}
81+
82+
; Function Attrs: argmemonly nounwind willreturn
83+
declare token @llvm.syncregion.start() #2
84+
85+
declare dso_local void @_Znwm() local_unnamed_addr #1
86+
87+
attributes #0 = { "target-cpu"="x86-64" }
88+
attributes #1 = { "use-soft-float"="false" }
89+
attributes #2 = { argmemonly nounwind willreturn }
90+
attributes #3 = { builtin }
91+
92+
!llvm.ident = !{!0}
93+
94+
!0 = !{!"clang version 12.0.0 ([email protected]:OpenCilk/opencilk-project.git 973aa8d610bafa8c98286f78c034ce1c27c26eec)"}

0 commit comments

Comments
 (0)