1//===- RISCVInstrInfoVVLPatterns.td - RVV VL 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/// This file contains the required infrastructure and VL patterns to 10/// support code generation for the standard 'V' (Vector) extension, version 11/// 0.10. This version is still experimental as the 'V' extension hasn't been 12/// ratified yet. 13/// 14/// This file is included from and depends upon RISCVInstrInfoVPseudos.td 15/// 16/// Note: the patterns for RVV intrinsics are found in 17/// RISCVInstrInfoVPseudos.td. 18/// 19//===----------------------------------------------------------------------===// 20 21//===----------------------------------------------------------------------===// 22// Helpers to define the VL patterns. 23//===----------------------------------------------------------------------===// 24 25def SDT_RISCVVLE_VL : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisPtrTy<1>, 26 SDTCisVT<2, XLenVT>]>; 27def SDT_RISCVVSE_VL : SDTypeProfile<0, 3, [SDTCisVec<0>, SDTCisPtrTy<1>, 28 SDTCisVT<2, XLenVT>]>; 29 30def SDT_RISCVIntBinOp_VL : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, 31 SDTCisSameAs<0, 2>, 32 SDTCisVec<0>, SDTCisInt<0>, 33 SDTCVecEltisVT<3, i1>, 34 SDTCisSameNumEltsAs<0, 3>, 35 SDTCisVT<4, XLenVT>]>; 36 37def SDT_RISCVFPUnOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 38 SDTCisVec<0>, SDTCisFP<0>, 39 SDTCVecEltisVT<2, i1>, 40 SDTCisSameNumEltsAs<0, 2>, 41 SDTCisVT<3, XLenVT>]>; 42def SDT_RISCVFPBinOp_VL : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, 43 SDTCisSameAs<0, 2>, 44 SDTCisVec<0>, SDTCisFP<0>, 45 SDTCVecEltisVT<3, i1>, 46 SDTCisSameNumEltsAs<0, 3>, 47 SDTCisVT<4, XLenVT>]>; 48 49def riscv_vmv_v_x_vl : SDNode<"RISCVISD::VMV_V_X_VL", 50 SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisInt<0>, 51 SDTCisVT<1, XLenVT>, 52 SDTCisVT<2, XLenVT>]>>; 53def riscv_vfmv_v_f_vl : SDNode<"RISCVISD::VFMV_V_F_VL", 54 SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisFP<0>, 55 SDTCisEltOfVec<1, 0>, 56 SDTCisVT<2, XLenVT>]>>; 57 58def riscv_vle_vl : SDNode<"RISCVISD::VLE_VL", SDT_RISCVVLE_VL, 59 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 60def riscv_vse_vl : SDNode<"RISCVISD::VSE_VL", SDT_RISCVVSE_VL, 61 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 62 63def riscv_add_vl : SDNode<"RISCVISD::ADD_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 64def riscv_sub_vl : SDNode<"RISCVISD::SUB_VL", SDT_RISCVIntBinOp_VL>; 65def riscv_mul_vl : SDNode<"RISCVISD::MUL_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 66def riscv_and_vl : SDNode<"RISCVISD::AND_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 67def riscv_or_vl : SDNode<"RISCVISD::OR_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 68def riscv_xor_vl : SDNode<"RISCVISD::XOR_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 69def riscv_sdiv_vl : SDNode<"RISCVISD::SDIV_VL", SDT_RISCVIntBinOp_VL>; 70def riscv_srem_vl : SDNode<"RISCVISD::SREM_VL", SDT_RISCVIntBinOp_VL>; 71def riscv_udiv_vl : SDNode<"RISCVISD::UDIV_VL", SDT_RISCVIntBinOp_VL>; 72def riscv_urem_vl : SDNode<"RISCVISD::UREM_VL", SDT_RISCVIntBinOp_VL>; 73def riscv_shl_vl : SDNode<"RISCVISD::SHL_VL", SDT_RISCVIntBinOp_VL>; 74def riscv_sra_vl : SDNode<"RISCVISD::SRA_VL", SDT_RISCVIntBinOp_VL>; 75def riscv_srl_vl : SDNode<"RISCVISD::SRL_VL", SDT_RISCVIntBinOp_VL>; 76def riscv_smin_vl : SDNode<"RISCVISD::SMIN_VL", SDT_RISCVIntBinOp_VL>; 77def riscv_smax_vl : SDNode<"RISCVISD::SMAX_VL", SDT_RISCVIntBinOp_VL>; 78def riscv_umin_vl : SDNode<"RISCVISD::UMIN_VL", SDT_RISCVIntBinOp_VL>; 79def riscv_umax_vl : SDNode<"RISCVISD::UMAX_VL", SDT_RISCVIntBinOp_VL>; 80def riscv_fadd_vl : SDNode<"RISCVISD::FADD_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>; 81def riscv_fsub_vl : SDNode<"RISCVISD::FSUB_VL", SDT_RISCVFPBinOp_VL>; 82def riscv_fmul_vl : SDNode<"RISCVISD::FMUL_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>; 83def riscv_fdiv_vl : SDNode<"RISCVISD::FDIV_VL", SDT_RISCVFPBinOp_VL>; 84def riscv_fneg_vl : SDNode<"RISCVISD::FNEG_VL", SDT_RISCVFPUnOp_VL>; 85def riscv_fabs_vl : SDNode<"RISCVISD::FABS_VL", SDT_RISCVFPUnOp_VL>; 86def riscv_fsqrt_vl : SDNode<"RISCVISD::FSQRT_VL", SDT_RISCVFPUnOp_VL>; 87 88def SDT_RISCVVecFMA_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>, 89 SDTCisSameAs<0, 2>, 90 SDTCisSameAs<0, 3>, 91 SDTCisVec<0>, SDTCisFP<0>, 92 SDTCVecEltisVT<4, i1>, 93 SDTCisSameNumEltsAs<0, 4>, 94 SDTCisVT<5, XLenVT>]>; 95def riscv_fma_vl : SDNode<"RISCVISD::FMA_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>; 96 97def riscv_setcc_vl : SDNode<"RISCVISD::SETCC_VL", 98 SDTypeProfile<1, 5, [SDTCVecEltisVT<0, i1>, 99 SDTCisVec<1>, 100 SDTCisSameNumEltsAs<0, 1>, 101 SDTCisSameAs<1, 2>, 102 SDTCisVT<3, OtherVT>, 103 SDTCisSameAs<0, 4>, 104 SDTCisVT<5, XLenVT>]>>; 105 106def riscv_vrgather_vx_vl : SDNode<"RISCVISD::VRGATHER_VX_VL", 107 SDTypeProfile<1, 4, [SDTCisVec<0>, 108 SDTCisSameAs<0, 1>, 109 SDTCisVT<2, XLenVT>, 110 SDTCVecEltisVT<3, i1>, 111 SDTCisSameNumEltsAs<0, 3>, 112 SDTCisVT<4, XLenVT>]>>; 113 114def riscv_vselect_vl : SDNode<"RISCVISD::VSELECT_VL", 115 SDTypeProfile<1, 4, [SDTCisVec<0>, 116 SDTCisVec<1>, 117 SDTCisSameNumEltsAs<0, 1>, 118 SDTCVecEltisVT<1, i1>, 119 SDTCisSameAs<0, 2>, 120 SDTCisSameAs<2, 3>, 121 SDTCisVT<4, XLenVT>]>>; 122 123def SDT_RISCVMaskBinOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 124 SDTCisSameAs<0, 2>, 125 SDTCVecEltisVT<0, i1>, 126 SDTCisVT<3, XLenVT>]>; 127def riscv_vmand_vl : SDNode<"RISCVISD::VMAND_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 128def riscv_vmor_vl : SDNode<"RISCVISD::VMOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 129def riscv_vmxor_vl : SDNode<"RISCVISD::VMXOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 130 131def SDT_RISCVVMSETCLR_VL : SDTypeProfile<1, 1, [SDTCVecEltisVT<0, i1>, 132 SDTCisVT<1, XLenVT>]>; 133def riscv_vmclr_vl : SDNode<"RISCVISD::VMCLR_VL", SDT_RISCVVMSETCLR_VL>; 134def riscv_vmset_vl : SDNode<"RISCVISD::VMSET_VL", SDT_RISCVVMSETCLR_VL>; 135 136def true_mask : PatLeaf<(riscv_vmset_vl (XLenVT srcvalue))>; 137 138def riscv_vmnot_vl : PatFrag<(ops node:$rs, node:$vl), 139 (riscv_vmxor_vl node:$rs, true_mask, node:$vl)>; 140 141// Ignore the vl operand. 142def SplatFPOp : PatFrag<(ops node:$op), 143 (riscv_vfmv_v_f_vl node:$op, srcvalue)>; 144 145def sew8simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<8>", []>; 146def sew16simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<16>", []>; 147def sew32simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<32>", []>; 148def sew64simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<64>", []>; 149 150def sew8uimm5 : ComplexPattern<XLenVT, 1, "selectRVVUimm5<8>", []>; 151def sew16uimm5 : ComplexPattern<XLenVT, 1, "selectRVVUimm5<16>", []>; 152def sew32uimm5 : ComplexPattern<XLenVT, 1, "selectRVVUimm5<32>", []>; 153def sew64uimm5 : ComplexPattern<XLenVT, 1, "selectRVVUimm5<64>", []>; 154 155class VPatBinaryVL_VV<SDNode vop, 156 string instruction_name, 157 ValueType result_type, 158 ValueType op_type, 159 ValueType mask_type, 160 int sew, 161 LMULInfo vlmul, 162 VReg RetClass, 163 VReg op_reg_class> : 164 Pat<(result_type (vop 165 (op_type op_reg_class:$rs1), 166 (op_type op_reg_class:$rs2), 167 (mask_type true_mask), 168 (XLenVT (VLOp GPR:$vl)))), 169 (!cast<Instruction>(instruction_name#"_VV_"# vlmul.MX) 170 op_reg_class:$rs1, 171 op_reg_class:$rs2, 172 GPR:$vl, sew)>; 173 174class VPatBinaryVL_XI<SDNode vop, 175 string instruction_name, 176 string suffix, 177 ValueType result_type, 178 ValueType vop_type, 179 ValueType mask_type, 180 int sew, 181 LMULInfo vlmul, 182 VReg RetClass, 183 VReg vop_reg_class, 184 ComplexPattern SplatPatKind, 185 DAGOperand xop_kind> : 186 Pat<(result_type (vop 187 (vop_type vop_reg_class:$rs1), 188 (vop_type (SplatPatKind xop_kind:$rs2)), 189 (mask_type true_mask), 190 (XLenVT (VLOp GPR:$vl)))), 191 (!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX) 192 vop_reg_class:$rs1, 193 xop_kind:$rs2, 194 GPR:$vl, sew)>; 195 196multiclass VPatBinaryVL_VV_VX<SDNode vop, string instruction_name> { 197 foreach vti = AllIntegerVectors in { 198 def : VPatBinaryVL_VV<vop, instruction_name, 199 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 200 vti.LMul, vti.RegClass, vti.RegClass>; 201 def : VPatBinaryVL_XI<vop, instruction_name, "VX", 202 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 203 vti.LMul, vti.RegClass, vti.RegClass, 204 SplatPat, GPR>; 205 } 206} 207 208multiclass VPatBinaryVL_VV_VX_VI<SDNode vop, string instruction_name, 209 Operand ImmType = simm5> { 210 foreach vti = AllIntegerVectors in { 211 def : VPatBinaryVL_VV<vop, instruction_name, 212 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 213 vti.LMul, vti.RegClass, vti.RegClass>; 214 def : VPatBinaryVL_XI<vop, instruction_name, "VX", 215 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 216 vti.LMul, vti.RegClass, vti.RegClass, 217 SplatPat, GPR>; 218 def : VPatBinaryVL_XI<vop, instruction_name, "VI", 219 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 220 vti.LMul, vti.RegClass, vti.RegClass, 221 !cast<ComplexPattern>(SplatPat#_#ImmType), 222 ImmType>; 223 } 224} 225 226class VPatBinaryVL_VF<SDNode vop, 227 string instruction_name, 228 ValueType result_type, 229 ValueType vop_type, 230 ValueType mask_type, 231 int sew, 232 LMULInfo vlmul, 233 VReg RetClass, 234 VReg vop_reg_class, 235 RegisterClass scalar_reg_class> : 236 Pat<(result_type (vop (vop_type vop_reg_class:$rs1), 237 (vop_type (SplatFPOp scalar_reg_class:$rs2)), 238 (mask_type true_mask), 239 (XLenVT (VLOp GPR:$vl)))), 240 (!cast<Instruction>(instruction_name#"_"#vlmul.MX) 241 vop_reg_class:$rs1, 242 scalar_reg_class:$rs2, 243 GPR:$vl, sew)>; 244 245multiclass VPatBinaryFPVL_VV_VF<SDNode vop, string instruction_name> { 246 foreach vti = AllFloatVectors in { 247 def : VPatBinaryVL_VV<vop, instruction_name, 248 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 249 vti.LMul, vti.RegClass, vti.RegClass>; 250 def : VPatBinaryVL_VF<vop, instruction_name#"_V"#vti.ScalarSuffix, 251 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 252 vti.LMul, vti.RegClass, vti.RegClass, 253 vti.ScalarRegClass>; 254 } 255} 256 257multiclass VPatBinaryFPVL_R_VF<SDNode vop, string instruction_name> { 258 foreach fvti = AllFloatVectors in 259 def : Pat<(fvti.Vector (vop (SplatFPOp fvti.ScalarRegClass:$rs2), 260 fvti.RegClass:$rs1, 261 (fvti.Mask true_mask), 262 (XLenVT (VLOp GPR:$vl)))), 263 (!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 264 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 265 GPR:$vl, fvti.SEW)>; 266} 267 268multiclass VPatIntegerSetCCVL_VV<VTypeInfo vti, string instruction_name, 269 CondCode cc> { 270 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 271 vti.RegClass:$rs2, cc, 272 (vti.Mask true_mask), 273 (XLenVT (VLOp GPR:$vl)))), 274 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 275 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, 276 vti.SEW)>; 277} 278 279// Inherits from VPatIntegerSetCCVL_VV and adds a pattern with operands swapped. 280multiclass VPatIntegerSetCCVL_VV_Swappable<VTypeInfo vti, string instruction_name, 281 CondCode cc, CondCode invcc> : 282 VPatIntegerSetCCVL_VV<vti, instruction_name, cc> { 283 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs2), 284 vti.RegClass:$rs1, invcc, 285 (vti.Mask true_mask), 286 (XLenVT (VLOp GPR:$vl)))), 287 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 288 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, 289 vti.SEW)>; 290} 291 292multiclass VPatIntegerSetCCVL_VX_Swappable<VTypeInfo vti, string instruction_name, 293 CondCode cc, CondCode invcc> { 294 defvar instruction = !cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX); 295 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 296 (SplatPat GPR:$rs2), cc, 297 (vti.Mask true_mask), 298 (XLenVT (VLOp GPR:$vl)))), 299 (instruction vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 300 def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat GPR:$rs2), 301 (vti.Vector vti.RegClass:$rs1), invcc, 302 (vti.Mask true_mask), 303 (XLenVT (VLOp GPR:$vl)))), 304 (instruction vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 305} 306 307multiclass VPatIntegerSetCCVL_VI_Swappable<VTypeInfo vti, string instruction_name, 308 CondCode cc, CondCode invcc> { 309 defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX); 310 defvar ImmPat = !cast<ComplexPattern>("sew"#vti.SEW#"simm5"); 311 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 312 (SplatPat_simm5 simm5:$rs2), cc, 313 (vti.Mask true_mask), 314 (XLenVT (VLOp GPR:$vl)))), 315 (instruction vti.RegClass:$rs1, XLenVT:$rs2, GPR:$vl, vti.SEW)>; 316 def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat_simm5 simm5:$rs2), 317 (vti.Vector vti.RegClass:$rs1), invcc, 318 (vti.Mask true_mask), 319 (XLenVT (VLOp GPR:$vl)))), 320 (instruction vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.SEW)>; 321} 322 323multiclass VPatFPSetCCVL_VV_VF_FV<CondCode cc, 324 string inst_name, 325 string swapped_op_inst_name> { 326 foreach fvti = AllFloatVectors in { 327 def : Pat<(fvti.Mask (riscv_setcc_vl (fvti.Vector fvti.RegClass:$rs1), 328 fvti.RegClass:$rs2, 329 cc, 330 (fvti.Mask true_mask), 331 (XLenVT (VLOp GPR:$vl)))), 332 (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX) 333 fvti.RegClass:$rs1, fvti.RegClass:$rs2, GPR:$vl, fvti.SEW)>; 334 def : Pat<(fvti.Mask (riscv_setcc_vl (fvti.Vector fvti.RegClass:$rs1), 335 (SplatFPOp fvti.ScalarRegClass:$rs2), 336 cc, 337 (fvti.Mask true_mask), 338 (XLenVT (VLOp GPR:$vl)))), 339 (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 340 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 341 GPR:$vl, fvti.SEW)>; 342 def : Pat<(fvti.Mask (riscv_setcc_vl (SplatFPOp fvti.ScalarRegClass:$rs2), 343 (fvti.Vector fvti.RegClass:$rs1), 344 cc, 345 (fvti.Mask true_mask), 346 (XLenVT (VLOp GPR:$vl)))), 347 (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 348 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 349 GPR:$vl, fvti.SEW)>; 350 } 351} 352 353//===----------------------------------------------------------------------===// 354// Patterns. 355//===----------------------------------------------------------------------===// 356 357let Predicates = [HasStdExtV] in { 358 359// 7.4. Vector Unit-Stride Instructions 360foreach vti = AllVectors in { 361 defvar load_instr = !cast<Instruction>("PseudoVLE"#vti.SEW#"_V_"#vti.LMul.MX); 362 defvar store_instr = !cast<Instruction>("PseudoVSE"#vti.SEW#"_V_"#vti.LMul.MX); 363 // Load 364 def : Pat<(vti.Vector (riscv_vle_vl BaseAddr:$rs1, (XLenVT (VLOp GPR:$vl)))), 365 (load_instr BaseAddr:$rs1, GPR:$vl, vti.SEW)>; 366 // Store 367 def : Pat<(riscv_vse_vl (vti.Vector vti.RegClass:$rs2), BaseAddr:$rs1, 368 (XLenVT (VLOp GPR:$vl))), 369 (store_instr vti.RegClass:$rs2, BaseAddr:$rs1, GPR:$vl, vti.SEW)>; 370} 371 372foreach mti = AllMasks in { 373 defvar load_instr = !cast<Instruction>("PseudoVLE1_V_"#mti.BX); 374 defvar store_instr = !cast<Instruction>("PseudoVSE1_V_"#mti.BX); 375 def : Pat<(mti.Mask (riscv_vle_vl BaseAddr:$rs1, (XLenVT (VLOp GPR:$vl)))), 376 (load_instr BaseAddr:$rs1, GPR:$vl, mti.SEW)>; 377 def : Pat<(riscv_vse_vl (mti.Mask VR:$rs2), BaseAddr:$rs1, 378 (XLenVT (VLOp GPR:$vl))), 379 (store_instr VR:$rs2, BaseAddr:$rs1, GPR:$vl, mti.SEW)>; 380} 381 382// 12.1. Vector Single-Width Integer Add and Subtract 383defm "" : VPatBinaryVL_VV_VX_VI<riscv_add_vl, "PseudoVADD">; 384defm "" : VPatBinaryVL_VV_VX<riscv_sub_vl, "PseudoVSUB">; 385// Handle VRSUB specially since it's the only integer binary op with reversed 386// pattern operands 387foreach vti = AllIntegerVectors in { 388 def : Pat<(riscv_sub_vl (vti.Vector (SplatPat GPR:$rs2)), 389 (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), 390 (XLenVT (VLOp GPR:$vl))), 391 (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX) 392 vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 393 def : Pat<(riscv_sub_vl (vti.Vector (SplatPat_simm5 simm5:$rs2)), 394 (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), 395 (XLenVT (VLOp GPR:$vl))), 396 (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX) 397 vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.SEW)>; 398} 399 400// 12.5. Vector Bitwise Logical Instructions 401defm "" : VPatBinaryVL_VV_VX_VI<riscv_and_vl, "PseudoVAND">; 402defm "" : VPatBinaryVL_VV_VX_VI<riscv_or_vl, "PseudoVOR">; 403defm "" : VPatBinaryVL_VV_VX_VI<riscv_xor_vl, "PseudoVXOR">; 404 405// 12.6. Vector Single-Width Bit Shift Instructions 406defm "" : VPatBinaryVL_VV_VX_VI<riscv_shl_vl, "PseudoVSLL", uimm5>; 407defm "" : VPatBinaryVL_VV_VX_VI<riscv_srl_vl, "PseudoVSRL", uimm5>; 408defm "" : VPatBinaryVL_VV_VX_VI<riscv_sra_vl, "PseudoVSRA", uimm5>; 409 410// 12.8. Vector Integer Comparison Instructions 411foreach vti = AllIntegerVectors in { 412 defm "" : VPatIntegerSetCCVL_VV<vti, "PseudoVMSEQ", SETEQ>; 413 defm "" : VPatIntegerSetCCVL_VV<vti, "PseudoVMSNE", SETNE>; 414 415 defm "" : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLT", SETLT, SETGT>; 416 defm "" : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>; 417 defm "" : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 418 defm "" : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 419 420 defm "" : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>; 421 defm "" : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>; 422 defm "" : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLT", SETLT, SETGT>; 423 defm "" : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>; 424 defm "" : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 425 defm "" : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 426 defm "" : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGT", SETGT, SETLT>; 427 defm "" : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGTU", SETUGT, SETULT>; 428 // There is no VMSGE(U)_VX instruction 429 430 // FIXME: Support immediate forms of these by choosing SGT and decrementing 431 // the immediate 432 defm "" : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>; 433 defm "" : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>; 434 defm "" : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 435 defm "" : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 436} // foreach vti = AllIntegerVectors 437 438// 12.9. Vector Integer Min/Max Instructions 439defm "" : VPatBinaryVL_VV_VX<riscv_umin_vl, "PseudoVMINU">; 440defm "" : VPatBinaryVL_VV_VX<riscv_smin_vl, "PseudoVMIN">; 441defm "" : VPatBinaryVL_VV_VX<riscv_umax_vl, "PseudoVMAXU">; 442defm "" : VPatBinaryVL_VV_VX<riscv_smax_vl, "PseudoVMAX">; 443 444// 12.10. Vector Single-Width Integer Multiply Instructions 445defm "" : VPatBinaryVL_VV_VX<riscv_mul_vl, "PseudoVMUL">; 446 447// 12.11. Vector Integer Divide Instructions 448defm "" : VPatBinaryVL_VV_VX<riscv_udiv_vl, "PseudoVDIVU">; 449defm "" : VPatBinaryVL_VV_VX<riscv_sdiv_vl, "PseudoVDIV">; 450defm "" : VPatBinaryVL_VV_VX<riscv_urem_vl, "PseudoVREMU">; 451defm "" : VPatBinaryVL_VV_VX<riscv_srem_vl, "PseudoVREM">; 452 453// 12.16. Vector Integer Merge Instructions 454foreach vti = AllIntegerVectors in { 455 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 456 vti.RegClass:$rs1, 457 vti.RegClass:$rs2, 458 (XLenVT (VLOp GPR:$vl)))), 459 (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX) 460 vti.RegClass:$rs2, vti.RegClass:$rs1, VMV0:$vm, 461 GPR:$vl, vti.SEW)>; 462 463 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 464 (SplatPat XLenVT:$rs1), 465 vti.RegClass:$rs2, 466 (XLenVT (VLOp GPR:$vl)))), 467 (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX) 468 vti.RegClass:$rs2, GPR:$rs1, VMV0:$vm, GPR:$vl, vti.SEW)>; 469 470 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 471 (SplatPat_simm5 simm5:$rs1), 472 vti.RegClass:$rs2, 473 (XLenVT (VLOp GPR:$vl)))), 474 (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX) 475 vti.RegClass:$rs2, simm5:$rs1, VMV0:$vm, GPR:$vl, vti.SEW)>; 476} 477 478// 12.17. Vector Integer Move Instructions 479foreach vti = AllIntegerVectors in { 480 def : Pat<(vti.Vector (riscv_vmv_v_x_vl GPR:$rs2, (XLenVT (VLOp GPR:$vl)))), 481 (!cast<Instruction>("PseudoVMV_V_X_"#vti.LMul.MX) 482 $rs2, GPR:$vl, vti.SEW)>; 483 defvar ImmPat = !cast<ComplexPattern>("sew"#vti.SEW#"simm5"); 484 def : Pat<(vti.Vector (riscv_vmv_v_x_vl (ImmPat XLenVT:$imm5), 485 (XLenVT (VLOp GPR:$vl)))), 486 (!cast<Instruction>("PseudoVMV_V_I_"#vti.LMul.MX) 487 XLenVT:$imm5, GPR:$vl, vti.SEW)>; 488} 489 490} // Predicates = [HasStdExtV] 491 492let Predicates = [HasStdExtV, HasStdExtF] in { 493 494// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions 495defm "" : VPatBinaryFPVL_VV_VF<riscv_fadd_vl, "PseudoVFADD">; 496defm "" : VPatBinaryFPVL_VV_VF<riscv_fsub_vl, "PseudoVFSUB">; 497defm "" : VPatBinaryFPVL_R_VF<riscv_fsub_vl, "PseudoVFRSUB">; 498 499// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 500defm "" : VPatBinaryFPVL_VV_VF<riscv_fmul_vl, "PseudoVFMUL">; 501defm "" : VPatBinaryFPVL_VV_VF<riscv_fdiv_vl, "PseudoVFDIV">; 502defm "" : VPatBinaryFPVL_R_VF<riscv_fdiv_vl, "PseudoVFRDIV">; 503 504// 14.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions. 505foreach vti = AllFloatVectors in { 506 // NOTE: We choose VFMADD because it has the most commuting freedom. So it 507 // works best with how TwoAddressInstructionPass tries commuting. 508 defvar suffix = vti.LMul.MX # "_COMMUTABLE"; 509 def : Pat<(vti.Vector (riscv_fma_vl vti.RegClass:$rs1, vti.RegClass:$rd, 510 vti.RegClass:$rs2, (vti.Mask true_mask), 511 (XLenVT (VLOp GPR:$vl)))), 512 (!cast<Instruction>("PseudoVFMADD_VV_"# suffix) 513 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 514 GPR:$vl, vti.SEW)>; 515 def : Pat<(vti.Vector (riscv_fma_vl vti.RegClass:$rs1, vti.RegClass:$rd, 516 (riscv_fneg_vl vti.RegClass:$rs2, 517 (vti.Mask true_mask), 518 (XLenVT (VLOp GPR:$vl))), 519 (vti.Mask true_mask), 520 (XLenVT (VLOp GPR:$vl)))), 521 (!cast<Instruction>("PseudoVFMSUB_VV_"# suffix) 522 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 523 GPR:$vl, vti.SEW)>; 524 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl vti.RegClass:$rs1, 525 (vti.Mask true_mask), 526 (XLenVT (VLOp GPR:$vl))), 527 vti.RegClass:$rd, 528 (riscv_fneg_vl vti.RegClass:$rs2, 529 (vti.Mask true_mask), 530 (XLenVT (VLOp GPR:$vl))), 531 (vti.Mask true_mask), 532 (XLenVT (VLOp GPR:$vl)))), 533 (!cast<Instruction>("PseudoVFNMADD_VV_"# suffix) 534 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 535 GPR:$vl, vti.SEW)>; 536 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl vti.RegClass:$rs1, 537 (vti.Mask true_mask), 538 (XLenVT (VLOp GPR:$vl))), 539 vti.RegClass:$rd, vti.RegClass:$rs2, 540 (vti.Mask true_mask), 541 (XLenVT (VLOp GPR:$vl)))), 542 (!cast<Instruction>("PseudoVFNMSUB_VV_"# suffix) 543 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 544 GPR:$vl, vti.SEW)>; 545 546 // The choice of VFMADD here is arbitrary, vfmadd.vf and vfmacc.vf are equally 547 // commutable. 548 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 549 vti.RegClass:$rd, vti.RegClass:$rs2, 550 (vti.Mask true_mask), 551 (XLenVT (VLOp GPR:$vl)))), 552 (!cast<Instruction>("PseudoVFMADD_V" # vti.ScalarSuffix # "_" # suffix) 553 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 554 GPR:$vl, vti.SEW)>; 555 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 556 vti.RegClass:$rd, 557 (riscv_fneg_vl vti.RegClass:$rs2, 558 (vti.Mask true_mask), 559 (XLenVT (VLOp GPR:$vl))), 560 (vti.Mask true_mask), 561 (XLenVT (VLOp GPR:$vl)))), 562 (!cast<Instruction>("PseudoVFMSUB_V" # vti.ScalarSuffix # "_" # suffix) 563 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 564 GPR:$vl, vti.SEW)>; 565 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 566 (riscv_fneg_vl vti.RegClass:$rd, 567 (vti.Mask true_mask), 568 (XLenVT (VLOp GPR:$vl))), 569 (riscv_fneg_vl vti.RegClass:$rs2, 570 (vti.Mask true_mask), 571 (XLenVT (VLOp GPR:$vl))), 572 (vti.Mask true_mask), 573 (XLenVT (VLOp GPR:$vl)))), 574 (!cast<Instruction>("PseudoVFNMADD_V" # vti.ScalarSuffix # "_" # suffix) 575 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 576 GPR:$vl, vti.SEW)>; 577 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 578 (riscv_fneg_vl vti.RegClass:$rd, 579 (vti.Mask true_mask), 580 (XLenVT (VLOp GPR:$vl))), 581 vti.RegClass:$rs2, 582 (vti.Mask true_mask), 583 (XLenVT (VLOp GPR:$vl)))), 584 (!cast<Instruction>("PseudoVFNMSUB_V" # vti.ScalarSuffix # "_" # suffix) 585 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 586 GPR:$vl, vti.SEW)>; 587 588 // The splat might be negated. 589 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl (SplatFPOp vti.ScalarRegClass:$rs1), 590 (vti.Mask true_mask), 591 (XLenVT (VLOp GPR:$vl))), 592 vti.RegClass:$rd, 593 (riscv_fneg_vl vti.RegClass:$rs2, 594 (vti.Mask true_mask), 595 (XLenVT (VLOp GPR:$vl))), 596 (vti.Mask true_mask), 597 (XLenVT (VLOp GPR:$vl)))), 598 (!cast<Instruction>("PseudoVFNMADD_V" # vti.ScalarSuffix # "_" # suffix) 599 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 600 GPR:$vl, vti.SEW)>; 601 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl (SplatFPOp vti.ScalarRegClass:$rs1), 602 (vti.Mask true_mask), 603 (XLenVT (VLOp GPR:$vl))), 604 vti.RegClass:$rd, vti.RegClass:$rs2, 605 (vti.Mask true_mask), 606 (XLenVT (VLOp GPR:$vl)))), 607 (!cast<Instruction>("PseudoVFNMSUB_V" # vti.ScalarSuffix # "_" # suffix) 608 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 609 GPR:$vl, vti.SEW)>; 610} 611 612// 14.11. Vector Floating-Point Compare Instructions 613defm "" : VPatFPSetCCVL_VV_VF_FV<SETEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 614defm "" : VPatFPSetCCVL_VV_VF_FV<SETOEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 615 616defm "" : VPatFPSetCCVL_VV_VF_FV<SETNE, "PseudoVMFNE", "PseudoVMFNE">; 617defm "" : VPatFPSetCCVL_VV_VF_FV<SETUNE, "PseudoVMFNE", "PseudoVMFNE">; 618 619defm "" : VPatFPSetCCVL_VV_VF_FV<SETLT, "PseudoVMFLT", "PseudoVMFGT">; 620defm "" : VPatFPSetCCVL_VV_VF_FV<SETOLT, "PseudoVMFLT", "PseudoVMFGT">; 621 622defm "" : VPatFPSetCCVL_VV_VF_FV<SETLE, "PseudoVMFLE", "PseudoVMFGE">; 623defm "" : VPatFPSetCCVL_VV_VF_FV<SETOLE, "PseudoVMFLE", "PseudoVMFGE">; 624 625// 14.12. Vector Floating-Point Sign-Injection Instructions 626// Handle fneg with VFSGNJN using the same input for both operands. 627foreach vti = AllFloatVectors in { 628 // 14.8. Vector Floating-Point Square-Root Instruction 629 def : Pat<(riscv_fsqrt_vl (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), 630 (XLenVT (VLOp GPR:$vl))), 631 (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX) 632 vti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 633 634 // 14.12. Vector Floating-Point Sign-Injection Instructions 635 def : Pat<(riscv_fabs_vl (vti.Vector vti.RegClass:$rs), (vti.Mask true_mask), 636 (XLenVT (VLOp GPR:$vl))), 637 (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX) 638 vti.RegClass:$rs, vti.RegClass:$rs, GPR:$vl, vti.SEW)>; 639 // Handle fneg with VFSGNJN using the same input for both operands. 640 def : Pat<(riscv_fneg_vl (vti.Vector vti.RegClass:$rs), (vti.Mask true_mask), 641 (XLenVT (VLOp GPR:$vl))), 642 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX) 643 vti.RegClass:$rs, vti.RegClass:$rs, GPR:$vl, vti.SEW)>; 644} 645 646foreach fvti = AllFloatVectors in { 647 // Floating-point vselects: 648 // 12.16. Vector Integer Merge Instructions 649 // 14.13. Vector Floating-Point Merge Instruction 650 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 651 fvti.RegClass:$rs1, 652 fvti.RegClass:$rs2, 653 (XLenVT (VLOp GPR:$vl)))), 654 (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX) 655 fvti.RegClass:$rs2, fvti.RegClass:$rs1, VMV0:$vm, 656 GPR:$vl, fvti.SEW)>; 657 658 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 659 (SplatFPOp fvti.ScalarRegClass:$rs1), 660 fvti.RegClass:$rs2, 661 (XLenVT (VLOp GPR:$vl)))), 662 (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX) 663 fvti.RegClass:$rs2, 664 (fvti.Scalar fvti.ScalarRegClass:$rs1), 665 VMV0:$vm, GPR:$vl, fvti.SEW)>; 666 667 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 668 (SplatFPOp (fvti.Scalar fpimm0)), 669 fvti.RegClass:$rs2, 670 (XLenVT (VLOp GPR:$vl)))), 671 (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX) 672 fvti.RegClass:$rs2, 0, VMV0:$vm, GPR:$vl, fvti.SEW)>; 673 674 // 14.16. Vector Floating-Point Move Instruction 675 // If we're splatting fpimm0, use vmv.v.x vd, x0. 676 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 677 (fvti.Scalar (fpimm0)), (XLenVT (VLOp GPR:$vl)))), 678 (!cast<Instruction>("PseudoVMV_V_I_"#fvti.LMul.MX) 679 0, GPR:$vl, fvti.SEW)>; 680 681 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 682 (fvti.Scalar fvti.ScalarRegClass:$rs2), (XLenVT (VLOp GPR:$vl)))), 683 (!cast<Instruction>("PseudoVFMV_V_" # fvti.ScalarSuffix # "_" # 684 fvti.LMul.MX) 685 (fvti.Scalar fvti.ScalarRegClass:$rs2), 686 GPR:$vl, fvti.SEW)>; 687} 688 689} // Predicates = [HasStdExtV, HasStdExtF] 690 691// 16.1 Vector Mask-Register Logical Instructions 692let Predicates = [HasStdExtV] in { 693 694foreach mti = AllMasks in { 695 def : Pat<(mti.Mask (riscv_vmset_vl (XLenVT (VLOp GPR:$vl)))), 696 (!cast<Instruction>("PseudoVMSET_M_" # mti.BX) GPR:$vl, mti.SEW)>; 697 def : Pat<(mti.Mask (riscv_vmclr_vl (XLenVT (VLOp GPR:$vl)))), 698 (!cast<Instruction>("PseudoVMCLR_M_" # mti.BX) GPR:$vl, mti.SEW)>; 699 700 def : Pat<(mti.Mask (riscv_vmand_vl VR:$rs1, VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 701 (!cast<Instruction>("PseudoVMAND_MM_" # mti.LMul.MX) 702 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 703 def : Pat<(mti.Mask (riscv_vmor_vl VR:$rs1, VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 704 (!cast<Instruction>("PseudoVMOR_MM_" # mti.LMul.MX) 705 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 706 def : Pat<(mti.Mask (riscv_vmxor_vl VR:$rs1, VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 707 (!cast<Instruction>("PseudoVMXOR_MM_" # mti.LMul.MX) 708 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 709 710 def : Pat<(mti.Mask (riscv_vmand_vl (riscv_vmnot_vl VR:$rs1, 711 (XLenVT (VLOp GPR:$vl))), 712 VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 713 (!cast<Instruction>("PseudoVMANDNOT_MM_" # mti.LMul.MX) 714 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 715 def : Pat<(mti.Mask (riscv_vmor_vl (riscv_vmnot_vl VR:$rs1, 716 (XLenVT (VLOp GPR:$vl))), 717 VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 718 (!cast<Instruction>("PseudoVMORNOT_MM_" # mti.LMul.MX) 719 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 720 // XOR is associative so we need 2 patterns for VMXNOR. 721 def : Pat<(mti.Mask (riscv_vmxor_vl (riscv_vmnot_vl VR:$rs1, 722 (XLenVT (VLOp GPR:$vl))), 723 VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 724 (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.LMul.MX) 725 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 726 727 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmand_vl VR:$rs1, VR:$rs2, 728 (XLenVT (VLOp GPR:$vl))), 729 (XLenVT (VLOp GPR:$vl)))), 730 (!cast<Instruction>("PseudoVMNAND_MM_" # mti.LMul.MX) 731 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 732 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmor_vl VR:$rs1, VR:$rs2, 733 (XLenVT (VLOp GPR:$vl))), 734 (XLenVT (VLOp GPR:$vl)))), 735 (!cast<Instruction>("PseudoVMNOR_MM_" # mti.LMul.MX) 736 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 737 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmxor_vl VR:$rs1, VR:$rs2, 738 (XLenVT (VLOp GPR:$vl))), 739 (XLenVT (VLOp GPR:$vl)))), 740 (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.LMul.MX) 741 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 742 743 // Match the not idiom to the vnot.mm pseudo. 744 def : Pat<(mti.Mask (riscv_vmnot_vl VR:$rs, (XLenVT (VLOp GPR:$vl)))), 745 (!cast<Instruction>("PseudoVMNAND_MM_" # mti.LMul.MX) 746 VR:$rs, VR:$rs, GPR:$vl, mti.SEW)>; 747} 748 749} // Predicates = [HasStdExtV] 750 751// 17.4. Vector Register GAther Instruction 752let Predicates = [HasStdExtV] in { 753 754foreach vti = AllIntegerVectors in { 755 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1, 756 (vti.Mask true_mask), 757 (XLenVT (VLOp GPR:$vl)))), 758 (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX) 759 vti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.SEW)>; 760 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, uimm5:$imm, 761 (vti.Mask true_mask), 762 (XLenVT (VLOp GPR:$vl)))), 763 (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX) 764 vti.RegClass:$rs2, uimm5:$imm, GPR:$vl, vti.SEW)>; 765} 766 767} // Predicates = [HasStdExtV] 768 769let Predicates = [HasStdExtV, HasStdExtF] in { 770 771foreach vti = AllFloatVectors in { 772 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1, 773 (vti.Mask true_mask), 774 (XLenVT (VLOp GPR:$vl)))), 775 (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX) 776 vti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.SEW)>; 777 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, uimm5:$imm, 778 (vti.Mask true_mask), 779 (XLenVT (VLOp GPR:$vl)))), 780 (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX) 781 vti.RegClass:$rs2, uimm5:$imm, GPR:$vl, vti.SEW)>; 782} 783 784} // Predicates = [HasStdExtV, HasStdExtF] 785 786//===----------------------------------------------------------------------===// 787// Miscellaneous RISCVISD SDNodes 788//===----------------------------------------------------------------------===// 789 790def riscv_vid_vl : SDNode<"RISCVISD::VID_VL", SDTypeProfile<1, 2, 791 [SDTCisVec<0>, SDTCVecEltisVT<1, i1>, 792 SDTCisSameNumEltsAs<0, 1>, SDTCisVT<2, XLenVT>]>, []>; 793 794def SDTRVVSlide : SDTypeProfile<1, 5, [ 795 SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>, SDTCisVT<3, XLenVT>, 796 SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<0, 4>, SDTCisVT<5, XLenVT> 797]>; 798 799def riscv_slideup_vl : SDNode<"RISCVISD::VSLIDEUP_VL", SDTRVVSlide, []>; 800def riscv_slidedown_vl : SDNode<"RISCVISD::VSLIDEDOWN_VL", SDTRVVSlide, []>; 801 802let Predicates = [HasStdExtV] in { 803 804foreach vti = AllIntegerVectors in 805 def : Pat<(vti.Vector (riscv_vid_vl (vti.Mask true_mask), 806 (XLenVT (VLOp GPR:$vl)))), 807 (!cast<Instruction>("PseudoVID_V_"#vti.LMul.MX) GPR:$vl, vti.SEW)>; 808 809foreach vti = !listconcat(AllIntegerVectors, AllFloatVectors) in { 810 def : Pat<(vti.Vector (riscv_slideup_vl (vti.Vector vti.RegClass:$rs3), 811 (vti.Vector vti.RegClass:$rs1), 812 uimm5:$rs2, (vti.Mask true_mask), 813 (XLenVT (VLOp GPR:$vl)))), 814 (!cast<Instruction>("PseudoVSLIDEUP_VI_"#vti.LMul.MX) 815 vti.RegClass:$rs3, vti.RegClass:$rs1, uimm5:$rs2, 816 GPR:$vl, vti.SEW)>; 817 818 def : Pat<(vti.Vector (riscv_slideup_vl (vti.Vector vti.RegClass:$rs3), 819 (vti.Vector vti.RegClass:$rs1), 820 GPR:$rs2, (vti.Mask true_mask), 821 (XLenVT (VLOp GPR:$vl)))), 822 (!cast<Instruction>("PseudoVSLIDEUP_VX_"#vti.LMul.MX) 823 vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2, 824 GPR:$vl, vti.SEW)>; 825 826 def : Pat<(vti.Vector (riscv_slidedown_vl (vti.Vector vti.RegClass:$rs3), 827 (vti.Vector vti.RegClass:$rs1), 828 uimm5:$rs2, (vti.Mask true_mask), 829 (XLenVT (VLOp GPR:$vl)))), 830 (!cast<Instruction>("PseudoVSLIDEDOWN_VI_"#vti.LMul.MX) 831 vti.RegClass:$rs3, vti.RegClass:$rs1, uimm5:$rs2, 832 GPR:$vl, vti.SEW)>; 833 834 def : Pat<(vti.Vector (riscv_slidedown_vl (vti.Vector vti.RegClass:$rs3), 835 (vti.Vector vti.RegClass:$rs1), 836 GPR:$rs2, (vti.Mask true_mask), 837 (XLenVT (VLOp GPR:$vl)))), 838 (!cast<Instruction>("PseudoVSLIDEDOWN_VX_"#vti.LMul.MX) 839 vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2, 840 GPR:$vl, vti.SEW)>; 841} 842 843} // Predicates = [HasStdExtV] 844