diff options
author | Min-Yih Hsu <min.hsu@sifive.com> | 2025-05-27 12:15:37 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-27 12:15:37 -0700 |
commit | ea8838446678a1163b361b0598b1259e9f476900 (patch) | |
tree | 599f75476ff220c567d6046e8c07a957bc56e069 /llvm/lib/IR/Module.cpp | |
parent | 8a21e0f4ff97f5564e8d134f841ae59ed2c5cdb0 (diff) | |
download | llvm-ea8838446678a1163b361b0598b1259e9f476900.zip llvm-ea8838446678a1163b361b0598b1259e9f476900.tar.gz llvm-ea8838446678a1163b361b0598b1259e9f476900.tar.bz2 |
[RISCV][InsertVSETVLI] Remove redundant vsetvli by coalescing blocks from bottom up (#141298)
I ran into a relatively rare case in RISCVInsertVSETVLIPass, where right
after the `emitVSETVLI` phase but before the `coalesceVSETVLIs` phase,
we have two blocks that look like this:
```
bb.first:
%46:gprnox0 = PseudoVSETIVLI %30:gprnox0, 199 /* e8, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype
%76:gpr = PseudoVSETVLIX0 killed $x0, ..., implicit-def $vl, implicit-def $vtype
$v10m2 = PseudoVMV_V_I_M2 undef renamable $v10m2, 0, -1, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
...
bb.second:
$x0 = PseudoVSETVLI %46, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
$v10 = PseudoVMV_S_X undef $v10(tied-def 0), undef %53:gpr, $noreg, 5, implicit $vl, implicit $vtype
$x0 = PseudoVSETVLI %30, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
$v8 = PseudoVREDSUM_VS_M2_E32 undef $v8(tied-def 0), killed $v8m2, killed $v10, $noreg, 5, 0, implicit $vl, implicit $vtype
```
After the `coalesceVSETVLIs` phase, it turns into:
``` diff
bb.first:
- %46:gprnox0 = PseudoVSETIVLI %30:gprnox0, 199 /* e8, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype
+ dead %46:gprnox0 = PseudoVSETIVLI %30:gprnox0, 199 /* e8, mf2, ta, ma */, implicit-def $vl, implicit-def $vtype
%76:gpr = PseudoVSETVLIX0 killed $x0, ..., implicit-def $vl, implicit-def $vtype
$v10m2 = PseudoVMV_V_I_M2 undef renamable $v10m2, 0, -1, 5 /* e32 */, 0 /* tu, mu */, implicit $vl, implicit $vtype
...
bb.second:
- $x0 = PseudoVSETVLI %46, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
+ $x0 = PseudoVSETVLI %30, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
$v10 = PseudoVMV_S_X undef $v10(tied-def 0), undef %53:gpr, $noreg, 5, implicit $vl, implicit $vtype
- $x0 = PseudoVSETVLI %30, 209 /* e32, m2, ta, ma */, implicit-def $vl, implicit-def $vtype
$v8 = PseudoVREDSUM_VS_M2_E32 undef $v8(tied-def 0), killed $v8m2, killed $v10, $noreg, 5, 0, implicit $vl, implicit $vtype
```
We forwarded `%30` to any use of `%46` and further reduced the number of
VSETVLI we need in `bb.second`. But the problem is, if `bb.first` is
processed before `bb.second` -- which is the majority of the cases --
then we're not able to remove the vsetvli which defines the now-dead
`%46` in `bb.first` after coalescing `bb.second`.
This will produce assembly code like this:
```
vsetvli zero, s0, e8, mf2, ta, ma
vsetvli a0, zero, e32, m2, ta, ma
vmv.v.i v10, 0
```
This patch fixes this issue by coalescing the blocks from bottom up such
that we can account for dead VSETVLI in the earlier blocks after its
uses are eliminated in later blocks.
---------
Co-authored-by: Luke Lau <luke@igalia.com>
Diffstat (limited to 'llvm/lib/IR/Module.cpp')
0 files changed, 0 insertions, 0 deletions