Commit Graph

72 Commits

Author SHA1 Message Date
Craig Topper d32ed9b27e [RISCV] Use a ComplexPattern to merge the PatFrags for removing unneeded masks on shift amounts.
Rather than having patterns with and without an AND, use a
ComplexPattern to handle both cases.

Reduces the isel table by about 700 bytes.
2021-02-12 14:03:23 -08:00
Craig Topper 875c76de2b [RISCV] Add support for matching .vx and .vi forms of binary instructions for fixed vectors.
Unlike scalable vectors, I'm only using a ComplexPattern for
the immediate itself. The vmv_v_x is matched explicitly. We igore
the VL argument when matching a binary operator, but we do check
it when matching splat directly.

I left out tests for vXi64 as they fail on rv32 right now.

Reviewed By: frasercrmck

Differential Revision: https://reviews.llvm.org/D96365
2021-02-12 09:18:10 -08:00
ShihPo Hung 9e62c9146d [RISCV] Initial support for insert/extract subvector
This patch handles cast-like insert_subvector & extract_subvector
in which case:
1. index starts from 0.
2. inserting a fixed-width vector into a scalable vector,
   or extracting a fixed-width vector from a scalable vector.

Reviewed By: craig.topper, frasercrmck

Differential Revision: https://reviews.llvm.org/D96352
2021-02-11 14:35:49 -08:00
Craig Topper fd5adae02c [RISCV] Remove SRO* and SLO* instructions from bitmanip.
As of the current draft these are no longer being considered
for the bitmanip spec. It wasn't clear what sub extension they
belonged in in the 0.93 spec.

So remove them. They can always be added back if something changes.

Reviewed By: frasercrmck

Differential Revision: https://reviews.llvm.org/D96157
2021-02-09 09:35:05 -08:00
Hsiangkai Wang c7189ba785 [RISCV] Add new vector instructions in v0.10.
* Add new vector instructions in v0.10.
 - load/store for mask value vle1.v vse1.v
 - vsetivli for 0-31 immediate vector length.
* Rename vector instructions in v0.10.
 - vfrsqrte7 -> vfrsqrt7
 - vfrece7 -> vfrec7
* Reserve memory width encodings for EEW>128b.

Differential Revision: https://reviews.llvm.org/D95781
2021-02-03 13:28:58 +08:00
Craig Topper 912306ef21 [RISCV] Use a ComplexPattern to merge isel patterns for vector load/store with GPR and FrameIndex addresses.
This reduces the isel table size by about 3000 bytes.

Reviewed By: frasercrmck

Differential Revision: https://reviews.llvm.org/D95844
2021-02-02 10:20:52 -08:00
Craig Topper e7f9a83499 [RISCV] Replace NoX0 SDNodeXForm with a ComplexPattern to do the selection of the VL operand.
I think this is a more standard way of doing this.

Reviewed By: rogfer01

Differential Revision: https://reviews.llvm.org/D95833
2021-02-02 00:08:58 -08:00
Craig Topper 6a3ab66625 [RISCV] Update comment text from D95774. NFC 2021-02-01 09:52:43 -08:00
Craig Topper 1097ee61bf [RISCV] Optimize (srl (and X, 0xffff), C) -> (srli (slli X, 16), 16 + C).
Rather than materializing the 0xffff immediate for the AND, use
a shift left to remove the upper bits and then shift in zeros
from the right.

This pattern occurs when type legalizing an i16 right shift.

I've implemented this with custom selection code for a number of
reasons. I've limited this to the AND having a single use. We need
to compensate for SimplifyDemandedBits altering the AND mask. I'm
using *W opcodes on RV64. We may want to generlize this in the
future. For all these reason it seemed easiest to do it this way.

Reviewed By: luismarques

Differential Revision: https://reviews.llvm.org/D95774
2021-02-01 09:37:55 -08:00
Craig Topper 3fdf2a56dd [RISCV] Use MVT instead of EVT in RISCVISelDAGToDAG.cpp
All this code runs post type legalization so we should have
exclusively legal types. The methods on MVT should be more
efficient than EVT.
2021-01-30 15:57:15 -08:00
Simon Pilgrim aa76cebab5 Fix "32-bit shift result used in 64-bit comparison" MSVC warning. NFCI. 2021-01-28 11:21:36 +00:00
Craig Topper 5d05cdf55c [RISCV] Copy isUnneededShiftMask from X86.
In d2927f786e, I added patterns
to remove (and X, 31) from sllw/srlw/sraw shift amounts.

