diff options
author | Alex Bradbury <asb@lowrisc.org> | 2018-10-12 23:18:52 +0000 |
---|---|---|
committer | Alex Bradbury <asb@lowrisc.org> | 2018-10-12 23:18:52 +0000 |
commit | 748d080e6288ec3b2edd1a1bfdcf21491e816fd3 (patch) | |
tree | 0e74da5b9307e3ef6d1a553cdc446f1b81693c9e /llvm/lib/Target | |
parent | 71f484c967ad7b41c9cca6b8c3aef6cf340a8877 (diff) | |
download | bcm5719-llvm-748d080e6288ec3b2edd1a1bfdcf21491e816fd3.tar.gz bcm5719-llvm-748d080e6288ec3b2edd1a1bfdcf21491e816fd3.zip |
[RISCV] Eliminate unnecessary masking of promoted shift amounts
SelectionDAGBuilder::visitShift will always zero-extend a shift amount when it
is promoted to the ShiftAmountTy. This results in zero-extension (masking)
which is unnecessary for RISC-V as the shift operations only read the lower 5
or 6 bits (RV32 or RV64).
I initially proposed adding a getExtendForShiftAmount hook so the shift amount
can be any-extended (D52975). @efriedma explained this was unsafe, so I have
instead eliminate the unnecessary and operations at instruction selection time
in a manner similar to X86InstrCompiler.td.
Differential Revision: https://reviews.llvm.org/D53224
llvm-svn: 344432
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/RISCV/RISCVInstrInfo.td | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td index 5ca1cbd165d..50012569a74 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td @@ -205,6 +205,12 @@ def ixlenimm : Operand<XLenVT> { // Standalone (codegen-only) immleaf patterns. def simm32 : ImmLeaf<XLenVT, [{return isInt<32>(Imm);}]>; def simm32hi20 : ImmLeaf<XLenVT, [{return isShiftedInt<20, 12>(Imm);}]>; +// A mask value that won't affect significant shift bits. +def immshiftxlen : ImmLeaf<XLenVT, [{ + if (Subtarget->is64Bit()) + return countTrailingOnes<uint64_t>(Imm) >= 6; + return countTrailingOnes<uint64_t>(Imm) >= 5; +}]>; // Addressing modes. // Necessary because a frameindex can't be matched directly in a pattern. @@ -646,13 +652,24 @@ def : PatGprGpr<and, AND>; def : PatGprSimm12<and, ANDI>; def : PatGprGpr<xor, XOR>; def : PatGprSimm12<xor, XORI>; -def : PatGprGpr<shl, SLL>; def : PatGprUimmLog2XLen<shl, SLLI>; -def : PatGprGpr<srl, SRL>; def : PatGprUimmLog2XLen<srl, SRLI>; -def : PatGprGpr<sra, SRA>; def : PatGprUimmLog2XLen<sra, SRAI>; +// Match both a plain shift and one where the shift amount is masked (this is +// typically introduced when the legalizer promotes the shift amount and +// zero-extends it). For RISC-V, the mask is unnecessary as shifts in the base +// ISA only read the least significant 5 bits (RV32I) or 6 bits (RV64I). +multiclass VarShiftXLenPat<PatFrag ShiftOp, RVInst Inst> { + def : Pat<(ShiftOp GPR:$rs1, GPR:$rs2), (Inst GPR:$rs1, GPR:$rs2)>; + def : Pat<(ShiftOp GPR:$rs1, (and GPR:$rs2, immshiftxlen)), + (Inst GPR:$rs1, GPR:$rs2)>; +} + +defm : VarShiftXLenPat<shl, SLL>; +defm : VarShiftXLenPat<srl, SRL>; +defm : VarShiftXLenPat<sra, SRA>; + /// FrameIndex calculations def : Pat<(add (i32 AddrFI:$Rs), simm12:$imm12), |