This is an archive of the discontinued LLVM Phabricator instance.

[LegalizeTypes][VP] Add splitting support for binary VP ops
ClosedPublic

Authored by frasercrmck on Aug 12 2021, 5:09 AM.

Details

Summary

This patch extends D107904's introduction of vector-predicated (VP)
operation legalization to include vector splitting.

When the result of a binary VP operation needs splitting, all of its
operands are split in kind. The two operands and the mask are split as
usual, and the vector-length parameter EVL is "split" such that the low
and high halves each execute the correct number of elements.

Tests have been added to the RISC-V target to show splitting several
scenarios for fixed- and scalable-vector types. Without support for
umax (e.g. in the B extension) the generated code starts to branch.
Ideally a cost model would prevent their insertion in the first place.

Through these tests many opportunities for better codegen can be seen:
combining known-undef VP operations and for constant-folding operations
on ISD::VSCALE, to name but a few.

Diff Detail

Event Timeline

frasercrmck created this revision.Aug 12 2021, 5:09 AM
frasercrmck requested review of this revision.Aug 12 2021, 5:09 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 12 2021, 5:09 AM
RKSimon added inline comments.Aug 17 2021, 2:10 PM
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
2256

Why not just expand DAGTypeLegalizer::SplitVecRes_BinOp to handle VP ops?

  • unify VP and non-VP
frasercrmck marked an inline comment as done.Aug 18 2021, 2:25 AM
frasercrmck added inline comments.
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
2256

Same reason as in D107904, really. Updated now to share a common function.

frasercrmck marked an inline comment as done.Aug 18 2021, 2:53 AM
  • rebase & clang-format
RKSimon added inline comments.Aug 19 2021, 6:59 AM
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
1190

Should we need to assert this isKnownEven like we do in EVT::getHalfNumVectorElementsVT ?

frasercrmck added inline comments.Aug 20 2021, 4:23 AM
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
1190

I was unsure. For some reason I was under the impression that SplitVecRes_BinOp and splitting in general could only be called on even-sized vectors. And because VecVT is the result type of the split node in question, we know it's even. Is that not the case?

RKSimon accepted this revision.Aug 20 2021, 7:08 AM

LGTM (with the addition of the half elts assertion)

llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
1190

I think an assert will do no harm and will show we've at least thought about it.

This revision is now accepted and ready to land.Aug 20 2021, 7:08 AM
  • assert the mask vector length also divisible by two
frasercrmck marked 2 inline comments as done.Aug 20 2021, 8:16 AM
frasercrmck added inline comments.
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
1190

Yeah good idea. Cheers.

llvm/test/CodeGen/RISCV/rvv/vadd-vp.ll
1627

@craig.topper, do you have any thoughts about this issue? I don't think it's specific to this patch but rather is just exposed by it. We could probably generated a reduced test case on the current main.

frasercrmck marked an inline comment as done.
  • rebase
craig.topper added inline comments.Aug 31 2021, 9:19 AM
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
1191

evently -> evenly

  • rebase & fix assertion typo
frasercrmck marked an inline comment as done.Sep 1 2021, 1:14 AM
frasercrmck added inline comments.
llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
1191

Whoops, thanks.

llvm/test/CodeGen/RISCV/rvv/vadd-vp.ll
1627

FWIW this is a problem in main but only in the sense that we could create something like

%0:gpr = COPY $x0
dead %1:gpr = PseudoVSETVLI %0, 89, implicit-def $vl, implicit-def $vtype

which can then be register-coalesced into PseudoVSETVLI $x0. We tend not to generate this sort of thing. It's just that in this example the COPY $x0 isn't immediately apparent during instruction selection due to the pseudo instructions.

I couldn't find a way of stopping the coalescer do its job here. It's legal from an ISA to do it, but it's not from a semantics point-of-view. It's almost like we need two different PseudoVSETVLI instructions: one that takes x0 and one that doesn't.

simoll added a project: Restricted Project.Sep 1 2021, 5:33 AM
craig.topper added inline comments.Sep 1 2021, 9:34 AM
llvm/test/CodeGen/RISCV/rvv/vadd-vp.ll
1627

I'm looking into this.

craig.topper added inline comments.Sep 1 2021, 12:39 PM
llvm/test/CodeGen/RISCV/rvv/vadd-vp.ll
1627

This specific case should be gone after ccbb4c8b4ffd00588f0c21c7e5208bf210b26a53 This doesn't fix the underlying issue that the coalescer was allowed to do this. It just fixes the specific circumstance that allowed a copy from x0 to be an input to a vector instruction. We'll now see the 0 earlier and use vsetivli.

frasercrmck marked 3 inline comments as done.
  • rebase on top of test changes
llvm/test/CodeGen/RISCV/rvv/vadd-vp.ll
1627

Thanks, @craig.topper! I started fixing the SELECT_CC as you did but didn't want to lose the motivation to fix our VSETVLIs the "right way" before we'd had a chance to discuss what to do.

Ignoring other machine passes that may do the same illegal transform, I don't know if it is possible to fix the coalescer to do the same thing. In some ways we're lucky it's only a simple X0/no-X0 split. It'd be tricky if there were more complicated constraints going on.

frasercrmck edited the summary of this revision. (Show Details)Sep 2 2021, 2:25 AM
This revision was landed with ongoing or failed builds.Sep 2 2021, 2:26 AM
This revision was automatically updated to reflect the committed changes.