There is code in SelectionDAGISel.cpp that knows to use
computeKnownBits to fill in bits of the mask that were removed
by SimplifyDemandedBits based on bits being known zero.

The non-W shift patterns use immbottomxlenset which allows the
mask to have more than log2(xlen) trailing ones, but doesn't
have a call to computeKnownBits to fill in bits of the mask that may
have been cleared by SimplifyDemandedBits.

This patch copies code from X86 to handle more than log2(xlen)
bottom bits set and uses computeKnownBits to fill in missing bits
before counting.

Reviewed By: luismarques

Differential Revision: https://reviews.llvm.org/D95422
2021-01-27 20:46:10 -08:00
Craig Topper a40e01e442 [RISCV] Rework fault first only load isel.
-Remove the ISD opcode for READ_VL. Just emit the MachineSDNode directly.
-Move segmented fault first only load intrinsic handling completely to
 RISCVISelDAGToDAG.cpp and emit the ReadVL MachineSDNode there
 instead of lowering to ISD opcodes first.
2021-01-27 11:51:41 -08:00
Hsiangkai Wang b69932b550 [RISCV] Implement vlsegff intrinsics.
Differential Revision: https://reviews.llvm.org/D95303
2021-01-26 12:02:43 +08:00
Craig Topper c50457f3e4 [RISCV] Make the code in MatchSLLIUW ignore the lower bits of the AND mask where the shift has guaranteed zeros.
This avoids being dependent on SimplifyDemandedBits having cleared
those bits.

It could make sense to teach SimplifyDemandedBits to keep all
lower bits 1 in an AND mask when possible. This could be
implemented with slli+srli in the general case rather than
needing to materialize the constant.
2021-01-24 00:34:45 -08:00
Hsiangkai Wang 66a49aef69 [RISCV] Implement vsoxseg/vsuxseg intrinsics.
Define vsoxseg/vsuxseg intrinsics and pseudo instructions.
Lower vsoxseg/vsuxseg intrinsics to pseudo instructions in RISCVDAGToDAGISel.

Differential Revision: https://reviews.llvm.org/D94940
2021-01-23 08:54:56 +08:00
Hsiangkai Wang 97e33feb08 [RISCV] Implement vloxseg/vluxseg intrinsics.
Define vloxseg/vluxseg intrinsics and pseudo instructions.
Lower vloxseg/vluxseg intrinsics to pseudo instructions in RISCVDAGToDAGISel.

Differential Revision: https://reviews.llvm.org/D94903
2021-01-23 08:54:56 +08:00
Hsiangkai Wang a8b96eadfd [RISCV] Implement vssseg intrinsics.
Define vlsseg intrinsics and pseudo instructions. Lower vlsseg
intrinsics to pseudo instructions in RISCVDAGToDAGISel.

Differential Revision: https://reviews.llvm.org/D94863
2021-01-21 11:51:35 +08:00
Hsiangkai Wang e5e329023b [RISCV] Implement vlsseg intrinsics.
Define vlsseg intrinsics and pseudo instructions. Lower vlsseg intrinsics
to pseudo instructions in RISCVDAGToDAGISel.

Differential Revision: https://reviews.llvm.org/D94763
2021-01-21 11:51:35 +08:00
Hsiangkai Wang 47228f7854 [RISCV] Implement vsseg intrinsics.
Define vsseg intrinsics and pseudo instructions. Lower vsseg intrinsics
to pseudo instructions in RISCVDAGToDAGISel.

Differential Revision: https://reviews.llvm.org/D94688
2021-01-21 11:51:35 +08:00
Hsiangkai Wang 8ca4b174d7 [RISCV] Implement vlseg intrinsics.
For Zvlsseg, we need continuous vector registers for the values. We need
to define new register classes for the different combinations of (number
of fields and LMUL). For example,

