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 (XLenVT (VLOp GPR:$vl)))), 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 xop_kind:$rs2)), 278 (mask_type true_mask), 279 (XLenVT (VLOp GPR:$vl)))), 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 (XLenVT (VLOp GPR:$vl)))), 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 (XLenVT (VLOp GPR:$vl)))), 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 (XLenVT (VLOp GPR:$vl)))), 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 (XLenVT (VLOp GPR:$vl)))), 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 GPR:$rs2), cc, 386 (vti.Mask true_mask), 387 (XLenVT (VLOp GPR:$vl)))), 388 (instruction vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 389 def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat GPR:$rs2), 390 (vti.Vector vti.RegClass:$rs1), invcc, 391 (vti.Mask true_mask), 392 (XLenVT (VLOp GPR:$vl)))), 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 defvar ImmPat = !cast<ComplexPattern>("sew"#vti.SEW#"simm5"); 400 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 401 (SplatPat_simm5 simm5:$rs2), cc, 402 (vti.Mask true_mask), 403 (XLenVT (VLOp GPR:$vl)))), 404 (instruction vti.RegClass:$rs1, XLenVT:$rs2, GPR:$vl, vti.SEW)>; 405 def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat_simm5 simm5:$rs2), 406 (vti.Vector vti.RegClass:$rs1), invcc, 407 (vti.Mask true_mask), 408 (XLenVT (VLOp GPR:$vl)))), 409 (instruction vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.SEW)>; 410} 411 412multiclass VPatFPSetCCVL_VV_VF_FV<CondCode cc, 413 string inst_name, 414 string swapped_op_inst_name> { 415 foreach fvti = AllFloatVectors in { 416 def : Pat<(fvti.Mask (riscv_setcc_vl (fvti.Vector fvti.RegClass:$rs1), 417 fvti.RegClass:$rs2, 418 cc, 419 (fvti.Mask true_mask), 420 (XLenVT (VLOp GPR:$vl)))), 421 (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX) 422 fvti.RegClass:$rs1, fvti.RegClass:$rs2, GPR:$vl, fvti.SEW)>; 423 def : Pat<(fvti.Mask (riscv_setcc_vl (fvti.Vector fvti.RegClass:$rs1), 424 (SplatFPOp fvti.ScalarRegClass:$rs2), 425 cc, 426 (fvti.Mask true_mask), 427 (XLenVT (VLOp GPR:$vl)))), 428 (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 429 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 430 GPR:$vl, fvti.SEW)>; 431 def : Pat<(fvti.Mask (riscv_setcc_vl (SplatFPOp fvti.ScalarRegClass:$rs2), 432 (fvti.Vector fvti.RegClass:$rs1), 433 cc, 434 (fvti.Mask true_mask), 435 (XLenVT (VLOp GPR:$vl)))), 436 (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 437 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 438 GPR:$vl, fvti.SEW)>; 439 } 440} 441 442multiclass VPatExtendSDNode_V_VL<SDNode vop, string inst_name, string suffix, 443 list <VTypeInfoToFraction> fraction_list> { 444 foreach vtiTofti = fraction_list in { 445 defvar vti = vtiTofti.Vti; 446 defvar fti = vtiTofti.Fti; 447 def : Pat<(vti.Vector (vop (fti.Vector fti.RegClass:$rs2), 448 true_mask, (XLenVT (VLOp GPR:$vl)))), 449 (!cast<Instruction>(inst_name#"_"#suffix#"_"#vti.LMul.MX) 450 fti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 451 } 452} 453 454multiclass VPatConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> { 455 foreach fvti = AllFloatVectors in { 456 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 457 def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1), 458 (fvti.Mask true_mask), 459 (XLenVT (VLOp GPR:$vl)))), 460 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX) 461 fvti.RegClass:$rs1, GPR:$vl, ivti.SEW)>; 462 } 463} 464 465multiclass VPatConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> { 466 foreach fvti = AllFloatVectors in { 467 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 468 def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1), 469 (ivti.Mask true_mask), 470 (XLenVT (VLOp GPR:$vl)))), 471 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 472 ivti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 473 } 474} 475 476multiclass VPatWConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> { 477 foreach fvtiToFWti = AllWidenableFloatVectors in { 478 defvar fvti = fvtiToFWti.Vti; 479 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 480 def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1), 481 (fvti.Mask true_mask), 482 (XLenVT (VLOp GPR:$vl)))), 483 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 484 fvti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 485 } 486} 487 488multiclass VPatWConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> { 489 foreach vtiToWti = AllWidenableIntToFloatVectors in { 490 defvar ivti = vtiToWti.Vti; 491 defvar fwti = vtiToWti.Wti; 492 def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1), 493 (ivti.Mask true_mask), 494 (XLenVT (VLOp GPR:$vl)))), 495 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX) 496 ivti.RegClass:$rs1, GPR:$vl, ivti.SEW)>; 497 } 498} 499 500multiclass VPatNConvertFP2ISDNode_V_VL<SDNode vop, string instruction_name> { 501 foreach vtiToWti = AllWidenableIntToFloatVectors in { 502 defvar vti = vtiToWti.Vti; 503 defvar fwti = vtiToWti.Wti; 504 def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1), 505 (fwti.Mask true_mask), 506 (XLenVT (VLOp GPR:$vl)))), 507 (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX) 508 fwti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 509 } 510} 511 512multiclass VPatNConvertI2FPSDNode_V_VL<SDNode vop, string instruction_name> { 513 foreach fvtiToFWti = AllWidenableFloatVectors in { 514 defvar fvti = fvtiToFWti.Vti; 515 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 516 def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1), 517 (iwti.Mask true_mask), 518 (XLenVT (VLOp GPR:$vl)))), 519 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 520 iwti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 521 } 522} 523 524multiclass VPatReductionVL<SDNode vop, string instruction_name, bit is_float> { 525 foreach vti = !if(is_float, AllFloatVectors, AllIntegerVectors) in { 526 defvar vti_m1 = !cast<VTypeInfo>(!if(is_float, "VF", "VI") # vti.SEW # "M1"); 527 def: Pat<(vti_m1.Vector (vop (vti.Vector vti.RegClass:$rs1), VR:$rs2, 528 (vti.Mask true_mask), 529 (XLenVT (VLOp GPR:$vl)))), 530 (!cast<Instruction>(instruction_name#"_VS_"#vti.LMul.MX) 531 (vti_m1.Vector (IMPLICIT_DEF)), 532 (vti.Vector vti.RegClass:$rs1), 533 (vti_m1.Vector VR:$rs2), 534 GPR:$vl, vti.SEW)>; 535 } 536} 537 538//===----------------------------------------------------------------------===// 539// Patterns. 540//===----------------------------------------------------------------------===// 541 542let Predicates = [HasStdExtV] in { 543 544// 7.4. Vector Unit-Stride Instructions 545foreach vti = AllVectors in { 546 defvar load_instr = !cast<Instruction>("PseudoVLE"#vti.SEW#"_V_"#vti.LMul.MX); 547 defvar store_instr = !cast<Instruction>("PseudoVSE"#vti.SEW#"_V_"#vti.LMul.MX); 548 // Load 549 def : Pat<(vti.Vector (riscv_vle_vl BaseAddr:$rs1, (XLenVT (VLOp GPR:$vl)))), 550 (load_instr BaseAddr:$rs1, GPR:$vl, vti.SEW)>; 551 // Store 552 def : Pat<(riscv_vse_vl (vti.Vector vti.RegClass:$rs2), BaseAddr:$rs1, 553 (XLenVT (VLOp GPR:$vl))), 554 (store_instr vti.RegClass:$rs2, BaseAddr:$rs1, GPR:$vl, vti.SEW)>; 555} 556 557foreach mti = AllMasks in { 558 defvar load_instr = !cast<Instruction>("PseudoVLE1_V_"#mti.BX); 559 defvar store_instr = !cast<Instruction>("PseudoVSE1_V_"#mti.BX); 560 def : Pat<(mti.Mask (riscv_vle_vl BaseAddr:$rs1, (XLenVT (VLOp GPR:$vl)))), 561 (load_instr BaseAddr:$rs1, GPR:$vl, mti.SEW)>; 562 def : Pat<(riscv_vse_vl (mti.Mask VR:$rs2), BaseAddr:$rs1, 563 (XLenVT (VLOp GPR:$vl))), 564 (store_instr VR:$rs2, BaseAddr:$rs1, GPR:$vl, mti.SEW)>; 565} 566 567// 12.1. Vector Single-Width Integer Add and Subtract 568defm : VPatBinaryVL_VV_VX_VI<riscv_add_vl, "PseudoVADD">; 569defm : VPatBinaryVL_VV_VX<riscv_sub_vl, "PseudoVSUB">; 570// Handle VRSUB specially since it's the only integer binary op with reversed 571// pattern operands 572foreach vti = AllIntegerVectors in { 573 def : Pat<(riscv_sub_vl (vti.Vector (SplatPat GPR:$rs2)), 574 (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), 575 (XLenVT (VLOp GPR:$vl))), 576 (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX) 577 vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 578 def : Pat<(riscv_sub_vl (vti.Vector (SplatPat_simm5 simm5:$rs2)), 579 (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), 580 (XLenVT (VLOp GPR:$vl))), 581 (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX) 582 vti.RegClass:$rs1, simm5:$rs2, GPR:$vl, vti.SEW)>; 583} 584 585// 12.3. Vector Integer Extension 586defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF2", 587 AllFractionableVF2IntVectors>; 588defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF2", 589 AllFractionableVF2IntVectors>; 590defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF4", 591 AllFractionableVF4IntVectors>; 592defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF4", 593 AllFractionableVF4IntVectors>; 594defm : VPatExtendSDNode_V_VL<riscv_zext_vl, "PseudoVZEXT", "VF8", 595 AllFractionableVF8IntVectors>; 596defm : VPatExtendSDNode_V_VL<riscv_sext_vl, "PseudoVSEXT", "VF8", 597 AllFractionableVF8IntVectors>; 598 599// 12.5. Vector Bitwise Logical Instructions 600defm : VPatBinaryVL_VV_VX_VI<riscv_and_vl, "PseudoVAND">; 601defm : VPatBinaryVL_VV_VX_VI<riscv_or_vl, "PseudoVOR">; 602defm : VPatBinaryVL_VV_VX_VI<riscv_xor_vl, "PseudoVXOR">; 603 604// 12.6. Vector Single-Width Bit Shift Instructions 605defm : VPatBinaryVL_VV_VX_VI<riscv_shl_vl, "PseudoVSLL", uimm5>; 606defm : VPatBinaryVL_VV_VX_VI<riscv_srl_vl, "PseudoVSRL", uimm5>; 607defm : VPatBinaryVL_VV_VX_VI<riscv_sra_vl, "PseudoVSRA", uimm5>; 608 609// 12.7. Vector Narrowing Integer Right Shift Instructions 610foreach vtiTofti = AllFractionableVF2IntVectors in { 611 defvar vti = vtiTofti.Vti; 612 defvar fti = vtiTofti.Fti; 613 def : Pat<(fti.Vector (riscv_trunc_vector_vl (vti.Vector vti.RegClass:$rs1), 614 (vti.Mask true_mask), 615 (XLenVT (VLOp GPR:$vl)))), 616 (!cast<Instruction>("PseudoVNSRL_WI_"#fti.LMul.MX) 617 vti.RegClass:$rs1, 0, GPR:$vl, fti.SEW)>; 618} 619 620// 12.8. Vector Integer Comparison Instructions 621foreach vti = AllIntegerVectors in { 622 defm : VPatIntegerSetCCVL_VV<vti, "PseudoVMSEQ", SETEQ>; 623 defm : VPatIntegerSetCCVL_VV<vti, "PseudoVMSNE", SETNE>; 624 625 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLT", SETLT, SETGT>; 626 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>; 627 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 628 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 629 630 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>; 631 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>; 632 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLT", SETLT, SETGT>; 633 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>; 634 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 635 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 636 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGT", SETGT, SETLT>; 637 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGTU", SETUGT, SETULT>; 638 // There is no VMSGE(U)_VX instruction 639 640 // FIXME: Support immediate forms of these by choosing SGT and decrementing 641 // the immediate 642 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>; 643 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>; 644 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 645 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 646} // foreach vti = AllIntegerVectors 647 648// 12.9. Vector Integer Min/Max Instructions 649defm : VPatBinaryVL_VV_VX<riscv_umin_vl, "PseudoVMINU">; 650defm : VPatBinaryVL_VV_VX<riscv_smin_vl, "PseudoVMIN">; 651defm : VPatBinaryVL_VV_VX<riscv_umax_vl, "PseudoVMAXU">; 652defm : VPatBinaryVL_VV_VX<riscv_smax_vl, "PseudoVMAX">; 653 654// 12.10. Vector Single-Width Integer Multiply Instructions 655defm : VPatBinaryVL_VV_VX<riscv_mul_vl, "PseudoVMUL">; 656defm : VPatBinaryVL_VV_VX<riscv_mulhs_vl, "PseudoVMULH">; 657defm : VPatBinaryVL_VV_VX<riscv_mulhu_vl, "PseudoVMULHU">; 658 659// 12.11. Vector Integer Divide Instructions 660defm : VPatBinaryVL_VV_VX<riscv_udiv_vl, "PseudoVDIVU">; 661defm : VPatBinaryVL_VV_VX<riscv_sdiv_vl, "PseudoVDIV">; 662defm : VPatBinaryVL_VV_VX<riscv_urem_vl, "PseudoVREMU">; 663defm : VPatBinaryVL_VV_VX<riscv_srem_vl, "PseudoVREM">; 664 665// 12.15. Vector Integer Merge Instructions 666foreach vti = AllIntegerVectors in { 667 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 668 vti.RegClass:$rs1, 669 vti.RegClass:$rs2, 670 (XLenVT (VLOp GPR:$vl)))), 671 (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX) 672 vti.RegClass:$rs2, vti.RegClass:$rs1, VMV0:$vm, 673 GPR:$vl, vti.SEW)>; 674 675 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 676 (SplatPat XLenVT:$rs1), 677 vti.RegClass:$rs2, 678 (XLenVT (VLOp GPR:$vl)))), 679 (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX) 680 vti.RegClass:$rs2, GPR:$rs1, VMV0:$vm, GPR:$vl, vti.SEW)>; 681 682 def : Pat<(vti.Vector (riscv_vselect_vl (vti.Mask VMV0:$vm), 683 (SplatPat_simm5 simm5:$rs1), 684 vti.RegClass:$rs2, 685 (XLenVT (VLOp GPR:$vl)))), 686 (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX) 687 vti.RegClass:$rs2, simm5:$rs1, VMV0:$vm, GPR:$vl, vti.SEW)>; 688} 689 690// 12.16. Vector Integer Move Instructions 691foreach vti = AllIntegerVectors in { 692 def : Pat<(vti.Vector (riscv_vmv_v_x_vl GPR:$rs2, (XLenVT (VLOp GPR:$vl)))), 693 (!cast<Instruction>("PseudoVMV_V_X_"#vti.LMul.MX) 694 $rs2, GPR:$vl, vti.SEW)>; 695 defvar ImmPat = !cast<ComplexPattern>("sew"#vti.SEW#"simm5"); 696 def : Pat<(vti.Vector (riscv_vmv_v_x_vl (ImmPat XLenVT:$imm5), 697 (XLenVT (VLOp GPR:$vl)))), 698 (!cast<Instruction>("PseudoVMV_V_I_"#vti.LMul.MX) 699 XLenVT:$imm5, GPR:$vl, vti.SEW)>; 700} 701 702} // Predicates = [HasStdExtV] 703 704// 15.1. Vector Single-Width Integer Reduction Instructions 705let Predicates = [HasStdExtV] in { 706defm : VPatReductionVL<rvv_vecreduce_ADD_vl, "PseudoVREDSUM", /*is_float*/0>; 707defm : VPatReductionVL<rvv_vecreduce_UMAX_vl, "PseudoVREDMAXU", /*is_float*/0>; 708defm : VPatReductionVL<rvv_vecreduce_SMAX_vl, "PseudoVREDMAX", /*is_float*/0>; 709defm : VPatReductionVL<rvv_vecreduce_UMIN_vl, "PseudoVREDMINU", /*is_float*/0>; 710defm : VPatReductionVL<rvv_vecreduce_SMIN_vl, "PseudoVREDMIN", /*is_float*/0>; 711defm : VPatReductionVL<rvv_vecreduce_AND_vl, "PseudoVREDAND", /*is_float*/0>; 712defm : VPatReductionVL<rvv_vecreduce_OR_vl, "PseudoVREDOR", /*is_float*/0>; 713defm : VPatReductionVL<rvv_vecreduce_XOR_vl, "PseudoVREDXOR", /*is_float*/0>; 714} // Predicates = [HasStdExtV] 715 716// 15.3. Vector Single-Width Floating-Point Reduction Instructions 717let Predicates = [HasStdExtV, HasStdExtF] in { 718defm : VPatReductionVL<rvv_vecreduce_SEQ_FADD_vl, "PseudoVFREDOSUM", /*is_float*/1>; 719defm : VPatReductionVL<rvv_vecreduce_FADD_vl, "PseudoVFREDSUM", /*is_float*/1>; 720} // Predicates = [HasStdExtV, HasStdExtF] 721 722let Predicates = [HasStdExtV, HasStdExtF] in { 723 724// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions 725defm : VPatBinaryFPVL_VV_VF<riscv_fadd_vl, "PseudoVFADD">; 726defm : VPatBinaryFPVL_VV_VF<riscv_fsub_vl, "PseudoVFSUB">; 727defm : VPatBinaryFPVL_R_VF<riscv_fsub_vl, "PseudoVFRSUB">; 728 729// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 730defm : VPatBinaryFPVL_VV_VF<riscv_fmul_vl, "PseudoVFMUL">; 731defm : VPatBinaryFPVL_VV_VF<riscv_fdiv_vl, "PseudoVFDIV">; 732defm : VPatBinaryFPVL_R_VF<riscv_fdiv_vl, "PseudoVFRDIV">; 733 734// 14.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions. 735foreach vti = AllFloatVectors in { 736 // NOTE: We choose VFMADD because it has the most commuting freedom. So it 737 // works best with how TwoAddressInstructionPass tries commuting. 738 defvar suffix = vti.LMul.MX # "_COMMUTABLE"; 739 def : Pat<(vti.Vector (riscv_fma_vl vti.RegClass:$rs1, vti.RegClass:$rd, 740 vti.RegClass:$rs2, (vti.Mask true_mask), 741 (XLenVT (VLOp GPR:$vl)))), 742 (!cast<Instruction>("PseudoVFMADD_VV_"# suffix) 743 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 744 GPR:$vl, vti.SEW)>; 745 def : Pat<(vti.Vector (riscv_fma_vl vti.RegClass:$rs1, vti.RegClass:$rd, 746 (riscv_fneg_vl vti.RegClass:$rs2, 747 (vti.Mask true_mask), 748 (XLenVT (VLOp GPR:$vl))), 749 (vti.Mask true_mask), 750 (XLenVT (VLOp GPR:$vl)))), 751 (!cast<Instruction>("PseudoVFMSUB_VV_"# suffix) 752 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 753 GPR:$vl, vti.SEW)>; 754 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl vti.RegClass:$rs1, 755 (vti.Mask true_mask), 756 (XLenVT (VLOp GPR:$vl))), 757 vti.RegClass:$rd, 758 (riscv_fneg_vl vti.RegClass:$rs2, 759 (vti.Mask true_mask), 760 (XLenVT (VLOp GPR:$vl))), 761 (vti.Mask true_mask), 762 (XLenVT (VLOp GPR:$vl)))), 763 (!cast<Instruction>("PseudoVFNMADD_VV_"# suffix) 764 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 765 GPR:$vl, vti.SEW)>; 766 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl vti.RegClass:$rs1, 767 (vti.Mask true_mask), 768 (XLenVT (VLOp GPR:$vl))), 769 vti.RegClass:$rd, vti.RegClass:$rs2, 770 (vti.Mask true_mask), 771 (XLenVT (VLOp GPR:$vl)))), 772 (!cast<Instruction>("PseudoVFNMSUB_VV_"# suffix) 773 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 774 GPR:$vl, vti.SEW)>; 775 776 // The choice of VFMADD here is arbitrary, vfmadd.vf and vfmacc.vf are equally 777 // commutable. 778 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 779 vti.RegClass:$rd, vti.RegClass:$rs2, 780 (vti.Mask true_mask), 781 (XLenVT (VLOp GPR:$vl)))), 782 (!cast<Instruction>("PseudoVFMADD_V" # vti.ScalarSuffix # "_" # suffix) 783 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 784 GPR:$vl, vti.SEW)>; 785 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 786 vti.RegClass:$rd, 787 (riscv_fneg_vl vti.RegClass:$rs2, 788 (vti.Mask true_mask), 789 (XLenVT (VLOp GPR:$vl))), 790 (vti.Mask true_mask), 791 (XLenVT (VLOp GPR:$vl)))), 792 (!cast<Instruction>("PseudoVFMSUB_V" # vti.ScalarSuffix # "_" # suffix) 793 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 794 GPR:$vl, vti.SEW)>; 795 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 796 (riscv_fneg_vl vti.RegClass:$rd, 797 (vti.Mask true_mask), 798 (XLenVT (VLOp GPR:$vl))), 799 (riscv_fneg_vl vti.RegClass:$rs2, 800 (vti.Mask true_mask), 801 (XLenVT (VLOp GPR:$vl))), 802 (vti.Mask true_mask), 803 (XLenVT (VLOp GPR:$vl)))), 804 (!cast<Instruction>("PseudoVFNMADD_V" # vti.ScalarSuffix # "_" # suffix) 805 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 806 GPR:$vl, vti.SEW)>; 807 def : Pat<(vti.Vector (riscv_fma_vl (SplatFPOp vti.ScalarRegClass:$rs1), 808 (riscv_fneg_vl vti.RegClass:$rd, 809 (vti.Mask true_mask), 810 (XLenVT (VLOp GPR:$vl))), 811 vti.RegClass:$rs2, 812 (vti.Mask true_mask), 813 (XLenVT (VLOp GPR:$vl)))), 814 (!cast<Instruction>("PseudoVFNMSUB_V" # vti.ScalarSuffix # "_" # suffix) 815 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 816 GPR:$vl, vti.SEW)>; 817 818 // The splat might be negated. 819 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl (SplatFPOp vti.ScalarRegClass:$rs1), 820 (vti.Mask true_mask), 821 (XLenVT (VLOp GPR:$vl))), 822 vti.RegClass:$rd, 823 (riscv_fneg_vl vti.RegClass:$rs2, 824 (vti.Mask true_mask), 825 (XLenVT (VLOp GPR:$vl))), 826 (vti.Mask true_mask), 827 (XLenVT (VLOp GPR:$vl)))), 828 (!cast<Instruction>("PseudoVFNMADD_V" # vti.ScalarSuffix # "_" # suffix) 829 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 830 GPR:$vl, vti.SEW)>; 831 def : Pat<(vti.Vector (riscv_fma_vl (riscv_fneg_vl (SplatFPOp vti.ScalarRegClass:$rs1), 832 (vti.Mask true_mask), 833 (XLenVT (VLOp GPR:$vl))), 834 vti.RegClass:$rd, vti.RegClass:$rs2, 835 (vti.Mask true_mask), 836 (XLenVT (VLOp GPR:$vl)))), 837 (!cast<Instruction>("PseudoVFNMSUB_V" # vti.ScalarSuffix # "_" # suffix) 838 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 839 GPR:$vl, vti.SEW)>; 840} 841 842// 14.13. Vector Floating-Point Compare Instructions 843defm : VPatFPSetCCVL_VV_VF_FV<SETEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 844defm : VPatFPSetCCVL_VV_VF_FV<SETOEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 845 846defm : VPatFPSetCCVL_VV_VF_FV<SETNE, "PseudoVMFNE", "PseudoVMFNE">; 847defm : VPatFPSetCCVL_VV_VF_FV<SETUNE, "PseudoVMFNE", "PseudoVMFNE">; 848 849defm : VPatFPSetCCVL_VV_VF_FV<SETLT, "PseudoVMFLT", "PseudoVMFGT">; 850defm : VPatFPSetCCVL_VV_VF_FV<SETOLT, "PseudoVMFLT", "PseudoVMFGT">; 851 852defm : VPatFPSetCCVL_VV_VF_FV<SETLE, "PseudoVMFLE", "PseudoVMFGE">; 853defm : VPatFPSetCCVL_VV_VF_FV<SETOLE, "PseudoVMFLE", "PseudoVMFGE">; 854 855foreach vti = AllFloatVectors in { 856 // 14.8. Vector Floating-Point Square-Root Instruction 857 def : Pat<(riscv_fsqrt_vl (vti.Vector vti.RegClass:$rs2), (vti.Mask true_mask), 858 (XLenVT (VLOp GPR:$vl))), 859 (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX) 860 vti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 861 862 // 14.12. Vector Floating-Point Sign-Injection Instructions 863 def : Pat<(riscv_fabs_vl (vti.Vector vti.RegClass:$rs), (vti.Mask true_mask), 864 (XLenVT (VLOp GPR:$vl))), 865 (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX) 866 vti.RegClass:$rs, vti.RegClass:$rs, GPR:$vl, vti.SEW)>; 867 // Handle fneg with VFSGNJN using the same input for both operands. 868 def : Pat<(riscv_fneg_vl (vti.Vector vti.RegClass:$rs), (vti.Mask true_mask), 869 (XLenVT (VLOp GPR:$vl))), 870 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX) 871 vti.RegClass:$rs, vti.RegClass:$rs, GPR:$vl, vti.SEW)>; 872 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 873 (vti.Vector vti.RegClass:$rs2), 874 (vti.Mask true_mask), 875 (XLenVT (VLOp GPR:$vl))), 876 (!cast<Instruction>("PseudoVFSGNJ_VV_"# vti.LMul.MX) 877 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 878 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 879 (riscv_fneg_vl vti.RegClass:$rs2, 880 (vti.Mask true_mask), 881 (XLenVT (VLOp GPR:$vl))), 882 (vti.Mask true_mask), 883 (XLenVT (VLOp GPR:$vl))), 884 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX) 885 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, vti.SEW)>; 886 887 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 888 (SplatFPOp vti.ScalarRegClass:$rs2), 889 (vti.Mask true_mask), 890 (XLenVT (VLOp GPR:$vl))), 891 (!cast<Instruction>("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"# vti.LMul.MX) 892 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, GPR:$vl, vti.SEW)>; 893} 894 895foreach fvti = AllFloatVectors in { 896 // Floating-point vselects: 897 // 12.15. Vector Integer Merge Instructions 898 // 14.15. Vector Floating-Point Merge Instruction 899 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 900 fvti.RegClass:$rs1, 901 fvti.RegClass:$rs2, 902 (XLenVT (VLOp GPR:$vl)))), 903 (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX) 904 fvti.RegClass:$rs2, fvti.RegClass:$rs1, VMV0:$vm, 905 GPR:$vl, fvti.SEW)>; 906 907 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 908 (SplatFPOp fvti.ScalarRegClass:$rs1), 909 fvti.RegClass:$rs2, 910 (XLenVT (VLOp GPR:$vl)))), 911 (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX) 912 fvti.RegClass:$rs2, 913 (fvti.Scalar fvti.ScalarRegClass:$rs1), 914 VMV0:$vm, GPR:$vl, fvti.SEW)>; 915 916 def : Pat<(fvti.Vector (riscv_vselect_vl (fvti.Mask VMV0:$vm), 917 (SplatFPOp (fvti.Scalar fpimm0)), 918 fvti.RegClass:$rs2, 919 (XLenVT (VLOp GPR:$vl)))), 920 (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX) 921 fvti.RegClass:$rs2, 0, VMV0:$vm, GPR:$vl, fvti.SEW)>; 922 923 // 14.16. Vector Floating-Point Move Instruction 924 // If we're splatting fpimm0, use vmv.v.x vd, x0. 925 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 926 (fvti.Scalar (fpimm0)), (XLenVT (VLOp GPR:$vl)))), 927 (!cast<Instruction>("PseudoVMV_V_I_"#fvti.LMul.MX) 928 0, GPR:$vl, fvti.SEW)>; 929 930 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 931 (fvti.Scalar fvti.ScalarRegClass:$rs2), (XLenVT (VLOp GPR:$vl)))), 932 (!cast<Instruction>("PseudoVFMV_V_" # fvti.ScalarSuffix # "_" # 933 fvti.LMul.MX) 934 (fvti.Scalar fvti.ScalarRegClass:$rs2), 935 GPR:$vl, fvti.SEW)>; 936 937 // 14.17. Vector Single-Width Floating-Point/Integer Type-Convert Instructions 938 defm : VPatConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFCVT_RTZ_X_F_V">; 939 defm : VPatConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFCVT_RTZ_XU_F_V">; 940 defm : VPatConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFCVT_F_X_V">; 941 defm : VPatConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFCVT_F_XU_V">; 942 943 // 14.18. Widening Floating-Point/Integer Type-Convert Instructions 944 defm : VPatWConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFWCVT_RTZ_X_F_V">; 945 defm : VPatWConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFWCVT_RTZ_XU_F_V">; 946 defm : VPatWConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFWCVT_F_X_V">; 947 defm : VPatWConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFWCVT_F_XU_V">; 948 foreach fvtiToFWti = AllWidenableFloatVectors in { 949 defvar fvti = fvtiToFWti.Vti; 950 defvar fwti = fvtiToFWti.Wti; 951 def : Pat<(fwti.Vector (riscv_fpextend_vl (fvti.Vector fvti.RegClass:$rs1), 952 (fvti.Mask true_mask), 953 (XLenVT (VLOp GPR:$vl)))), 954 (!cast<Instruction>("PseudoVFWCVT_F_F_V_"#fvti.LMul.MX) 955 fvti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 956 } 957 958 // 14.19 Narrowing Floating-Point/Integer Type-Convert Instructions 959 defm : VPatNConvertFP2ISDNode_V_VL<riscv_fp_to_sint_vl, "PseudoVFNCVT_RTZ_X_F_W">; 960 defm : VPatNConvertFP2ISDNode_V_VL<riscv_fp_to_uint_vl, "PseudoVFNCVT_RTZ_XU_F_W">; 961 defm : VPatNConvertI2FPSDNode_V_VL<riscv_sint_to_fp_vl, "PseudoVFNCVT_F_X_W">; 962 defm : VPatNConvertI2FPSDNode_V_VL<riscv_uint_to_fp_vl, "PseudoVFNCVT_F_XU_W">; 963 foreach fvtiToFWti = AllWidenableFloatVectors in { 964 defvar fvti = fvtiToFWti.Vti; 965 defvar fwti = fvtiToFWti.Wti; 966 def : Pat<(fvti.Vector (riscv_fpround_vl (fwti.Vector fwti.RegClass:$rs1), 967 (fwti.Mask true_mask), 968 (XLenVT (VLOp GPR:$vl)))), 969 (!cast<Instruction>("PseudoVFNCVT_F_F_W_"#fvti.LMul.MX) 970 fwti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 971 972 def : Pat<(fvti.Vector (riscv_fncvt_rod_vl (fwti.Vector fwti.RegClass:$rs1), 973 (fwti.Mask true_mask), 974 (XLenVT (VLOp GPR:$vl)))), 975 (!cast<Instruction>("PseudoVFNCVT_ROD_F_F_W_"#fvti.LMul.MX) 976 fwti.RegClass:$rs1, GPR:$vl, fvti.SEW)>; 977 } 978} 979 980} // Predicates = [HasStdExtV, HasStdExtF] 981 982let Predicates = [HasStdExtV] in { 983 984foreach mti = AllMasks in { 985 // 16.1 Vector Mask-Register Logical Instructions 986 def : Pat<(mti.Mask (riscv_vmset_vl (XLenVT (VLOp GPR:$vl)))), 987 (!cast<Instruction>("PseudoVMSET_M_" # mti.BX) GPR:$vl, mti.SEW)>; 988 def : Pat<(mti.Mask (riscv_vmclr_vl (XLenVT (VLOp GPR:$vl)))), 989 (!cast<Instruction>("PseudoVMCLR_M_" # mti.BX) GPR:$vl, mti.SEW)>; 990 991 def : Pat<(mti.Mask (riscv_vmand_vl VR:$rs1, VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 992 (!cast<Instruction>("PseudoVMAND_MM_" # mti.LMul.MX) 993 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 994 def : Pat<(mti.Mask (riscv_vmor_vl VR:$rs1, VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 995 (!cast<Instruction>("PseudoVMOR_MM_" # mti.LMul.MX) 996 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 997 def : Pat<(mti.Mask (riscv_vmxor_vl VR:$rs1, VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 998 (!cast<Instruction>("PseudoVMXOR_MM_" # mti.LMul.MX) 999 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1000 1001 def : Pat<(mti.Mask (riscv_vmand_vl (riscv_vmnot_vl VR:$rs1, 1002 (XLenVT (VLOp GPR:$vl))), 1003 VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 1004 (!cast<Instruction>("PseudoVMANDNOT_MM_" # mti.LMul.MX) 1005 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1006 def : Pat<(mti.Mask (riscv_vmor_vl (riscv_vmnot_vl VR:$rs1, 1007 (XLenVT (VLOp GPR:$vl))), 1008 VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 1009 (!cast<Instruction>("PseudoVMORNOT_MM_" # mti.LMul.MX) 1010 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1011 // XOR is associative so we need 2 patterns for VMXNOR. 1012 def : Pat<(mti.Mask (riscv_vmxor_vl (riscv_vmnot_vl VR:$rs1, 1013 (XLenVT (VLOp GPR:$vl))), 1014 VR:$rs2, (XLenVT (VLOp GPR:$vl)))), 1015 (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.LMul.MX) 1016 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1017 1018 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmand_vl VR:$rs1, VR:$rs2, 1019 (XLenVT (VLOp GPR:$vl))), 1020 (XLenVT (VLOp GPR:$vl)))), 1021 (!cast<Instruction>("PseudoVMNAND_MM_" # mti.LMul.MX) 1022 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1023 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmor_vl VR:$rs1, VR:$rs2, 1024 (XLenVT (VLOp GPR:$vl))), 1025 (XLenVT (VLOp GPR:$vl)))), 1026 (!cast<Instruction>("PseudoVMNOR_MM_" # mti.LMul.MX) 1027 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1028 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmxor_vl VR:$rs1, VR:$rs2, 1029 (XLenVT (VLOp GPR:$vl))), 1030 (XLenVT (VLOp GPR:$vl)))), 1031 (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.LMul.MX) 1032 VR:$rs1, VR:$rs2, GPR:$vl, mti.SEW)>; 1033 1034 // Match the not idiom to the vnot.mm pseudo. 1035 def : Pat<(mti.Mask (riscv_vmnot_vl VR:$rs, (XLenVT (VLOp GPR:$vl)))), 1036 (!cast<Instruction>("PseudoVMNAND_MM_" # mti.LMul.MX) 1037 VR:$rs, VR:$rs, GPR:$vl, mti.SEW)>; 1038 1039 // 16.2 Vector Mask Population Count vpopc 1040 def : Pat<(XLenVT (riscv_vpopc_vl (mti.Mask VR:$rs2), (mti.Mask true_mask), 1041 (XLenVT (VLOp GPR:$vl)))), 1042 (!cast<Instruction>("PseudoVPOPC_M_" # mti.BX) 1043 VR:$rs2, GPR:$vl, mti.SEW)>; 1044} 1045 1046} // Predicates = [HasStdExtV] 1047 1048let Predicates = [HasStdExtV] in { 1049// 17.1. Integer Scalar Move Instructions 1050// 17.4. Vector Register Gather Instruction 1051foreach vti = AllIntegerVectors in { 1052 def : Pat<(vti.Vector (riscv_vmv_s_x_vl (vti.Vector vti.RegClass:$merge), 1053 (XLenVT vti.ScalarRegClass:$rs1), 1054 (XLenVT (VLOp GPR:$vl)))), 1055 (!cast<Instruction>("PseudoVMV_S_X_"#vti.LMul.MX) 1056 vti.RegClass:$merge, 1057 (vti.Scalar vti.ScalarRegClass:$rs1), GPR:$vl, vti.SEW)>; 1058 def : Pat<(vti.Vector (riscv_vrgather_vv_vl vti.RegClass:$rs2, 1059 (vti.Vector vti.RegClass:$rs1), 1060 (vti.Mask true_mask), 1061 (XLenVT (VLOp GPR:$vl)))), 1062 (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX) 1063 vti.RegClass:$rs2, vti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 1064 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1, 1065 (vti.Mask true_mask), 1066 (XLenVT (VLOp GPR:$vl)))), 1067 (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX) 1068 vti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.SEW)>; 1069 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, uimm5:$imm, 1070 (vti.Mask true_mask), 1071 (XLenVT (VLOp GPR:$vl)))), 1072 (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX) 1073 vti.RegClass:$rs2, uimm5:$imm, GPR:$vl, vti.SEW)>; 1074 1075 // emul = lmul * 16 / sew 1076 defvar vlmul = vti.LMul; 1077 defvar octuple_lmul = octuple_from_str<vlmul.MX>.ret; 1078 defvar octuple_emul = !srl(!mul(octuple_lmul, 16), shift_amount<vti.SEW>.val); 1079 if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then { 1080 defvar emul_str = octuple_to_str<octuple_emul>.ret; 1081 defvar ivti = !cast<VTypeInfo>("VI16" # emul_str); 1082 defvar inst = "PseudoVRGATHEREI16_VV_" # vti.LMul.MX # "_" # emul_str; 1083 def : Pat<(vti.Vector (riscv_vrgatherei16_vv_vl vti.RegClass:$rs2, 1084 (ivti.Vector ivti.RegClass:$rs1), 1085 (vti.Mask true_mask), 1086 (XLenVT (VLOp GPR:$vl)))), 1087 (!cast<Instruction>(inst) 1088 vti.RegClass:$rs2, ivti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 1089 } 1090} 1091 1092} // Predicates = [HasStdExtV] 1093 1094let Predicates = [HasStdExtV, HasStdExtF] in { 1095 1096// 17.2. Floating-Point Scalar Move Instructions 1097foreach vti = AllFloatVectors in { 1098 def : Pat<(vti.Vector (riscv_vfmv_s_f_vl (vti.Vector vti.RegClass:$merge), 1099 vti.ScalarRegClass:$rs1, 1100 (XLenVT (VLOp GPR:$vl)))), 1101 (!cast<Instruction>("PseudoVFMV_S_"#vti.ScalarSuffix#"_"#vti.LMul.MX) 1102 vti.RegClass:$merge, 1103 (vti.Scalar vti.ScalarRegClass:$rs1), GPR:$vl, vti.SEW)>; 1104 defvar ivti = GetIntVTypeInfo<vti>.Vti; 1105 def : Pat<(vti.Vector (riscv_vrgather_vv_vl vti.RegClass:$rs2, 1106 (ivti.Vector vti.RegClass:$rs1), 1107 (vti.Mask true_mask), 1108 (XLenVT (VLOp GPR:$vl)))), 1109 (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX) 1110 vti.RegClass:$rs2, vti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 1111 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1, 1112 (vti.Mask true_mask), 1113 (XLenVT (VLOp GPR:$vl)))), 1114 (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX) 1115 vti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.SEW)>; 1116 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, uimm5:$imm, 1117 (vti.Mask true_mask), 1118 (XLenVT (VLOp GPR:$vl)))), 1119 (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX) 1120 vti.RegClass:$rs2, uimm5:$imm, GPR:$vl, vti.SEW)>; 1121 1122 defvar vlmul = vti.LMul; 1123 defvar octuple_lmul = octuple_from_str<vlmul.MX>.ret; 1124 defvar octuple_emul = !srl(!mul(octuple_lmul, 16), shift_amount<vti.SEW>.val); 1125 if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then { 1126 defvar emul_str = octuple_to_str<octuple_emul>.ret; 1127 defvar ivti = !cast<VTypeInfo>("VI16" # emul_str); 1128 defvar inst = "PseudoVRGATHEREI16_VV_" # vti.LMul.MX # "_" # emul_str; 1129 def : Pat<(vti.Vector (riscv_vrgatherei16_vv_vl vti.RegClass:$rs2, 1130 (ivti.Vector ivti.RegClass:$rs1), 1131 (vti.Mask true_mask), 1132 (XLenVT (VLOp GPR:$vl)))), 1133 (!cast<Instruction>(inst) 1134 vti.RegClass:$rs2, ivti.RegClass:$rs1, GPR:$vl, vti.SEW)>; 1135 } 1136} 1137 1138} // Predicates = [HasStdExtV, HasStdExtF] 1139 1140//===----------------------------------------------------------------------===// 1141// Miscellaneous RISCVISD SDNodes 1142//===----------------------------------------------------------------------===// 1143 1144def riscv_vid_vl : SDNode<"RISCVISD::VID_VL", SDTypeProfile<1, 2, 1145 [SDTCisVec<0>, SDTCVecEltisVT<1, i1>, 1146 SDTCisSameNumEltsAs<0, 1>, SDTCisVT<2, XLenVT>]>, []>; 1147 1148def SDTRVVSlide : SDTypeProfile<1, 5, [ 1149 SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>, SDTCisVT<3, XLenVT>, 1150 SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<0, 4>, SDTCisVT<5, XLenVT> 1151]>; 1152def SDTRVVSlide1 : SDTypeProfile<1, 4, [ 1153 SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisInt<0>, SDTCisVT<2, XLenVT>, 1154 SDTCVecEltisVT<3, i1>, SDTCisSameNumEltsAs<0, 3>, SDTCisVT<4, XLenVT> 1155]>; 1156 1157def riscv_slideup_vl : SDNode<"RISCVISD::VSLIDEUP_VL", SDTRVVSlide, []>; 1158def riscv_slide1up_vl : SDNode<"RISCVISD::VSLIDE1UP_VL", SDTRVVSlide1, []>; 1159def riscv_slidedown_vl : SDNode<"RISCVISD::VSLIDEDOWN_VL", SDTRVVSlide, []>; 1160def riscv_slide1down_vl : SDNode<"RISCVISD::VSLIDE1DOWN_VL", SDTRVVSlide1, []>; 1161 1162let Predicates = [HasStdExtV] in { 1163 1164foreach vti = AllIntegerVectors in { 1165 def : Pat<(vti.Vector (riscv_vid_vl (vti.Mask true_mask), 1166 (XLenVT (VLOp GPR:$vl)))), 1167 (!cast<Instruction>("PseudoVID_V_"#vti.LMul.MX) GPR:$vl, vti.SEW)>; 1168 1169 def : Pat<(vti.Vector (riscv_slide1up_vl (vti.Vector vti.RegClass:$rs1), 1170 GPR:$rs2, (vti.Mask true_mask), 1171 (XLenVT (VLOp GPR:$vl)))), 1172 (!cast<Instruction>("PseudoVSLIDE1UP_VX_"#vti.LMul.MX) 1173 vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 1174 def : Pat<(vti.Vector (riscv_slide1down_vl (vti.Vector vti.RegClass:$rs1), 1175 GPR:$rs2, (vti.Mask true_mask), 1176 (XLenVT (VLOp GPR:$vl)))), 1177 (!cast<Instruction>("PseudoVSLIDE1DOWN_VX_"#vti.LMul.MX) 1178 vti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.SEW)>; 1179} 1180 1181foreach vti = !listconcat(AllIntegerVectors, AllFloatVectors) in { 1182 def : Pat<(vti.Vector (riscv_slideup_vl (vti.Vector vti.RegClass:$rs3), 1183 (vti.Vector vti.RegClass:$rs1), 1184 uimm5:$rs2, (vti.Mask true_mask), 1185 (XLenVT (VLOp GPR:$vl)))), 1186 (!cast<Instruction>("PseudoVSLIDEUP_VI_"#vti.LMul.MX) 1187 vti.RegClass:$rs3, vti.RegClass:$rs1, uimm5:$rs2, 1188 GPR:$vl, vti.SEW)>; 1189 1190 def : Pat<(vti.Vector (riscv_slideup_vl (vti.Vector vti.RegClass:$rs3), 1191 (vti.Vector vti.RegClass:$rs1), 1192 GPR:$rs2, (vti.Mask true_mask), 1193 (XLenVT (VLOp GPR:$vl)))), 1194 (!cast<Instruction>("PseudoVSLIDEUP_VX_"#vti.LMul.MX) 1195 vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2, 1196 GPR:$vl, vti.SEW)>; 1197 1198 def : Pat<(vti.Vector (riscv_slidedown_vl (vti.Vector vti.RegClass:$rs3), 1199 (vti.Vector vti.RegClass:$rs1), 1200 uimm5:$rs2, (vti.Mask true_mask), 1201 (XLenVT (VLOp GPR:$vl)))), 1202 (!cast<Instruction>("PseudoVSLIDEDOWN_VI_"#vti.LMul.MX) 1203 vti.RegClass:$rs3, vti.RegClass:$rs1, uimm5:$rs2, 1204 GPR:$vl, vti.SEW)>; 1205 1206 def : Pat<(vti.Vector (riscv_slidedown_vl (vti.Vector vti.RegClass:$rs3), 1207 (vti.Vector vti.RegClass:$rs1), 1208 GPR:$rs2, (vti.Mask true_mask), 1209 (XLenVT (VLOp GPR:$vl)))), 1210 (!cast<Instruction>("PseudoVSLIDEDOWN_VX_"#vti.LMul.MX) 1211 vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2, 1212 GPR:$vl, vti.SEW)>; 1213} 1214 1215} // Predicates = [HasStdExtV] 1216