[RISCV] Fix evalutePCRelLo for symbols at the end of a fragment
authorJames Clarke <jrtc27@jrtc27.com>
Wed, 8 Jan 2020 04:32:04 +0000 (04:32 +0000)
committerJames Clarke <jrtc27@jrtc27.com>
Wed, 8 Jan 2020 04:32:06 +0000 (04:32 +0000)
Summary:
This is analogous to D58943, which correctly finds the corresponding
fixup. However, when linker relaxations are disabled and we evaluate the
fixup, we need to also ensure we use an offset of 0 rather than the size
of the previous fragment.

Reviewers: asb, efriedma, lenary

Reviewed By: efriedma

Subscribers: hiraditya, rbar, johnrusso, simoncook, sabuasal, niosHD, kito-cheng, shiva0217, MaskRay, zzheng, edward-jones, rogfer01, MartinMosbeck, brucehoult, the_o, rkruppe, PkmX, jocewei, psnobl, benna, Jim, s.egerton, pzheng, sameer.abuasal, apazos, luismarques, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D71978

llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
llvm/test/MC/RISCV/option-mix.s

index ae25ec8..7aa9b5e 100644 (file)
@@ -139,7 +139,11 @@ bool RISCVMCExpr::evaluatePCRelLo(MCValue &Res, const MCAsmLayout *Layout,
       findAssociatedFragment()->getParent())
     return false;
 
-  uint64_t AUIPCOffset = AUIPCSymbol->getOffset();
+  // We must use TargetFixup rather than AUIPCSymbol here. They will almost
+  // always have the same offset, except for the case when AUIPCSymbol is at
+  // the end of a fragment and the fixup comes from offset 0 in the next
+  // fragment.
+  uint64_t AUIPCOffset = TargetFixup->getOffset();
 
   Res = MCValue::get(Target.getSymA(), nullptr,
                      Target.getConstant() + (Fixup->getOffset() - AUIPCOffset));
index 633b85d..fdbb42c 100644 (file)
@@ -1,12 +1,19 @@
-# RUN: llvm-mc %s -triple=riscv32 | FileCheck -check-prefix=ASM %s
-# RUN: llvm-mc %s -triple=riscv64 | FileCheck -check-prefix=ASM %s
+# RUN: llvm-mc %s -triple=riscv32 | FileCheck -check-prefixes=ASM %s
+# RUN: llvm-mc %s -triple=riscv64 | FileCheck -check-prefixes=ASM %s
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+relax | FileCheck -check-prefix=ASM %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+relax | FileCheck -check-prefix=ASM %s
 # RUN: llvm-mc -filetype=obj -triple riscv32 < %s \
-# RUN:   | llvm-objdump -d -M no-aliases - | FileCheck -check-prefix=DISASM %s
+# RUN:   | llvm-objdump -d -M no-aliases - | FileCheck -check-prefixes=DISASM,DISASM-NORELAX %s
 # RUN: llvm-mc -filetype=obj -triple riscv64 < %s \
-# RUN:   | llvm-objdump -d -M no-aliases - | FileCheck -check-prefix=DISASM %s
+# RUN:   | llvm-objdump -d -M no-aliases - | FileCheck -check-prefixes=DISASM,DISASM-NORELAX %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+relax < %s \
+# RUN:   | llvm-objdump -d -M no-aliases - | FileCheck -check-prefixes=DISASM,DISASM-RELAX %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+relax < %s \
+# RUN:   | llvm-objdump -d -M no-aliases - | FileCheck -check-prefixes=DISASM,DISASM-RELAX %s
 
-# Checks change of options does not cause error: could not find corresponding %pcrel_hi 
-# when assembling pseudoinstruction and its extended form.
+# Checks change of options does not cause error: could not find corresponding %pcrel_hi
+# when assembling pseudoinstruction and its extended form. Also checks that we
+# evaluate the correct value for local symbols in such a situation.
 
 .option push
 .option norelax
 .option pop
   la a1, another_symbol
 
-# ASM: .Lpcrel_hi0:
-# ASM: auipc   a0, %pcrel_hi(a_symbol)
-# ASM: addi    a0, a0, %pcrel_lo(.Lpcrel_hi0)
-# ASM: .Lpcrel_hi1:
-# ASM: auipc   a1, %pcrel_hi(another_symbol)
-# ASM: addi    a1, a1, %pcrel_lo(.Lpcrel_hi1)
+# ASM-LABEL: .Lpcrel_hi0:
+# ASM-NEXT: auipc   a0, %pcrel_hi(a_symbol)
+# ASM-NEXT: addi    a0, a0, %pcrel_lo(.Lpcrel_hi0)
+# ASM-LABEL: .Lpcrel_hi1:
+# ASM-NEXT: auipc   a1, %pcrel_hi(another_symbol)
+# ASM-NEXT: addi    a1, a1, %pcrel_lo(.Lpcrel_hi1)
 
