[Mips] MIPS-I to MIPS-III may trigger error: out of range PC16 fixup in edge cases
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Inspired by #220953, as it fixes `getInstSizeInBytes` for MIPS R6 forbidden slots, MIPS-I load delay slots, MIPS-I to -III FPU delay slots, and MFLO delay slots. However, [this code](https://github.com/llvm/llvm-project/blob/7caac9be9a7f9ecda3f31802ef451a25f2b61658/llvm/lib/Target/Mips/MipsBranchExpansion.cpp#L947) looks suspicious, so I crafted the following MIR test cases with agentic assistance.
mips1-load-delay-slot-long-branch.mir
```yaml
# RUN: llc -mtriple=mipsel-sony-psx -mcpu=mips1 -filetype=obj -o /dev/null %s
# RUN: llc -mtriple=mipsel-sony-psx -mcpu=mips1 -stop-after mips-branch-expansion -o - %s | FileCheck %s --check-prefixes=MIPS1
--- |
define void @load_delay_slot_long_branch() {
ret void
}
...
---
name: load_delay_slot_long_branch
alignment: 4
tracksRegLiveness: true
body: |
; MIPS1-LABEL: name: load_delay_slot_long_branch
; MIPS1: bb.0:
; MIPS1: BNE $a0, $a1, %bb.{{[0-9]+}}
bb.0:
successors: %bb.1, %bb.3
liveins: $a0, $a1
BEQ undef $a0, undef $a1, %bb.3, implicit-def $at
bb.1:
successors: %bb.2, %bb.4
liveins: $a0, $a1
INLINEASM &".space 131040", sideeffect attdialect
BEQ undef $a0, undef $a1, %bb.4, implicit-def $at
; MIPS1: bb.2:
; MIPS1: $v1 = LW renamable $a0, 0
; MIPS1-NEXT: $zero = SLL $zero, 0
bb.2:
successors: %bb.3, %bb.4
liveins: $a0, $v1
$v1 = LW renamable $a0, 0
$v1 = LW renamable $v1, 0
BEQ undef $a0, undef $v1, %bb.4, implicit-def $at
bb.3:
JR undef $ra
bb.4:
PseudoReturn undef $ra
...
```
mips2-fpu-mflo-delay-slot-long-branch.mir
```yaml
# RUN: llc -mtriple=mipsel-sony-psp -mcpu=mips2 -mattr=+single-float -filetype=obj -o /dev/null %s
# RUN: llc -mtriple=mipsel-sony-psp -mcpu=mips2 -mattr=+single-float -stop-after mips-branch-expansion -o - %s | FileCheck %s --check-prefixes=MIPS2
--- |
define void @mflo_delay_slot_bundle_size() {
ret void
}
define void @fpu_delay_slot_bundle_size() {
ret void
}
...
---
name: mflo_delay_slot_bundle_size
alignment: 4
tracksRegLiveness: true
body: |
; MIPS2-LABEL: name: mflo_delay_slot_bundle_size
; MIPS2: bb.0:
; MIPS2: BNE $a0, $a1, %bb.{{[0-9]+}}
; MIPS2-NEXT: $zero = SLL $zero, 0
; MIPS2: J %bb.{{[0-9]+}}
bb.0:
successors: %bb.1, %bb.3
liveins: $a0, $a1
BEQ undef $a0, undef $a1, %bb.3, implicit-def $at
bb.1:
successors: %bb.2, %bb.4
liveins: $a0, $v0
INLINEASM &".space 131036", sideeffect attdialect
BEQ undef $a0, undef $v0, %bb.4, implicit-def $at
; MIPS2: bb.2:
; MIPS2: $a0 = MFLO implicit $ac0
; MIPS2-NEXT: $zero = SLL $zero, 0
; MIPS2-NEXT: $zero = SLL $zero, 0
bb.2:
successors: %bb.3, %bb.4
liveins: $a0, $v1, $ac0
$a0 = MFLO implicit $ac0
renamable $ac0 = PseudoMULT $a0, $v1
$a0 = MFLO implicit $ac0
BEQ killed $a0, killed $v1, %bb.4, implicit-def $at
bb.3:
PseudoReturn undef $ra
bb.4:
PseudoReturn undef $ra
...
---
name: fpu_delay_slot_bundle_size
alignment: 4
tracksRegLiveness: true
body: |
; MIPS2-LABEL: name: fpu_delay_slot_bundle_size
; MIPS2: bb.0:
; MIPS2: BNE $a0, $a1, %bb.{{[0-9]+}}
bb.0:
successors: %bb.1, %bb.3
liveins: $a0, $a1
BEQ undef $a0, undef $a1, %bb.3, implicit-def $at
bb.1:
successors: %bb.2, %bb.4
liveins: $a0, $v0
INLINEASM &".space 131044", sideeffect attdialect
BEQ undef $a0, undef $v0, %bb.4, implicit-def $at
; MIPS2: bb.2:
; MIPS2: FCMP_S32 killed $f0, $f0, 1, implicit-def $fcc0
; MIPS2-NEXT: $zero = SLL $zero, 0
bb.2:
successors: %bb.3, %bb.4
liveins: $a0, $f0
FCMP_S32 killed $f0, $f0, 1, implicit-def $fcc0
BC1T killed $fcc0, %bb.4, implicit-def $at
bb.3:
PseudoReturn undef $ra
bb.4:
PseudoReturn undef $ra
...
```
And llvm-lit "fails successfully".
Contributor guide
Research direction
Read llvm/lib/Target/Mips/MipsBranchExpansion.cpp around the linked branch-expansion code, then run the mips1-load-delay-slot-long-branch.mir and mips2-fpu-mflo-delay-slot-long-branch.mir cases with llvm-lit. Compare the generated MIR and object compilation against the embedded FileCheck expectations; done means the edge cases no longer trigger the out-of-range PC16 fixup error and the tests pass.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100