diff options
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 17 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.h | 4 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/win64-jumptable.ll | 60 |
3 files changed, 71 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 919fc485398..9d7c96a1b8e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -208,8 +208,10 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB, } // Mark 'Sym' as starting our funclet. - if (shouldEmitMoves || shouldEmitPersonality) + if (shouldEmitMoves || shouldEmitPersonality) { + CurrentFuncletTextSection = Asm->OutStreamer->getCurrentSectionOnly(); Asm->OutStreamer->EmitWinCFIStartProc(Sym); + } if (shouldEmitPersonality) { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); @@ -243,10 +245,6 @@ void WinException::endFunclet() { if (F->hasPersonalityFn()) Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts()); - // The .seh_handlerdata directive implicitly switches section, push the - // current section so that we may return to it. - Asm->OutStreamer->PushSection(); - // Emit an UNWIND_INFO struct describing the prologue. Asm->OutStreamer->EmitWinEHHandlerData(); @@ -265,11 +263,10 @@ void WinException::endFunclet() { emitCSpecificHandlerTable(MF); } - // Switch back to the previous section now that we are done writing to - // .xdata. - Asm->OutStreamer->PopSection(); - - // Emit a .seh_endproc directive to mark the end of the function. + // Switch back to the funclet start .text section now that we are done + // writing to .xdata, and emit an .seh_endproc directive to mark the end of + // the function. + Asm->OutStreamer->SwitchSection(CurrentFuncletTextSection); Asm->OutStreamer->EmitWinCFIEndProc(); } diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.h b/llvm/lib/CodeGen/AsmPrinter/WinException.h index acb30101691..371061c2c2e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.h +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.h @@ -21,6 +21,7 @@ class Function; class GlobalValue; class MachineFunction; class MCExpr; +class MCSection; class Value; struct WinEHFuncInfo; @@ -40,6 +41,9 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer { /// Pointer to the current funclet entry BB. const MachineBasicBlock *CurrentFuncletEntry = nullptr; + /// The section of the last funclet start. + MCSection *CurrentFuncletTextSection = nullptr; + void emitCSpecificHandlerTable(const MachineFunction *MF); void emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo, diff --git a/llvm/test/CodeGen/X86/win64-jumptable.ll b/llvm/test/CodeGen/X86/win64-jumptable.ll new file mode 100644 index 00000000000..6bb9d64c05c --- /dev/null +++ b/llvm/test/CodeGen/X86/win64-jumptable.ll @@ -0,0 +1,60 @@ +; RUN: llc < %s -relocation-model static | FileCheck %s + +; FIXME: Remove '-relocation-model static' when it is no longer necessary to +; trigger the separate .rdata section. + +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.0.24215" + +define void @f(i32 %x) { +entry: + switch i32 %x, label %sw.epilog [ + i32 0, label %sw.bb + i32 1, label %sw.bb1 + i32 2, label %sw.bb2 + i32 3, label %sw.bb3 + ] + +sw.bb: ; preds = %entry + tail call void @g(i32 0) #2 + br label %sw.epilog + +sw.bb1: ; preds = %entry + tail call void @g(i32 1) #2 + br label %sw.epilog + +sw.bb2: ; preds = %entry + tail call void @g(i32 2) #2 + br label %sw.epilog + +sw.bb3: ; preds = %entry + tail call void @g(i32 3) #2 + br label %sw.epilog + +sw.epilog: ; preds = %entry, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb + tail call void @g(i32 10) #2 + ret void +} + +declare void @g(i32) + +; CHECK: .text +; CHECK: f: +; CHECK: .seh_proc f +; CHECK: jmpq *.LJTI0_0 +; CHECK: .LBB0_{{.*}}: # %sw.bb +; CHECK: .LBB0_{{.*}}: # %sw.bb1 +; CHECK: .LBB0_{{.*}}: # %sw.bb2 +; CHECK: .LBB0_{{.*}}: # %sw.bb3 +; CHECK: callq g +; CHECK: jmp g # TAILCALL +; CHECK: .section .rdata,"dr" +; CHECK: .quad .LBB0_ +; CHECK: .quad .LBB0_ +; CHECK: .quad .LBB0_ +; CHECK: .quad .LBB0_ +; CHECK: .seh_handlerdata + +; It's important that we switch back to .text here, not .rdata. +; CHECK: .text +; CHECK: .seh_endproc |