-# DISASM: .Lpcrel_hi0:
-# DISASM: auipc   a0, 0
-# DISASM: addi    a0, a0, 0
-# DISASM:.Lpcrel_hi1:
-# DISASM: auipc   a1, 0
-# DISASM: addi    a1, a1, 0
+# DISASM-LABEL: .Lpcrel_hi0:
+# DISASM-NEXT: auipc   a0, 0
+# DISASM-NEXT: addi    a0, a0, 0
+# DISASM-LABEL:.Lpcrel_hi1:
+# DISASM-NEXT: auipc   a1, 0
+# DISASM-NEXT: addi    a1, a1, 0
 
 .option push
 .option norelax
 2:auipc   a1, %pcrel_hi(another_symbol)
   addi    a1, a1, %pcrel_lo(2b)
 
-# ASM: .Ltmp0:
-# ASM: auipc   a0, %pcrel_hi(a_symbol)
-# ASM: addi    a0, a0, %pcrel_lo(.Ltmp0)
-# ASM: .Ltmp1:
-# ASM: auipc   a1, %pcrel_hi(another_symbol)
-# ASM: addi    a1, a1, %pcrel_lo(.Ltmp1)
-
-# DISASM: .Ltmp0:
-# DISASM: auipc   a0, 0
-# DISASM: addi    a0, a0, 0
-# DISASM: .Ltmp1:
-# DISASM: auipc   a1, 0
-# DISASM: addi    a1, a1, 0
+# ASM-LABEL: .Ltmp0:
+# ASM-NEXT: auipc   a0, %pcrel_hi(a_symbol)
+# ASM-NEXT: addi    a0, a0, %pcrel_lo(.Ltmp0)
+# ASM-LABEL: .Ltmp1:
+# ASM-NEXT: auipc   a1, %pcrel_hi(another_symbol)
+# ASM-NEXT: addi    a1, a1, %pcrel_lo(.Ltmp1)
+
+# DISASM-LABEL: .Ltmp0:
+# DISASM-NEXT: auipc   a0, 0
+# DISASM-NEXT: addi    a0, a0, 0
+# DISASM-LABEL: .Ltmp1:
+# DISASM-NEXT: auipc   a1, 0
+# DISASM-NEXT: addi    a1, a1, 0
+
+.option push
+.option norelax
+  la a0, a_symbol
+.option pop
+  la a1, local_symbol1
+
+local_symbol1:
+  nop
+
+# ASM-LABEL: .Lpcrel_hi2:
+# ASM-NEXT: auipc   a0, %pcrel_hi(a_symbol)
+# ASM-NEXT: addi    a0, a0, %pcrel_lo(.Lpcrel_hi2)
+# ASM-LABEL: .Lpcrel_hi3:
+# ASM-NEXT: auipc   a1, %pcrel_hi(local_symbol1)
+# ASM-NEXT: addi    a1, a1, %pcrel_lo(.Lpcrel_hi3)
+
+# DISASM-LABEL: .Lpcrel_hi2:
+# DISASM-NEXT: auipc   a0, 0
+# DISASM-NEXT: addi    a0, a0, 0
+# DISASM-NORELAX-NEXT: auipc   a1, 0
+# DISASM-NORELAX-NEXT: addi    a1, a1, 8
+# DISASM-RELAX-LABEL: .Lpcrel_hi3:
+# DISASM-RELAX-NEXT: auipc   a1, 0
+# DISASM-RELAX-NEXT: addi    a1, a1, 0
+
+.option push
+.option norelax
+1:auipc   a0, %pcrel_hi(a_symbol)
+  addi    a0, a0, %pcrel_lo(1b)
+.option pop
+2:auipc   a1, %pcrel_hi(local_symbol2)
+  addi    a1, a1, %pcrel_lo(2b)
+
+local_symbol2:
+  nop
+
+# ASM-LABEL: .Ltmp2:
+# ASM-NEXT: auipc   a0, %pcrel_hi(a_symbol)
+# ASM-NEXT: addi    a0, a0, %pcrel_lo(.Ltmp2)
+# ASM-LABEL: .Ltmp3:
+# ASM-NEXT: auipc   a1, %pcrel_hi(local_symbol2)
+# ASM-NEXT: addi    a1, a1, %pcrel_lo(.Ltmp3)
+
+# DISASM-LABEL: .Ltmp2:
+# DISASM-NEXT: auipc   a0, 0
+# DISASM-NEXT: addi    a0, a0, 0
+# DISASM-NORELAX-NEXT: auipc   a1, 0
+# DISASM-NORELAX-NEXT: addi    a1, a1, 8
+# DISASM-RELAX-LABEL: .Ltmp3:
+# DISASM-RELAX-NEXT: auipc   a1, 0
+# DISASM-RELAX-NEXT: addi    a1, a1, 0