when the number of fields(NF) = 3, LMUL = 2, the values will be assigned
to (V0M2, V2M2, V4M2), (V2M2, V4M2, V6M2), (V4M2, V6M2, V8M2), ...

We define the vlseg intrinsics with multiple outputs. There is no way to
describe the codegen patterns with multiple outputs in the tablegen
files. We do the codegen in RISCVISelDAGToDAG and use EXTRACT_SUBREG to
extract the values of output.

The multiple scalable vector values will be put into a struct. This
patch is depended on the support for scalable vector struct.

Differential Revision: https://reviews.llvm.org/D94229
2021-01-20 14:26:04 +08:00
Craig Topper 387d3c2479 [RISCV] Merge Utils library into MCTargetDesc
MCTargetDesc includes headers from Utils and Utils includes headers
from MCTargetDesc. So from a library layering perspective it makes sense
for them to be in the same library. I guess the other option might be to
move the tablegen includes from RISCVMCTargetDesc.h to RISCVBaseInfo.h
so that RISCVBaseInfo.h didn't need to include RISCVMCTargetDesc.h.
Everything else that depends on Utils also depends on MCTargetDesc so
having one library seemed simpler.

Differential Revision: https://reviews.llvm.org/D93168
2021-01-14 11:47:30 -08:00
Craig Topper 7b5a0e2f88 [RISCV] Move shift ComplexPatterns and custom isel to PatFrags with predicates
ComplexPatterns are kind of weird, they don't call any of the predicates on their operands. And their "complexity" used for tablegen ordering purposes in the matcher table is hand specified.

This started as an attempt to just use sext_inreg + SLOIPat to implement SLOIW just to have one less Select function. The matching for the or+shl is the same as long as you know the immediate is less than 32 for SLOIW. But that didn't work out because using uimm5 with SLOIPat didn't do anything if it was a ComplexPattern.

I realized I could just use a PatFrag with the opcodes I wanted to match and an immediate predicate would then evaluate correctly. This also computes the complexity just like any other pattern does. Then I just needed to check the constraints on the immediates in the predicate. Conveniently the predicate is evaluated after the fragment has been matched. So the structure has already been checked, we just need to find the constants.

I'll note that this is unusual, I didn't find any other targets looking through operands in PatFrag predicate. There is a PredicateCodeUsesOperands feature that can be used to collect the operands into an array that is used by AMDGPU/VOP3Instructions.td. I believe that feature exists to handle commuted matching, but since the nodes here use constants, they aren't ever commuted

Differential Revision: https://reviews.llvm.org/D91901
2021-01-05 11:37:48 -08:00
Fraser Cormack d85a198e85 [RISCV] Pattern-match more vector-splatted constants
This patch extends the pattern-matching capability of vector-splatted
constants. When illegally-typed constants are legalized they are
canonically sign-extended to XLenVT. This preserves the sign and allows
us to match simm5. If they were zero-extended for whatever reason we'd
lose that ability: e.g. `(i8 -1) -> (XLenVT 255)` would not be matched
under the current logic.

To address this we first manually sign-extend the splatted constant from
the vector element type to int64_t. This preserves the semantics while
removing any implicitly-truncated bits.

The corresponding logic for uimm5 was not updated, the rationale being
that neither sign- nor zero-extending a legal uimm5 immediate should
change that (unless we expect actual "garbage" upper bits).

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D93837
2020-12-28 07:11:10 +00:00
Fraser Cormack 1a7ac29a89 [RISCV] Add ISel support for RVV vector/scalar forms
This patch extends the SDNode ISel support for RVV from only the
vector/vector instructions to include the vector/scalar and
vector/immediate forms.

It uses splat_vector to carry the scalar in each case, except when
XLEN<SEW (RV32 SEW=64) when a custom node `SPLAT_VECTOR_I64` is used for
type-legalization and to encode the fact that the value is sign-extended
to SEW. When the scalar is a full 64-bit value we use a sequence to
materialize the constant into the vector register.

The non-intrinsic ISel patterns have also been split into their own
file.

