]> granicus.if.org Git - llvm/commitdiff
Revert [Windows] Disable TrapUnreachable for Win64, add SEH_NoReturn
authorReid Kleckner <rnk@google.com>
Tue, 3 Sep 2019 22:27:27 +0000 (22:27 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 3 Sep 2019 22:27:27 +0000 (22:27 +0000)
This reverts r370525 (git commit 0bb1630685fba255fa93def92603f064c2ffd203)
Also reverts r370543 (git commit 185ddc08eed6542781040b8499ef7ad15c8ae9f4)

The approach I took only works for functions marked `noreturn`. In
general, a call that is not known to be noreturn may be followed by
unreachable for other reasons. For example, there could be multiple call
sites to a function that throws sometimes, and at some call sites, it is
known to always throw, so it is followed by unreachable. We need to
insert an `int3` in these cases to pacify the Windows unwinder.

I think this probably deserves its own standalone, Win64-only fixup pass
that runs after block placement. Implementing that will take some time,
so let's revert to TrapUnreachable in the mean time.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370829 91177308-0d34-0410-b5e6-96231b3b80d8

21 files changed:
lib/Target/X86/X86FrameLowering.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrCompiler.td
lib/Target/X86/X86InstrInfo.td
lib/Target/X86/X86MCInstLower.cpp
lib/Target/X86/X86TargetMachine.cpp
test/CodeGen/WinEH/wineh-noret-cleanup.ll
test/CodeGen/X86/br-fold.ll
test/CodeGen/X86/catchpad-lifetime.ll
test/CodeGen/X86/catchpad-regmask.ll
test/CodeGen/X86/catchret-regmask.ll
test/CodeGen/X86/empty-function.ll
test/CodeGen/X86/funclet-layout.ll
test/CodeGen/X86/noreturn-call-win64.ll [deleted file]
test/CodeGen/X86/pr24374.ll
test/CodeGen/X86/trap.ll
test/CodeGen/X86/unreachable-trap.ll
test/CodeGen/X86/win64_call_epi.ll
test/CodeGen/X86/win64_eh.ll
test/DebugInfo/COFF/local-variable-gap.ll

index 681a618e2d53afa3fc72a52983fa214d100d5356..e1ed5aa5abcceae1e532339f147f972a92f6f75a 100644 (file)
@@ -2558,7 +2558,7 @@ bool blockEndIsUnreachable(const MachineBasicBlock &MBB,
              MBB.succ_begin(), MBB.succ_end(),
              [](const MachineBasicBlock *Succ) { return Succ->isEHPad(); }) &&
          std::all_of(MBBI, MBB.end(), [](const MachineInstr &MI) {
-           return MI.isMetaInstruction() || MI.getOpcode() == X86::SEH_NoReturn;
+           return MI.isMetaInstruction();
          });
 }
 
index 90ea103ac8f1b733b2fac01cabba8c192bdc06ff..3cc45a7add198b5c4f60b1348ebeaa5a8b5c7a0a 100644 (file)
@@ -4101,17 +4101,6 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
     InFlag = Chain.getValue(1);
   }
 
-  // Insert a pseudo instruction after noreturn calls that expands to int3 if
-  // this would be the last instruction in the funclet. If the return address of
-  // a call refers to the last PC of a function, the Windows SEH machinery can
-  // get confused about which function or scope the return address belongs to.
-  // MSVC inserts int3 after every noreturn function call, but LLVM only places
-  // them when it would cause a problem otherwise.
-  if (CLI.DoesNotReturn && Subtarget.isTargetWin64()) {
-    Chain = DAG.getNode(X86ISD::SEH_NORETURN, dl, NodeTys, Chain, InFlag);
-    InFlag = Chain.getValue(1);
-  }
-
   // Handle result values, copying them out of physregs into vregs that we
   // return.
   return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, DAG,
@@ -28729,7 +28718,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   case X86ISD::VASTART_SAVE_XMM_REGS: return "X86ISD::VASTART_SAVE_XMM_REGS";
   case X86ISD::VAARG_64:           return "X86ISD::VAARG_64";
   case X86ISD::WIN_ALLOCA:         return "X86ISD::WIN_ALLOCA";
-  case X86ISD::SEH_NORETURN:       return "X86ISD::SEH_NORETURN";
   case X86ISD::MEMBARRIER:         return "X86ISD::MEMBARRIER";
   case X86ISD::MFENCE:             return "X86ISD::MFENCE";
   case X86ISD::SEG_ALLOCA:         return "X86ISD::SEG_ALLOCA";
