Skip to content

Commit 2a40131

Browse files
committed
SjLj EH could produce a machine basic block that legitimately has more than one
landing pad as its successor. SjLj exception handling jumps to the correct landing pad via a switch statement that's generated right before code-gen. Loosen the constraint in the machine instruction verifier to allow for this. Note, this isn't the most rigorous check since we cannot determine where that switch statement came from. But it's marginally better than turning this check off when SjLj exceptions are used. <rdar://problem/9187612> llvm-svn: 130881
1 parent 306f8db commit 2a40131

File tree

2 files changed

+102
-1
lines changed

2 files changed

+102
-1
lines changed

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
// the verifier errors.
2424
//===----------------------------------------------------------------------===//
2525

26+
#include "llvm/Instructions.h"
2627
#include "llvm/Function.h"
2728
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
2829
#include "llvm/CodeGen/LiveVariables.h"
@@ -32,6 +33,7 @@
3233
#include "llvm/CodeGen/MachineMemOperand.h"
3334
#include "llvm/CodeGen/MachineRegisterInfo.h"
3435
#include "llvm/CodeGen/Passes.h"
36+
#include "llvm/MC/MCAsmInfo.h"
3537
#include "llvm/Target/TargetMachine.h"
3638
#include "llvm/Target/TargetRegisterInfo.h"
3739
#include "llvm/Target/TargetInstrInfo.h"
@@ -394,7 +396,13 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
394396
if ((*I)->isLandingPad())
395397
LandingPadSuccs.insert(*I);
396398
}
397-
if (LandingPadSuccs.size() > 1)
399+
400+
const MCAsmInfo *AsmInfo = TM->getMCAsmInfo();
401+
const BasicBlock *BB = MBB->getBasicBlock();
402+
if (LandingPadSuccs.size() > 1 &&
403+
!(AsmInfo &&
404+
AsmInfo->getExceptionHandlingType() == ExceptionHandling::SjLj &&
405+
BB && isa<SwitchInst>(BB->getTerminator())))
398406
report("MBB has more than one landing pad successor", MBB);
399407

400408
// Call AnalyzeBranch. If it succeeds, there several more conditions to check.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
; RUN: llc < %s -verify-machineinstrs
2+
; <rdar://problem/9187612>
3+
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
4+
target triple = "thumbv7-apple-darwin"
5+
6+
define void @func() unnamed_addr align 2 {
7+
entry:
8+
br label %for.cond
9+
10+
for.cond:
11+
%tmp2 = phi i32 [ 0, %entry ], [ %add, %for.cond.backedge ]
12+
%cmp = icmp ult i32 %tmp2, 14
13+
br i1 %cmp, label %for.body, label %for.end
14+
15+
for.body:
16+
%add = add i32 %tmp2, 1
17+
switch i32 %tmp2, label %sw.default [
18+
i32 0, label %sw.bb
19+
i32 1, label %sw.bb
20+
i32 2, label %sw.bb
21+
i32 4, label %sw.bb
22+
i32 5, label %sw.bb
23+
i32 10, label %sw.bb
24+
]
25+
26+
sw.bb:
27+
invoke void @foo()
28+
to label %invoke.cont17 unwind label %lpad
29+
30+
invoke.cont17:
31+
invoke void @foo()
32+
to label %for.cond.backedge unwind label %lpad26
33+
34+
for.cond.backedge:
35+
br label %for.cond
36+
37+
lpad:
38+
%exn = tail call i8* @llvm.eh.exception() nounwind
39+
%eh.selector = tail call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn, i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*), i8* null) nounwind
40+
invoke void @foo()
41+
to label %eh.resume unwind label %terminate.lpad
42+
43+
lpad26:
44+
%exn27 = tail call i8* @llvm.eh.exception() nounwind
45+
%eh.selector28 = tail call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn27, i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*), i8* null) nounwind
46+
invoke void @foo()
47+
to label %eh.resume unwind label %terminate.lpad
48+
49+
sw.default:
50+
br label %for.cond.backedge
51+
52+
for.end:
53+
invoke void @foo()
54+
to label %call8.i.i.i.noexc unwind label %lpad44
55+
56+
call8.i.i.i.noexc:
57+
ret void
58+
59+
lpad44:
60+
%exn45 = tail call i8* @llvm.eh.exception() nounwind
61+
%eh.selector46 = tail call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn45, i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*), i8* null) nounwind
62+
invoke void @foo()
63+
to label %eh.resume unwind label %terminate.lpad
64+
65+
eh.resume:
66+
%exn.slot.0 = phi i8* [ %exn27, %lpad26 ], [ %exn, %lpad ], [ %exn45, %lpad44 ]
67+
tail call void @_Unwind_SjLj_Resume_or_Rethrow(i8* %exn.slot.0) noreturn
68+
unreachable
69+
70+
terminate.lpad:
71+
%exn51 = tail call i8* @llvm.eh.exception() nounwind
72+
%eh.selector52 = tail call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exn51, i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*), i8* null) nounwind
73+
tail call void @_ZSt9terminatev() noreturn nounwind
74+
unreachable
75+
}
76+
77+
declare void @foo()
78+
79+
declare i8* @llvm.eh.exception() nounwind readonly
80+
81+
declare i32 @__gxx_personality_sj0(...)
82+
83+
declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
84+
85+
declare void @_Unwind_SjLj_Resume_or_Rethrow(i8*)
86+
87+
declare void @_ZSt9terminatev()
88+
89+
!0 = metadata !{metadata !"any pointer", metadata !1}
90+
!1 = metadata !{metadata !"omnipotent char", metadata !2}
91+
!2 = metadata !{metadata !"Simple C/C++ TBAA", null}
92+
!3 = metadata !{metadata !"bool", metadata !1}
93+
!4 = metadata !{metadata !"int", metadata !1}

0 commit comments

Comments
 (0)