Skip to content

[RISCV] Don't delete all fixups in RISCVMCCodeEmitter::expandLongCondBr. #109513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 23, 2024

Conversation

topperc
Copy link
Collaborator

@topperc topperc commented Sep 21, 2024

The Fixups vector passed into this function may already have fixups in it from earlier instructions. We should not erase those. We just want to erase fixups added by this function.

Fixes #108612.

The Fixups vector passed into this function may already have fixups
in it from earlier instructions. We should not erase those. We
just want to erase fixups added by this function.

Fixes llvm#108612.
@topperc topperc changed the title [RISCV} Don't delete all fixups in RISCVMCCodeEmitter::expandLongCondBr. [RISCV] Don't delete all fixups in RISCVMCCodeEmitter::expandLongCondBr. Sep 21, 2024
@llvmbot llvmbot added backend:RISC-V mc Machine (object) code labels Sep 21, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 21, 2024

@llvm/pr-subscribers-mc

Author: Craig Topper (topperc)

Changes

The Fixups vector passed into this function may already have fixups in it from earlier instructions. We should not erase those. We just want to erase fixups added by this function.

Fixes #108612.


Full diff: https://github.com/llvm/llvm-project/pull/109513.diff

2 Files Affected:

  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp (+6-1)
  • (added) llvm/test/MC/RISCV/long-conditional-jump-crash.s (+19)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 75323632dd5333..66394dc8cd138b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -283,13 +283,18 @@ void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
     Offset = 4;
   }
 
+  // Save the number fixups.
+  size_t N = Fixups.size();
+
   // Emit an unconditional jump to the destination.
   MCInst TmpInst =
       MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
   uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
   support::endian::write(CB, Binary, llvm::endianness::little);
 
-  Fixups.clear();
+  // Drop any fixup added so we can add the correct one.
+  Fixups.resize(N);
+
   if (SrcSymbol.isExpr()) {
     Fixups.push_back(MCFixup::create(Offset, SrcSymbol.getExpr(),
                                      MCFixupKind(RISCV::fixup_riscv_jal),
diff --git a/llvm/test/MC/RISCV/long-conditional-jump-crash.s b/llvm/test/MC/RISCV/long-conditional-jump-crash.s
new file mode 100644
index 00000000000000..bac0036ca5568f
--- /dev/null
+++ b/llvm/test/MC/RISCV/long-conditional-jump-crash.s
@@ -0,0 +1,19 @@
+# RUN: llvm-mc %s -mc-relax-all -triple=riscv64 -filetype=obj \
+# RUN:     | llvm-objdump -d -M no-aliases - \
+# RUN:     | FileCheck --check-prefix=CHECK %s
+
+# This test previously crashed because expanding a conditional branch deleted
+# all fixups in the fragment.
+
+# CHECK:      beq     s0, zero, 0x8
+# CHECK-NEXT: jal     zero, 0x14
+# CHECK-NEXT: jal     zero, 0x14
+# CHECK-NEXT: bne     s0, zero, 0x14
+# CHECK-NEXT: jal     zero, 0x14
+
+# CHECK:      jalr    zero, 0x0(ra)
+  bnez s0, .foo
+  j    .foo
+  beqz s0, .foo
+.foo:
+  ret

@llvmbot
Copy link
Member

llvmbot commented Sep 21, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

Changes

The Fixups vector passed into this function may already have fixups in it from earlier instructions. We should not erase those. We just want to erase fixups added by this function.

Fixes #108612.


Full diff: https://github.com/llvm/llvm-project/pull/109513.diff

2 Files Affected:

  • (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp (+6-1)
  • (added) llvm/test/MC/RISCV/long-conditional-jump-crash.s (+19)
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 75323632dd5333..66394dc8cd138b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -283,13 +283,18 @@ void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
     Offset = 4;
   }
 
+  // Save the number fixups.
+  size_t N = Fixups.size();
+
   // Emit an unconditional jump to the destination.
   MCInst TmpInst =
       MCInstBuilder(RISCV::JAL).addReg(RISCV::X0).addOperand(SrcSymbol);
   uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
   support::endian::write(CB, Binary, llvm::endianness::little);
 
-  Fixups.clear();
+  // Drop any fixup added so we can add the correct one.
+  Fixups.resize(N);
+
   if (SrcSymbol.isExpr()) {
     Fixups.push_back(MCFixup::create(Offset, SrcSymbol.getExpr(),
                                      MCFixupKind(RISCV::fixup_riscv_jal),
diff --git a/llvm/test/MC/RISCV/long-conditional-jump-crash.s b/llvm/test/MC/RISCV/long-conditional-jump-crash.s
new file mode 100644
index 00000000000000..bac0036ca5568f
--- /dev/null
+++ b/llvm/test/MC/RISCV/long-conditional-jump-crash.s
@@ -0,0 +1,19 @@
+# RUN: llvm-mc %s -mc-relax-all -triple=riscv64 -filetype=obj \
+# RUN:     | llvm-objdump -d -M no-aliases - \
+# RUN:     | FileCheck --check-prefix=CHECK %s
+
+# This test previously crashed because expanding a conditional branch deleted
+# all fixups in the fragment.
+
+# CHECK:      beq     s0, zero, 0x8
+# CHECK-NEXT: jal     zero, 0x14
+# CHECK-NEXT: jal     zero, 0x14
+# CHECK-NEXT: bne     s0, zero, 0x14
+# CHECK-NEXT: jal     zero, 0x14
+
+# CHECK:      jalr    zero, 0x0(ra)
+  bnez s0, .foo
+  j    .foo
+  beqz s0, .foo
+.foo:
+  ret

@@ -283,13 +283,18 @@ void RISCVMCCodeEmitter::expandLongCondBr(const MCInst &MI,
Offset = 4;
}

// Save the number fixups.
size_t N = Fixups.size();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps FixupStartIndex to be similar to MCELFStreamer.cpp:550

@@ -0,0 +1,19 @@
# RUN: llvm-mc %s -mc-relax-all -triple=riscv64 -filetype=obj \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

llvm/test/MC/RISCV/rv64-relax-all.s tests -mc-relax-all. Add the test there, perhaps rename the file?

@topperc topperc merged commit c3d3cef into llvm:main Sep 23, 2024
8 checks passed
@topperc topperc deleted the pr/long-branch-crash branch September 23, 2024 05:31
tru pushed a commit to llvmbot/llvm-project that referenced this pull request Nov 12, 2024
…Br. (llvm#109513)

The Fixups vector passed into this function may already have fixups in
it from earlier instructions. We should not erase those. We just want to
erase fixups added by this function.

Fixes llvm#108612.

(cherry picked from commit c3d3cef)
tru pushed a commit to llvmbot/llvm-project that referenced this pull request Nov 15, 2024
…Br. (llvm#109513)

The Fixups vector passed into this function may already have fixups in
it from earlier instructions. We should not erase those. We just want to
erase fixups added by this function.

Fixes llvm#108612.

(cherry picked from commit c3d3cef)
nikic pushed a commit to rust-lang/llvm-project that referenced this pull request Nov 20, 2024
…Br. (llvm#109513)

The Fixups vector passed into this function may already have fixups in
it from earlier instructions. We should not erase those. We just want to
erase fixups added by this function.

Fixes llvm#108612.

(cherry picked from commit c3d3cef)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[RISCV] Clang 19.1 Compiler segfaults in 'RISC-V Assembly Printer' pass
4 participants