[RISCV] Add patterns for RV64I SLLW/SRLW/SRAW instructions
authorAlex Bradbury <asb@lowrisc.org>
Sat, 12 Jan 2019 07:32:31 +0000 (07:32 +0000)
committerAlex Bradbury <asb@lowrisc.org>
Sat, 12 Jan 2019 07:32:31 +0000 (07:32 +0000)
commitd05eae7a7b24444c676238383037552816072052
tree37afb48bd292f52e3eb5e984adfe0a2b64080d44
parenta69d903204377a971d73bbc096e28521e116e364
[RISCV] Add patterns for RV64I SLLW/SRLW/SRAW instructions

This restores support for selecting the SLLW/SRLW/SRAW instructions, which was
removed in rL348067 as the previous patterns made some unsafe assumptions.
Also see the related llvm-dev discussion
<http://lists.llvm.org/pipermail/llvm-dev/2018-December/128497.html>

Ultimately I didn't introduce a custom SelectionDAG node, but instead added a
DAG combine that inserts an AssertZext i5 on the shift amount for an i32
variable-length shift and also added an ANY_EXTEND DAG-combine which will
instead produce a SIGN_EXTEND for an i32 variable-length shift, increasing the
opportunity to safely select SLLW/SRLW/SRAW.

There are obviously different ways of addressing this (a number discussed in
the llvm-dev thread), so I'd welcome further feedback and comments.

Note that there are now some cases in
test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll where sraw/srlw/sllw is
selected even though sra/srl/sll could be used without any extra instructions.
Given both are semantically equivalent, there doesn't seem a good reason to
prefer one vs the other. Given that would require more logic to still select
sra/srl/sll in those cases, I've left it preferring the *w variants.

Differential Revision: https://reviews.llvm.org/D56264

llvm-svn: 350992
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/test/CodeGen/RISCV/alu32.ll
llvm/test/CodeGen/RISCV/alu64.ll
llvm/test/CodeGen/RISCV/rv64i-exhaustive-w-insts.ll