1 //===-- RISCVGIsel.td - RISC-V GlobalISel Patterns ---------*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file contains patterns that are relevant to GlobalISel, including
11 /// GIComplexOperandMatcher definitions for equivalent SelectionDAG
14 //===----------------------------------------------------------------------===//
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>;
46 GICustomOperandRenderer<"renderImmPlus1">,
47 GISDNodeXFormEquiv<ImmPlus1>;
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
65 GIComplexOperandMatcher<s32, "selectShiftMask">,
66 GIComplexPatternEquiv<shiftMaskXLen>;
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>;