Skip to content

[Mips] Fix getInstSizeInBytes for instructions with delay slots - #216665

Merged
yingopq merged 2 commits into
llvm:mainfrom
yingopq:Fix_bug_issue_112010
Aug 20, 2026
Merged

[Mips] Fix getInstSizeInBytes for instructions with delay slots#216665
yingopq merged 2 commits into
llvm:mainfrom
yingopq:Fix_bug_issue_112010

Conversation

@yingopq

@yingopq yingopq commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

MIPS branch/jump instructions (B, BEQ, JALR64Pseudo, PseudoReturn64, etc.) have a delay slot. The actual encoded size is 8 bytes (instr + NOP). This fixes "out of range PC16 fixup" errors on large functions.

This issue was exposed in llvm 23 by commit pr #191460 which changed MipsBranchExpansion to use MBB::iterator instead of instr_iterator, making the MBB size calculation more accurate and revealing the pre-existing bug.

Thanks for the pr #187703 AllowOverEstimate to help find instr which actual size mismatch expected size .

Fix #112010.

@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-backend-mips

Author: yingopq

Changes

MIPS branch/jump instructions (B, BEQ, JALR64Pseudo, PseudoReturn64, etc.) have a delay slot. The actual encoded size is 8 bytes (instr + NOP). This fixes "out of range PC16 fixup" errors on large functions.

This issue was exposed in llvm 23 by commit pr #191460 which changed MipsBranchExpansion to use MBB::iterator instead of instr_iterator, making the MBB size calculation more accurate and revealing the pre-existing bug.

Thanks for the pr #187703 AllowOverEstimate to help find instr which actual size mismatch expected size .

Fix #112010.


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

1 Files Affected:

  • (modified) llvm/lib/Target/Mips/MipsInstrInfo.cpp (+4)
diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp
index 8648aa0836693..446d02ebfc4d8 100644
--- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp
+++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp
@@ -708,6 +708,10 @@ bool MipsInstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const {
 unsigned MipsInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
   switch (MI.getOpcode()) {
   default:
+    if (MI.hasDelaySlot()) {
+      // instr + 1 nop
+      return 8;
+    }
     return MI.getDesc().getSize();
   case  TargetOpcode::INLINEASM:
   case  TargetOpcode::INLINEASM_BR: {       // Inline Asm: Variable size.

@alexrp

alexrp commented Aug 18, 2026

Copy link
Copy Markdown
Member

I rebuilt LLVM 23.1.0-rc3 with this patch, reverted https://codeberg.org/ziglang/zig/commit/4223910ab69147b2deb63aed38f40888a6977bc2, and can confirm that Zig's module tests pass for all MIPS targets again.

Let's make sure this is backported to 23.x.

@yingopq

yingopq commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

@nikic Can you help review?

Comment thread llvm/lib/Target/Mips/MipsInstrInfo.cpp Outdated
default:
if (MI.hasDelaySlot()) {
// instr + 1 nop
return 8;

@nikic nikic Aug 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you make this an addition on top of MI.getDesc().getSize() instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Applied.

@nikic nikic left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 202293 tests passed
  • 5607 tests skipped

✅ The build succeeded and all tests passed.

MIPS branch/jump instructions (B, BEQ, JALR64Pseudo, PseudoReturn64,
etc.) have a delay slot. The actual encoded size is 8 bytes (instr + NOP).
This fixes "out of range PC16 fixup" errors on large functions.

This issue was exposed in llvm 23 by commit pr#191460 which changed
MipsBranchExpansion to use MBB::iterator instead of instr_iterator,
making the MBB size calculation more accurate and revealing the pre-existing bug.

Thanks for the pr#187703 `AllowOverEstimate` to help find instr which
actual size mismatch expected size .

Fix llvm#112010.
@yingopq
yingopq force-pushed the Fix_bug_issue_112010 branch from 3e7468e to 365e9c3 Compare August 19, 2026 07:52
@dyung dyung moved this from Needs Triage to Needs Backport PR in LLVM Release Status Aug 19, 2026
@yingopq
yingopq merged commit a97f512 into llvm:main Aug 20, 2026
12 checks passed
@github-project-automation github-project-automation Bot moved this from Needs Backport PR to Done in LLVM Release Status Aug 20, 2026
dyung pushed a commit to llvmbot/llvm-project that referenced this pull request Aug 20, 2026
…#216665)

MIPS branch/jump instructions (B, BEQ, JALR64Pseudo, PseudoReturn64,
etc.) have a delay slot. The actual encoded size is 8 bytes (instr +
NOP). This fixes "out of range PC16 fixup" errors on large functions.

This issue was exposed in llvm 23 by commit pr llvm#191460 which changed
MipsBranchExpansion to use MBB::iterator instead of instr_iterator,
making the MBB size calculation more accurate and revealing the
pre-existing bug.

Thanks for the pr llvm#187703 `AllowOverEstimate` to help find instr which
actual size mismatch expected size .

Fix llvm#112010.

(cherry picked from commit a97f512)
kieroxide pushed a commit to kieroxide/llvm-project that referenced this pull request Aug 21, 2026
…#216665)

MIPS branch/jump instructions (B, BEQ, JALR64Pseudo, PseudoReturn64,
etc.) have a delay slot. The actual encoded size is 8 bytes (instr +
NOP). This fixes "out of range PC16 fixup" errors on large functions.

This issue was exposed in llvm 23 by commit pr llvm#191460 which changed
MipsBranchExpansion to use MBB::iterator instead of instr_iterator,
making the MBB size calculation more accurate and revealing the
pre-existing bug.

Thanks for the pr llvm#187703 `AllowOverEstimate` to help find instr which
actual size mismatch expected size .

Fix llvm#112010.
FlyGoat added a commit to FlyGoat/llvm-project that referenced this pull request Aug 24, 2026
Follow-up to llvm#216665. Count complete instruction bundles so long-branch expansion includes both delay-slot and forbidden-slot instructions when estimating offsets.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

[Mips] out of range PC16 fixup when linking the Zig compiler for some target triples

4 participants