index e8255da23936e109891ae5d5546ac7267d1f1ee5..05e4f16fc49d11d0850911ea7f0a56078b8e923d 100644 (file)
@@ -531,9 +531,6 @@ namespace llvm {
       // Windows's _chkstk call to do stack probing.
       WIN_ALLOCA,
 
-      // Expands to int3 or nothing, depending on basic block layout.
-      SEH_NORETURN,
-
       // For allocating variable amounts of stack space when using
       // segmented stacks. Check if the current stacklet has enough space, and
       // falls back to heap allocation if not.
index 8462f42ffbe9c6c1b9c3ef8396ea097784d07396..efaccdc9ee96d4c7b69257392defff55ba7dc430 100644 (file)
@@ -239,9 +239,6 @@ let isPseudo = 1, SchedRW = [WriteSystem] in {
                             "#SEH_EndPrologue", []>;
   def SEH_Epilogue : I<0, Pseudo, (outs), (ins),
                             "#SEH_Epilogue", []>;
-  let hasSideEffects = 1 in
-    def SEH_NoReturn : I<0, Pseudo, (outs), (ins),
-                         "#SEH_NoReturn", [(X86SehNoReturn)]>;
 }
 
 //===----------------------------------------------------------------------===//
index 8745a35a84198d59902b7edd5bff33b83596c9ba..75958dd6c9e1002bbcd2d9a0d5c373f5117d7eef 100644 (file)
@@ -289,9 +289,6 @@ def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>;
 def X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_ALLOCA,
                           [SDNPHasChain, SDNPOutGlue]>;
 
-def X86SehNoReturn : SDNode<"X86ISD::SEH_NORETURN", SDTX86Void,
-                            [SDNPHasChain, SDNPInGlue, SDNPOutGlue]>;
-
 def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA,
                           [SDNPHasChain]>;
 
index d48e4a9998b81deb1362354cc783dfdd4f07d27b..0726b91c1966cd81ef2068a2ed36c7ded99917e3 100644 (file)
@@ -1921,20 +1921,6 @@ void X86AsmPrinter::EmitInstruction(const MachineInstr *MI) {
     return;
   }
 
-  case X86::SEH_NoReturn: {
-    // Materialize an int3 if this instruction is in the last basic block in the
-    // function. The int3 serves the same purpose as the noop emitted above for
-    // SEH_Epilogue, which is to make the Win64 unwinder happy. If the return
-    // address of the preceding call appears to precede an epilogue or a new
-    // function, then the unwinder may get lost.
-    const MachineBasicBlock *MBB = MI->getParent();
-    const MachineBasicBlock *NextMBB = MBB->getNextNode();
-    if (!NextMBB || NextMBB->isEHPad()) {
-      EmitAndCountInstruction(MCInstBuilder(X86::INT3));
-    }
-    return;
-  }
-
   // Lower PSHUFB and VPERMILP normally but add a comment if we can find
   // a constant shuffle mask. We won't be able to do this at the MC layer
   // because the mask isn't an immediate.
index f9839f39ec99459c0b1ca34aad346804240ba01f..d33a7a0b96309e9e1c51d089db67d0ff8b17b8c3 100644 (file)
@@ -219,9 +219,17 @@ X86TargetMachine::X86TargetMachine(const Target &T, const Triple &TT,
           getEffectiveX86CodeModel(CM, JIT, TT.getArch() == Triple::x86_64),
           OL),
       TLOF(createTLOF(getTargetTriple())) {
+  // Windows stack unwinder gets confused when execution flow "falls through"
+  // after a call to 'noreturn' function.
+  // To prevent that, we emit a trap for 'unreachable' IR instructions.
+  // (which on X86, happens to be the 'ud2' instruction)
   // On PS4, the "return address" of a 'noreturn' call must still be within
   // the calling function, and TrapUnreachable is an easy way to get that.
-  if (TT.isPS4() || TT.isOSBinFormatMachO()) {
+  // The check here for 64-bit windows is a bit icky, but as we're unlikely
+  // to ever want to mix 32 and 64-bit windows code in a single module
+  // this should be fine.
+  if ((TT.isOSWindows() && TT.getArch() == Triple::x86_64) || TT.isPS4() ||
+      TT.isOSBinFormatMachO()) {
     this->Options.TrapUnreachable = true;
     this->Options.NoTrapAfterNoreturn = TT.isOSBinFormatMachO();
   }
index 7d4d833aa9ba920abd818cca757f9d085dd85afc..9f7c995e5e77965122133c38651928c933095e61 100644 (file)
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
 ; RUN: sed -e s/.Cxx:// %s | llc -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefix=CXX
 ; RUN: sed -e s/.Seh:// %s | llc -mtriple=x86_64-pc-windows-msvc | FileCheck %s --check-prefix=SEH
 
@@ -68,13 +69,13 @@ catch.body.2:
 ; SEH-NEXT:    .long   .Ltmp0@IMGREL+1
 ; SEH-NEXT:    .long   .Ltmp1@IMGREL+1
 ; SEH-NEXT:    .long   dummy_filter@IMGREL
-; SEH-NEXT:    .long   .LBB0_5@IMGREL
+; SEH-NEXT:    .long   .LBB0_2@IMGREL
 ; SEH-NEXT:    .long   .Ltmp2@IMGREL+1
 ; SEH-NEXT:    .long   .Ltmp3@IMGREL+1
-; SEH-NEXT:    .long   "?dtor$2@?0?test@4HA"@IMGREL
+; SEH-NEXT:    .long   "?dtor$5@?0?test@4HA"@IMGREL 
 ; SEH-NEXT:    .long   0
 ; SEH-NEXT:    .long   .Ltmp2@IMGREL+1
 ; SEH-NEXT:    .long   .Ltmp3@IMGREL+1
 ; SEH-NEXT:    .long   dummy_filter@IMGREL
-; SEH-NEXT:    .long   .LBB0_5@IMGREL
+; SEH-NEXT:    .long   .LBB0_2@IMGREL
 ; SEH-NEXT:  .Llsda_end0:
index 6cd9b78c1c7edf8df02785d2a579a80a26678ca0..bcd672eb51712b429e3f2130872b32452a7f0d8c 100644 (file)
@@ -5,18 +5,18 @@
 ; RUN: llc -mtriple=x86_64-scei-ps4 < %s | FileCheck -check-prefix=PS4 %s
 
 ; X64_DARWIN: orq
-; X64_DARWIN-NEXT: ud2
+; X64-DARWIN-NEXT: ud2
 
 ; X64_LINUX: orq %rax, %rcx
 ; X64_LINUX-NEXT: jne
 ; X64_LINUX-NEXT: %bb8.i329
 
 ; X64_WINDOWS: orq %rax, %rcx
-; X64_WINDOWS-NEXT: jne
+; X64_WINDOWS-NEXT: ud2
 
 ; X64_WINDOWS_GNU: movq .refptr._ZN11xercesc_2_513SchemaSymbols21fgURI_SCHEMAFORSCHEMAE(%rip), %rax
 ; X64_WINDOWS_GNU: orq .refptr._ZN11xercesc_2_56XMLUni16fgNotationStringE(%rip), %rax
-; X64_WINDOWS_GNU-NEXT: jne
+; X64_WINDOWS_GNU-NEXT: ud2
 
 ; PS4: orq %rax, %rcx
 ; PS4-NEXT: ud2
index 8a6d4cbd271de7e2fc97d4bcc0577fe9f33ce466..d85adec360c8a2a8465e598178bc5a6d686557fb 100644 (file)
@@ -7,8 +7,6 @@ declare void @throw()
 
 declare i32 @__CxxFrameHandler3(...)
 
-declare void @llvm.trap()
-
 define void @test1() personality i32 (...)* @__CxxFrameHandler3 {
 entry:
   %alloca2 = alloca i8*, align 4
@@ -32,7 +30,6 @@ catch.pad:                                        ; preds = %catch.dispatch
   %bc2 = bitcast i8** %alloca2 to i8*
   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bc2)
   store volatile i8* null, i8** %alloca1
-  call void @llvm.trap()
   unreachable
 
 ; CHECK-LABEL: "?catch$2@?0?test1@4HA"
@@ -70,7 +67,6 @@ catch.pad:                                        ; preds = %catch.dispatch
   %bc2 = bitcast i8** %alloca2 to i8*
   call void @llvm.lifetime.start.p0i8(i64 4, i8* %bc2)
   store volatile i8* null, i8** %alloca1
-  call void @llvm.trap()
   unreachable
 
 ; CHECK-LABEL: "?catch$2@?0?test2@4HA"
index 0981f8e15f12f750d25fefe4e498ea18379b4e1e..0d436f6eb595dffd4162e13c2981c1ed286e8ffc 100644 (file)
@@ -75,7 +75,7 @@ unreachable:                                      ; preds = %entry
 ; CHECK: popq %rbp
 ; CHECK: retq
 
-; CHECK: "?catch${{[0-9]+}}@?0?global_array@4HA":
+; CHECK: "?catch$2@?0?global_array@4HA":
 ; CHECK: pushq   %rbp
 ; CHECK: movslq  {{.*}}, %[[idx:[^ ]*]]
 ; CHECK: leaq    array(%rip), %[[base:[^ ]*]]
@@ -122,7 +122,7 @@ unreachable:                                      ; preds = %entry
 ; CHECK: popq %rbp
 ; CHECK: retq
 
-; CHECK: "?catch${{[0-9]+}}@?0?access_imported@4HA":
+; CHECK: "?catch$2@?0?access_imported@4HA":
 ; CHECK: pushq   %rbp
 ; CHECK: movq    __imp_imported(%rip), %[[base:[^ ]*]]
 ; CHECK: movl    $222, (%[[base]])
index 4af57e109f18300c9e0e092af80acb6b4f366d2c..1231172a7e95147a283f0e98f300c331ab10fce6 100644 (file)
@@ -6,7 +6,6 @@ target triple = "x86_64-pc-windows-msvc"
 declare i32 @__CxxFrameHandler3(...)
 declare void @throw() noreturn uwtable
 declare i8* @getval()
-declare void @llvm.trap()
 
 define i8* @reload_out_of_pad(i8* %arg) #0 personality i32 (...)* @__CxxFrameHandler3 {
 assertPassed:
@@ -20,7 +19,6 @@ catch:
   ; This block *must* appear after the catchret to test the bug.
   ; FIXME: Make this an MIR test so we can control MBB layout.
 unreachable:
-  call void @llvm.trap()
   unreachable
 
 catch.dispatch:
@@ -37,7 +35,7 @@ return:
 ; CHECK: movq -[[arg_slot]](%rbp), %rax # 8-byte Reload
 ; CHECK: retq
 
-; CHECK: "?catch${{[0-9]+}}@?0?reload_out_of_pad@4HA":
+; CHECK: "?catch$3@?0?reload_out_of_pad@4HA":
 ; CHECK-NOT: Reload
 ; CHECK: retq
 
@@ -52,7 +50,6 @@ catch:
   catchret from %cp to label %return
 
 unreachable:
-  call void @llvm.trap()
   unreachable
 
 catch.dispatch:
@@ -68,7 +65,7 @@ return:
 ; CHECK: movq -[[val_slot:[0-9]+]](%rbp), %rax # 8-byte Reload
 ; CHECK: retq
 
-; CHECK: "?catch${{[0-9]+}}@?0?spill_in_pad@4HA":
+; CHECK: "?catch$3@?0?spill_in_pad@4HA":
 ; CHECK: callq getval
 ; CHECK: movq %rax, -[[val_slot]](%rbp) # 8-byte Spill
 ; CHECK: retq
index 7d908311ec8dc54fb6a595ef5e0663392fd5a2f8..92bebd0ab1a7cbfdce21ba6accf81d5c1bb5860d 100644 (file)
@@ -15,7 +15,7 @@ entry:
 
 ; CHECK-LABEL: f:
 ; WIN32: nop
-; WIN64: nop
+; WIN64: ud2
 ; LINUX-NOT: nop
 ; LINUX-NOT: ud2
 
index 72f60ea72d43d271eb1cffccad566d2c527be1a6..0942645cf5a40e5f491896659adfed2ca49ef578 100644 (file)
@@ -9,8 +9,6 @@ target triple = "x86_64-pc-windows-msvc"
 @"\01??_7type_info@@6B@" = external constant i8*
 @"\01??_R0H@8" = internal global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }
 
-declare void @llvm.trap()
-
 define void @test1(i1 %B) personality i32 (...)* @__CxxFrameHandler3 {
 entry:
   invoke void @g()
@@ -33,7 +31,6 @@ try.cont:
   ret void
 
 unreachable:
-  call void @llvm.trap()
   unreachable
 }
 
@@ -79,7 +76,6 @@ try.cont.5:                                       ; preds = %try.cont
   ret i32 0
 
 unreachable:                                      ; preds = %catch, %entry
-  call void @llvm.trap()
   unreachable
 }
 
@@ -129,13 +125,11 @@ try.cont:                                         ; preds = %entry
   br i1 %V, label %exit_one, label %exit_two
 
 exit_one:
-  tail call void @g()
-  call void @llvm.trap()
+  tail call void @exit(i32 0)
   unreachable
 
 exit_two:
-  tail call void @g()
-  call void @llvm.trap()
+  tail call void @exit(i32 0)
   unreachable
 }
 
