[llvm] 0980038 - Handle CET for -exception-model sjlj

Xiang1 Zhang via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 19 20:14:25 PDT 2020


Author: Xiang1 Zhang
Date: 2020-04-20T11:13:40+08:00
New Revision: 0980038a5e449a669727f2fbf403e843c1dc1018

URL: https://github.com/llvm/llvm-project/commit/0980038a5e449a669727f2fbf403e843c1dc1018
DIFF: https://github.com/llvm/llvm-project/commit/0980038a5e449a669727f2fbf403e843c1dc1018.diff

LOG: Handle CET for -exception-model sjlj

Summary:
In SjLj exception mode, the old landingpad BB will create a new landingpad BB and use indirect branch jump to the old landingpad BB in lowering.
So we should add 2 endbr for this exception model.

Reviewers: hjl.tools, craig.topper, annita.zhang, LuoYuanke, pengfei, efriedma

Reviewed By: LuoYuanke

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D77124

Added: 
    llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll

Modified: 
    llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
    llvm/test/CodeGen/X86/indirect-branch-tracking-eh.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
index 0a79b793a980..fe28c3ef8d7b 100644
--- a/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
+++ b/llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
@@ -138,17 +138,38 @@ bool X86IndirectBranchTrackingPass::runOnMachineFunction(MachineFunction &MF) {
     if (MBB.hasAddressTaken())
       Changed |= addENDBR(MBB, MBB.begin());
 
-    // Exception handle may indirectly jump to catch pad, So we should add
-    // ENDBR before catch pad instructions.
-    bool EHPadIBTNeeded = MBB.isEHPad();
-
     for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
       if (I->isCall() && IsCallReturnTwice(I->getOperand(0)))
         Changed |= addENDBR(MBB, std::next(I));
+    }
 
-      if (EHPadIBTNeeded && I->isEHLabel()) {
+    // Exception handle may indirectly jump to catch pad, So we should add
+    // ENDBR before catch pad instructions. For SjLj exception model, it will
+    // create a new BB(new landingpad) indirectly jump to the old landingpad.
+    if (TM->Options.ExceptionModel == ExceptionHandling::SjLj) {
+      for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
+        // New Landingpad BB without EHLabel.
+        if (MBB.isEHPad()) {
+          if (I->isDebugInstr())
+            continue;
+          Changed |= addENDBR(MBB, I);
+          break;
+        } else if (I->isEHLabel()) {
+          // Old Landingpad BB (is not Landingpad now) with
+          // the the old "callee" EHLabel.
+          MCSymbol *Sym = I->getOperand(0).getMCSymbol();
+          if (!MF.hasCallSiteLandingPad(Sym))
+            continue;
+          Changed |= addENDBR(MBB, std::next(I));
+          break;
+        }
+      }
+    } else if (MBB.isEHPad()){
+      for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
+        if (!I->isEHLabel())
+          continue;
         Changed |= addENDBR(MBB, std::next(I));
-        EHPadIBTNeeded = false;
+        break;
       }
     }
   }

diff  --git a/llvm/test/CodeGen/X86/indirect-branch-tracking-eh.ll b/llvm/test/CodeGen/X86/indirect-branch-tracking-eh.ll
index c14e82dc8f3d..ef36e0e1b593 100644
--- a/llvm/test/CodeGen/X86/indirect-branch-tracking-eh.ll
+++ b/llvm/test/CodeGen/X86/indirect-branch-tracking-eh.ll
@@ -1,15 +1,78 @@
-; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
-; RUN: llc -mtriple=i386-unknown-unknown < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=X86_64
+; RUN: llc -mtriple=i386-unknown-unknown < %s | FileCheck %s --check-prefix=X86
+; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj -verify-machineinstrs=0 < %s | FileCheck %s --check-prefix=SJLJ
+; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj -verify-machineinstrs=0 < %s | FileCheck %s --check-prefix=NUM
+
+; X86_64:       test_eh:                                # @test_eh
+; X86_64-NEXT:  .Lfunc_begin0:
+; X86_64:       # %bb.0:                                # %entry
+; X86_64-NEXT:          endbr64
+; X86_64-NEXT:          pushq   %rax
+; X86_64:       .Ltmp0:
+; X86_64-NEXT:          callq   _Z20function_that_throwsv
+; X86_64-NEXT:  .Ltmp1:
+; X86_64-NEXT:  # %bb.1:                                # %try.cont
+; X86_64:               retq
+; X86_64-NEXT:  .LBB0_2:                                # %lpad
+; X86_64-NEXT:          .cfi_def_cfa_offset 16
+; X86_64-NEXT:  .Ltmp2:
+; X86_64-NEXT:          endbr64
+; X86_64:               callq   __cxa_begin_catch
+
+
+; X86:       test_eh:                                # @test_eh
+; X86-NEXT:  .Lfunc_begin0:
+; X86:       # %bb.0:                                # %entry
+; X86-NEXT:          endbr32
+; X86-NEXT:  .Ltmp0:
+; X86:               calll   _Z20function_that_throwsv
+; X86-NEXT:  .Ltmp1:
+; X86-NEXT:  # %bb.1:                                # %try.cont
+; X86-NEXT:          retl
+; X86-NEXT:  .LBB0_2:                                # %lpad
+; X86-NEXT:  .Ltmp2:
+; X86-NEXT:          endbr32
+; X86:               calll   __cxa_begin_catch
+
+; NUM-COUNT-3: endbr32
+
+; SJLJ:       test_eh:
+; SJLJ-NEXT:  Lfunc_begin0:
+; SJLJ-NEXT:  # %bb.0:                                # %entry
+; SJLJ-NEXT:          endbr32
+; SJLJ:               calll   __Unwind_SjLj_Register
+; SJLJ:       Ltmp0:
+; SJLJ:               calll   __Z20function_that_throwsv
+; SJLJ:       LBB0_2:                                 # %try.cont
+; SJLJ:               calll   __Unwind_SjLj_Unregister
+; SJLJ:               retl
+
+; SJLJ:       LBB0_3:
+; SJLJ-NEXT:          endbr32
+; SJLJ-NEXT:          leal
+; SJLJ-NEXT:          movl
+; SJLJ-NEXT:          cmpl
+; SJLJ-NEXT:          jb      LBB0_4
+
+; SJLJ:       LBB0_4:
+; SJLJ-NEXT:          jmpl    *LJTI0_0(,%eax,4)
+
+; SJLJ:       LBB0_6:                                 # %lpad
+; SJLJ-NEXT:  Ltmp2:
+; SJLJ-NEXT:          endbr32
+; SJLJ:               calll   ___cxa_begin_catch
+; SJLJ:               jmp     LBB0_2
+; SJLJ:       LJTI0_0:
+; SJLJ-NEXT:          .long   LBB0_6
+
 
