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>]>>; 57def riscv_vmv_s_x_vl : SDNode<"RISCVISD::VMV_S_X_VL", 58 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 59 SDTCisInt<0>, 60 SDTCisVT<2, XLenVT>, 61 SDTCisVT<3, XLenVT>]>>; 62def riscv_vfmv_s_f_vl : SDNode<"RISCVISD::VFMV_S_F_VL", 63 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 64 SDTCisFP<0>, 65 SDTCisEltOfVec<2, 0>, 66 SDTCisVT<3, XLenVT>]>>; 67 68def riscv_vle_vl : SDNode<"RISCVISD::VLE_VL", SDT_RISCVVLE_VL, 69 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 70def riscv_vse_vl : SDNode<"RISCVISD::VSE_VL", SDT_RISCVVSE_VL, 71 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 72 73def riscv_add_vl : SDNode<"RISCVISD::ADD_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 74def riscv_sub_vl : SDNode<"RISCVISD::SUB_VL", SDT_RISCVIntBinOp_VL>; 75def riscv_mul_vl : SDNode<"RISCVISD::MUL_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 76def riscv_mulhs_vl : SDNode<"RISCVISD::MULHS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 77def riscv_mulhu_vl : SDNode<"RISCVISD::MULHU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 78def riscv_and_vl : SDNode<"RISCVISD::AND_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 79def riscv_or_vl : SDNode<"RISCVISD::OR_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 80def riscv_xor_vl : SDNode<"RISCVISD::XOR_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 81def riscv_sdiv_vl : SDNode<"RISCVISD::SDIV_VL", SDT_RISCVIntBinOp_VL>; 82def riscv_srem_vl : SDNode<"RISCVISD::SREM_VL", SDT_RISCVIntBinOp_VL>; 83def riscv_udiv_vl : SDNode<"RISCVISD::UDIV_VL", SDT_RISCVIntBinOp_VL>; 84def riscv_urem_vl : SDNode<"RISCVISD::UREM_VL", SDT_RISCVIntBinOp_VL>; 85def riscv_shl_vl : SDNode<"RISCVISD::SHL_VL", SDT_RISCVIntBinOp_VL>; 86def riscv_sra_vl : SDNode<"RISCVISD::SRA_VL", SDT_RISCVIntBinOp_VL>; 87def riscv_srl_vl : SDNode<"RISCVISD::SRL_VL", SDT_RISCVIntBinOp_VL>; 88def riscv_smin_vl : SDNode<"RISCVISD::SMIN_VL", SDT_RISCVIntBinOp_VL>; 89def riscv_smax_vl : SDNode<"RISCVISD::SMAX_VL", SDT_RISCVIntBinOp_VL>; 90def riscv_umin_vl : SDNode<"RISCVISD::UMIN_VL", SDT_RISCVIntBinOp_VL>; 91def riscv_umax_vl : SDNode<"RISCVISD::UMAX_VL", SDT_RISCVIntBinOp_VL>; 92def riscv_fadd_vl : SDNode<"RISCVISD::FADD_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>; 93def riscv_fsub_vl : SDNode<"RISCVISD::FSUB_VL", SDT_RISCVFPBinOp_VL>; 94def riscv_fmul_vl : SDNode<"RISCVISD::FMUL_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>; 95def riscv_fdiv_vl : SDNode<"RISCVISD::FDIV_VL", SDT_RISCVFPBinOp_VL>; 96def riscv_fneg_vl : SDNode<"RISCVISD::FNEG_VL", SDT_RISCVFPUnOp_VL>; 97def riscv_fabs_vl : SDNode<"RISCVISD::FABS_VL", SDT_RISCVFPUnOp_VL>; 98def riscv_fsqrt_vl : SDNode<"RISCVISD::FSQRT_VL", SDT_RISCVFPUnOp_VL>; 99def riscv_fcopysign_vl : SDNode<"RISCVISD::FCOPYSIGN_VL", SDT_RISCVFPBinOp_VL>; 100 101def SDT_RISCVVecFMA_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>, 102 SDTCisSameAs<0, 2>, 103 SDTCisSameAs<0, 3>, 104 SDTCisVec<0>, SDTCisFP<0>, 105 SDTCVecEltisVT<4, i1>, 106 SDTCisSameNumEltsAs<0, 4>, 107 SDTCisVT<5, XLenVT>]>; 108def riscv_fma_vl : SDNode<"RISCVISD::FMA_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>; 109 110def SDT_RISCVFPRoundOp_VL : SDTypeProfile<1, 3, [ 111 SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>, 112 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT> 113]>; 114def SDT_RISCVFPExtendOp_VL : SDTypeProfile<1, 3, [ 115 SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>, 116 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT> 117]>; 118 119def riscv_fpround_vl : SDNode<"RISCVISD::FP_ROUND_VL", SDT_RISCVFPRoundOp_VL>; 120def riscv_fpextend_vl : SDNode<"RISCVISD::FP_EXTEND_VL", SDT_RISCVFPExtendOp_VL>; 121def riscv_fncvt_rod_vl : SDNode<"RISCVISD::VFNCVT_ROD_VL", SDT_RISCVFPRoundOp_VL>; 122 123def SDT_RISCVFP2IOp_VL : SDTypeProfile<1, 3, [ 124 SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>, 125 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT> 126]>; 127def SDT_RISCVI2FPOp_VL : SDTypeProfile<1, 3, [ 128 SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1>, 129 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT> 130]>; 131 132def riscv_fp_to_sint_vl : SDNode<"RISCVISD::FP_TO_SINT_VL", SDT_RISCVFP2IOp_VL>; 133def riscv_fp_to_uint_vl : SDNode<"RISCVISD::FP_TO_UINT_VL", SDT_RISCVFP2IOp_VL>; 134def riscv_sint_to_fp_vl : SDNode<"RISCVISD::SINT_TO_FP_VL", SDT_RISCVI2FPOp_VL>; 135def riscv_uint_to_fp_vl : SDNode<"RISCVISD::UINT_TO_FP_VL", SDT_RISCVI2FPOp_VL>; 136 137def riscv_setcc_vl : SDNode<"RISCVISD::SETCC_VL", 138 SDTypeProfile<1, 5, [SDTCVecEltisVT<0, i1>, 139 SDTCisVec<1>, 140 SDTCisSameNumEltsAs<0, 1>, 141 SDTCisSameAs<1, 2>, 142 SDTCisVT<3, OtherVT>, 143 SDTCisSameAs<0, 4>, 144 SDTCisVT<5, XLenVT>]>>; 145 146def riscv_vrgather_vx_vl : SDNode<"RISCVISD::VRGATHER_VX_VL", 147 SDTypeProfile<1, 4, [SDTCisVec<0>, 148 SDTCisSameAs<0, 1>, 149 SDTCisVT<2, XLenVT>, 150 SDTCVecEltisVT<3, i1>, 151 SDTCisSameNumEltsAs<0, 3>, 152 SDTCisVT<4, XLenVT>]>>; 153def riscv_vrgather_vv_vl : SDNode<"RISCVISD::VRGATHER_VV_VL", 154 SDTypeProfile<1, 4, [SDTCisVec<0>, 155 SDTCisSameAs<0, 1>, 156 SDTCisInt<2>, 157 SDTCisSameNumEltsAs<0, 2>, 158 SDTCisSameSizeAs<0, 2>, 159 SDTCVecEltisVT<3, i1>, 160 SDTCisSameNumEltsAs<0, 3>, 161 SDTCisVT<4, XLenVT>]>>; 162def riscv_vrgatherei16_vv_vl : SDNode<"RISCVISD::VRGATHEREI16_VV_VL", 163 SDTypeProfile<1, 4, [SDTCisVec<0>, 164 SDTCisSameAs<0, 1>, 165 SDTCisInt<2>, 166 SDTCVecEltisVT<2, i16>, 167 SDTCisSameNumEltsAs<0, 2>, 168 SDTCVecEltisVT<3, i1>, 169 SDTCisSameNumEltsAs<0, 3>, 170 SDTCisVT<4, XLenVT>]>>; 171 172def riscv_vselect_vl : SDNode<"RISCVISD::VSELECT_VL", 173 SDTypeProfile<1, 4, [SDTCisVec<0>, 174 SDTCisVec<1>, 175 SDTCisSameNumEltsAs<0, 1>, 176 SDTCVecEltisVT<1, i1>, 177 SDTCisSameAs<0, 2>, 178 SDTCisSameAs<2, 3>, 179 SDTCisVT<4, XLenVT>]>>; 180 181def SDT_RISCVMaskBinOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 182 SDTCisSameAs<0, 2>, 183 SDTCVecEltisVT<0, i1>, 184 SDTCisVT<3, XLenVT>]>; 185def riscv_vmand_vl : SDNode<"RISCVISD::VMAND_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 186def riscv_vmor_vl : SDNode<"RISCVISD::VMOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 187def riscv_vmxor_vl : SDNode<"RISCVISD::VMXOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 188 189def SDT_RISCVVMSETCLR_VL : SDTypeProfile<1, 1, [SDTCVecEltisVT<0, i1>, 190 SDTCisVT<1, XLenVT>]>; 191def riscv_vmclr_vl : SDNode<"RISCVISD::VMCLR_VL", SDT_RISCVVMSETCLR_VL>; 192def riscv_vmset_vl : SDNode<"RISCVISD::VMSET_VL", SDT_RISCVVMSETCLR_VL>; 193 194def true_mask : PatLeaf<(riscv_vmset_vl (XLenVT srcvalue))>; 195 196def riscv_vmnot_vl : PatFrag<(ops node:$rs, node:$vl), 197 (riscv_vmxor_vl node:$rs, true_mask, node:$vl)>; 198 199def riscv_vpopc_vl : SDNode<"RISCVISD::VPOPC_VL", 200 SDTypeProfile<1, 3, [SDTCisVT<0, XLenVT>, 201 SDTCisVec<1>, SDTCisInt<1>, 202 SDTCVecEltisVT<2, i1>, 203 SDTCisSameNumEltsAs<1, 2>, 204 SDTCisVT<3, XLenVT>]>>; 205 206def SDT_RISCVVEXTEND_VL : SDTypeProfile<1, 3, [SDTCisVec<0>, 207 SDTCisSameNumEltsAs<0, 1>, 208 SDTCisSameNumEltsAs<1, 2>, 209 SDTCVecEltisVT<2, i1>, 210 SDTCisVT<3, XLenVT>]>; 211def riscv_sext_vl : SDNode<"RISCVISD::VSEXT_VL", SDT_RISCVVEXTEND_VL>; 212def riscv_zext_vl : SDNode<"RISCVISD::VZEXT_VL", SDT_RISCVVEXTEND_VL>; 213 214def riscv_trunc_vector_vl : SDNode<"RISCVISD::TRUNCATE_VECTOR_VL", 215 SDTypeProfile<1, 3, [SDTCisVec<0>, 216 SDTCisVec<1>, 217 SDTCisSameNumEltsAs<0, 2>, 218 SDTCVecEltisVT<2, i1>, 219 SDTCisVT<3, XLenVT>]>>; 220 221def SDTRVVVecReduce : SDTypeProfile<1, 4, [ 222 SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2>, SDTCVecEltisVT<3, i1>, 223 SDTCisSameNumEltsAs<1, 3>, SDTCisVT<4, XLenVT> 224]>; 225 226foreach kind = ["ADD", "UMAX", "SMAX", "UMIN", "SMIN", "AND", "OR", "XOR", 227 "FADD", "SEQ_FADD"] in 228 def rvv_vecreduce_#kind#_vl : SDNode<"RISCVISD::VECREDUCE_"#kind#"_VL", SDTRVVVecReduce>; 229 230// Ignore the vl operand. 231def SplatFPOp : PatFrag<(ops node:$op), 232 (riscv_vfmv_v_f_vl node:$op, srcvalue)>; 233 234def sew8simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<8>", []>; 235def sew16simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<16>", []>; 236def sew32simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<32>", []>; 237def sew64simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<64>", []>; 238 239def sew8uimm5 : ComplexPattern<XLenVT, 1, "selectRVVUimm5<8>", []>; 240def sew16uimm5 : ComplexPattern<XLenVT, 1, "selectRVVUimm5<16>", []>; 241def sew32uimm5 : ComplexPattern<XLenVT, 1, "selectRVVUimm5<32>", []>; 242def sew64uimm5 : ComplexPattern<XLenVT, 1, "selectRVVUimm5<64>", []>; 243 244class VPatBinaryVL_VV<SDNode vop, 245 string instruction_name, 246 ValueType result_type, 247 ValueType op_type, 248 ValueType mask_type, 249 int sew, 250 LMULInfo vlmul, 251 VReg RetClass, 252 VReg op_reg_class> : 253 Pat<(result_type (vop 254 (op_type op_reg_class:$rs1), 255 (op_type op_reg_class:$rs2), 256 (mask_type true_mask), 257 VLOpFrag)), 258 (!cast<Instruction>(instruction_name#"_VV_"# vlmul.MX) 259 op_reg_class:$rs1, 260 op_reg_class:$rs2, 261 GPR:$vl, sew)>; 262 263class VPatBinaryVL_XI<SDNode vop, 264 string instruction_name, 265 string suffix, 266 ValueType result_type, 267 ValueType vop_type, 268 ValueType mask_type, 269 int sew, 270 LMULInfo vlmul, 271 VReg RetClass, 272 VReg vop_reg_class, 273 ComplexPattern SplatPatKind, 274 DAGOperand xop_kind> : 275 Pat<(result_type (vop 276 (vop_type vop_reg_class:$rs1), 277 (vop_type (SplatPatKind (XLenVT xop_kind:$rs2))), 278 (mask_type true_mask), 279 VLOpFrag)), 280 (!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX) 281 vop_reg_class:$rs1, 282 xop_kind:$rs2, 283 GPR:$vl, sew)>; 284 285multiclass VPatBinaryVL_VV_VX<SDNode vop, string instruction_name> { 286 foreach vti = AllIntegerVectors in { 287 def : VPatBinaryVL_VV<vop, instruction_name, 288 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 289 vti.LMul, vti.RegClass, vti.RegClass>; 290 def : VPatBinaryVL_XI<vop, instruction_name, "VX", 291 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 292 vti.LMul, vti.RegClass, vti.RegClass, 293 SplatPat, GPR>; 294 } 295} 296 297multiclass VPatBinaryVL_VV_VX_VI<SDNode vop, string instruction_name, 298 Operand ImmType = simm5> { 299 foreach vti = AllIntegerVectors in { 300 def : VPatBinaryVL_VV<vop, instruction_name, 301 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 302 vti.LMul, vti.RegClass, vti.RegClass>; 303 def : VPatBinaryVL_XI<vop, instruction_name, "VX", 304 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 305 vti.LMul, vti.RegClass, vti.RegClass, 306 SplatPat, GPR>; 307 def : VPatBinaryVL_XI<vop, instruction_name, "VI", 308 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 309 vti.LMul, vti.RegClass, vti.RegClass, 310 !cast<ComplexPattern>(SplatPat#_#ImmType), 311 ImmType>; 312 } 313} 314 315class VPatBinaryVL_VF<SDNode vop, 316 string instruction_name, 317 ValueType result_type, 318 ValueType vop_type, 319 ValueType mask_type, 320 int sew, 321 LMULInfo vlmul, 322 VReg RetClass, 323 VReg vop_reg_class, 324 RegisterClass scalar_reg_class> : 325 Pat<(result_type (vop (vop_type vop_reg_class:$rs1), 326 (vop_type (SplatFPOp scalar_reg_class:$rs2)), 327 (mask_type true_mask), 328 VLOpFrag)), 329 (!cast<Instruction>(instruction_name#"_"#vlmul.MX) 330 vop_reg_class:$rs1, 331 scalar_reg_class:$rs2, 332 GPR:$vl, sew)>; 333 334multiclass VPatBinaryFPVL_VV_VF<SDNode vop, string instruction_name> { 335 foreach vti = AllFloatVectors in { 336 def : VPatBinaryVL_VV<vop, instruction_name, 337 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 338 vti.LMul, vti.RegClass, vti.RegClass>; 339 def : VPatBinaryVL_VF<vop, instruction_name#"_V"#vti.ScalarSuffix, 340 vti.Vector, vti.Vector, vti.Mask, vti.SEW, 341 vti.LMul, vti.RegClass, vti.RegClass, 342 vti.ScalarRegClass>; 343 } 344} 345 346multiclass VPatBinaryFPVL_R_VF<SDNode vop, string instruction_name> { 347 foreach fvti = AllFloatVectors in 348 def : Pat<(fvti.Vector (vop (SplatFPOp fvti.ScalarRegClass:$rs2), 349 fvti.RegClass:$rs1, 350 (fvti.Mask true_mask), 351 VLOpFrag)), 352 (!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 353 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 354 GPR:$vl, fvti.SEW)>; 355} 356 357multiclass VPatIntegerSetCCVL_VV<VTypeInfo vti, string instruction_name, 358 CondCode cc> { 359 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 360 vti.RegClass:$rs2, cc, 361 (vti.Mask true_mask), 362 VLOpFrag)), 363 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 364 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, 365 vti.SEW)>; 366} 367 368// Inherits from VPatIntegerSetCCVL_VV and adds a pattern with operands swapped. 369multiclass VPatIntegerSetCCVL_VV_Swappable<VTypeInfo vti, string instruction_name, 370 CondCode cc, CondCode invcc> : 371 VPatIntegerSetCCVL_VV<vti, instruction_name, cc> { 372 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs2), 373 vti.RegClass:$rs1, invcc, 374 (vti.Mask true_mask), 375 VLOpFrag)), 376 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 377 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, 378 vti.SEW)>; 379} 380 381multiclass VPatIntegerSetCCVL_VX_Swappable<VTypeInfo vti, string instruction_name, 382 CondCode cc, CondCode invcc> { 383 defvar instruction = !cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX); 384 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 385 (SplatPat (XLenVT GPR:$rs2)), cc, 386 (vti.Mask true_mask), 387 VLOpFrag)), 388 (instruction vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 389 def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat (XLenVT GPR:$rs2)), 390 (vti.Vector vti.RegClass:$rs1), invcc, 391 (vti.Mask true_mask), 392 VLOpFrag)), 393 (instruction vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 394} 395 396multiclass VPatIntegerSetCCVL_VI_Swappable<VTypeInfo vti, string instruction_name, 397 CondCode cc, CondCode invcc> { 398 defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX); 399 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 400 (SplatPat_simm5 simm5:$rs2), cc, 401 (vti.Mask true_mask), 402 VLOpFrag)), 403 (instruction vti.RegClass:$rs1, XLenVT:$rs2, GPR:$vl, vti.SEW)>; 404 def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat_simm5 simm5:$rs2), 405 (vti.Vector vti.RegClass:$rs1), invcc, 406 (vti.Mask true_mask), 407 VLOpFrag)), 408 (instruction vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.SEW)>; 409} 410 411multiclass VPatIntegerSetCCVL_VIPlus1<VTypeInfo vti, string instruction_name, 412 CondCode cc, ComplexPattern splatpat_kind> { 413 defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX); 414 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 415 (splatpat_kind simm5:$rs2), cc, 416 (vti.Mask true_mask), 417 VLOpFrag)), 418 (instruction vti.RegClass:$rs1, (DecImm simm5:$rs2), 419 GPR:$vl, vti.SEW)>; 420} 421 422multiclass VPatFPSetCCVL_VV_VF_FV<CondCode cc, 423 string inst_name, 424 string swapped_op_inst_name> { 425 foreach fvti = AllFloatVectors in { 426 def : Pat<(fvti.Mask (riscv_setcc_vl (fvti.Vector fvti.RegClass:$rs1), 427 fvti.RegClass:$rs2, 428 cc, 429 (fvti.Mask true_mask), 430 VLOpFrag)), 431 (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX) 432 fvti.RegClass:$rs1, fvti.RegClass:$rs2, GPR:$vl, fvti.SEW)>; 433 def : Pat<(fvti.Mask (riscv_setcc_vl (fvti.Vector fvti.RegClass:$rs1), 434 (SplatFPOp fvti.ScalarRegClass:$rs2), 435 cc, 436 (fvti.Mask true_mask), 437 VLOpFrag)), 438 (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 439 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 440 GPR:$vl, fvti.SEW)>; 441 def : Pat<(fvti.Mask (riscv_setcc_vl (SplatFPOp fvti.ScalarRegClass:$rs2), 442 (fvti.Vector fvti.RegClass:$rs1), 443 cc, 444 (fvti.Mask true_mask), 445 VLOpFrag)), 446 (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 447 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 448 GPR:$vl, fvti.SEW)>; 449 } 450} 451 452multiclass VPatExtendSDNode_V_VL<SDNode vop, string inst_name, string suffix, 453 list <VTypeInfoToFraction> fraction_list> { 454 foreach vtiTofti = fraction_list in { 455 defvar vti = vtiTofti.Vti; 456 defvar fti = vtiTofti.Fti; 457 def : Pat<(vti.Vector (vop (fti.Vector fti.RegClass:$rs2), 458 true_mask, VLOpFrag)), 459 (!cast<Instruction>(inst_name#"_"#suffix#"_"#vti.LMul.MX) 460 fti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 461 } 462} 463 464multiclass VPatConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> { 465 foreach fvti = AllFloatVectors in { 466 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 467 def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1), 468 (fvti.Mask true_mask), 469 VLOpFrag)), 470 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX) 471 fvti.RegClass:$rs1, GPR:$vl, ivti.SEW)>; 472 } 473} 474 475multiclass VPatConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> { 476 foreach fvti = AllFloatVectors in { 477 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 478 def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1), 479 (ivti.Mask true_mask), 480 VLOpFrag)), 481 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 482 ivti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 483 } 484} 485 486multiclass VPatWConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> { 487 foreach fvtiToFWti = AllWidenableFloatVectors in { 488 defvar fvti = fvtiToFWti.Vti; 489 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 490 def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1), 491 (fvti.Mask true_mask), 492 VLOpFrag)), 493 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 494 fvti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 495 } 496} 497 498multiclass VPatWConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> { 499 foreach vtiToWti = AllWidenableIntToFloatVectors in { 500 defvar ivti = vtiToWti.Vti; 501 defvar fwti = vtiToWti.Wti; 502 def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1), 503 (ivti.Mask true_mask), 504 VLOpFrag)), 505 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX) 506 ivti.RegClass:$rs1, GPR:$vl, ivti.SEW)>; 507 } 508} 509 510multiclass VPatNConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> { 511 foreach vtiToWti = AllWidenableIntToFloatVectors in { 512 defvar vti = vtiToWti.Vti; 513 defvar fwti = vtiToWti.Wti; 514 def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1), 515 (fwti.Mask true_mask), 516 VLOpFrag)), 517 (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX) 518 fwti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 519 } 520} 521 522multiclass VPatNConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> { 523 foreach fvtiToFWti = AllWidenableFloatVectors in { 524 defvar fvti = fvtiToFWti.Vti; 525 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 526 def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1), 527 (iwti.Mask true_mask), 528 VLOpFrag)), 529 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 530 iwti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 531 } 532} 533 534multiclass VPatReductionVL<SDNode vop, string instruction_name, bit is_float> { 535 foreach vti = !if(is_float, AllFloatVectors, AllIntegerVectors) in { 536 defvar vti_m1 = !cast<VTypeInfo>(!if(is_float, "VF", "VI") # vti.SEW # "M1"); 537 def: Pat<(vti_m1.Vector (vop (vti.Vector vti.RegClass:$rs1), VR:$rs2, 538 (vti.Mask true_mask), 539 VLOpFrag)), 540 (!cast<Instruction>(instruction_name#"_VS_"#vti.LMul.MX) 541 (vti_m1.Vector (IMPLICIT_DEF)), 542 (vti.Vector vti.RegClass:$rs1), 543 (vti_m1.Vector VR:$rs2), 544 GPR:$vl, vti.SEW)>; 545 } 546} 547 548//===----------------------------------------------------------------------===// 549// Patterns. 550//===----------------------------------------------------------------------===// 551 552let Predicates = [HasStdExtV] in { 553 554// 7.4. Vector Unit-Stride Instructions 555foreach vti = AllVectors in { 556 defvar load_instr = !cast<Instruction>("PseudoVLE"#vti.SEW#"_V_"#vti.LMul.MX); 557 defvar store_instr = !cast<Instruction>("PseudoVSE"#vti.SEW#"_V_"#vti.LMul.MX); 558 // Load 559 def : Pat<(vti.Vector (riscv_vle_vl BaseAddr:$rs1, VLOpFrag)), 560 (load_instr BaseAddr:$rs1, GPR:$vl, vti.SEW)>; 561 // Store 562 def : Pat<(riscv_vse_vl (vti.Vector vti.RegClass:$rs2), BaseAddr:$rs1, 563 VLOpFrag), 564 (store_instr vti.RegClass:$rs2, BaseAddr:$rs1, GPR:$vl, vti.SEW)>; 565} 566 567foreach mti = AllMasks in { 568 defvar load_instr = !cast<Instruction>("PseudoVLE1_V_"#mti.BX); 569 defvar store_instr = !cast<Instruction>("PseudoVSE1_V_"#mti.BX); 570 def : Pat<(mti.Mask (riscv_vle_vl BaseAddr:$rs1, VLOpFrag)), 571 (load_instr BaseAddr:$rs1, GPR:$vl, mti.SEW)>; 572 def : Pat<(riscv_vse_vl (mti.Mask VR:$rs2), BaseAddr:$rs1, 573 VLOpFrag), 574 (store_instr VR:$rs2, BaseAddr:$rs1, GPR:$vl, mti.SEW)>; 575} 576 577// 12.1. Vector Single-Width Integer Add and Subtract 578defm : VPatBinaryVL_VV_VX_VI<riscv_add_vl, "PseudoVADD">; 579defm : VPatBinaryVL_VV_VX<riscv_sub_vl, "PseudoVSUB">; 580// Handle VRSUB specially since it's the only integer binary op with reversed 581// pattern operands 582foreach vti = AllIntegerVectors in { 583 def : Pat<(riscv_sub_vl (vti.Vector (SplatPat (XLenVT GPR:$rs2))), 584 (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), 585 VLOpFrag), 586 (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX) 587 vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 588 def : Pat<(riscv_sub_vl (vti.Vector (SplatPat_simm5 simm5:$rs2)), 589 (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), 590 VLOpFrag), 591 (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX) 592 vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.SEW)>; 593} 594 595// 12.3. Vector Integer Extension 596defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF2", 597 AllFractionableVF2IntVectors>; 598defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF2", 599 AllFractionableVF2IntVectors>; 600defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF4", 601 AllFractionableVF4IntVectors>; 602defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF4", 603 AllFractionableVF4IntVectors>; 604defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF8", 605 AllFractionableVF8IntVectors>; 606defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF8", 607 AllFractionableVF8IntVectors>; 608 609// 12.5. Vector Bitwise Logical Instructions 610defm : VPatBinaryVL_VV_VX_VI<riscv_and_vl, "PseudoVAND">; 611defm : VPatBinaryVL_VV_VX_VI<riscv_or_vl, "PseudoVOR">; 612defm : VPatBinaryVL_VV_VX_VI<riscv_xor_vl, "PseudoVXOR">; 613 614// 12.6. Vector Single-Width Bit Shift Instructions 615defm : VPatBinaryVL_VV_VX_VI<riscv_shl_vl, "PseudoVSLL", uimm5>; 616defm : VPatBinaryVL_VV_VX_VI<riscv_srl_vl, "PseudoVSRL", uimm5>; 617defm : VPatBinaryVL_VV_VX_VI<riscv_sra_vl, "PseudoVSRA", uimm5>; 618 619// 12.7. Vector Narrowing Integer Right Shift Instructions 620foreach vtiTofti = AllFractionableVF2IntVectors in { 621 defvar vti = vtiTofti.Vti; 622 defvar fti = vtiTofti.Fti; 623 def : Pat<(fti.Vector (riscv_trunc_vector_vl (vti.Vector vti.RegClass:$rs1), 624 (vti.Mask true_mask), 625 VLOpFrag)), 626 (!cast<Instruction>("PseudoVNSRL_WI_"#fti.LMul.MX) 627 vti.RegClass:$rs1, 0, GPR:$vl, fti.SEW)>; 628} 629 630// 12.8. Vector Integer Comparison Instructions 631foreach vti = AllIntegerVectors in { 632 defm : VPatIntegerSetCCVL_VV<vti, "PseudoVMSEQ", SETEQ>; 633 defm : VPatIntegerSetCCVL_VV<vti, "PseudoVMSNE", SETNE>; 634 635 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLT", SETLT, SETGT>; 636 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>; 637 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 638 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 639 640 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>; 641 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>; 642 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLT", SETLT, SETGT>; 643 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>; 644 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 645 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 646 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGT", SETGT, SETLT>; 647 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGTU", SETUGT, SETULT>; 648 // There is no VMSGE(U)_VX instruction 649 650 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>; 651 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>; 652 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 653 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 654 655 defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSLE", SETLT, 656 SplatPat_simm5_plus1>; 657 defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSLEU", SETULT, 658 SplatPat_simm5_plus1_nonzero>; 659 defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSGT", SETGE, 660 SplatPat_simm5_plus1>; 661 defm : VPatIntegerSetCCVL_VIPlus1<vti, "PseudoVMSGTU", SETUGE, 662 SplatPat_simm5_plus1_nonzero>; 663} // foreach vti = AllIntegerVectors 664 665// 12.9. Vector Integer Min/Max Instructions 666defm : VPatBinaryVL_VV_VX<riscv_umin_vl, "PseudoVMINU">; 667defm : VPatBinaryVL_VV_VX<riscv_smin_vl, "PseudoVMIN">; 668defm : VPatBinaryVL_VV_VX<riscv_umax_vl, "PseudoVMAXU">; 669defm : VPatBinaryVL_VV_VX<riscv_smax_vl, "PseudoVMAX">; 670 671// 12.10. Vector Single-Width Integer Multiply Instructions 672defm : VPatBinaryVL_VV_VX<riscv_mul_vl, "PseudoVMUL">; 673defm : VPatBinaryVL_VV_VX<riscv_mulhs_vl, "PseudoVMULH">; 674defm : VPatBinaryVL_VV_VX<riscv_mulhu_vl, "PseudoVMULHU">; 675 676// 12.11. Vector Integer Divide Instructions 677defm : VPatBinaryVL_VV_VX<riscv_udiv_vl, "PseudoVDIVU">; 678defm : VPatBinaryVL_VV_VX<riscv_sdiv_vl, "PseudoVDIV">; 679defm : VPatBinaryVL_VV_VX<riscv_urem_vl, "PseudoVREMU">; 680defm : VPatBinaryVL_VV_VX<riscv_srem_vl, "PseudoVREM">; 681 682// 12.15. Vector Integer Merge Instructions 683foreach vti = AllIntegerVectors in { 684 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 685 vti.RegClass:$rs1, 686 vti.RegClass:$rs2, 687 VLOpFrag)), 688 (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX) 689 vti.RegClass:$rs2, vti.RegClass:$rs1, VMV0:$vm, 690 GPR:$vl, vti.SEW)>; 691 692 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 693 (SplatPat XLenVT:$rs1), 694 vti.RegClass:$rs2, 695 VLOpFrag)), 696 (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX) 697 vti.RegClass:$rs2, GPR:$rs1, VMV0:$vm, GPR:$vl, vti.SEW)>; 698 699 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 700 (SplatPat_simm5 simm5:$rs1), 701 vti.RegClass:$rs2, 702 VLOpFrag)), 703 (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX) 704 vti.RegClass:$rs2, simm5:$rs1, VMV0:$vm, GPR:$vl, vti.SEW)>; 705} 706 707// 12.16. Vector Integer Move Instructions 708foreach vti = AllIntegerVectors in { 709 def : Pat<(vti.Vector (riscv_vmv_v_x_vl GPR:$rs2, VLOpFrag)), 710 (!cast<Instruction>("PseudoVMV_V_X_"#vti.LMul.MX) 711 $rs2, GPR:$vl, vti.SEW)>; 712 defvar ImmPat = !cast<ComplexPattern>("sew"#vti.SEW#"simm5"); 713 def : Pat<(vti.Vector (riscv_vmv_v_x_vl (ImmPat XLenVT:$imm5), 714 VLOpFrag)), 715 (!cast<Instruction>("PseudoVMV_V_I_"#vti.LMul.MX) 716 XLenVT:$imm5, GPR:$vl, vti.SEW)>; 717} 718 719} // Predicates = [HasStdExtV] 720 721// 15.1. Vector Single-Width Integer Reduction Instructions 722let Predicates = [HasStdExtV] in { 723defm : VPatReductionVL<rvv_vecreduce_ADD_vl, "PseudoVREDSUM", /*is_float*/0>; 724defm : VPatReductionVL<rvv_vecreduce_UMAX_vl, "PseudoVREDMAXU", /*is_float*/0>; 725defm : VPatReductionVL<rvv_vecreduce_SMAX_vl, "PseudoVREDMAX", /*is_float*/0>; 726defm : VPatReductionVL<rvv_vecreduce_UMIN_vl, "PseudoVREDMINU", /*is_float*/0>; 727defm : VPatReductionVL<rvv_vecreduce_SMIN_vl, "PseudoVREDMIN", /*is_float*/0>; 728defm : VPatReductionVL<rvv_vecreduce_AND_vl, "PseudoVREDAND", /*is_float*/0>; 729defm : VPatReductionVL<rvv_vecreduce_OR_vl, "PseudoVREDOR", /*is_float*/0>; 730defm : VPatReductionVL<rvv_vecreduce_XOR_vl, "PseudoVREDXOR", /*is_float*/0>; 731} // Predicates = [HasStdExtV] 732 733// 15.3. Vector Single-Width Floating-Point Reduction Instructions 734let Predicates = [HasStdExtV, HasStdExtF] in { 735defm : VPatReductionVL<rvv_vecreduce_SEQ_FADD_vl, "PseudoVFREDOSUM", /*is_float*/1>; 736defm : VPatReductionVL<rvv_vecreduce_FADD_vl, "PseudoVFREDSUM", /*is_float*/1>; 737} // Predicates = [HasStdExtV, HasStdExtF] 738 739let Predicates = [HasStdExtV, HasStdExtF] in { 740 741// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions 742defm : VPatBinaryFPVL_VV_VF<riscv_fadd_vl, "PseudoVFADD">; 743defm : VPatBinaryFPVL_VV_VF<riscv_fsub_vl, "PseudoVFSUB">; 744defm : VPatBinaryFPVL_R_VF<riscv_fsub_vl, "PseudoVFRSUB">; 745 746// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 747defm : VPatBinaryFPVL_VV_VF<riscv_fmul_vl, "PseudoVFMUL">; 748defm : VPatBinaryFPVL_VV_VF<riscv_fdiv_vl, "PseudoVFDIV">; 749defm : VPatBinaryFPVL_R_VF<riscv_fdiv_vl, "PseudoVFRDIV">; 750 751// 14.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions. 752foreach vti = AllFloatVectors in { 753 // NOTE: We choose VFMADD because it has the most commuting freedom. So it 754 // works best with how TwoAddressInstructionPass tries commuting. 755 defvar suffix = vti.LMul.MX # "_COMMUTABLE"; 756 def : Pat<(vti.Vector (riscv_fma_vl vti.RegClass:$rs1, vti.RegClass:$rd, 757 vti.RegClass:$rs2, (vti.Mask true_mask), 758 VLOpFrag)), 759 (!cast<Instruction>("PseudoVFMADD_VV_"# suffix) 760 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 761 GPR:$vl, vti.SEW)>; 762 def : Pat<(vti.Vector (riscv_fma_vl vti.RegClass:$rs1, vti.RegClass:$rd, 763 (riscv_fneg_vl vti.RegClass:$rs2, 764 (vti.Mask true_mask), 765 VLOpFrag), 766 (vti.Mask true_mask), 767 VLOpFrag)), 768 (!cast<Instruction>("PseudoVFMSUB_VV_"# suffix) 769 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 770 GPR:$vl, vti.SEW)>; 771 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl vti.RegClass:$rs1, 772 (vti.Mask true_mask), 773 VLOpFrag), 774 vti.RegClass:$rd, 775 (riscv_fneg_vl vti.RegClass:$rs2, 776 (vti.Mask true_mask), 777 VLOpFrag), 778 (vti.Mask true_mask), 779 VLOpFrag)), 780 (!cast<Instruction>("PseudoVFNMADD_VV_"# suffix) 781 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 782 GPR:$vl, vti.SEW)>; 783 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl vti.RegClass:$rs1, 784 (vti.Mask true_mask), 785 VLOpFrag), 786 vti.RegClass:$rd, vti.RegClass:$rs2, 787 (vti.Mask true_mask), 788 VLOpFrag)), 789 (!cast<Instruction>("PseudoVFNMSUB_VV_"# suffix) 790 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 791 GPR:$vl, vti.SEW)>; 792 793 // The choice of VFMADD here is arbitrary, vfmadd.vf and vfmacc.vf are equally 794 // commutable. 795 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 796 vti.RegClass:$rd, vti.RegClass:$rs2, 797 (vti.Mask true_mask), 798 VLOpFrag)), 799 (!cast<Instruction>("PseudoVFMADD_V" # vti.ScalarSuffix # "_" # suffix) 800 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 801 GPR:$vl, vti.SEW)>; 802 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 803 vti.RegClass:$rd, 804 (riscv_fneg_vl vti.RegClass:$rs2, 805 (vti.Mask true_mask), 806 VLOpFrag), 807 (vti.Mask true_mask), 808 VLOpFrag)), 809 (!cast<Instruction>("PseudoVFMSUB_V" # vti.ScalarSuffix # "_" # suffix) 810 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 811 GPR:$vl, vti.SEW)>; 812 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 813 (riscv_fneg_vl vti.RegClass:$rd, 814 (vti.Mask true_mask), 815 VLOpFrag), 816 (riscv_fneg_vl vti.RegClass:$rs2, 817 (vti.Mask true_mask), 818 VLOpFrag), 819 (vti.Mask true_mask), 820 VLOpFrag)), 821 (!cast<Instruction>("PseudoVFNMADD_V" # vti.ScalarSuffix # "_" # suffix) 822 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 823 GPR:$vl, vti.SEW)>; 824 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 825 (riscv_fneg_vl vti.RegClass:$rd, 826 (vti.Mask true_mask), 827 VLOpFrag), 828 vti.RegClass:$rs2, 829 (vti.Mask true_mask), 830 VLOpFrag)), 831 (!cast<Instruction>("PseudoVFNMSUB_V" # vti.ScalarSuffix # "_" # suffix) 832 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 833 GPR:$vl, vti.SEW)>; 834 835 // The splat might be negated. 836 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl (SplatFPOp vti.ScalarRegClass:$rs1), 837 (vti.Mask true_mask), 838 VLOpFrag), 839 vti.RegClass:$rd, 840 (riscv_fneg_vl vti.RegClass:$rs2, 841 (vti.Mask true_mask), 842 VLOpFrag), 843 (vti.Mask true_mask), 844 VLOpFrag)), 845 (!cast<Instruction>("PseudoVFNMADD_V" # vti.ScalarSuffix # "_" # suffix) 846 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 847 GPR:$vl, vti.SEW)>; 848 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl (SplatFPOp vti.ScalarRegClass:$rs1), 849 (vti.Mask true_mask), 850 VLOpFrag), 851 vti.RegClass:$rd, vti.RegClass:$rs2, 852 (vti.Mask true_mask), 853 VLOpFrag)), 854 (!cast<Instruction>("PseudoVFNMSUB_V" # vti.ScalarSuffix # "_" # suffix) 855 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 856 GPR:$vl, vti.SEW)>; 857} 858 859// 14.13. Vector Floating-Point Compare Instructions 860defm : VPatFPSetCCVL_VV_VF_FV<SETEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 861defm : VPatFPSetCCVL_VV_VF_FV<SETOEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 862 863defm : VPatFPSetCCVL_VV_VF_FV<SETNE, "PseudoVMFNE", "PseudoVMFNE">; 864defm : VPatFPSetCCVL_VV_VF_FV<SETUNE, "PseudoVMFNE", "PseudoVMFNE">; 865 866defm : VPatFPSetCCVL_VV_VF_FV<SETLT, "PseudoVMFLT", "PseudoVMFGT">; 867defm : VPatFPSetCCVL_VV_VF_FV<SETOLT, "PseudoVMFLT", "PseudoVMFGT">; 868 869defm : VPatFPSetCCVL_VV_VF_FV<SETLE, "PseudoVMFLE", "PseudoVMFGE">; 870defm : VPatFPSetCCVL_VV_VF_FV<SETOLE, "PseudoVMFLE", "PseudoVMFGE">; 871 872foreach vti = AllFloatVectors in { 873 // 14.8. Vector Floating-Point Square-Root Instruction 874 def : Pat<(riscv_fsqrt_vl (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), 875 VLOpFrag), 876 (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX) 877 vti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 878 879 // 14.12. Vector Floating-Point Sign-Injection Instructions 880 def : Pat<(riscv_fabs_vl (vti.Vector vti.RegClass:$rs), (vti.Mask true_mask), 881 VLOpFrag), 882 (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX) 883 vti.RegClass:$rs, vti.RegClass:$rs, GPR:$vl, vti.SEW)>; 884 // Handle fneg with VFSGNJN using the same input for both operands. 885 def : Pat<(riscv_fneg_vl (vti.Vector vti.RegClass:$rs), (vti.Mask true_mask), 886 VLOpFrag), 887 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX) 888 vti.RegClass:$rs, vti.RegClass:$rs, GPR:$vl, vti.SEW)>; 889 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 890 (vti.Vector vti.RegClass:$rs2), 891 (vti.Mask true_mask), 892 VLOpFrag), 893 (!cast<Instruction>("PseudoVFSGNJ_VV_"# vti.LMul.MX) 894 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 895 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 896 (riscv_fneg_vl vti.RegClass:$rs2, 897 (vti.Mask true_mask), 898 VLOpFrag), 899 (vti.Mask true_mask), 900 VLOpFrag), 901 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX) 902 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 903 904 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 905 (SplatFPOp vti.ScalarRegClass:$rs2), 906 (vti.Mask true_mask), 907 VLOpFrag), 908 (!cast<Instruction>("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"# vti.LMul.MX) 909 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, GPR:$vl, vti.SEW)>; 910} 911 912foreach fvti = AllFloatVectors in { 913 // Floating-point vselects: 914 // 12.15. Vector Integer Merge Instructions 915 // 14.15. Vector Floating-Point Merge Instruction 916 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 917 fvti.RegClass:$rs1, 918 fvti.RegClass:$rs2, 919 VLOpFrag)), 920 (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX) 921 fvti.RegClass:$rs2, fvti.RegClass:$rs1, VMV0:$vm, 922 GPR:$vl, fvti.SEW)>; 923 924 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 925 (SplatFPOp fvti.ScalarRegClass:$rs1), 926 fvti.RegClass:$rs2, 927 VLOpFrag)), 928 (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX) 929 fvti.RegClass:$rs2, 930 (fvti.Scalar fvti.ScalarRegClass:$rs1), 931 VMV0:$vm, GPR:$vl, fvti.SEW)>; 932 933 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 934 (SplatFPOp (fvti.Scalar fpimm0)), 935 fvti.RegClass:$rs2, 936 VLOpFrag)), 937 (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX) 938 fvti.RegClass:$rs2, 0, VMV0:$vm, GPR:$vl, fvti.SEW)>; 939 940 // 14.16. Vector Floating-Point Move Instruction 941 // If we're splatting fpimm0, use vmv.v.x vd, x0. 942 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 943 (fvti.Scalar (fpimm0)), VLOpFrag)), 944 (!cast<Instruction>("PseudoVMV_V_I_"#fvti.LMul.MX) 945 0, GPR:$vl, fvti.SEW)>; 946 947 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 948 (fvti.Scalar fvti.ScalarRegClass:$rs2), VLOpFrag)), 949 (!cast<Instruction>("PseudoVFMV_V_" # fvti.ScalarSuffix # "_" # 950 fvti.LMul.MX) 951 (fvti.Scalar fvti.ScalarRegClass:$rs2), 952 GPR:$vl, fvti.SEW)>; 953 954 // 14.17. Vector Single-Width Floating-Point/Integer Type-Convert Instructions 955 defm : VPatConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFCVT_RTZ_X_F_V">; 956 defm : VPatConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFCVT_RTZ_XU_F_V">; 957 defm : VPatConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFCVT_F_X_V">; 958 defm : VPatConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFCVT_F_XU_V">; 959 960 // 14.18. Widening Floating-Point/Integer Type-Convert Instructions 961 defm : VPatWConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFWCVT_RTZ_X_F_V">; 962 defm : VPatWConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFWCVT_RTZ_XU_F_V">; 963 defm : VPatWConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFWCVT_F_X_V">; 964 defm : VPatWConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFWCVT_F_XU_V">; 965 foreach fvtiToFWti = AllWidenableFloatVectors in { 966 defvar fvti = fvtiToFWti.Vti; 967 defvar fwti = fvtiToFWti.Wti; 968 def : Pat<(fwti.Vector (riscv_fpextend_vl (fvti.Vector fvti.RegClass:$rs1), 969 (fvti.Mask true_mask), 970 VLOpFrag)), 971 (!cast<Instruction>("PseudoVFWCVT_F_F_V_"#fvti.LMul.MX) 972 fvti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 973 } 974 975 // 14.19 Narrowing Floating-Point/Integer Type-Convert Instructions 976 defm : VPatNConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFNCVT_RTZ_X_F_W">; 977 defm : VPatNConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFNCVT_RTZ_XU_F_W">; 978 defm : VPatNConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFNCVT_F_X_W">; 979 defm : VPatNConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFNCVT_F_XU_W">; 980 foreach fvtiToFWti = AllWidenableFloatVectors in { 981 defvar fvti = fvtiToFWti.Vti; 982 defvar fwti = fvtiToFWti.Wti; 983 def : Pat<(fvti.Vector (riscv_fpround_vl (fwti.Vector fwti.RegClass:$rs1), 984 (fwti.Mask true_mask), 985 VLOpFrag)), 986 (!cast<Instruction>("PseudoVFNCVT_F_F_W_"#fvti.LMul.MX) 987 fwti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 988 989 def : Pat<(fvti.Vector (riscv_fncvt_rod_vl (fwti.Vector fwti.RegClass:$rs1), 990 (fwti.Mask true_mask), 991 VLOpFrag)), 992 (!cast<Instruction>("PseudoVFNCVT_ROD_F_F_W_"#fvti.LMul.MX) 993 fwti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 994 } 995} 996 997} // Predicates = [HasStdExtV, HasStdExtF] 998 999let Predicates = [HasStdExtV] in { 1000 1001foreach mti = AllMasks in { 1002 // 16.1 Vector Mask-Register Logical Instructions 1003 def : Pat<(mti.Mask (riscv_vmset_vl VLOpFrag)), 1004 (!cast<Instruction>("PseudoVMSET_M_" # mti.BX) GPR:$vl, mti.SEW)>; 1005 def : Pat<(mti.Mask (riscv_vmclr_vl VLOpFrag)), 1006 (!cast<Instruction>("PseudoVMCLR_M_" # mti.BX) GPR:$vl, mti.SEW)>; 1007 1008 def : Pat<(mti.Mask (riscv_vmand_vl VR:$rs1, VR:$rs2, VLOpFrag)), 1009 (!cast<Instruction>("PseudoVMAND_MM_" # mti.LMul.MX) 1010 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1011 def : Pat<(mti.Mask (riscv_vmor_vl VR:$rs1, VR:$rs2, VLOpFrag)), 1012 (!cast<Instruction>("PseudoVMOR_MM_" # mti.LMul.MX) 1013 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1014 def : Pat<(mti.Mask (riscv_vmxor_vl VR:$rs1, VR:$rs2, VLOpFrag)), 1015 (!cast<Instruction>("PseudoVMXOR_MM_" # mti.LMul.MX) 1016 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1017 1018 def : Pat<(mti.Mask (riscv_vmand_vl (riscv_vmnot_vl VR:$rs1, 1019 VLOpFrag), 1020 VR:$rs2, VLOpFrag)), 1021 (!cast<Instruction>("PseudoVMANDNOT_MM_" # mti.LMul.MX) 1022 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1023 def : Pat<(mti.Mask (riscv_vmor_vl (riscv_vmnot_vl VR:$rs1, 1024 VLOpFrag), 1025 VR:$rs2, VLOpFrag)), 1026 (!cast<Instruction>("PseudoVMORNOT_MM_" # mti.LMul.MX) 1027 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1028 // XOR is associative so we need 2 patterns for VMXNOR. 1029 def : Pat<(mti.Mask (riscv_vmxor_vl (riscv_vmnot_vl VR:$rs1, 1030 VLOpFrag), 1031 VR:$rs2, VLOpFrag)), 1032 (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.LMul.MX) 1033 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1034 1035 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmand_vl VR:$rs1, VR:$rs2, 1036 VLOpFrag), 1037 VLOpFrag)), 1038 (!cast<Instruction>("PseudoVMNAND_MM_" # mti.LMul.MX) 1039 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1040 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmor_vl VR:$rs1, VR:$rs2, 1041 VLOpFrag), 1042 VLOpFrag)), 1043 (!cast<Instruction>("PseudoVMNOR_MM_" # mti.LMul.MX) 1044 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1045 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmxor_vl VR:$rs1, VR:$rs2, 1046 VLOpFrag), 1047 VLOpFrag)), 1048 (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.LMul.MX) 1049 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1050 1051 // Match the not idiom to the vnot.mm pseudo. 1052 def : Pat<(mti.Mask (riscv_vmnot_vl VR:$rs, VLOpFrag)), 1053 (!cast<Instruction>("PseudoVMNAND_MM_" # mti.LMul.MX) 1054 VR:$rs, VR:$rs, GPR:$vl, mti.SEW)>; 1055 1056 // 16.2 Vector Mask Population Count vpopc 1057 def : Pat<(XLenVT (riscv_vpopc_vl (mti.Mask VR:$rs2), (mti.Mask true_mask), 1058 VLOpFrag)), 1059 (!cast<Instruction>("PseudoVPOPC_M_" # mti.BX) 1060 VR:$rs2, GPR:$vl, mti.SEW)>; 1061} 1062 1063} // Predicates = [HasStdExtV] 1064 1065let Predicates = [HasStdExtV] in { 1066// 17.1. Integer Scalar Move Instructions 1067// 17.4. Vector Register Gather Instruction 1068foreach vti = AllIntegerVectors in { 1069 def : Pat<(vti.Vector (riscv_vmv_s_x_vl (vti.Vector vti.RegClass:$merge), 1070 vti.ScalarRegClass:$rs1, 1071 VLOpFrag)), 1072 (!cast<Instruction>("PseudoVMV_S_X_"#vti.LMul.MX) 1073 vti.RegClass:$merge, 1074 (vti.Scalar vti.ScalarRegClass:$rs1), GPR:$vl, vti.SEW)>; 1075 def : Pat<(vti.Vector (riscv_vrgather_vv_vl vti.RegClass:$rs2, 1076 (vti.Vector vti.RegClass:$rs1), 1077 (vti.Mask true_mask), 1078 VLOpFrag)), 1079 (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX) 1080 vti.RegClass:$rs2, vti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 1081 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1, 1082 (vti.Mask true_mask), 1083 VLOpFrag)), 1084 (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX) 1085 vti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.SEW)>; 1086 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, uimm5:$imm, 1087 (vti.Mask true_mask), 1088 VLOpFrag)), 1089 (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX) 1090 vti.RegClass:$rs2, uimm5:$imm, GPR:$vl, vti.SEW)>; 1091 1092 // emul = lmul * 16 / sew 1093 defvar vlmul = vti.LMul; 1094 defvar octuple_lmul = octuple_from_str<vlmul.MX>.ret; 1095 defvar octuple_emul = !srl(!mul(octuple_lmul, 16), shift_amount<vti.SEW>.val); 1096 if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then { 1097 defvar emul_str = octuple_to_str<octuple_emul>.ret; 1098 defvar ivti = !cast<VTypeInfo>("VI16" # emul_str); 1099 defvar inst = "PseudoVRGATHEREI16_VV_" # vti.LMul.MX # "_" # emul_str; 1100 def : Pat<(vti.Vector (riscv_vrgatherei16_vv_vl vti.RegClass:$rs2, 1101 (ivti.Vector ivti.RegClass:$rs1), 1102 (vti.Mask true_mask), 1103 VLOpFrag)), 1104 (!cast<Instruction>(inst) 1105 vti.RegClass:$rs2, ivti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 1106 } 1107} 1108 1109} // Predicates = [HasStdExtV] 1110 1111let Predicates = [HasStdExtV, HasStdExtF] in { 1112 1113// 17.2. Floating-Point Scalar Move Instructions 1114foreach vti = AllFloatVectors in { 1115 def : Pat<(vti.Vector (riscv_vfmv_s_f_vl (vti.Vector vti.RegClass:$merge), 1116 vti.ScalarRegClass:$rs1, 1117 VLOpFrag)), 1118 (!cast<Instruction>("PseudoVFMV_S_"#vti.ScalarSuffix#"_"#vti.LMul.MX) 1119 vti.RegClass:$merge, 1120 (vti.Scalar vti.ScalarRegClass:$rs1), GPR:$vl, vti.SEW)>; 1121 defvar ivti = GetIntVTypeInfo<vti>.Vti; 1122 def : Pat<(vti.Vector (riscv_vrgather_vv_vl vti.RegClass:$rs2, 1123 (ivti.Vector vti.RegClass:$rs1), 1124 (vti.Mask true_mask), 1125 VLOpFrag)), 1126 (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX) 1127 vti.RegClass:$rs2, vti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 1128 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1, 1129 (vti.Mask true_mask), 1130 VLOpFrag)), 1131 (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX) 1132 vti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.SEW)>; 1133 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, uimm5:$imm, 1134 (vti.Mask true_mask), 1135 VLOpFrag)), 1136 (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX) 1137 vti.RegClass:$rs2, uimm5:$imm, GPR:$vl, vti.SEW)>; 1138 1139 defvar vlmul = vti.LMul; 1140 defvar octuple_lmul = octuple_from_str<vlmul.MX>.ret; 1141 defvar octuple_emul = !srl(!mul(octuple_lmul, 16), shift_amount<vti.SEW>.val); 1142 if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then { 1143 defvar emul_str = octuple_to_str<octuple_emul>.ret; 1144 defvar ivti = !cast<VTypeInfo>("VI16" # emul_str); 1145 defvar inst = "PseudoVRGATHEREI16_VV_" # vti.LMul.MX # "_" # emul_str; 1146 def : Pat<(vti.Vector (riscv_vrgatherei16_vv_vl vti.RegClass:$rs2, 1147 (ivti.Vector ivti.RegClass:$rs1), 1148 (vti.Mask true_mask), 1149 VLOpFrag)), 1150 (!cast<Instruction>(inst) 1151 vti.RegClass:$rs2, ivti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 1152 } 1153} 1154 1155} // Predicates = [HasStdExtV, HasStdExtF] 1156 1157//===----------------------------------------------------------------------===// 1158// Miscellaneous RISCVISD SDNodes 1159//===----------------------------------------------------------------------===// 1160 1161def riscv_vid_vl : SDNode<"RISCVISD::VID_VL", SDTypeProfile<1, 2, 1162 [SDTCisVec<0>, SDTCVecEltisVT<1, i1>, 1163 SDTCisSameNumEltsAs<0, 1>, SDTCisVT<2, XLenVT>]>, []>; 1164 1165def SDTRVVSlide : SDTypeProfile<1, 5, [ 1166 SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>, SDTCisVT<3, XLenVT>, 1167 SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<0, 4>, SDTCisVT<5, XLenVT> 1168]>; 1169def SDTRVVSlide1 : SDTypeProfile<1, 4, [ 1170 SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisInt<0>, SDTCisVT<2, XLenVT>, 1171 SDTCVecEltisVT<3, i1>, SDTCisSameNumEltsAs<0, 3>, SDTCisVT<4, XLenVT> 1172]>; 1173 1174def riscv_slideup_vl : SDNode<"RISCVISD::VSLIDEUP_VL", SDTRVVSlide, []>; 1175def riscv_slide1up_vl : SDNode<"RISCVISD::VSLIDE1UP_VL", SDTRVVSlide1, []>; 1176def riscv_slidedown_vl : SDNode<"RISCVISD::VSLIDEDOWN_VL", SDTRVVSlide, []>; 1177def riscv_slide1down_vl : SDNode<"RISCVISD::VSLIDE1DOWN_VL", SDTRVVSlide1, []>; 1178 1179let Predicates = [HasStdExtV] in { 1180 1181foreach vti = AllIntegerVectors in { 1182 def : Pat<(vti.Vector (riscv_vid_vl (vti.Mask true_mask), 1183 VLOpFrag)), 1184 (!cast<Instruction>("PseudoVID_V_"#vti.LMul.MX) GPR:$vl, vti.SEW)>; 1185 1186 def : Pat<(vti.Vector (riscv_slide1up_vl (vti.Vector vti.RegClass:$rs1), 1187 GPR:$rs2, (vti.Mask true_mask), 1188 VLOpFrag)), 1189 (!cast<Instruction>("PseudoVSLIDE1UP_VX_"#vti.LMul.MX) 1190 vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 1191 def : Pat<(vti.Vector (riscv_slide1down_vl (vti.Vector vti.RegClass:$rs1), 1192 GPR:$rs2, (vti.Mask true_mask), 1193 VLOpFrag)), 1194 (!cast<Instruction>("PseudoVSLIDE1DOWN_VX_"#vti.LMul.MX) 1195 vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 1196} 1197 1198foreach vti = !listconcat(AllIntegerVectors, AllFloatVectors) in { 1199 def : Pat<(vti.Vector (riscv_slideup_vl (vti.Vector vti.RegClass:$rs3), 1200 (vti.Vector vti.RegClass:$rs1), 1201 uimm5:$rs2, (vti.Mask true_mask), 1202 VLOpFrag)), 1203 (!cast<Instruction>("PseudoVSLIDEUP_VI_"#vti.LMul.MX) 1204 vti.RegClass:$rs3, vti.RegClass:$rs1, uimm5:$rs2, 1205 GPR:$vl, vti.SEW)>; 1206 1207 def : Pat<(vti.Vector (riscv_slideup_vl (vti.Vector vti.RegClass:$rs3), 1208 (vti.Vector vti.RegClass:$rs1), 1209 GPR:$rs2, (vti.Mask true_mask), 1210 VLOpFrag)), 1211 (!cast<Instruction>("PseudoVSLIDEUP_VX_"#vti.LMul.MX) 1212 vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2, 1213 GPR:$vl, vti.SEW)>; 1214 1215 def : Pat<(vti.Vector (riscv_slidedown_vl (vti.Vector vti.RegClass:$rs3), 1216 (vti.Vector vti.RegClass:$rs1), 1217 uimm5:$rs2, (vti.Mask true_mask), 1218 VLOpFrag)), 1219 (!cast<Instruction>("PseudoVSLIDEDOWN_VI_"#vti.LMul.MX) 1220 vti.RegClass:$rs3, vti.RegClass:$rs1, uimm5:$rs2, 1221 GPR:$vl, vti.SEW)>; 1222 1223 def : Pat<(vti.Vector (riscv_slidedown_vl (vti.Vector vti.RegClass:$rs3), 1224 (vti.Vector vti.RegClass:$rs1), 1225 GPR:$rs2, (vti.Mask true_mask), 1226 VLOpFrag)), 1227 (!cast<Instruction>("PseudoVSLIDEDOWN_VX_"#vti.LMul.MX) 1228 vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2, 1229 GPR:$vl, vti.SEW)>; 1230} 1231 1232} // Predicates = [HasStdExtV] 1233