Authored-by: Roger Ferrer Ibanez <rofirrim@gmail.com>
Co-Authored-by: Fraser Cormack <fraser@codeplay.com>

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D93312
2020-12-23 20:16:18 +00:00
Craig Topper 69c8d121f7 [RISCV] Add intrinsics for vsetvli instruction
This patch adds two IR intrinsics for vsetvli instruction. One to set the vector length to a user specified value and one to set it to vlmax. The vlmax uses the X0 source register encoding.

Clang builtins will follow in a separate patch

Differential Revision: https://reviews.llvm.org/D92973
2020-12-18 12:10:09 -08:00
Craig Topper aaa925795f [RISCV] Use SDLoc created early in RISCVDAGToDAGISel::Select instead of recreating it in multiple cases in the switch. NFC 2020-12-08 21:13:25 -08:00
Craig Topper 3e86fbc971 [RISCV] Replace custom isel code for RISCVISD::READ_CYCLE_WIDE with isel pattern
This node returns 2 results and uses a chain. As long as we use a DAG as part of the pseudo instruction definition where we can use the "set" operator, it looks like tablegen can handle use a pattern for this without a problem. I believe the original implementation was copied from PowerPC.

This also fixes the pseudo instruction so that it is marked as having side effects to match the definition of CSRRS and the RV64 instruction. And we don't need to explicitly clear mayLoad/mayStore since those can be inferred now.

Differential Revision: https://reviews.llvm.org/D92786
2020-12-08 10:23:37 -08:00
Hsiangkai Wang f7bc7c2981 [RISCV] Support Zfh half-precision floating-point extension.
Support "Zfh" extension according to
https://github.com/riscv/riscv-isa-manual/blob/zfh/src/zfh.tex

Differential Revision: https://reviews.llvm.org/D90738
2020-12-03 09:16:33 +08:00
Craig Topper 78767b7f8e [RISCV] Add RISCVISD::ROLW/RORW use those for custom legalizing i32 rotl/rotr on RV64IZbb.
This should result in better utilization of RORIW since we
don't need to look for a SIGN_EXTEND_INREG that may not exist.

Also remove rotl/rotr isel matching to GREVI and just prefer RORI.
This is to keep consistency so we don't have to match ROLW/RORW
to GREVIW as well. I imagine RORI/RORIW performance will be the
same or better than GREVI.

Differential Revision: https://reviews.llvm.org/D91449
2020-11-20 10:25:47 -08:00
Craig Topper 124c93c528 [RISCV] When matching SROIW, check all 64 bits of the OR mask
We need to make sure the upper 32 bits are all ones to ensure the result is properly sign extended. Previously we only checked the lower 32 bits of the mask. I've also added a check that the shift amount is less than 32. Without that the original code asserts inside maskLeadingOnes if the SROI check is removed or the SROIW pattern is checked first. I've refactored the code to use early outs to reduce nesting.

I've also updated SLOIW matching with the same changes, but I couldn't find a broken test case with the existing code.

Differential Revision: https://reviews.llvm.org/D90961
2020-11-16 10:08:15 -08:00
Craig Topper 857563eaf0 [RISCV] Check all 64-bits of the mask in SelectRORIW.
We need to ensure the upper 32 bits of the mask are zero.
So that the srl shifts zeroes into the lower 32 bits.

Differential Revision: https://reviews.llvm.org/D90585
2020-11-04 10:15:30 -08:00
Craig Topper 3701e33a22 [RISCV] Remove custom isel for (srl (shl val, 32), imm). Use pattern instead. NFCI
We don't need custom matching, we just a need a predicate to check
the immediate is greater than 32. We can use the existing ImmSub32
to adjust the immediate.

I've also used the new predicate in the other location that used
ImmSub32. I tried to create a test case where we would break without
the greater than 32 check on that pattern, but DAG combine defeated me.
Still seemed safer to have it.

Differential Revision: https://reviews.llvm.org/D90546
2020-11-04 09:59:14 -08:00
Craig Topper 00eff96e1d [RISCV] Add missing patterns for rotr with immediate for Zbb/Zbp extensions.
DAGCombine doesn't canonicalize rotl/rotr with immediate so we
need patterns for both.

