[PATCH] D47456: [PowerPC] fix broken JIT-compiled code with tail call optimization
Hiroshi Inoue via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon May 28 23:40:12 PDT 2018
inouehrs created this revision.
inouehrs added reviewers: lhames, hfinkel, echristo, kbarton, nemanjai.
The relocation for branch instructions in the dynamic loader of ExecutionEngine assumes branch instructions with R_PPC64_REL24 relocation type are only `bl`. However, with the tail call optimization, `b` instructions can be also used to jump into another function.
This patch makes the relocation to keep bits in the branch instruction other than the jump offset to avoid relocation rewrites a `b` instruction into `bl`.
This problem makes NNVM, a deep learning optimizer which uses LLVM as backend https://github.com/dmlc/nnvm, crash on POWER.
https://reviews.llvm.org/D47456
Files:
lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_reloc.s
Index: test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_reloc.s
===================================================================
--- /dev/null
+++ test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_reloc.s
@@ -0,0 +1,48 @@
+# test for little endian
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple=powerpc64le-unknown-linux-gnu -filetype=obj -o %t/ppc64_reloc.o %s
+# RUN: llvm-mc -triple=powerpc64le-unknown-linux-gnu -filetype=obj -o %t/ppc64_elf_module_b.o %S/Inputs/ppc64_elf_module_b.s
+# RUN: llvm-rtdyld -triple=powerpc64le-unknown-linux-gnu -verify -check=%s %t/ppc64_reloc.o %t/ppc64_elf_module_b.o
+# test for big endian
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple=powerpc64-unknown-linux-gnu -filetype=obj -o %t/ppc64_reloc.o %s
+# RUN: llvm-mc -triple=powerpc64-unknown-linux-gnu -filetype=obj -o %t/ppc64_elf_module_b.o %S/Inputs/ppc64_elf_module_b.s
+# RUN: llvm-rtdyld -triple=powerpc64-unknown-linux-gnu -verify -check=%s %t/ppc64_reloc.o %t/ppc64_elf_module_b.o
+
+ .text
+ .abiversion 2
+ .file "test.c"
+ .globl func
+ .p2align 4
+ .type func, at function
+func: # @func
+.Lfunc_begin0:
+.Lfunc_gep0:
+ addis 2, 12, .TOC.-.Lfunc_gep0 at ha
+ addi 2, 2, .TOC.-.Lfunc_gep0 at l
+.Lfunc_lep0:
+ .localentry func, .Lfunc_lep0-.Lfunc_gep0
+ mflr 0
+ std 31, -8(1)
+ std 0, 16(1)
+ stdu 1, -112(1)
+ mr 31, 1
+# confirm that LK flag is set for bl
+# rtdyld-check: (*{4}call_bl) & 1 = 1
+call_bl:
+ bl foo
+ nop
+
+ li 3, 0
+ addi 1, 1, 112
+ ld 0, 16(1)
+ ld 31, -8(1)
+ mtlr 0
+# confirm that LK flag is not set for b
+# rtdyld-check: (*{4}call_b) & 1 = 0
+call_b:
+ b foo
+ .long 0
+ .quad 0
+.Lfunc_end0:
+ .size func, .Lfunc_end0-.Lfunc_begin0
Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
===================================================================
--- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
@@ -772,8 +772,9 @@
int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend);
if (SignExtend64<26>(delta) != delta)
llvm_unreachable("Relocation R_PPC64_REL24 overflow");
- // Generates a 'bl <address>' instruction
- writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
+ // We preserve bits other than LI field, i.e. PO and AA/LK fields.
+ uint32_t Inst = readBytesUnaligned(LocalAddress, 4);
+ writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
} break;
case ELF::R_PPC64_REL32: {
uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47456.148848.patch
Type: text/x-patch
Size: 2574 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180529/4aa4c799/attachment.bin>
More information about the llvm-commits
mailing list