@@ -144,7 +138,7 @@ exit_two:
 ; The entry funclet contains %entry and %try.cont
 ; CHECK: # %entry
 ; CHECK: # %try.cont
-; CHECK: callq g
+; CHECK: callq exit
 ; CHECK-NOT: # exit_one
 ; CHECK-NOT: # exit_two
 ; CHECK: ud2
@@ -152,12 +146,12 @@ exit_two:
 ; The catch(...) funclet contains %catch.2
 ; CHECK: # %catch.2{{$}}
 ; CHECK: callq exit
-; CHECK-NEXT: int3
+; CHECK: ud2
 
 ; The catch(int) funclet contains %catch
 ; CHECK: # %catch{{$}}
 ; CHECK: callq exit
-; CHECK-NEXT: int3
+; CHECK: ud2
 
 declare void @exit(i32) noreturn nounwind
 declare void @_CxxThrowException(i8*, %eh.ThrowInfo*)
diff --git a/test/CodeGen/X86/noreturn-call-win64.ll b/test/CodeGen/X86/noreturn-call-win64.ll
deleted file mode 100644 (file)
index 6289eef..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s
-
-; Function Attrs: noinline nounwind optnone uwtable
-define dso_local i32 @foo() {
-entry:
-  %call = call i32 @cond()
-  %tobool = icmp ne i32 %call, 0
-  br i1 %tobool, label %if.then, label %if.end
-
-if.then:                                          ; preds = %entry
-  call void @abort1()
-  unreachable
-
-if.end:                                           ; preds = %entry
-  %call1 = call i32 @cond()
-  %tobool2 = icmp ne i32 %call1, 0
-  br i1 %tobool2, label %if.then3, label %if.end4
-
-if.then3:                                         ; preds = %if.end
-  call void @abort2()
-  unreachable
-
-if.end4:                                          ; preds = %if.end
-  %call5 = call i32 @cond()
-  %tobool6 = icmp ne i32 %call5, 0
-  br i1 %tobool6, label %if.then7, label %if.end8
-
-if.then7:                                         ; preds = %if.end4
-  call void @abort3()
-  unreachable
-
-if.end8:                                          ; preds = %if.end4
-  ret i32 0
-}
-
-; CHECK-LABEL: foo:
-; CHECK: callq cond
-; CHECK: callq cond
-; CHECK: callq cond
-;   We don't need int3's between these calls to abort, since they won't confuse
-;   the unwinder.
-; CHECK: callq abort1
-; CHECK-NEXT:   # %if.then3
-; CHECK: callq abort2
-; CHECK-NEXT:   # %if.then7
-; CHECK: callq abort3
-; CHECK-NEXT: int3
-
-declare dso_local i32 @cond()
-
-declare dso_local void @abort1() noreturn
-declare dso_local void @abort2() noreturn
-declare dso_local void @abort3() noreturn
index 7ad05e8b77a89d64cfb048d29201b8d8dce259da..dab3b3f41599a1ecbb5384d064148cbf03772765 100644 (file)
@@ -31,6 +31,6 @@ define void @g() {
   unreachable
 }
 ; CHECK-LABEL: g:
