llvm / llvm/llvm-project

[Mips] MIPS-I to MIPS-III may trigger error: out of range PC16 fixup in edge cases

Open
#222,224 4 comments 0 reactions 0 assignees View on GitHub
backend:MIPS confirmed crash-on-valid
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.