}
}
- if (SplitPos == &NormalDestBB->front())
- assumeLive(A, *NormalDestBB);
+ if (SplitPos == &NormalDestBB->front()) {
+ // If this is an invoke of a noreturn function the edge to the normal
+ // destination block is dead but not necessarily the block itself.
+ // TODO: We need to move to an edge based system during deduction and
+ // also manifest.
+ assert(!NormalDestBB->isLandingPad() &&
+ "Expected the normal destination not to be a landingpad!");
+ BasicBlock *SplitBB =
+ SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
+ // The split block is live even if it contains only an unreachable
+ // instruction at the end.
+ assumeLive(A, *SplitBB);
+ SplitPos = SplitBB->getTerminator();
+ }
}
BB = SplitPos->getParent();
%call = invoke i32 @foo_noreturn() to label %continue
unwind label %cleanup
; CHECK: %call = invoke i32 @foo_noreturn()
- ; CHECK-NEXT: to label %continue unwind label %cleanup
+ ; CHECK-NEXT: to label %continue.dead unwind label %cleanup
cond.false: ; preds = %entry
call void @normal_call()
ret i32 %cond
continue:
- ; CHECK: continue:
+ ; CHECK: continue.dead:
; CHECK-NEXT: unreachable
br label %cond.end
; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-NEXT: define internal void @non_dead_d15()
; CHECK-NOT: define internal void @dead_e
+
+
+declare void @blowup() noreturn
+define void @live_with_dead_entry() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+; CHECK: define void @live_with_dead_entry(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: invoke void @blowup()
+; CHECK-NEXT: to label %live_with_dead_entry.dead unwind label %lpad
+; CHECK: lpad: ; preds = %entry
+; CHECK-NEXT: %0 = landingpad { i8*, i32 }
+; CHECK-NEXT: catch i8* null
+; CHECK-NEXT: br label %live_with_dead_entry
+; CHECK: live_with_dead_entry.dead: ; preds = %entry
+; CHECK-NEXT: unreachable
+; CHECK: live_with_dead_entry: ; preds = %lpad
+; CHECK-NEXT: ret void
+entry:
+ invoke void @blowup() to label %live_with_dead_entry unwind label %lpad
+lpad:
+ %0 = landingpad { i8*, i32 } catch i8* null
+ br label %live_with_dead_entry
+live_with_dead_entry:
+ ret void
+}
+
+define void @live_with_dead_entry_lp() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+; CHECK: define void @live_with_dead_entry_lp(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: invoke void @blowup()
+; CHECK-NEXT: to label %live_with_dead_entry.dead unwind label %lp1
+; CHECK: lp1: ; preds = %entry
+; CHECK-NEXT: %lp = landingpad { i8*, i32 }
+; CHECK-NEXT: catch i8* null
+; CHECK-NEXT: invoke void @blowup()
+; CHECK-NEXT: to label %live_with_dead_entry.dead1 unwind label %lp2
+; CHECK: lp2: ; preds = %lp1
+; CHECK-NEXT: %0 = landingpad { i8*, i32 }
+; CHECK-NEXT: catch i8* null
+; CHECK-NEXT: br label %live_with_dead_entry
+; CHECK: live_with_dead_entry.dead: ; preds = %entry
+; CHECK-NEXT: unreachable
+; CHECK: live_with_dead_entry.dead1: ; preds = %lp1
+; CHECK-NEXT: unreachable
+; CHECK: live_with_dead_entry: ; preds = %lp2
+; CHECK-NEXT: ret void
+entry:
+ invoke void @blowup() to label %live_with_dead_entry unwind label %lp1
+lp1:
+ %lp = landingpad { i8*, i32 } catch i8* null
+ invoke void @blowup() to label %live_with_dead_entry unwind label %lp2
+lp2:
+ %0 = landingpad { i8*, i32 } catch i8* null
+ br label %live_with_dead_entry
+live_with_dead_entry:
+ ret void
+}
%retval = alloca i32, align 4
%__exception_code = alloca i32, align 4
; CHECK: invoke void @"?overflow@@YAXXZ"()
-; CHECK: to label %invoke.cont unwind label %catch.dispatch
+; CHECK: to label %invoke.cont.dead unwind label %catch.dispatch
invoke void @"?overflow@@YAXXZ"()
to label %invoke.cont unwind label %catch.dispatch
invoke.cont: ; preds = %entry
-; CHECK: invoke.cont:
+; CHECK: invoke.cont.dead:
; CHECK-NEXT: unreachable
br label %invoke.cont1
%retval = alloca i32, align 4
%__exception_code = alloca i32, align 4
; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"()
-; CHECK: to label %invoke.cont unwind label %catch.dispatch
+; CHECK: to label %invoke.cont.dead unwind label %catch.dispatch
invoke void @"?overflow@@YAXXZ_may_throw"()
to label %invoke.cont unwind label %catch.dispatch
invoke.cont: ; preds = %entry
-; CHECK: invoke.cont:
+; CHECK: invoke.cont.dead:
; CHECK-NEXT: unreachable
br label %invoke.cont1
%retval = alloca i32, align 4
%__exception_code = alloca i32, align 4
; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"()
-; CHECK: to label %invoke.cont unwind label %catch.dispatch
+; CHECK: to label %invoke.cont.dead unwind label %catch.dispatch
invoke void @"?overflow@@YAXXZ_may_throw"()
to label %invoke.cont unwind label %catch.dispatch
invoke.cont: ; preds = %entry
-; CHECK: invoke.cont:
+; CHECK: invoke.cont.dead:
; CHECK-NEXT: unreachable
br label %invoke.cont1