[llvm] 9920943 - [JITLink] Fix the incorrect relocation behavior for R_RISCV_BRANCH

via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 6 22:39:06 PST 2022


Author: luxufan
Date: 2022-02-07T14:34:19+08:00
New Revision: 9920943ea201189f9b34918c7663d8a03d7e4676

URL: https://github.com/llvm/llvm-project/commit/9920943ea201189f9b34918c7663d8a03d7e4676
DIFF: https://github.com/llvm/llvm-project/commit/9920943ea201189f9b34918c7663d8a03d7e4676.diff

LOG: [JITLink] Fix the incorrect relocation behavior for R_RISCV_BRANCH

In D116573, the relocation behavior of R_RISCV_BRANCH didn't consider that branch instruction like 'bge' has a branch target address which is given as a PC-relative offset, sign-extend and multiplied by 2.
Although the target address is a 12-bits number, acctually its range is [-4096, 4094].

This patch fix it.

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

Added: 
    

Modified: 
    llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
    llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
    llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h b/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
index 5abd4cf11deaf..d0d3a3786e55d 100644
--- a/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
+++ b/llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
@@ -37,10 +37,10 @@ enum EdgeKind_riscv : Edge::Kind {
   ///
   R_RISCV_64,
 
-  /// Low 12 bits of PC-relative branch pointer value relocation
+  /// PC-relative branch pointer value relocation
   ///
   /// Fixup expression:
-  ///   Fixup <- (Target - Fixup + Addend) & 0xFFF
+  ///   Fixup <- (Target - Fixup + Addend)
   ///
   R_RISCV_BRANCH,
 

diff  --git a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
index f83001417e946..90f3a38b81d53 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
@@ -160,7 +160,7 @@ static Expected<const Edge &> getRISCVPCRelHi20(const Edge &E) {
 }
 
 static uint32_t extractBits(uint32_t Num, unsigned Low, unsigned Size) {
-  return (Num & (((1ULL << (Size + 1)) - 1) << Low)) >> Low;
+  return (Num & (((1ULL << Size) - 1) << Low)) >> Low;
 }
 
 inline Error checkAlignment(llvm::orc::ExecutorAddr loc, uint64_t v, int n,
@@ -212,11 +212,10 @@ class ELFJITLinker_riscv : public JITLinker<ELFJITLinker_riscv> {
       if (AlignmentIssue) {
         return AlignmentIssue;
       }
-      int64_t Lo = Value & 0xFFF;
-      uint32_t Imm31_25 = extractBits(Lo, 5, 6) << 25 | extractBits(Lo, 12, 1)
-                                                            << 31;
-      uint32_t Imm11_7 = extractBits(Lo, 1, 4) << 8 | extractBits(Lo, 11, 1)
-                                                          << 7;
+      uint32_t Imm31_25 =
+          extractBits(Value, 5, 6) << 25 | extractBits(Value, 12, 1) << 31;
+      uint32_t Imm11_7 =
+          extractBits(Value, 1, 4) << 8 | extractBits(Value, 11, 1) << 7;
       uint32_t RawInstr = *(little32_t *)FixupPtr;
       *(little32_t *)FixupPtr = (RawInstr & 0x1FFF07F) | Imm31_25 | Imm11_7;
       break;

diff  --git a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s
index 0e7a83eff1c80..5a5a9e8336bf1 100644
--- a/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s
+++ b/llvm/test/ExecutionEngine/JITLink/RISCV/ELF_branch.s
@@ -4,18 +4,16 @@
 # RUN: llvm-mc -triple=riscv32 -filetype=obj \
 # RUN:     -o %t/elf_riscv32_branch.o %s
 # RUN: llvm-jitlink -noexec \
-# RUN:     -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
-# RUN:     -abs external_func=0xfe \
+# RUN:     -slab-allocate 100Kb -slab-address 0xfff00ff4 -slab-page-size 4096 \
+# RUN:     -abs external_func_positive_offset=0xfff00ffc -abs external_func_negative_offset=0xfff00000\
 # RUN:     -check %s %t/elf_riscv64_branch.o
 # RUN: llvm-jitlink -noexec \
-# RUN:     -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
-# RUN:     -abs external_func=0xfe \
+# RUN:     -slab-allocate 100Kb -slab-address 0xfff00ff4 -slab-page-size 4096 \
+# RUN:     -abs external_func_positive_offset=0xfff00ffc -abs external_func_negative_offset=0xfff00000 \
 # RUN:     -check %s %t/elf_riscv32_branch.o
 #
 
         .text
-        .file   "testcase.c"
-
 # Empty main entry point.
         .globl  main
         .p2align  1
@@ -27,11 +25,13 @@ main:
 
 # Test R_RISCV_BRANCH
 
-# jitlink-check: decode_operand(test_branch, 2)[11:0] = (external_func - test_branch)[11:0]
+# jitlink-check: decode_operand(test_branch, 2)[12:0] = (external_func_positive_offset - test_branch)[12:0]
+# jitlink-check: decode_operand(test_branch+4, 2)[12:0] = (external_func_negative_offset - test_branch - 4)[12:0]
   .globl  test_branch
   .p2align  1
   .type  test_branch, at function
 test_branch:
-  bge	a0, a1, external_func
+  bge  a0, a1, external_func_positive_offset
+  bge  a0, a1, external_func_negative_offset
 
   .size test_branch, .-test_branch


        


More information about the llvm-commits mailing list