[llvm] 8f45b5a - RISCV: permit unaligned nop-slide padding emission

Saleem Abdulrasool via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 24 13:27:17 PDT 2022


Author: Saleem Abdulrasool
Date: 2022-08-24T20:26:48Z
New Revision: 8f45b5a7a90f24ae1dabeff161e22594039a8b0a

URL: https://github.com/llvm/llvm-project/commit/8f45b5a7a90f24ae1dabeff161e22594039a8b0a
DIFF: https://github.com/llvm/llvm-project/commit/8f45b5a7a90f24ae1dabeff161e22594039a8b0a.diff

LOG: RISCV: permit unaligned nop-slide padding emission

We may be requested to emit an unaligned nop sequence (e.g. 7-bytes or
3-bytes).  These should be 0-filled even though that is not a valid
instruction.  This matches the behaviour on other architectures like
ARM, X86, and MIPS.  When a custom section is emitted, it may be
classified as text even though it may be a data section or we may be
emitting data into a text segment (e.g. a literal pool).  In such cases,
we should be resilient to the emission request.

This was originally identified by the Linux kernel build and reported on
D131270 by Nathan Chancellor.

Differential Revision: https://reviews.llvm.org/D132482
Reviewed By: luismarques
Tested By: Nathan Chancellor

Added: 
    llvm/test/MC/RISCV/nop-slide.s

Modified: 
    lld/test/ELF/riscv-relax-align-rvc.s
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
    llvm/test/MC/RISCV/align.s

Removed: 
    


################################################################################
diff  --git a/lld/test/ELF/riscv-relax-align-rvc.s b/lld/test/ELF/riscv-relax-align-rvc.s
index 37758ed813219..0134b7734df5d 100644
--- a/lld/test/ELF/riscv-relax-align-rvc.s
+++ b/lld/test/ELF/riscv-relax-align-rvc.s
@@ -25,10 +25,10 @@
 # CHECK-NEXT:           c.addi    a0, 1
 # CHECK-EMPTY:
 # CHECK-NEXT: <a>:
+# CHECK-NEXT:           c.nop
 # CHECK-NEXT:           addi    zero, zero, 0
 # CHECK-NEXT:           addi    zero, zero, 0
 # CHECK-NEXT:           addi    zero, zero, 0
-# CHECK-NEXT:           c.nop
 # CHECK-EMPTY:
 # CHECK-NEXT: <b>:
 # CHECK-NEXT:   10010:  c.addi  a0, 2

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index a494adf8e2106..96af23d60161a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -354,20 +354,28 @@ bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst,
 
 bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
                                    const MCSubtargetInfo *STI) const {
-  bool HasStdExtC = STI->getFeatureBits()[RISCV::FeatureStdExtC];
-  unsigned MinNopLen = HasStdExtC ? 2 : 4;
+  // We mostly follow binutils' convention here: align to even boundary with a
+  // 0-fill padding.  We emit up to 1 2-byte nop, though we use c.nop if RVC is
+  // enabled or 0-fill otherwise.  The remainder is now padded with 4-byte nops.
+
+  // Instructions always are at even addresses.  We must be in a data area or
+  // be unaligned due to some other reason.
+  if (Count % 2) {
+    OS.write("\0", 1);
+    Count -= 1;
+  }
 
-  if ((Count % MinNopLen) != 0)
-    return false;
+  // The canonical nop on RVC is c.nop.
+  if (Count % 4 == 2) {
+    OS.write(STI->getFeatureBits()[RISCV::FeatureStdExtC] ? "\x01\0" : "\0\0",
+             2);
+    Count -= 2;
+  }
 
   // The canonical nop on RISC-V is addi x0, x0, 0.
   for (; Count >= 4; Count -= 4)
     OS.write("\x13\0\0\0", 4);
 
-  // The canonical nop on RVC is c.nop.
-  if (Count && HasStdExtC)
-    OS.write("\x01\0", 2);
-
   return true;
 }
 

diff  --git a/llvm/test/MC/RISCV/align.s b/llvm/test/MC/RISCV/align.s
index 75ea8eb77bbd4..cd9f47a7dd4b5 100644
--- a/llvm/test/MC/RISCV/align.s
+++ b/llvm/test/MC/RISCV/align.s
@@ -48,8 +48,8 @@ test:
 # RELAX-RELOC: R_RISCV_ALIGN - 0x4
 # RELAX-INST:  addi    zero, zero, 0
 # C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x6
-# C-EXT-RELAX-INST:  addi    zero, zero, 0
 # C-EXT-RELAX-INST:  c.nop
+# C-EXT-RELAX-INST:  addi    zero, zero, 0
 # C-EXT-NORELAX-INST: addi    zero, zero, 0
 	add	a0, a0, a1
 	.align 4
@@ -75,7 +75,7 @@ test:
 # NORELAX-INST: addi    zero, zero, 0
 # C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x6
 # C-EXT-RELAX-INST:  addi    zero, zero, 0
-# C-EXT-RELAX-INST:  c.nop
+# C-EXT-RELAX-INST-NOT:  c.nop
 # C-EXT-INST: addi    zero, zero, 0
 # C-EXT-INST: c.nop
 	add	a0, a0, a1

diff  --git a/llvm/test/MC/RISCV/nop-slide.s b/llvm/test/MC/RISCV/nop-slide.s
new file mode 100644
index 0000000000000..353c6f95a6fe5
--- /dev/null
+++ b/llvm/test/MC/RISCV/nop-slide.s
@@ -0,0 +1,27 @@
+# RUN: llvm-mc -triple riscv64 -mattr +c,-relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s -check-prefix CHECK-RVC-NORELAX
+# RUN: llvm-mc -triple riscv64 -mattr +c,+relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s -check-prefix CHECK-RVC-RELAX
+# RUN: llvm-mc -triple riscv64 -mattr -c,-relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s
+# RUN: llvm-mc -triple riscv64 -mattr -c,+relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s
+
+.balign 4
+.byte 0
+
+.balign 4
+auipc a0, 0
+
+# CHECK-RVC-NORELAX: 0000000000000000 <.text>:
+# CHECK-RVC-NORELAX-NEXT: 0: 00 00        	unimp
+# CHECK-RVC-NORELAX-NEXT: 2: 01 00        	nop
+# CHECK-RVC-NORELAX-NEXT: 4: 17 05 00 00  	auipc	a0, 0
+
+# CHECK-RVC-RELAX: 0000000000000000 <.text>:
+# CHECK-RVC-RELAX-NEXT:   0: 01 00        	nop
+# CHECK-RVC-RELAX-NEXT:   2: 00 01        	addi	s0, sp, 128
+# CHECK-RVC-RELAX-NEXT:   4: 00 17        	addi	s0, sp, 928
+# CHECK-RVC-RELAX-NEXT:   6: 05 00        	c.nop	1
+# CHECK-RVC-RELAX-NEXT:   8: 00           	<unknown>
+
+# CHECK: 0000000000000000 <.text>:
+# CHECK-NEXT: 0: 00 00        	<unknown>
+# CHECK-NEXT: 2: 00 00        	<unknown>
+# CHECK-NEXT: 4: 17 05 00 00  	auipc	a0, 0


        


More information about the llvm-commits mailing list