Skip to content

Commit 8f45b5a

Browse files
committed
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
1 parent 38d58c1 commit 8f45b5a

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

lld/test/ELF/riscv-relax-align-rvc.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@
2525
# CHECK-NEXT: c.addi a0, 1
2626
# CHECK-EMPTY:
2727
# CHECK-NEXT: <a>:
28+
# CHECK-NEXT: c.nop
2829
# CHECK-NEXT: addi zero, zero, 0
2930
# CHECK-NEXT: addi zero, zero, 0
3031
# CHECK-NEXT: addi zero, zero, 0
31-
# CHECK-NEXT: c.nop
3232
# CHECK-EMPTY:
3333
# CHECK-NEXT: <b>:
3434
# CHECK-NEXT: 10010: c.addi a0, 2

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -354,20 +354,28 @@ bool RISCVAsmBackend::mayNeedRelaxation(const MCInst &Inst,
354354

355355
bool RISCVAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
356356
const MCSubtargetInfo *STI) const {
357-
bool HasStdExtC = STI->getFeatureBits()[RISCV::FeatureStdExtC];
358-
unsigned MinNopLen = HasStdExtC ? 2 : 4;
357+
// We mostly follow binutils' convention here: align to even boundary with a
358+
// 0-fill padding. We emit up to 1 2-byte nop, though we use c.nop if RVC is
359+
// enabled or 0-fill otherwise. The remainder is now padded with 4-byte nops.
360+
361+
// Instructions always are at even addresses. We must be in a data area or
362+
// be unaligned due to some other reason.
363+
if (Count % 2) {
364+
OS.write("\0", 1);
365+
Count -= 1;
366+
}
359367

360-
if ((Count % MinNopLen) != 0)
361-
return false;
368+
// The canonical nop on RVC is c.nop.
369+
if (Count % 4 == 2) {
370+
OS.write(STI->getFeatureBits()[RISCV::FeatureStdExtC] ? "\x01\0" : "\0\0",
371+
2);
372+
Count -= 2;
373+
}
362374

363375
// The canonical nop on RISC-V is addi x0, x0, 0.
364376
for (; Count >= 4; Count -= 4)
365377
OS.write("\x13\0\0\0", 4);
366378

367-
// The canonical nop on RVC is c.nop.
368-
if (Count && HasStdExtC)
369-
OS.write("\x01\0", 2);
370-
371379
return true;
372380
}
373381

llvm/test/MC/RISCV/align.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ test:
4848
# RELAX-RELOC: R_RISCV_ALIGN - 0x4
4949
# RELAX-INST: addi zero, zero, 0
5050
# C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x6
51-
# C-EXT-RELAX-INST: addi zero, zero, 0
5251
# C-EXT-RELAX-INST: c.nop
52+
# C-EXT-RELAX-INST: addi zero, zero, 0
5353
# C-EXT-NORELAX-INST: addi zero, zero, 0
5454
add a0, a0, a1
5555
.align 4
@@ -75,7 +75,7 @@ test:
7575
# NORELAX-INST: addi zero, zero, 0
7676
# C-EXT-RELAX-RELOC: R_RISCV_ALIGN - 0x6
7777
# C-EXT-RELAX-INST: addi zero, zero, 0
78-
# C-EXT-RELAX-INST: c.nop
78+
# C-EXT-RELAX-INST-NOT: c.nop
7979
# C-EXT-INST: addi zero, zero, 0
8080
# C-EXT-INST: c.nop
8181
add a0, a0, a1

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# RUN: llvm-mc -triple riscv64 -mattr +c,-relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s -check-prefix CHECK-RVC-NORELAX
2+
# RUN: llvm-mc -triple riscv64 -mattr +c,+relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s -check-prefix CHECK-RVC-RELAX
3+
# RUN: llvm-mc -triple riscv64 -mattr -c,-relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s
4+
# RUN: llvm-mc -triple riscv64 -mattr -c,+relax -filetype obj -o - %s | llvm-objdump -d - | FileCheck %s
5+
6+
.balign 4
7+
.byte 0
8+
9+
.balign 4
10+
auipc a0, 0
11+
12+
# CHECK-RVC-NORELAX: 0000000000000000 <.text>:
13+
# CHECK-RVC-NORELAX-NEXT: 0: 00 00 unimp
14+
# CHECK-RVC-NORELAX-NEXT: 2: 01 00 nop
15+
# CHECK-RVC-NORELAX-NEXT: 4: 17 05 00 00 auipc a0, 0
16+
17+
# CHECK-RVC-RELAX: 0000000000000000 <.text>:
18+
# CHECK-RVC-RELAX-NEXT: 0: 01 00 nop
19+
# CHECK-RVC-RELAX-NEXT: 2: 00 01 addi s0, sp, 128
20+
# CHECK-RVC-RELAX-NEXT: 4: 00 17 addi s0, sp, 928
21+
# CHECK-RVC-RELAX-NEXT: 6: 05 00 c.nop 1
22+
# CHECK-RVC-RELAX-NEXT: 8: 00 <unknown>
23+
24+
# CHECK: 0000000000000000 <.text>:
25+
# CHECK-NEXT: 0: 00 00 <unknown>
26+
# CHECK-NEXT: 2: 00 00 <unknown>
27+
# CHECK-NEXT: 4: 17 05 00 00 auipc a0, 0

0 commit comments

Comments
 (0)