Remove the custom matcher for rotl to RORI and just use a SDNodeXForm
to convert the immediate instead. Doing this gives priority to the
rev32/rev16 versions of grevi over rori since an explicit immediate
is more precise than any immediate. I also added rotr patterns for
rev32/rev16. And removed the (or (shl), (shr)) patterns that should be
combined to rotl by DAG combine.

There is at least one other grev pattern that probably needs a
another rotr pattern, but we need more test coverage first.

Differential Revision: https://reviews.llvm.org/D90575
2020-11-03 10:04:52 -08:00
Craig Topper 9ac2910093 [RISCV] Make SelectRORIW handle the commutability of OR.
The SHL and SRL could be in opposite order so account for that.

Differential Revision: https://reviews.llvm.org/D90586
2020-11-02 09:32:54 -08:00
Craig Topper 7142ec3aaf [RISCV] When matching RORIW, make sure the same input is given to both shifts.
The code is looking for (sext_inreg (or (shl X, C2), (shr (and Y, C3), C1))).
We need to ensure X and Y are the same.

Differential Revision: https://reviews.llvm.org/D90580
2020-11-02 09:12:40 -08:00
Jay Foad 0819a6416f [SelectionDAG] Better legalization for FSHL and FSHR
In SelectionDAGBuilder always translate the fshl and fshr intrinsics to
FSHL and FSHR (or ROTL and ROTR) instead of lowering them to shifts and
ORs. Improve the legalization of FSHL and FSHR to avoid code quality
regressions.

Differential Revision: https://reviews.llvm.org/D77152
2020-08-21 10:32:49 +01:00
lewis-revill c9c955ada8 [RISCV] Add matching of codegen patterns to RISCV Bit Manipulation Zbt asm instructions
This patch provides optimization of bit manipulation operations by
enabling the +experimental-b target feature.
It adds matching of single block patterns of instructions to specific
bit-manip instructions from the ternary subset (zbt subextension) of the
experimental B extension of RISC-V.
It adds also the correspondent codegen tests.

This patch is based on Claire Wolf's proposal for the bit manipulation
extension of RISCV:
https://github.com/riscv/riscv-bitmanip/blob/master/bitmanip-0.92.pdf

Differential Revision: https://reviews.llvm.org/D79875
2020-07-15 12:19:34 +01:00
lewis-revill 6144f0a1e5 [RISCV] Add matching of codegen patterns to RISCV Bit Manipulation Zbbp asm instructions
This patch provides optimization of bit manipulation operations by
enabling the +experimental-b target feature.
It adds matching of single block patterns of instructions to specific
bit-manip instructions belonging to both the permutation and the base
subsets of the experimental B extension of RISC-V.
It adds also the correspondent codegen tests.

This patch is based on Claire Wolf's proposal for the bit manipulation
extension of RISCV:
https://github.com/riscv/riscv-bitmanip/blob/master/bitmanip-0.92.pdf

Differential Revision: https://reviews.llvm.org/D79873
2020-07-15 12:19:34 +01:00
lewis-revill e2692f0ee7 [RISCV] Add matching of codegen patterns to RISCV Bit Manipulation Zbb asm instructions
This patch provides optimization of bit manipulation operations by
enabling the +experimental-b target feature.
It adds matching of single block patterns of instructions to specific
bit-manip instructions from the base subset (zbb subextension) of the
experimental B extension of RISC-V.
It adds also the correspondent codegen tests.

This patch is based on Claire Wolf's proposal for the bit manipulation
extension of RISCV:
https://github.com/riscv/riscv-bitmanip/blob/master/bitmanip-0.92.pdf

Differential Revision: https://reviews.llvm.org/D79870
2020-07-15 12:19:34 +01:00
Ben Shi 1e9d0811c9 [RISCV] optimize addition with a pair of (addi imm)
For an addition with an immediate in specific ranges, a pair of
addi-addi can be generated instead of the ordinary lui-addi-add serial.

Reviewed By: MaskRay, luismarques

