This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Add a pass to remove duplicate VSETVLI instructions in a basic block.
ClosedPublic

Authored by craig.topper on Dec 4 2020, 12:18 PM.

Details

Summary

Add simple pass for removing redundant vsetvli instructions within a basic block. This handles the case where the AVL register and VTYPE immediate are the same and no other instructions that change VTYPE or VL are between them.

There are going to be more opportunities for improvement in this space as we development more complex tests.

Diff Detail

Event Timeline

craig.topper created this revision.Dec 4 2020, 12:18 PM
craig.topper requested review of this revision.Dec 4 2020, 12:18 PM
Herald added a project: Restricted Project. · View Herald TranscriptDec 4 2020, 12:18 PM
Herald added a subscriber: MaskRay. · View Herald Transcript
rogfer01 added a comment.EditedDec 4 2020, 12:32 PM

As a first step to remove the most obviously redundant vsetvli cases, this LGTM.

llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp
73

I don't think we want to use GVL as term here. It is not a standard term of the V-spec.

The spec says new value of vl (https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#61-vsetvlivsetvl-instructions) which is a bit verbose, so perhaps just saying the VL output will do.

Replace GVL with just VL

craig.topper added inline comments.Dec 4 2020, 12:45 PM
llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp
86

Thinking about this more, this isn't correct if AVL is X0. I think we would need that the that they both have a non-X0 Def. Or that the one we're removing has an X0 def.

rogfer01 added inline comments.Dec 4 2020, 1:40 PM
llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp
86

Right.

If AVL is x0 we have the following cases

vsetvli rdest0, x0, sew,lmul # rdest0 != x0
vsetvli rdest1, x0, sew,lmul  # rdest1 != x0 → redundant as vl stays the same and rdest1 == rdest0. OK to remove if rdest1 is dead
vsetvli rdest, x0, sew,lmul # rdest != x0
vsetvli x0, x0, sew,lmul  # redundant, nothing has changed at all, OK to remove

As you already pointed it out:

# earlier we set vtype ← sew0,lmul0,...
vsetvli x0, x0, sew1,lmul1 # (A) rdest != x0. # This could reduce vl (because  sew1 * lmul1 < sew0 * lmul0)
vsetvli rdest, x0, sew1,lmul1  # (B) We  set vl to to vlmax(sew1,lmul1)

Because we don't really know the value of vl at (A) and given §6.2 of the 0.9 spec (which gives some additional freedom to the new value when the AVL is larger than VLMAX), I think the safe thing to do here is not to remove (B).

rogfer01 added inline comments.Dec 4 2020, 1:44 PM
llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp
86

Well, I forgot one case:

vsetvli x0, x0, sew,lmul 
vsetvli x0, x0, sew,lmul  # redundant, OK to remove
rogfer01 added inline comments.Dec 4 2020, 1:56 PM
llvm/lib/Target/RISCV/RISCVCleanupVSETVLI.cpp
86

Sorry it is late (and inline comments can't be amended)

Where I wrote above

# This could reduce vl (because  sew1 * lmul1 < sew0 * lmul0)

should read

# This could reduce vl (because  sew1 / lmul1 > sew0 / lmul0)

Add additional checks for when AVL is X0.

Add a MIR test to make sure we don't remove

vsetvli x0, x0
vsetvli vreg, x0

khchen added a subscriber: khchen.Dec 4 2020, 5:56 PM

Any more comments on this?

rogfer01 accepted this revision.Dec 11 2020, 8:46 AM

This looks good to me. Thanks a lot @craig.topper

This revision is now accepted and ready to land.Dec 11 2020, 8:46 AM