Skip to content

Commit f3aff31

Browse files
committedSep 10, 2015
[WinEH] Fix single-block cleanup coloring
Summary: The coloring code in WinEHPrepare queues cleanuprets' successors with the correct color (the parent one) when it sees their cleanuppad, and so later when iterating successors knows to skip processing cleanuprets since they've already been queued. This latter check was incorrectly under an 'else' condition and so inadvertently was not kicking in for single-block cleanups. This change sinks the check out of the 'else' to fix the bug. Reviewers: majnemer, andrew.w.kaylor, rnk Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D12751 llvm-svn: 247299
1 parent aa15bff commit f3aff31

File tree

2 files changed

+54
-17
lines changed

2 files changed

+54
-17
lines changed
 

‎llvm/lib/CodeGen/WinEHPrepare.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -3245,14 +3245,15 @@ void WinEHPrepare::colorFunclets(Function &F,
32453245
} else {
32463246
// Note that this is a member of the given color.
32473247
FuncletBlocks[Color].insert(Visiting);
3248-
TerminatorInst *Terminator = Visiting->getTerminator();
3249-
if (isa<CleanupReturnInst>(Terminator) ||
3250-
isa<CatchReturnInst>(Terminator) ||
3251-
isa<CleanupEndPadInst>(Terminator)) {
3252-
// These block's successors have already been queued with the parent
3253-
// color.
3254-
continue;
3255-
}
3248+
}
3249+
3250+
TerminatorInst *Terminator = Visiting->getTerminator();
3251+
if (isa<CleanupReturnInst>(Terminator) ||
3252+
isa<CatchReturnInst>(Terminator) ||
3253+
isa<CleanupEndPadInst>(Terminator)) {
3254+
// These blocks' successors have already been queued with the parent
3255+
// color.
3256+
continue;
32563257
}
32573258
for (BasicBlock *Succ : successors(Visiting)) {
32583259
if (isa<CatchEndPadInst>(Succ->getFirstNonPHI())) {

‎llvm/test/CodeGen/WinEH/wineh-cloning.ll

+45-9
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ endcatch:
2727
; Need two copies of the call to @h, one under entry and one under catch.
2828
; Currently we generate a load for each, though we shouldn't need one
2929
; for the use in entry's copy.
30-
; CHECK-LABEL: @test1(
30+
; CHECK-LABEL: define void @test1(
3131
; CHECK: entry:
3232
; CHECK: store i32 %x, i32* [[Slot:%[^ ]+]]
3333
; CHECK: invoke void @f()
@@ -56,7 +56,7 @@ exit:
5656
; Need two copies of %exit's call to @f -- the subsequent ret is only
5757
; valid when coming from %entry, but on the path from %cleanup, this
5858
; might be a valid call to @f which might dynamically not return.
59-
; CHECK-LABEL: @test2(
59+
; CHECK-LABEL: define void @test2(
6060
; CHECK: entry:
6161
; CHECK: invoke void @f()
6262
; CHECK: to label %[[exit:[^ ]+]] unwind label %cleanup
@@ -91,7 +91,7 @@ exit:
9191
}
9292
; Need two copies of %shared's call to @f (similar to @test2 but
9393
; the two regions here are siblings, not parent-child).
94-
; CHECK-LABEL: @test3(
94+
; CHECK-LABEL: define void @test3(
9595
; CHECK: invoke void @f()
9696
; CHECK: invoke void @f()
9797
; CHECK: to label %[[exit:[^ ]+]] unwind
@@ -143,7 +143,7 @@ exit:
143143
; Make sure we can clone regions that have internal control
144144
; flow and SSA values. Here we need two copies of everything
145145
; from %shared to %exit.
146-
; CHECK-LABEL: @test4(
146+
; CHECK-LABEL: define void @test4(
147147
; CHECK: entry:
148148
; CHECK: to label %[[shared_E:[^ ]+]] unwind label %catch
149149
; CHECK: catch:
@@ -221,7 +221,7 @@ exit:
221221
; Simple nested case (catch-inside-cleanup). Nothing needs
222222
; to be cloned. The def and use of %x are both in %outer
223223
; and so don't need to be spilled.
224-
; CHECK-LABEL: @test5(
224+
; CHECK-LABEL: define void @test5(
225225
; CHECK: outer:
226226
; CHECK: %x = call i32 @g()
227227
; CHECK-NEXT: invoke void @f()
@@ -277,7 +277,7 @@ exit:
277277
; %left still needs to be created because it's possible
278278
; the dynamic path enters %left, then enters %inner,
279279
; then calls @h, and that the call to @h doesn't return.
280-
; CHECK-LABEL: @test6(
280+
; CHECK-LABEL: define void @test6(
281281
; TODO: CHECKs
282282

283283

@@ -309,7 +309,7 @@ unreachable:
309309
; Another case of a two-parent child (like @test6), this time
310310
; with the join at the entry itself instead of following a
311311
; non-pad join.
312-
; CHECK-LABEL: @test7(
312+
; CHECK-LABEL: define void @test7(
313313
; TODO: CHECKs
314314

315315

@@ -347,7 +347,7 @@ unreachable:
347347
}
348348
; %inner is a two-parent child which itself has a child; need
349349
; to make two copies of both the %inner and %inner.child.
350-
; CHECK-LABEL: @test8(
350+
; CHECK-LABEL: define void @test8(
351351
; TODO: CHECKs
352352

353353

@@ -380,5 +380,41 @@ unreachable:
380380
; the parent of the other, but that we'd somehow lost track in the CFG
381381
; of which was which along the way; generating each possibility lets
382382
; whichever case was correct execute correctly.
383-
; CHECK-LABEL: @test9(
383+
; CHECK-LABEL: define void @test9(
384384
; TODO: CHECKs
385+
386+
define void @test10() personality i32 (...)* @__CxxFrameHandler3 {
387+
entry:
388+
invoke void @f()
389+
to label %unreachable unwind label %inner
390+
inner:
391+
%cleanup = cleanuppad []
392+
; make sure we don't overlook this cleanupret and try to process
393+
; successor %outer as a child of inner.
394+
cleanupret %cleanup unwind label %outer
395+
outer:
396+
%catch = catchpad [] to label %catch.body unwind label %endpad
397+
catch.body:
398+
catchret %catch to label %exit
399+
endpad:
400+
catchendpad unwind to caller
401+
exit:
402+
ret void
403+
unreachable:
404+
unreachable
405+
}
406+
; CHECK-LABEL: define void @test10(
407+
; CHECK-NEXT: entry:
408+
; CHECK-NEXT: invoke
409+
; CHECK-NEXT: to label %unreachable unwind label %inner
410+
; CHECK: inner:
411+
; CHECK-NEXT: %cleanup = cleanuppad
412+
; CHECK-NEXT: cleanupret %cleanup unwind label %outer
413+
; CHECK: outer:
414+
; CHECK-NEXT: %catch = catchpad [] to label %catch.body unwind label %endpad
415+
; CHECK: catch.body:
416+
; CHECK-NEXT: catchret %catch to label %exit
417+
; CHECK: endpad:
418+
; CHECK-NEXT: catchendpad unwind to caller
419+
; CHECK: exit:
420+
; CHECK-NEXT: ret void

0 commit comments

Comments
 (0)
Please sign in to comment.