llvm / llvm/llvm-project

[RISCV] Reg allocation cause sub-optimal result

Open
#161,038 16 comments 0 reactions 0 assignees View on GitHub
backend:RISC-V llvm:regalloc
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

To allocate register for case below:

```
624B %29:gprnox0 = PseudoVSETVLI %55:gprnox0, 211, implicit-def dead $vl, implicit-def dead $vtype
640B %30:vrm8 = PseudoVLE32_V_M8 undef %30:vrm8(tied-def 0), %53:gpr, %29:gprnox0, 5, 2 :: (load unknown-size from %ir.in.addr.041, align 4)
656B %31:vrm8 = PseudoVLE32_V_M8 undef %31:vrm8(tied-def 0), %54:gpr, %29:gprnox0, 5, 2 :: (load unknown-size from %ir.other.addr.040, align 4)
672B %41:vrm8nov0 = nofpexcept PseudoVFDIV_VV_M8_E32 undef %41:vrm8nov0(tied-def 0), %30:vrm8, %31:vrm8, 7, %29:gprnox0, 5, 0, implicit $frm
688B early-clobber %35:vr = nofpexcept PseudoVMFLT_VFPR32_M8 %41:vrm8nov0, %34:fpr32, %29:gprnox0, 5
704B early-clobber %38:vr = nofpexcept PseudoVMFGT_VFPR32_M8 %41:vrm8nov0, %37:fpr32, %29:gprnox0, 5
720B %39:vr = PseudoVMAND_MM_M2 %35:vr, %38:vr, %29:gprnox0, 0
736B %40:vrm8 = nofpexcept PseudoVFCVT_RTZ_X_F_V_M8 undef %40:vrm8(tied-def 0), %41:vrm8nov0, %29:gprnox0, 5, 0
752B $v0 = COPY %39:vr
784B %41:vrm8nov0 = nofpexcept PseudoVFCVT_F_X_V_M8_E32_MASK %41:vrm8nov0(tied-def 0), %40:vrm8, killed $v0, 7, %29:gprnox0, 5, 1, implicit $frm
800B %43:vrm8 = nofpexcept PseudoVFMUL_VV_M8_E32 undef %43:vrm8(tied-def 0), %41:vrm8nov0, %31:vrm8, 7, %29:gprnox0, 5, 0, implicit $frm
816B %44:vrm8 = nofpexcept PseudoVFSUB_VV_M8_E32 undef %44:vrm8(tied-def 0), %30:vrm8, %43:vrm8, 7, %29:gprnox0, 5, 0, implicit $frm
832B PseudoVSE32_V_M8 %44:vrm8, %52:gpr, %29:gprnox0, 5 :: (store unknown-size into %ir.out.addr.042, align 4)
848B %53:gpr = SH2ADD %29:gprnox0, %53:gpr
```

For 736B, before allocating %40, all vrm8 register class is running out(except v0-v7). So when allocating %40, because of some strategy of greedy allocation, assuming it evict %30 ,and then assign v8m8(allocating to %30 before) to %40. and then push %30 into queue. But for %40, between def (736B)and use(784B), there is no overlap for v8m8. so this spill/reload is redundant. For now, i add a pass to eliminate this scenario at post-ra stage.

Is there any better solution?

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the shown RISC-V machine-instruction sequence and inspecting greedy register allocation around 736B, where %40 evicts %30. Compare the resulting spill/reload behavior with the proposed post-register-allocation cleanup. Done means removing the redundant spill/reload without changing allocation correctness.

Written by the indexing model from the issue text.

Assessment

Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.