[llvm] 2f5fe16 - [RISCV][MC] Adjust conditions to emit R_RISCV_ADD*/R_RISCV_SUB* pairs

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 14 15:17:43 PDT 2023


Author: Fangrui Song
Date: 2023-03-14T15:17:38-07:00
New Revision: 2f5fe16e6d29c55ebd9ec098b03d4de47a804a18

URL: https://github.com/llvm/llvm-project/commit/2f5fe16e6d29c55ebd9ec098b03d4de47a804a18
DIFF: https://github.com/llvm/llvm-project/commit/2f5fe16e6d29c55ebd9ec098b03d4de47a804a18.diff

LOG: [RISCV][MC] Adjust conditions to emit R_RISCV_ADD*/R_RISCV_SUB* pairs

D132262 tried to simplify `IsMetadataOrEHFrameSection` originally introduced in
D127549 but caused a regression as `.quad` directives in

```
.section .note,"a", at note; note:
.quad extern-note    # extern is undefined

.section .rodata,"a", at progbits; rodata:
.quad extern-rodata  # extern is undefined

.section .nonalloc,"", at progbits; nw:
.quad extern-nw
```

are incorrectly rejected: these differences may be link-time constants and
are allowed in GNU assembler and LLVM MC's non-RISC-V ports.

Relax the conditions to allow these cases. For A-B, A may be defined later, but
this requiresFixups call has to eagerly make a decision. For now, emit ADD/SUB
unless A is `.L*`. This euristic handles many temporary label differences for
.debug_* and .apple_types sections. Ideally we should delay the decision of
PC-relative vs ADD/SUB until A is defined.

Reviewed By: compnerd

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

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
    llvm/test/MC/RISCV/riscv64-64b-pcrel.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
index 41399b231519..a05254b0ae57 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp
@@ -156,6 +156,16 @@ bool RISCVELFStreamer::requiresFixups(MCContext &C, const MCExpr *Value,
   if (B.isInSection() && B.getSection().getKind().isText())
     return true;
 
+  // If A is undefined and B is defined, we should emit ADD/SUB for A-B.
+  // Unfortunately, A may be defined later, but this requiresFixups call has to
+  // eagerly make a decision. For now, emit ADD/SUB unless A is .L*. This
+  // heuristic handles many temporary label 
diff erences for .debug_* and
+  // .apple_types sections.
+  //
+  // TODO Implement delayed relocation decision.
+  if (!A.isInSection() && !A.isTemporary() && B.isInSection())
+    return true;
+
   // Support cross-section symbolic 
diff erences ...
   return A.isInSection() && B.isInSection() &&
          A.getSection().getName() != B.getSection().getName();

diff  --git a/llvm/test/MC/RISCV/riscv64-64b-pcrel.s b/llvm/test/MC/RISCV/riscv64-64b-pcrel.s
index 7df442874fb4..9dd7879fc805 100644
--- a/llvm/test/MC/RISCV/riscv64-64b-pcrel.s
+++ b/llvm/test/MC/RISCV/riscv64-64b-pcrel.s
@@ -4,6 +4,14 @@
 # RUN:   | FileCheck %s --check-prefix=ERROR
 
 # CHECK:      Relocations [
+# CHECK-NEXT:   Section ({{.*}}) .rela.note {
+# CHECK-NEXT:     0x0 R_RISCV_ADD64 extern 0x0
+# CHECK-NEXT:     0x0 R_RISCV_SUB64 note 0x0
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Section ({{.*}}) .rela.rodata {
+# CHECK-NEXT:     0x0 R_RISCV_ADD64 extern 0x0
+# CHECK-NEXT:     0x0 R_RISCV_SUB64 rodata 0x0
+# CHECK-NEXT:   }
 # CHECK-NEXT:   Section ({{.*}}) .rela.alloc_w {
 # CHECK-NEXT:     0x0 R_RISCV_ADD64 extern 0x0
 # CHECK-NEXT:     0x0 R_RISCV_SUB64 w 0x0
@@ -24,20 +32,24 @@
 # CHECK-NEXT:     0x0 R_RISCV_ADD64 x 0x0
 # CHECK-NEXT:     0x0 R_RISCV_SUB64 y 0x0
 # CHECK-NEXT:   }
+# CHECK-NEXT:   Section ({{.*}}) .rela.nonalloc_w {
+# CHECK-NEXT:     0x0 R_RISCV_ADD64 extern 0x0
+# CHECK-NEXT:     0x0 R_RISCV_SUB64 nw 0x0
+# CHECK-NEXT:   }
+# CHECK-NEXT:   Section ({{.*}}) .rela.nonalloc_x {
+# CHECK-NEXT:     0x0 R_RISCV_ADD64 ny 0x0
+# CHECK-NEXT:     0x0 R_RISCV_SUB64 nx 0x0
+# CHECK-NEXT:   }
 # CHECK-NEXT:   Section ({{.*}}) .rela.nonalloc_y {
 # CHECK-NEXT:     0x0 R_RISCV_ADD64 nx 0x0
 # CHECK-NEXT:     0x0 R_RISCV_SUB64 ny 0x0
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
 
-.ifdef ERR
 .section .note,"a", at note; note:
-# ERROR: :[[#@LINE+1]]:7: error: unsupported relocation type
 .quad extern-note
 .section .rodata,"a", at progbits; rodata:
-# ERROR: :[[#@LINE+1]]:7: error: unsupported relocation type
 .quad extern-rodata
-.endif
 
 .section .alloc_w,"aw", at progbits; w:
 .quad extern-w   # extern is undefined
@@ -53,17 +65,13 @@ w1:
 .quad x-y
 
 .section .nonalloc_w; nw:
-.ifdef ERR
-# ERROR: :[[#@LINE+1]]:7: error: unsupported relocation type
 .quad extern-nw
+.ifdef ERR
 # ERROR: :[[#@LINE+1]]:7: error: symbol 'extern' can not be undefined in a subtraction expression
 .quad nw-extern
 .endif
 .section .nonalloc_x; nx:
-.ifdef ERR
-# ERROR: :[[#@LINE+1]]:7: error: unsupported relocation type
 .quad ny-nx
-.endif
 .section .nonalloc_y; ny:
 .quad nx-ny
 


        


More information about the llvm-commits mailing list