This is an archive of the discontinued LLVM Phabricator instance.

[RISCV] Move SHFLI matching to DAG combine. Add 32-bit support for RV64
ClosedPublic

Authored by craig.topper on Feb 14 2021, 12:26 AM.

Details

Summary

We previously used isel patterns for this, but that used quite
a bit of space in the isel table due to OR being associative
and commutative. It also wouldn't handle shifts/ands being in
reversed order.

This generalizes the shift/and matching from GREVI to
take the expected mask table as input so we can reuse it for
SHFLI.

There is no SHFLIW instruction, but we can promote a 32-bit
SHFLI to i64 on RV64. As long as bit 4 of the control bit isn't
set, a 64-bit SHFLI will preserve 33 sign bits if the input had
at least 33 sign bits. ComputeNumSignBits has been updated to
account for that to avoid sext.w in the tests.

Diff Detail

Event Timeline

craig.topper created this revision.Feb 14 2021, 12:26 AM
craig.topper requested review of this revision.Feb 14 2021, 12:26 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 14 2021, 12:26 AM
Herald added a subscriber: MaskRay. · View Herald Transcript

I think there are also a few linter issues to fix up here and there.

In general, though, it looks good. I'll take a closer look soon when I find some time.

llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2492

I wonder if this comment should be updated. It's more or less correct (for grev) but is now too specific.

2523

This bit seems specific to SHFL in a roundabout way. Is there a way to make it more generic, or at least explicit? I know we're only matching GREV or SHFL so we can expect certain preconditions but I worry it'd catch someone out if they wanted to use this method for other purposes.

llvm/test/CodeGen/RISCV/rv32Zbp.ll
2879

Are these changes in operand order creating cases that weren't previously optimized? I take it it's not now required for the optimization to work.

craig.topper added inline comments.Feb 18 2021, 9:28 AM
llvm/test/CodeGen/RISCV/rv32Zbp.ll
2879

Tablegen would automatically generate patterns for all permutations of the operands for the two ORs, but we weren't testing it. I changed the tests to make sure my commuting and associativity worked. Each test case should have a different permutation now.

Update comments and clang-format.

I've pre-committed the test changes where I changed the OR operand order.

llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2523

I've updated the header to provide a better description. We could add another parameter to make it explicit, but I figured the caller already had to size the array of expected masks correctly.

frasercrmck accepted this revision.Feb 19 2021, 1:05 AM

Thanks for pre-committing the test cases, I think it's cleaner now.

There's one comment I left but apart from that LGTM.

llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2505

Should 1 be C2 here and in the last line?

This revision is now accepted and ready to land.Feb 19 2021, 1:05 AM
RKSimon added inline comments.
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2521

@craig.topper Shouldn't this always early-out if ShAmt >= Width? Reported by coverity.

craig.topper added inline comments.Jun 6 2021, 12:07 PM
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2521

You mean should that be an || instead of &&?

RKSimon added inline comments.Jun 6 2021, 12:29 PM
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
2521

Yes - it might be a false positive but coverity is warning that *Mask can be shifted by 64 at line 2751.