diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -178,6 +178,9 @@ MCSection *getSectionForJumpTable(const Function &F, const TargetMachine &TM) const override; + bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, + const Function &F) const override; + /// Emit Obj-C garbage collection and linker options. void emitModuleMetadata(MCStreamer &Streamer, Module &M) const override; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -71,6 +71,10 @@ using namespace llvm; using namespace dwarf; +static cl::opt JumpTableInFunctionSection( + "jumptable-in-function-section", cl::Hidden, cl::init(false), + cl::desc("Putting Jump Table in function section")); + static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags, StringRef &Section) { SmallVector ModuleFlags; @@ -1777,6 +1781,24 @@ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); } +bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection( + bool UsesLabelDifference, const Function &F) const { + switch (TM->getTargetTriple().getArch()) { + case Triple::x86: + case Triple::x86_64: + if (!JumpTableInFunctionSection) { + // We can always create relative relocations, so use another section + // that can be marked non-executable. + return false; + } + break; + default: + break; + } + return TargetLoweringObjectFile::shouldPutJumpTableInFunctionSection( + UsesLabelDifference, F); +} + void TargetLoweringObjectFileCOFF::emitModuleMetadata(MCStreamer &Streamer, Module &M) const { emitLinkerDirectives(Streamer, M); diff --git a/llvm/test/MC/COFF/x86-jumptable-rdata.ll b/llvm/test/MC/COFF/x86-jumptable-rdata.ll new file mode 100644 --- /dev/null +++ b/llvm/test/MC/COFF/x86-jumptable-rdata.ll @@ -0,0 +1,36 @@ +; RUN: llc -mtriple x86_64-pc-win32 < %s | FileCheck %s +; RUN: llc -mtriple x86_64-pc-win32 -jumptable-in-function-section < %s | FileCheck --check-prefixes=CHECK-OPT %s + +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: + tail call void @g(i32 0, i32 4) + br label %sw.epilog + +sw.bb1: + tail call void @g(i32 1, i32 5) + br label %sw.epilog + +sw.bb2: + tail call void @g(i32 2, i32 6) + br label %sw.epilog + +sw.bb3: + tail call void @g(i32 3, i32 7) + br label %sw.epilog + +sw.epilog: + tail call void @g(i32 10, i32 8) + ret void +} + +declare void @g(i32, i32) +; CHECK: .section .rdata +; CHECK-OPT-NOT: .section .rdata