This is an archive of the discontinued LLVM Phabricator instance.

[SelectionDAG] Fix the representation of ISD::STEP_VECTOR.
ClosedPublic

Authored by efriedma on Jul 8 2021, 5:03 PM.

Details

Summary

The existing rule about the operand type is strange. Instead, just say the operand is a TargetConstant with the right width. (Legalization ignores TargetConstants, so it doesn't matter if that width is legal.)

Highlights:

  1. I had to substantially rewrite the AArch64 isel patterns to expect a TargetConstant. Nothing too exotic, but maybe a little hairy. Maybe worth considering a target-specific node with some dagcombines instead of this complicated nest of isel patterns.
  2. Our behavior on RV32 for vectors of i64 has changed slightly. In particular, we correctly preserve the width of the arithmetic through legalization. The result is a bit ugly in some cases.
  3. I explicitly defined the behavior around overflow. This is necessary to make the DAGCombine transforms legal, and I don't think it causes any practical issues.

Diff Detail

Event Timeline

efriedma created this revision.Jul 8 2021, 5:03 PM
efriedma requested review of this revision.Jul 8 2021, 5:03 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 8 2021, 5:03 PM
Herald added a subscriber: MaskRay. · View Herald Transcript

Hi @efriedma, I've not looked through all the AArch64 pattern changes yet, but on the surface switching from SDValue to APInt for the STEP_VECTOR seems reasonable, although I think @paulwalker-arm may have an interest in this as he left quite a few comments on my original patch regarding the interface and choice of type. I had a couple of comments so far about the vscale changes.

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
4205

Hi @efriedma, the commit message didn't mention anything about changing the legalisation for VSCALE. Is it possible to either 1) add something to commit message describing why we've also had to fix VSCALE legalisation as part of the patch, or 2) is it possible to do this in a separate patch?

4213

Can you call getFixedSizeInBits() here to avoid relying upon the implicit TypeSize -> uint64_t cast?

When the node was first added I figured it wouldn't be too long before somebody wanted to support a variable stride, so using an SDValue made sense so as to save some effort later. Personally I've never seen a need to support a variable stride and time has passed without such a request so I think locking the interface down now is a good move.

I'm still on holiday so have not done a proper review, just added a couple of observations.

llvm/include/llvm/CodeGen/SelectionDAG.h
838

We couldn't do this before because the type of Step was important. This is no longer the case so is it worth giving StepVal a default of 1? as a connivence. I know there's the assert that the sizes match but adding || StepVal.isOneValue() doesn't seem so bad.

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
1756

Now that you've define the overflow semantics, do these have to match? There is the StepVal * i part in the build vector block but that could sextOrTrunc StepVal?

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
1382–1389 ↗(On Diff #357390)

Why move the patterns outside of their multiclasess? What am I missing here?

efriedma added inline comments.Jul 12 2021, 11:50 AM
llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
4205

VSCALE legalization shows up as a consequence of the legalization changes on RV32. I guess I can split it off; an explicit call to llvm.vscale or whatever would probably trigger the same thing.

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
1756

Allowing an APInt with the wrong width seems like it's just asking for trouble; even if we can make it "work", likely the caller has a bug.

That said, it would be reasonable to add an overload that just defaults the step to 1; we repeat that pattern all over.

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
1382–1389 ↗(On Diff #357390)

The multiclasses were making it hard to understand what was actually going on because none of the names made sense, I was getting errors about unknown names, etc. I have a better handle on what it's doing, now; I think I could try to move it back.

I split a few patches off this. D105847 is still waiting for review.

Matt added a subscriber: Matt.Jul 20 2021, 6:39 AM
paulwalker-arm accepted this revision.Jul 20 2021, 10:46 AM

I'm happy with the patch from an SVE point of view. I'm less enamoured by the MOVi32imm changes from the prerequisite patch, but I won't loose sleep over it.

I guess it's up to the RISCV folk to decide if they're happy to accept the patch based on the RV32 regression or can suggest an easy fix.

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
1750–1753

Thanks for adding this overload.

This revision is now accepted and ready to land.Jul 20 2021, 10:46 AM

Without having dug in I suspect the RV32 regressions can be fixed with some improvements to the scalar splatting. In many of these cases we should be able to know that the scalar -- while not a constant -- is a sign-extended XLEN-sized value.

I'm okay with doing that separately after this merges because it sounds enough to me like a new feature. Plus 64-bit vectors on RV32 aren't our strongest suit to begin with. Perhaps someone else may disagree though? @craig.topper?

Without having dug in I suspect the RV32 regressions can be fixed with some improvements to the scalar splatting. In many of these cases we should be able to know that the scalar -- while not a constant -- is a sign-extended XLEN-sized value.

I'm okay with doing that separately after this merges because it sounds enough to me like a new feature. Plus 64-bit vectors on RV32 aren't our strongest suit to begin with. Perhaps someone else may disagree though? @craig.topper?

I'm also ok doing this after this merges. 64-bit vectors on RV32 aren't a priority for me right now.

This revision was landed with ongoing or failed builds.Jul 21 2021, 10:58 AM
This revision was automatically updated to reflect the committed changes.