-; CHECK: nop
+; CHECK: ud2
 
 attributes #0 = { nounwind }
index 452be48a605e59f524b478ed494772086bad7484..ca33f9e6b4e1e8dd4d3241d2a580e7564e67e292 100644 (file)
@@ -1,19 +1,13 @@
 ; RUN: llc < %s -mtriple=i686-apple-darwin8 -mcpu=yonah | FileCheck %s -check-prefix=DARWIN
 ; RUN: llc < %s -mtriple=i686-unknown-linux -mcpu=yonah | FileCheck %s -check-prefix=LINUX
 ; RUN: llc < %s -mtriple=x86_64-scei-ps4 | FileCheck %s -check-prefix=PS4
-; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s -check-prefix=WIN64
 
 ; DARWIN-LABEL: test0:
 ; DARWIN: ud2
 ; LINUX-LABEL: test0:
 ; LINUX: ud2
-; FIXME: PS4 probably doesn't want two ud2s.
 ; PS4-LABEL: test0:
 ; PS4: ud2
-; PS4: ud2
-; WIN64-LABEL: test0:
-; WIN64: ud2
-; WIN64-NOT: ud2
 define i32 @test0() noreturn nounwind  {
 entry:
        tail call void @llvm.trap( )
@@ -26,9 +20,6 @@ entry:
 ; LINUX: int3
 ; PS4-LABEL: test1:
 ; PS4: int     $65
-; WIN64-LABEL: test1:
-; WIN64: int3
-; WIN64-NOT: ud2
 define i32 @test1() noreturn nounwind  {
 entry:
        tail call void @llvm.debugtrap( )
index ee1a11c767784fcf77fa271b6f26a9881915d0d6..8de0510ed387b6db06f23280b337f447366e1f75 100644 (file)
@@ -1,13 +1,10 @@
-; RUN: llc -o - %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=CHECK,NORMAL
-; RUN: llc -o - %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefixes=CHECK,NORMAL
-; RUN: llc -o - %s -mtriple=x86_64-scei-ps4 | FileCheck %s --check-prefixes=CHECK,TRAP_AFTER_NORETURN
+; RUN: llc -o - %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefixes=CHECK,TRAP_AFTER_NORETURN
 ; RUN: llc -o - %s -mtriple=x86_64-apple-darwin | FileCheck %s --check-prefixes=CHECK,NO_TRAP_AFTER_NORETURN
 
 ; CHECK-LABEL: call_exit:
 ; CHECK: callq {{_?}}exit
 ; TRAP_AFTER_NORETURN: ud2
 ; NO_TRAP_AFTER_NORETURN-NOT: ud2
-; NORMAL-NOT: ud2
 define i32 @call_exit() noreturn nounwind {
   tail call void @exit(i32 0)
   unreachable
@@ -17,17 +14,13 @@ define i32 @call_exit() noreturn nounwind {
 ; CHECK: ud2
 ; TRAP_AFTER_NORETURN: ud2
 ; NO_TRAP_AFTER_NORETURN-NOT: ud2
-; NORMAL-NOT: ud2
 define i32 @trap() noreturn nounwind {
   tail call void @llvm.trap()
   unreachable
 }
 
 ; CHECK-LABEL: unreachable:
-; TRAP_AFTER_NORETURN: ud2
-; NO_TRAP_AFTER_NORETURN: ud2
-; NORMAL-NOT: ud2
-; NORMAL: # -- End function
+; CHECK: ud2
 define i32 @unreachable() noreturn nounwind {
   unreachable
 }
index 3e8f57e6514595d5e263eb467335450c5efe0a08..096cbe41c5404431ac903bbbefb262e14f5fe5a6 100644 (file)
@@ -24,9 +24,10 @@ catch:
 ; WIN64: nop
 ; WIN64: addq ${{[0-9]+}}, %rsp
 ; WIN64: retq
-; Check for 'int3' after noreturn call.
+; Check for 'ud2' after noreturn call
 ; WIN64: callq _Unwind_Resume
-; WIN64-NEXT: int3
+; WIN64-NEXT: ud2
+; WIN64: .seh_endproc
 
 
 ; Check it still works when blocks are reordered.
index caadea4fe2e4bbab93c843d79d333d47a00a31a2..7f6a3629613ceae39107d5481dd13330ba96b179 100644 (file)
@@ -125,11 +125,11 @@ endtryfinally:
 ; WIN64-LABEL: foo4:
 ; WIN64: .seh_proc foo4
 ; WIN64: .seh_handler _d_eh_personality, @unwind, @except
-; NORM:  subq $40, %rsp
-; ATOM:  leaq -40(%rsp), %rsp
-; WIN64: .seh_stackalloc 40
+; NORM:  subq $56, %rsp
+; ATOM:  leaq -56(%rsp), %rsp
+; WIN64: .seh_stackalloc 56
 ; WIN64: .seh_endprologue
-; WIN64: addq $40, %rsp
+; WIN64: addq $56, %rsp
 ; WIN64: ret
 ; WIN64: .seh_handlerdata
 ; WIN64: .seh_endproc
index 5bbc058b5b3ce51e02727218f89ce2c7e550b94a..db8de6327392a36c8473d68aff3292652cf3301b 100644 (file)
@@ -54,7 +54,7 @@
 ; ASM: [[p_b2:\.Ltmp[0-9]+]]:
 ; ASM:         #DEBUG_VALUE: p <- $esi
 ; ASM:         callq   call_noreturn
-; ASM:         int3
+; ASM:         ud2
 ; ASM: .Lfunc_end0:
 
 ; ASM:         .short  {{.*}}         # Record length