Differential Revision: https://reviews.llvm.org/D82262
2020-07-07 18:57:28 -07:00
Luís Marques 61c2a0bb82 [RISCV] Fold ADDIs into load/stores with nonzero offsets
We can often fold an ADDI into the offset of load/store instructions:

   (load (addi base, off1), off2) -> (load base, off1+off2)
   (store val, (addi base, off1), off2) -> (store val, base, off1+off2)

This is possible when the off1+off2 continues to fit the 12-bit immediate.
We remove the previous restriction where we would never fold the ADDIs if
the load/stores had nonzero offsets. We now do the fold the the resulting
constant still fits a 12-bit immediate, or if off1 is a variable's address
and we know based on that variable's alignment that off1+offs2 won't overflow.

Differential Revision: https://reviews.llvm.org/D79690
2020-07-06 17:32:57 +01:00
Sam Elliott 969e703427 [RISCV] Support Constant Pools in Load/Store Peephole
Summary:
RISC-V uses a post-select peephole pass to optimise
`(load/store (ADDI $reg, %lo(addr)), 0)` into `(load/store $reg, %lo(addr))`.
This peephole wasn't firing for accesses to constant pools, which is how we
materialise most floating point constants.

This adds support for the constantpool case, which improves code generation for
lots of small FP loading examples. I have not added any tests because this
structure is well-covered by the `fp-imm.ll` testcases, as well as almost
all other uses of floating point constants in the RISC-V backend tests.

Reviewed By: luismarques, asb

Differential Revision: https://reviews.llvm.org/D79523
2020-05-11 19:20:38 +01:00
Sam Elliott 3242e5653a Revert "[RISCV] Support Constant Pools in Load/Store Peephole"
This reverts commit fe69dfebcf, due to
a slight change in the API.
2020-05-11 18:14:05 +01:00
Sam Elliott fe69dfebcf [RISCV] Support Constant Pools in Load/Store Peephole
Summary:
RISC-V uses a post-select peephole pass to optimise
`(load/store (ADDI $reg, %lo(addr)), 0)` into `(load/store $reg, %lo(addr))`.
This peephole wasn't firing for accesses to constant pools, which is how we
materialise most floating point constants.

This adds support for the constantpool case, which improves code generation for
lots of small FP loading examples. I have not added any tests because this
structure is well-covered by the `fp-imm.ll` testcases, as well as almost
all other uses of floating point constants in the RISC-V backend tests.

Reviewed By: luismarques, asb

Differential Revision: https://reviews.llvm.org/D79523
2020-05-11 18:01:18 +01:00
Shiva Chen af0cd9073c [RISCV] Split RISCVISelDAGToDAG.cpp to RISCVISelDAGToDAG.h and RISCVISelDAGToDAG.cpp
For the downstream RISCV maintenance, it would be easier to inherent
RISCVISelDAGToDAG by including header and only override the method that needs
to be customized for the provider non-standard ISA extension without touching
RISCVISelDAGToDAG.cpp which may cause conflict when upgrading the downstream
LLVM version.

Differential Revision: https://reviews.llvm.org/D77117
2020-04-01 11:30:21 +08:00
Fangrui Song 5edb40c022 [SelectionDAG] Disallow indirect "i" constraint
This allows us to delete InlineAsm::Constraint_i workarounds in
SelectionDAGISel::SelectInlineAsmMemoryOperand overrides and
TargetLowering::getInlineAsmMemConstraint overrides.

They were introduced to X86 in r237517 to prevent crashes for
constraints like "=*imr". They were later copied to other targets.
2019-12-29 16:50:42 -08:00
Simon Pilgrim 29a5a6eed0 Fix uninitialized variable warning. NFCI. 2019-11-13 14:40:21 +00:00
Luis Marques 2d0cd6cac8 [RISCV] Fix static analysis issues
Unlikely to be problematic but still worth fixing.

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

llvm-svn: 372391
2019-09-20 13:48:02 +00:00
Lewis Revill 7abf863f76 [RISCV] Lower inline asm constraint A for RISC-V
This allows arguments with the constraint A to be lowered to input nodes
for RISC-V, which implies a memory address stored in a register.

This patch adds the minimal amount of code required to get operands with
the right constraints to compile.

https://reviews.llvm.org/D54296

llvm-svn: 369095
2019-08-16 10:28:34 +00:00