-;There should be 2 endbr* instruction at entry and catch pad.
-;CHECK-COUNT-2: endbr
 
 declare void @_Z20function_that_throwsv()
 declare i32 @__gxx_personality_sj0(...)
 declare i8* @__cxa_begin_catch(i8*)
 declare void @__cxa_end_catch()
 
-define void @test8() personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
+define void @test_eh() personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
 entry:
   invoke void @_Z20function_that_throwsv()
           to label %try.cont unwind label %lpad

diff  --git a/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll b/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
new file mode 100644
index 000000000000..312707a029cd
--- /dev/null
+++ b/llvm/test/CodeGen/X86/indirect-branch-tracking-eh2.ll
@@ -0,0 +1,149 @@
+; RUN: llc -mtriple x86_64-unknown-unknown -exception-model sjlj -verify-machineinstrs=0 < %s | FileCheck %s --check-prefix=NUM
+; RUN: llc -mtriple x86_64-unknown-unknown -exception-model sjlj -verify-machineinstrs=0 < %s | FileCheck %s --check-prefix=SJLJ
+
+; NUM-COUNT-3: endbr64
+
+;SJLJ:       main:                                  # @main
+;SJLJ-NEXT: .Lmain$local:
+;SJLJ-NEXT: .Lfunc_begin0:
+;SJLJ-NEXT: # %bb.0:                                # %entry
+;SJLJ-NEXT:         endbr64
+;SJLJ-NEXT:         pushq   %rbp
+;SJLJ:               callq   _Unwind_SjLj_Register
+;SJLJ-NEXT: .Ltmp0:
+;SJLJ-NEXT:         callq   _Z3foov
+;SJLJ-NEXT: .Ltmp1:
+;SJLJ-NEXT: # %bb.1:                                # %invoke.cont
+;SJLJ-NEXT:         movl
+;SJLJ-NEXT: .LBB0_7:                                # %return
+;SJLJ:               callq   _Unwind_SjLj_Unregister
+;SJLJ:               retq
+;SJLJ-NEXT: .LBB0_9:
+;SJLJ-NEXT:         endbr64
+;SJLJ-NEXT:         movl
+;SJLJ-NEXT:         cmpl
+;SJLJ-NEXT:         jb      .LBB0_10
+;SJLJ-NEXT: # %bb.11:
+;SJLJ-NEXT:         ud2
+;SJLJ-NEXT: .LBB0_10:
+;SJLJ-NEXT:         leaq    .LJTI0_0(%rip), %rcx
+;SJLJ-NEXT:         jmpq    *(%rcx,%rax,8)
+;SJLJ-NEXT: .LBB0_2:                                # %lpad
+;SJLJ-NEXT: .Ltmp2:
+;SJLJ-NEXT:         endbr64
+;SJLJ:               jne     .LBB0_4
+;SJLJ-NEXT: # %bb.3:                                # %catch3
+;SJLJ:               callq   __cxa_begin_catch
+;SJLJ:               jmp     .LBB0_6
+;SJLJ-NEXT: .LBB0_4:                                # %catch.fallthrough
+;SJLJ-NEXT:         cmpl
+;SJLJ-NEXT:         jne     .LBB0_8
+;SJLJ-NEXT: # %bb.5:                                # %catch
+;SJLJ:               callq   __cxa_begin_catch
+;SJLJ:               cmpb
+;SJLJ-NEXT: .LBB0_6:                                # %return
+;SJLJ:               callq   __cxa_end_catch
+;SJLJ-NEXT:         jmp     .LBB0_7
+;SJLJ-NEXT: .LBB0_8:                                # %eh.resume
+;SJLJ-NEXT:         movl
+;SJLJ-NEXT: .Lfunc_end0:
+;SJLJ:      .LJTI0_0:
+;SJLJ-NEXT:         .quad   .LBB0_2
+
+ at _ZTIi = external dso_local constant i8*
+ at _ZTIc = external dso_local constant i8*
+
+; Function Attrs: noinline norecurse optnone uwtable
+define dso_local i32 @main() #0 personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
+entry:
+  %retval = alloca i32, align 4
+  %exn.slot = alloca i8*
+  %ehselector.slot = alloca i32
+  %x = alloca i8, align 1
+  %x4 = alloca i32, align 4
+  store i32 0, i32* %retval, align 4
+  invoke void @_Z3foov()
+          to label %invoke.cont unwind label %lpad
+
+invoke.cont:                                      ; preds = %entry
+  br label %try.cont
+
+lpad:                                             ; preds = %entry
+  %0 = landingpad { i8*, i32 }
+          catch i8* bitcast (i8** @_ZTIi to i8*)
+          catch i8* bitcast (i8** @_ZTIc to i8*)
+  %1 = extractvalue { i8*, i32 } %0, 0
+  store i8* %1, i8** %exn.slot, align 8
+  %2 = extractvalue { i8*, i32 } %0, 1
+  store i32 %2, i32* %ehselector.slot, align 4
+  br label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %lpad
+  %sel = load i32, i32* %ehselector.slot, align 4
+  %3 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3
+  %matches = icmp eq i32 %sel, %3
+  br i1 %matches, label %catch3, label %catch.fallthrough
+
+catch3:                                           ; preds = %catch.dispatch
+  %exn5 = load i8*, i8** %exn.slot, align 8
+  %4 = call i8* @__cxa_begin_catch(i8* %exn5) #3
+  %5 = bitcast i8* %4 to i32*
+  %6 = load i32, i32* %5, align 4
+  store i32 %6, i32* %x4, align 4
+  %7 = load i32, i32* %x4, align 4
+  %cmp6 = icmp ne i32 %7, 5
+  %conv7 = zext i1 %cmp6 to i32
+  store i32 %conv7, i32* %retval, align 4
+  call void @__cxa_end_catch() #3
+  br label %return
+
+catch.fallthrough:                                ; preds = %catch.dispatch
+  %8 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIc to i8*)) #3
+  %matches1 = icmp eq i32 %sel, %8
+  br i1 %matches1, label %catch, label %eh.resume
+
+catch:                                            ; preds = %catch.fallthrough
+  %exn = load i8*, i8** %exn.slot, align 8
+  %9 = call i8* @__cxa_begin_catch(i8* %exn) #3
+  %10 = load i8, i8* %9, align 1
+  store i8 %10, i8* %x, align 1
+  %11 = load i8, i8* %x, align 1
+  %conv = sext i8 %11 to i32
+  %cmp = icmp ne i32 %conv, 3
+  %conv2 = zext i1 %cmp to i32
+  store i32 %conv2, i32* %retval, align 4
+  call void @__cxa_end_catch() #3
+  br label %return
+
+try.cont:                                         ; preds = %invoke.cont
+  store i32 1, i32* %retval, align 4
+  br label %return
+
+return:                                           ; preds = %try.cont, %catch3, %catch
+  %12 = load i32, i32* %retval, align 4
+  ret i32 %12
+
+eh.resume:                                        ; preds = %catch.fallthrough
+  %exn8 = load i8*, i8** %exn.slot, align 8
+  %sel9 = load i32, i32* %ehselector.slot, align 4
+  %lpad.val = insertvalue { i8*, i32 } undef, i8* %exn8, 0
+  %lpad.val10 = insertvalue { i8*, i32 } %lpad.val, i32 %sel9, 1
+  resume { i8*, i32 } %lpad.val10
+}
+
+declare dso_local void @_Z3foov() #1
+
+declare dso_local i32 @__gxx_personality_sj0(...)
+
+; Function Attrs: nounwind readnone
+declare i32 @llvm.eh.typeid.for(i8*) #2
+
+declare dso_local i8* @__cxa_begin_catch(i8*)
+
+declare dso_local void @__cxa_end_catch()
+
+!llvm.module.flags = !{!0, !1, !2}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 4, !"cf-protection-return", i32 1}
+!2 = !{i32 4, !"cf-protection-branch", i32 1}


        


More information about the llvm-commits mailing list