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