llvm / llvm/llvm-project

[RISCV][VLOPT] Vl optimizer cannot properly reduce the VL when vector split.

Open
#216,935 3 comments 0 reactions 0 assignees View on GitHub
backend:RISC-V enhancement
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

We found that the VL optimizer cannot reduce the VL from the VLMax when vector split.
This cause some regression when choosing a large VF but the trip count is small since it always perform VLMax operations.

godbolt: https://godbolt.org/z/MeG7d9EMb

```llvm
vector.body:
%index = phi i64 [ 0, %vector.ph ], [ %current.iteration.next, %vector.body ]
%avl = phi i64 [ %wide.trip.count, %vector.ph ], [ %avl.next, %vector.body ]
%vl = call i32 @llvm.experimental.get.vector.length.i64(i64 %avl, i32 64, i1 true)
%addr0.gep = getelementptr inbounds nuw i8, ptr %addr0, i64 %index
%load0 = call @llvm.vp.load.nxv64i8.p0(ptr align 1 %addr0.gep, splat (i1 true), i32 %vl), !alias.scope !0
%zext0 = zext %load0 to
%mul0 = mul nuw %zext0, %broadcast.splat
%addr1.gep = getelementptr inbounds nuw i8, ptr %addr1, i64 %index
%load1 = call @llvm.vp.load.nxv64i8.p0(ptr align 1 %addr1.gep, splat (i1 true), i32 %vl), !alias.scope !3, !noalias !0
%zext1 = zext %load1 to
%mul1 = mul nuw %broadcast.splat3, %zext1
%add = add %mul1, %mul0
%div = udiv %add, splat (i16 255)
%trunc = trunc %div to
call void @llvm.vp.store.nxv64i8.p0( %trunc, ptr align 1 %addr1.gep, splat (i1 true), i32 %vl), !alias.scope !3, !noalias !0
%vl.zext = zext i32 %vl to i64
%current.iteration.next = add nuw i64 %vl.zext, %index
%avl.next = sub nuw i64 %avl, %vl.zext
%done = icmp eq i64 %avl.next, 0
br i1 %done, label %middle.block, label %vector.body, !llvm.loop !5
...
```

will be lowered to

```asm
.LBB0_5:
add t1, a0, a5
mv a7, a4
vsetvli t0, a4, e8, m8, ta, ma
vle8.v v24, (t1)
vsetvli t1, zero, e16, m8, ta, ma. <= VLMax
addi t1, sp, 16
vzext.vf2 v8, v28.
vs8r.v v8, (t1)
add t1, a2, a5
add a5, a5, t0
vzext.vf2 v16, v24
vsetvli zero, a4, e8, m8, ta, ma
vle8.v v24, (t1)
vsetvli t2, zero, e16, m8, ta, ma. <= VLMax
addi t2, sp, 16
sub a4, a4, t0
vzext.vf2 v0, v24
vzext.vf2 v8, v28
vmul.vx v24, v0, a3
vmul.vx v8, v8, a3
vmacc.vx v24, a1, v16
vl8r.v v16, (t2)
vmacc.vx v8, a1, v16
vmulhu.vx v8, v8, a6
vmulhu.vx v16, v24, a6
vsetvli zero, zero, e8, m4, ta, ma
vnsrl.wi v24, v16, 7
vnsrl.wi v28, v8, 7
vsetvli zero, a7, e8, m8, ta, ma.
vse8.v v24, (t1)
bnez a4, .LBB0_5
```

CC @lukel97

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the Godbolt example and comparing the generated RISC-V assembly with the issue's output, focusing on the vector-split VL optimizer. Trace the vector-length handling that produces the marked VLMax operations; done means the optimizer reduces VL appropriately for a small trip count and the regression is resolved.

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
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.