[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / llvm / lib / Target / RISCV / RISCVGISel.td
blob5f16ffb0a0248e86e1a123eb69ed70feaf295b05
1 //===-- RISCVGIsel.td - RISC-V GlobalISel Patterns ---------*- tablegen -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// This file contains patterns that are relevant to GlobalISel, including
11 /// GIComplexOperandMatcher definitions for equivalent SelectionDAG
12 /// ComplexPatterns.
14 //===----------------------------------------------------------------------===//
16 include "RISCV.td"
17 include "RISCVCombine.td"
19 def simm12Plus1 : ImmLeaf<XLenVT, [{
20     return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;
21 def simm12Plus1i32 : ImmLeaf<i32, [{
22     return (isInt<12>(Imm) && Imm != -2048) || Imm == 2048;}]>;
24 // FIXME: This doesn't check that the G_CONSTANT we're deriving the immediate
25 // from is only used once
26 def simm12Minus1Nonzero : ImmLeaf<XLenVT, [{
27   return (Imm >= -2049 && Imm < 0) || (Imm > 0 && Imm <= 2046);}]>;
29 def simm12Minus1NonzeroNonNeg1 : ImmLeaf<XLenVT, [{
30   return (Imm >= -2049 && Imm < -1) || (Imm > 0 && Imm <= 2046);}]>;
32 // Return an immediate value plus 1.
33 def ImmPlus1 : SDNodeXForm<imm, [{
34   return CurDAG->getTargetConstant(N->getSExtValue() + 1, SDLoc(N),
35                                    N->getValuePtrVTpe(0));}]>;
37 def GINegImm : GICustomOperandRenderer<"renderNegImm">,
38   GISDNodeXFormEquiv<NegImm>;
40 def GIImmSubFromXLen : GICustomOperandRenderer<"renderImmSubFromXLen">,
41   GISDNodeXFormEquiv<ImmSubFromXLen>;
42 def GIImmSubFrom32 : GICustomOperandRenderer<"renderImmSubFrom32">,
43   GISDNodeXFormEquiv<ImmSubFrom32>;
45 def GIImmPlus1 :
46   GICustomOperandRenderer<"renderImmPlus1">,
47   GISDNodeXFormEquiv<ImmPlus1>;
49 def GIAddrRegImm :
50   GIComplexOperandMatcher<s32, "selectAddrRegImm">,
51   GIComplexPatternEquiv<AddrRegImm>;
53 def gi_as_i64imm : GICustomOperandRenderer<"renderImm">,
54   GISDNodeXFormEquiv<as_i64imm>;
56 def gi_trailing_zero : GICustomOperandRenderer<"renderTrailingZeros">,
57   GISDNodeXFormEquiv<TrailingZeros>;
59 // FIXME: This is labelled as handling 's32', however the ComplexPattern it
60 // refers to handles both i32 and i64 based on the HwMode. Currently this LLT
61 // parameter appears to be ignored so this pattern works for both, however we
62 // should add a LowLevelTypeByHwMode, and use that to define our XLenLLT instead
63 // here.
64 def GIShiftMaskXLen :
65     GIComplexOperandMatcher<s32, "selectShiftMask">,
66     GIComplexPatternEquiv<shiftMaskXLen>;
67 def GIShiftMask32 :
68     GIComplexOperandMatcher<s32, "selectShiftMask">,
69     GIComplexPatternEquiv<shiftMask32>;
71 def gi_sh1add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<1>">,
72                    GIComplexPatternEquiv<sh1add_op>;
73 def gi_sh2add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<2>">,
74                    GIComplexPatternEquiv<sh2add_op>;
75 def gi_sh3add_op : GIComplexOperandMatcher<s32, "selectSHXADDOp<3>">,
76                    GIComplexPatternEquiv<sh3add_op>;
78 def gi_sh1add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<1>">,
79                       GIComplexPatternEquiv<sh1add_uw_op>;
80 def gi_sh2add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<2>">,
81                       GIComplexPatternEquiv<sh2add_uw_op>;
82 def gi_sh3add_uw_op : GIComplexOperandMatcher<s32, "selectSHXADD_UWOp<3>">,
83                       GIComplexPatternEquiv<sh3add_uw_op>;
85 // FIXME: Canonicalize (sub X, C) -> (add X, -C) earlier.
86 def : Pat<(XLenVT (sub GPR:$rs1, simm12Plus1:$imm)),
87           (ADDI GPR:$rs1, (NegImm simm12Plus1:$imm))>;
89 let Predicates = [IsRV64] in {
90 def : Pat<(i32 (sub GPR:$rs1, simm12Plus1i32:$imm)),
91           (ADDIW GPR:$rs1, (i64 (NegImm $imm)))>;
93 def : Pat<(i32 (shl GPR:$rs1, (i32 GPR:$rs2))), (SLLW GPR:$rs1, GPR:$rs2)>;
94 def : Pat<(i32 (sra GPR:$rs1, (i32 GPR:$rs2))), (SRAW GPR:$rs1, GPR:$rs2)>;
95 def : Pat<(i32 (srl GPR:$rs1, (i32 GPR:$rs2))), (SRLW GPR:$rs1, GPR:$rs2)>;
98 // Ptr type used in patterns with GlobalISelEmitter
99 def PtrVT : PtrValueTypeByHwMode<XLenVT, 0>;
101 // Define pattern expansions for pointer ult/slt conditional codes
102 def : Pat<(XLenVT (setult (PtrVT GPR:$rs1), simm12:$imm12)),
103           (SLTIU GPR:$rs1, simm12:$imm12)>;
104 def : Pat<(XLenVT (setult (PtrVT GPR:$rs1), (PtrVT GPR:$rs2))),
105           (SLTU GPR:$rs1, GPR:$rs2)>;
106 def : Pat<(XLenVT (setlt (PtrVT GPR:$rs1), simm12:$imm12)),
107           (SLTI GPR:$rs1, simm12:$imm12)>;
108 def : Pat<(XLenVT (setlt (PtrVT GPR:$rs1), (PtrVT GPR:$rs2))),
109           (SLT GPR:$rs1, GPR:$rs2)>;
111 // Define pattern expansions for setcc operations that aren't directly
112 // handled by a RISC-V instruction.
113 foreach Ty = [PtrVT, XLenVT] in {
114 def : Pat<(XLenVT (seteq (Ty GPR:$rs1), (Ty 0))), (SLTIU GPR:$rs1, 1)>;
115 def : Pat<(XLenVT (seteq (Ty GPR:$rs1), (Ty simm12Plus1:$imm12))),
116           (SLTIU (ADDI GPR:$rs1, (NegImm simm12Plus1:$imm12)), 1)>;
117 def : Pat<(XLenVT (seteq (Ty GPR:$rs1), (Ty GPR:$rs2))),
118           (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>;
119 def : Pat<(XLenVT (setne (Ty GPR:$rs1), (Ty 0))), (SLTU (XLenVT X0), GPR:$rs1)>;
120 def : Pat<(XLenVT (setne (Ty GPR:$rs1), (Ty simm12Plus1:$imm12))),
121           (SLTU (XLenVT X0), (ADDI GPR:$rs1, (NegImm simm12Plus1:$imm12)))>;
122 def : Pat<(XLenVT (setne (Ty GPR:$rs1), (Ty GPR:$rs2))),
123           (SLTU (XLenVT X0), (XOR GPR:$rs1, GPR:$rs2))>;
124 def : Pat<(XLenVT (setugt (Ty GPR:$rs1), (Ty simm12Minus1NonzeroNonNeg1:$imm))),
125           (XORI (SLTIU GPR:$rs1,
126                        (ImmPlus1 simm12Minus1NonzeroNonNeg1:$imm)), 1)>;
127 def : Pat<(XLenVT (setugt (Ty GPR:$rs1), (Ty GPR:$rs2))),
128           (SLTU GPR:$rs2, GPR:$rs1)>;
129 def : Pat<(XLenVT (setgt (Ty GPR:$rs1), (Ty simm12Minus1Nonzero:$imm))),
130           (XORI (SLTI GPR:$rs1, (ImmPlus1 simm12Minus1Nonzero:$imm)), 1)>;
131 def : Pat<(XLenVT (setgt (Ty GPR:$rs1), (Ty GPR:$rs2))),
132           (SLT GPR:$rs2, GPR:$rs1)>;
133 def : Pat<(XLenVT (setuge (XLenVT GPR:$rs1), (Ty simm12:$imm))),
134           (XORI (SLTIU GPR:$rs1, simm12:$imm), 1)>;
135 def : Pat<(XLenVT (setuge (Ty GPR:$rs1), (Ty GPR:$rs2))),
136           (XORI (SLTU GPR:$rs1, GPR:$rs2), 1)>;
137 def : Pat<(XLenVT (setge (Ty GPR:$rs1), (Ty simm12:$imm))),
138           (XORI (SLTI GPR:$rs1, simm12:$imm), 1)>;
139 def : Pat<(XLenVT (setge (Ty GPR:$rs1), (Ty GPR:$rs2))),
140           (XORI (SLT GPR:$rs1, GPR:$rs2), 1)>;
141 def : Pat<(XLenVT (setule (Ty GPR:$rs1), (Ty simm12Minus1NonzeroNonNeg1:$imm))),
142           (SLTIU GPR:$rs1, (ImmPlus1 simm12Minus1NonzeroNonNeg1:$imm))>;
143 def : Pat<(XLenVT (setule (Ty GPR:$rs1), (Ty GPR:$rs2))),
144           (XORI (SLTU GPR:$rs2, GPR:$rs1), 1)>;
145 def : Pat<(XLenVT (setle (Ty GPR:$rs1), (Ty simm12Minus1Nonzero:$imm))),
146           (SLTI GPR:$rs1, (ImmPlus1 simm12Minus1Nonzero:$imm))>;
147 def : Pat<(XLenVT (setle (Ty GPR:$rs1), (Ty GPR:$rs2))),
148           (XORI (SLT GPR:$rs2, GPR:$rs1), 1)>;
151 let Predicates = [IsRV32] in {
152 def : LdPat<load, LW, PtrVT>;
153 def : StPat<store, SW, GPR, PtrVT>;
156 let Predicates = [IsRV64] in {
157 def : LdPat<load, LD, PtrVT>;
158 def : StPat<store, SD, GPR, PtrVT>;