]> granicus.if.org Git - llvm/commitdiff
Merging r352465:
authorHans Wennborg <hans@hanshq.net>
Mon, 4 Mar 2019 12:44:42 +0000 (12:44 +0000)
committerHans Wennborg <hans@hanshq.net>
Mon, 4 Mar 2019 12:44:42 +0000 (12:44 +0000)
------------------------------------------------------------------------
r352465 | mstorsjo | 2019-01-29 10:36:48 +0100 (Tue, 29 Jan 2019) | 17 lines

[COFF, ARM64] Don't put jump table into a separate COFF section for EK_LabelDifference32

Windows ARM64 has PIC relocation model and uses jump table kind
EK_LabelDifference32. This produces jump table entry as
".word LBB123 - LJTI1_2" which represents the distance between the block
and jump table.

A new relocation type (IMAGE_REL_ARM64_REL32) is needed to do the fixup
correctly if they are in different COFF section.

This change saves the jump table to the same COFF section as the
associated code. An ideal fix could be utilizing IMAGE_REL_ARM64_REL32
relocation type.

Patch by Tom Tan!

Differential Revision: https://reviews.llvm.org/D57277
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_80@355311 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AArch64/AArch64AsmPrinter.cpp
lib/Target/AArch64/AArch64TargetMachine.cpp
test/CodeGen/AArch64/win64-jumptable.ll [new file with mode: 0644]

index 0254a572434f46d927ede066f11e285a422c1490..2e1d1f1130a9db3c167e1090b2d851ca0ddad879 100644 (file)
@@ -471,9 +471,18 @@ void AArch64AsmPrinter::EmitJumpTableInfo() {
   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
   if (JT.empty()) return;
 
+  const Function &F = MF->getFunction();
   const TargetLoweringObjectFile &TLOF = getObjFileLowering();
-  MCSection *ReadOnlySec = TLOF.getSectionForJumpTable(MF->getFunction(), TM);
-  OutStreamer->SwitchSection(ReadOnlySec);
+  bool JTInDiffSection =
+      !STI->isTargetCOFF() ||
+      !TLOF.shouldPutJumpTableInFunctionSection(
+          MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32,
+          F);
+  if (JTInDiffSection) {
+      // Drop it in the readonly section.
+      MCSection *ReadOnlySec = TLOF.getSectionForJumpTable(F, TM);
+      OutStreamer->SwitchSection(ReadOnlySec);
+  }
 
   auto AFI = MF->getInfo<AArch64FunctionInfo>();
   for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
index 4e016525f7e4e6bc1fea1dad2b68c2b58904541b..219c33ef73c516de4695303d4720a5e93fc7b04b 100644 (file)
@@ -209,8 +209,8 @@ static std::string computeDataLayout(const Triple &TT,
 
 static Reloc::Model getEffectiveRelocModel(const Triple &TT,
                                            Optional<Reloc::Model> RM) {
-  // AArch64 Darwin is always PIC.
-  if (TT.isOSDarwin())
+  // AArch64 Darwin and Windows are always PIC.
+  if (TT.isOSDarwin() || TT.isOSWindows())
     return Reloc::PIC_;
   // On ELF platforms the default static relocation model has a smart enough
   // linker to cope with referencing external symbols defined in a shared
diff --git a/test/CodeGen/AArch64/win64-jumptable.ll b/test/CodeGen/AArch64/win64-jumptable.ll
new file mode 100644 (file)
index 0000000..8148a59
--- /dev/null
@@ -0,0 +1,48 @@
+; RUN: llc -o - %s -mtriple=aarch64-windows -aarch64-enable-compress-jump-tables=0 | FileCheck %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:                                            ; 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:               b       g
+; CHECK-NEXT:  .p2align        2
+; CHECK-NEXT:  .LJTI0_0:
+; CHECK:               .word   .LBB0_2-.LJTI0_0
+; CHECK:               .word   .LBB0_3-.LJTI0_0
+; CHECK:               .word   .LBB0_4-.LJTI0_0
+; CHECK:               .word   .LBB0_5-.LJTI0_0
+; CHECK:               .section        .xdata,"dr"
+; CHECK:               .seh_handlerdata
+; CHECK:               .text
+; CHECK:               .seh_endproc