From ec315806ef20eeb6735de959a97da8c70c0ccf7f Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Sat, 21 Dec 2019 14:11:55 +0100 Subject: [PATCH] Include upstream patch D60657 for rust support on riscv64. --- debian/changelog | 4 + debian/patches/D60657-riscv-pcrel_lo.diff | 126 ++++++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 131 insertions(+) create mode 100644 debian/patches/D60657-riscv-pcrel_lo.diff diff --git a/debian/changelog b/debian/changelog index b24bf4f2..55cdd06e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,11 @@ llvm-toolchain-9 (1:9.0.1-2) UNRELEASED; urgency=medium + [ James Clarke ] * Include upstream patch D71028 for rust mips tests (Closes: #946874) + [ Aurelien Jarno ] + * Include upstream patch D60657 for rust support on riscv64. + -- James Clarke Fri, 20 Dec 2019 18:30:29 +0000 llvm-toolchain-9 (1:9.0.1-1) unstable; urgency=medium diff --git a/debian/patches/D60657-riscv-pcrel_lo.diff b/debian/patches/D60657-riscv-pcrel_lo.diff new file mode 100644 index 00000000..b609bd22 --- /dev/null +++ b/debian/patches/D60657-riscv-pcrel_lo.diff @@ -0,0 +1,126 @@ +commit 41449c58c58e466bcf9cdc4f7415950382bad8d7 +Author: Roger Ferrer Ibanez +Date: Fri Nov 8 08:26:30 2019 +0000 + + [RISCV] Fix evaluation of %pcrel_lo + + The following testcase + + function: + .Lpcrel_label1: + auipc a0, %pcrel_hi(other_function) + addi a1, a0, %pcrel_lo(.Lpcrel_label1) + .p2align 2 # Causes a new fragment to be emitted + + .type other_function,@function + other_function: + ret + + exposes an odd behaviour in which only the %pcrel_hi relocation is + evaluated but not the %pcrel_lo. + + $ llvm-mc -triple riscv64 -filetype obj t.s | llvm-objdump -d -r - + + : file format ELF64-riscv + + Disassembly of section .text: + 0000000000000000 function: + 0: 17 05 00 00 auipc a0, 0 + 4: 93 05 05 00 mv a1, a0 + 0000000000000004: R_RISCV_PCREL_LO12_I other_function+4 + + 0000000000000008 other_function: + 8: 67 80 00 00 ret + + The reason seems to be that in RISCVAsmBackend::shouldForceRelocation we + only consider the fragment but in RISCVMCExpr::evaluatePCRelLo we + consider the section. This usually works but there are cases where the + section may still be the same but the fragment may be another one. In + that case we end forcing a %pcrel_lo relocation without any %pcrel_hi. + + This patch makes RISCVAsmBackend::shouldForceRelocation use the section, + if any, to determine if the relocation must be forced or not. + + Differential Revision: https://reviews.llvm.org/D60657 + +diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +index f6b727ae37c..5881a0a86ef 100644 +--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp ++++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +@@ -64,11 +64,15 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm, + case RISCV::fixup_riscv_tls_gd_hi20: + ShouldForce = true; + break; +- case RISCV::fixup_riscv_pcrel_hi20: +- ShouldForce = T->getValue()->findAssociatedFragment() != +- Fixup.getValue()->findAssociatedFragment(); ++ case RISCV::fixup_riscv_pcrel_hi20: { ++ MCFragment *TFragment = T->getValue()->findAssociatedFragment(); ++ MCFragment *FixupFragment = Fixup.getValue()->findAssociatedFragment(); ++ assert(FixupFragment && "We should have a fragment for this fixup"); ++ ShouldForce = ++ !TFragment || TFragment->getParent() != FixupFragment->getParent(); + break; + } ++ } + break; + } + +diff --git a/llvm/test/MC/RISCV/pcrel-fixups.s b/llvm/test/MC/RISCV/pcrel-fixups.s +new file mode 100644 +index 00000000000..1025988967a +--- /dev/null ++++ b/llvm/test/MC/RISCV/pcrel-fixups.s +@@ -0,0 +1,52 @@ ++# RUN: llvm-mc -triple riscv32 -mattr=-relax -filetype obj %s \ ++# RUN: | llvm-objdump -M no-aliases -d -r - \ ++# RUN: | FileCheck --check-prefix NORELAX %s ++# RUN: llvm-mc -triple riscv32 -mattr=+relax -filetype obj %s \ ++# RUN: | llvm-objdump -M no-aliases -d -r - \ ++# RUN: | FileCheck --check-prefix RELAX %s ++# RUN: llvm-mc -triple riscv64 -mattr=-relax -filetype obj %s \ ++# RUN: | llvm-objdump -M no-aliases -d -r - \ ++# RUN: | FileCheck --check-prefix NORELAX %s ++# RUN: llvm-mc -triple riscv64 -mattr=+relax -filetype obj %s \ ++# RUN: | llvm-objdump -M no-aliases -d -r - \ ++# RUN: | FileCheck --check-prefix RELAX %s ++ ++# Fixups for %pcrel_hi / %pcrel_lo can be evaluated within a section, ++# regardless of the fragment containing the target address. ++ ++function: ++.Lpcrel_label1: ++ auipc a0, %pcrel_hi(other_function) ++ addi a1, a0, %pcrel_lo(.Lpcrel_label1) ++# NORELAX: auipc a0, 0 ++# NORELAX-NOT: R_RISCV ++# NORELAX: addi a1, a0, 16 ++# NORELAX-NOT: R_RISCV ++ ++# RELAX: auipc a0, 0 ++# RELAX: R_RISCV_PCREL_HI20 other_function ++# RELAX: R_RISCV_RELAX *ABS* ++# RELAX: addi a1, a0, 0 ++# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label1 ++# RELAX: R_RISCV_RELAX *ABS* ++ ++ .p2align 2 # Cause a new fragment be emitted here ++.Lpcrel_label2: ++ auipc a0, %pcrel_hi(other_function) ++ addi a1, a0, %pcrel_lo(.Lpcrel_label2) ++# NORELAX: auipc a0, 0 ++# NORELAX-NOT: R_RISCV ++# NORELAX: addi a1, a0, 8 ++# NORELAX-NOT: R_RISCV ++ ++# RELAX: auipc a0, 0 ++# RELAX: R_RISCV_PCREL_HI20 other_function ++# RELAX: R_RISCV_RELAX *ABS* ++# RELAX: addi a1, a0, 0 ++# RELAX: R_RISCV_PCREL_LO12_I .Lpcrel_label2 ++# RELAX: R_RISCV_RELAX *ABS* ++ ++ .type other_function,@function ++other_function: ++ ret ++ diff --git a/debian/patches/series b/debian/patches/series index 1e16676d..479bcc08 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -129,6 +129,7 @@ bootstrap-fix-include-next.diff clang-riscv64-multiarch.diff clang-riscv64-rv64gc.diff llvm-riscv64-fix-cffi.diff +D60657-riscv-pcrel_lo.diff #try-to-unbreak-thinlto.diff D67877.patch