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/// version 1.0. 12/// 13/// This file is included from and depends upon RISCVInstrInfoVPseudos.td 14/// 15/// Note: the patterns for RVV intrinsics are found in 16/// RISCVInstrInfoVPseudos.td. 17/// 18//===----------------------------------------------------------------------===// 19 20// Splats an 64-bit value that has been split into two i32 parts. This is 21// expanded late to two scalar stores and a stride 0 vector load. 22// The first operand is passthru operand. 23// 24// This is only present to generate the correct TableGen SDNode description, 25// it is lowered before instruction selection. 26// FIXME: I'm not sure the types here are entirely correct. 27// Returns a vector. Operand 0 is a passthru, operand 1 and 2 are i32 scalars, operand 3 is VL 28def riscv_splat_vector_split_i64_vl : RVSDNode<"SPLAT_VECTOR_SPLIT_I64_VL", 29 SDTypeProfile<1, 4, [SDTCisVec<0>, 30 SDTCVecEltisVT<0, i64>, 31 SDTCisSameAs<1, 0>, 32 SDTCisVT<2, i32>, 33 SDTCisVT<3, i32>, 34 SDTCisVT<4, XLenVT>]>>; 35 36// RISC-V vector tuple type version of INSERT_SUBVECTOR/EXTRACT_SUBVECTOR. 37def riscv_tuple_insert : RVSDNode<"TUPLE_INSERT", 38 SDTypeProfile<1, 3, [SDTCisSameAs<1, 0>, 39 SDTCisVec<2>, 40 SDTCisVT<3, i32>]>>; 41def riscv_tuple_extract : RVSDNode<"TUPLE_EXTRACT", 42 SDTypeProfile<1, 2, [SDTCisVec<0>, 43 SDTCisVT<2, i32>]>>; 44 45 46//===----------------------------------------------------------------------===// 47// Helpers to define the VL patterns. 48//===----------------------------------------------------------------------===// 49 50def SDT_RISCVIntUnOp_VL : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, 51 SDTCisSameAs<0, 2>, 52 SDTCisVec<0>, SDTCisInt<0>, 53 SDTCVecEltisVT<3, i1>, 54 SDTCisSameNumEltsAs<0, 3>, 55 SDTCisVT<4, XLenVT>]>; 56 57def SDT_RISCVIntBinOp_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>, 58 SDTCisSameAs<0, 2>, 59 SDTCisVec<0>, SDTCisInt<0>, 60 SDTCisSameAs<0, 3>, 61 SDTCVecEltisVT<4, i1>, 62 SDTCisSameNumEltsAs<0, 4>, 63 SDTCisVT<5, XLenVT>]>; 64 65// Input: (vector, vector/scalar, passthru, mask, roundmode, vl) 66def SDT_RISCVVNBinOp_RM_VL : SDTypeProfile<1, 6, [SDTCisVec<0>, SDTCisInt<0>, 67 SDTCisSameAs<0, 3>, 68 SDTCisSameNumEltsAs<0, 1>, 69 SDTCisVec<1>, 70 SDTCisOpSmallerThanOp<2, 1>, 71 SDTCisSameAs<0, 2>, 72 SDTCisSameNumEltsAs<0, 4>, 73 SDTCVecEltisVT<4, i1>, 74 SDTCisVT<5, XLenVT>, 75 SDTCisVT<6, XLenVT>]>; 76 77def SDT_RISCVFPUnOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 78 SDTCisVec<0>, SDTCisFP<0>, 79 SDTCVecEltisVT<2, i1>, 80 SDTCisSameNumEltsAs<0, 2>, 81 SDTCisVT<3, XLenVT>]>; 82def SDT_RISCVFPBinOp_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>, 83 SDTCisSameAs<0, 2>, 84 SDTCisVec<0>, SDTCisFP<0>, 85 SDTCisSameAs<0, 3>, 86 SDTCVecEltisVT<4, i1>, 87 SDTCisSameNumEltsAs<0, 4>, 88 SDTCisVT<5, XLenVT>]>; 89 90def SDT_RISCVCopySign_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>, 91 SDTCisSameAs<0, 2>, 92 SDTCisVec<0>, SDTCisFP<0>, 93 SDTCisSameAs<0, 3>, 94 SDTCVecEltisVT<4, i1>, 95 SDTCisSameNumEltsAs<0, 4>, 96 SDTCisVT<5, XLenVT>]>; 97 98// VMV_V_V_VL matches the semantics of vmv.v.v but includes an extra operand 99// for the VL value to be used for the operation. The first operand is 100// passthru operand. 101def riscv_vmv_v_v_vl : RVSDNode<"VMV_V_V_VL", 102 SDTypeProfile<1, 3, [SDTCisVec<0>, 103 SDTCisSameAs<0, 1>, 104 SDTCisSameAs<0, 2>, 105 SDTCisVT<3, XLenVT>]>>; 106 107// VMV_V_X_VL matches the semantics of vmv.v.x but includes an extra operand 108// for the VL value to be used for the operation. The first operand is 109// passthru operand. 110def riscv_vmv_v_x_vl : RVSDNode<"VMV_V_X_VL", 111 SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisInt<0>, 112 SDTCisSameAs<0, 1>, 113 SDTCisVT<2, XLenVT>, 114 SDTCisVT<3, XLenVT>]>>; 115 116// VFMV_V_F_VL matches the semantics of vfmv.v.f but includes an extra operand 117// for the VL value to be used for the operation. The first operand is 118// passthru operand. 119def riscv_vfmv_v_f_vl : RVSDNode<"VFMV_V_F_VL", 120 SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisFP<0>, 121 SDTCisSameAs<0, 1>, 122 SDTCisEltOfVec<2, 0>, 123 SDTCisVT<3, XLenVT>]>>; 124 125// VMV_S_X_VL matches the semantics of vmv.s.x. It carries a VL operand. 126def riscv_vmv_s_x_vl : RVSDNode<"VMV_S_X_VL", 127 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 128 SDTCisInt<0>, 129 SDTCisVT<2, XLenVT>, 130 SDTCisVT<3, XLenVT>]>>; 131 132// VFMV_S_F_VL matches the semantics of vfmv.s.f. It carries a VL operand. 133def riscv_vfmv_s_f_vl : RVSDNode<"VFMV_S_F_VL", 134 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 135 SDTCisFP<0>, 136 SDTCisEltOfVec<2, 0>, 137 SDTCisVT<3, XLenVT>]>>; 138 139// Vector binary ops with a passthru as a third operand, a mask as a fourth 140// operand, and VL as a fifth operand. 141let HasPassthruOp = true, HasMaskOp = true in { 142 def riscv_add_vl : RVSDNode<"ADD_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 143 def riscv_sub_vl : RVSDNode<"SUB_VL", SDT_RISCVIntBinOp_VL>; 144 def riscv_mul_vl : RVSDNode<"MUL_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 145 def riscv_mulhs_vl : RVSDNode<"MULHS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 146 def riscv_mulhu_vl : RVSDNode<"MULHU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 147 def riscv_and_vl : RVSDNode<"AND_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 148 def riscv_or_vl : RVSDNode<"OR_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 149 def riscv_xor_vl : RVSDNode<"XOR_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 150 def riscv_sdiv_vl : RVSDNode<"SDIV_VL", SDT_RISCVIntBinOp_VL>; 151 def riscv_srem_vl : RVSDNode<"SREM_VL", SDT_RISCVIntBinOp_VL>; 152 def riscv_udiv_vl : RVSDNode<"UDIV_VL", SDT_RISCVIntBinOp_VL>; 153 def riscv_urem_vl : RVSDNode<"UREM_VL", SDT_RISCVIntBinOp_VL>; 154 def riscv_shl_vl : RVSDNode<"SHL_VL", SDT_RISCVIntBinOp_VL>; 155 def riscv_sra_vl : RVSDNode<"SRA_VL", SDT_RISCVIntBinOp_VL>; 156 def riscv_srl_vl : RVSDNode<"SRL_VL", SDT_RISCVIntBinOp_VL>; 157 def riscv_rotl_vl : RVSDNode<"ROTL_VL", SDT_RISCVIntBinOp_VL>; 158 def riscv_rotr_vl : RVSDNode<"ROTR_VL", SDT_RISCVIntBinOp_VL>; 159 def riscv_smin_vl : RVSDNode<"SMIN_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 160 def riscv_smax_vl : RVSDNode<"SMAX_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 161 def riscv_umin_vl : RVSDNode<"UMIN_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 162 def riscv_umax_vl : RVSDNode<"UMAX_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 163 164 def riscv_bitreverse_vl : RVSDNode<"BITREVERSE_VL", SDT_RISCVIntUnOp_VL>; 165 def riscv_bswap_vl : RVSDNode<"BSWAP_VL", SDT_RISCVIntUnOp_VL>; 166 def riscv_ctlz_vl : RVSDNode<"CTLZ_VL", SDT_RISCVIntUnOp_VL>; 167 def riscv_cttz_vl : RVSDNode<"CTTZ_VL", SDT_RISCVIntUnOp_VL>; 168 def riscv_ctpop_vl : RVSDNode<"CTPOP_VL", SDT_RISCVIntUnOp_VL>; 169 170 // Averaging adds of signed integers. 171 def riscv_avgfloors_vl : RVSDNode<"AVGFLOORS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 172 // Averaging adds of unsigned integers. 173 def riscv_avgflooru_vl : RVSDNode<"AVGFLOORU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 174 // Rounding averaging adds of signed integers. 175 def riscv_avgceils_vl : RVSDNode<"AVGCEILS_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 176 // Rounding averaging adds of unsigned integers. 177 def riscv_avgceilu_vl : RVSDNode<"AVGCEILU_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 178 def riscv_saddsat_vl : RVSDNode<"SADDSAT_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 179 def riscv_uaddsat_vl : RVSDNode<"UADDSAT_VL", SDT_RISCVIntBinOp_VL, [SDNPCommutative]>; 180 def riscv_ssubsat_vl : RVSDNode<"SSUBSAT_VL", SDT_RISCVIntBinOp_VL>; 181 def riscv_usubsat_vl : RVSDNode<"USUBSAT_VL", SDT_RISCVIntBinOp_VL>; 182 183 def riscv_fadd_vl : RVSDNode<"FADD_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>; 184 def riscv_fsub_vl : RVSDNode<"FSUB_VL", SDT_RISCVFPBinOp_VL>; 185 def riscv_fmul_vl : RVSDNode<"FMUL_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>; 186 def riscv_fdiv_vl : RVSDNode<"FDIV_VL", SDT_RISCVFPBinOp_VL>; 187} // let HasPassthruOp = true, HasMaskOp = true 188 189// Vector unary ops with a mask as a second operand and VL as a third operand. 190let HasMaskOp = true in { 191 def riscv_fneg_vl : RVSDNode<"FNEG_VL", SDT_RISCVFPUnOp_VL>; 192 def riscv_fabs_vl : RVSDNode<"FABS_VL", SDT_RISCVFPUnOp_VL>; 193 def riscv_fsqrt_vl : RVSDNode<"FSQRT_VL", SDT_RISCVFPUnOp_VL>; 194} // let HasMaskOp = true 195 196let HasPassthruOp = true, HasMaskOp = true in { 197 def riscv_fcopysign_vl : RVSDNode<"FCOPYSIGN_VL", SDT_RISCVCopySign_VL>; 198 def riscv_vfmin_vl : RVSDNode<"VFMIN_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>; 199 def riscv_vfmax_vl : RVSDNode<"VFMAX_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative]>; 200} // let HasPassthruOp = true, HasMaskOp = true 201 202let IsStrictFP = true, HasPassthruOp = true, HasMaskOp = true in { 203 def riscv_strict_fadd_vl : RVSDNode<"STRICT_FADD_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative, SDNPHasChain]>; 204 def riscv_strict_fsub_vl : RVSDNode<"STRICT_FSUB_VL", SDT_RISCVFPBinOp_VL, [SDNPHasChain]>; 205 def riscv_strict_fmul_vl : RVSDNode<"STRICT_FMUL_VL", SDT_RISCVFPBinOp_VL, [SDNPCommutative, SDNPHasChain]>; 206 def riscv_strict_fdiv_vl : RVSDNode<"STRICT_FDIV_VL", SDT_RISCVFPBinOp_VL, [SDNPHasChain]>; 207} // let IsStrictFP = true, HasPassthruOp = true, HasMaskOp = true 208 209let IsStrictFP = true, HasMaskOp = true in 210def riscv_strict_fsqrt_vl : RVSDNode<"STRICT_FSQRT_VL", SDT_RISCVFPUnOp_VL, [SDNPHasChain]>; 211 212def any_riscv_fadd_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl), 213 [(riscv_fadd_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl), 214 (riscv_strict_fadd_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl)]>; 215def any_riscv_fsub_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl), 216 [(riscv_fsub_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl), 217 (riscv_strict_fsub_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl)]>; 218def any_riscv_fmul_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl), 219 [(riscv_fmul_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl), 220 (riscv_strict_fmul_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl)]>; 221def any_riscv_fdiv_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl), 222 [(riscv_fdiv_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl), 223 (riscv_strict_fdiv_vl node:$lhs, node:$rhs, node:$passthru, node:$mask, node:$vl)]>; 224def any_riscv_fsqrt_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 225 [(riscv_fsqrt_vl node:$src, node:$mask, node:$vl), 226 (riscv_strict_fsqrt_vl node:$src, node:$mask, node:$vl)]>; 227 228let HasMaskOp = true in 229def riscv_fclass_vl : RVSDNode<"FCLASS_VL", 230 SDTypeProfile<1, 3, [SDTCisInt<0>, SDTCisVec<0>, 231 SDTCisFP<1>, SDTCisVec<1>, 232 SDTCisSameSizeAs<0, 1>, 233 SDTCisSameNumEltsAs<0, 1>, 234 SDTCVecEltisVT<2, i1>, 235 SDTCisSameNumEltsAs<0, 2>, 236 SDTCisVT<3, XLenVT>]>>; 237 238def SDT_RISCVVecFMA_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>, 239 SDTCisSameAs<0, 2>, 240 SDTCisSameAs<0, 3>, 241 SDTCisVec<0>, SDTCisFP<0>, 242 SDTCVecEltisVT<4, i1>, 243 SDTCisSameNumEltsAs<0, 4>, 244 SDTCisVT<5, XLenVT>]>; 245 246let HasMaskOp = true in { 247 // Vector FMA ops with a mask as a fourth operand and VL as a fifth operand. 248 def riscv_vfmadd_vl : RVSDNode<"VFMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>; 249 def riscv_vfnmadd_vl : RVSDNode<"VFNMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>; 250 def riscv_vfmsub_vl : RVSDNode<"VFMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>; 251 def riscv_vfnmsub_vl : RVSDNode<"VFNMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative]>; 252} 253 254def SDT_RISCVWVecFMA_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>, 255 SDTCisVec<1>, SDTCisFP<1>, 256 SDTCisOpSmallerThanOp<1, 0>, 257 SDTCisSameNumEltsAs<0, 1>, 258 SDTCisSameAs<1, 2>, 259 SDTCisSameAs<0, 3>, 260 SDTCVecEltisVT<4, i1>, 261 SDTCisSameNumEltsAs<0, 4>, 262 SDTCisVT<5, XLenVT>]>; 263 264let HasMaskOp = true in { 265 // Vector widening FMA ops with a mask as a fourth operand and VL as a fifth 266 // operand. 267 def riscv_vfwmadd_vl : RVSDNode<"VFWMADD_VL", SDT_RISCVWVecFMA_VL, [SDNPCommutative]>; 268 def riscv_vfwnmadd_vl : RVSDNode<"VFWNMADD_VL", SDT_RISCVWVecFMA_VL, [SDNPCommutative]>; 269 def riscv_vfwmsub_vl : RVSDNode<"VFWMSUB_VL", SDT_RISCVWVecFMA_VL, [SDNPCommutative]>; 270 def riscv_vfwnmsub_vl : RVSDNode<"VFWNMSUB_VL", SDT_RISCVWVecFMA_VL, [SDNPCommutative]>; 271 272 let IsStrictFP = true in { 273 def riscv_strict_vfmadd_vl : RVSDNode<"STRICT_VFMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>; 274 def riscv_strict_vfnmadd_vl : RVSDNode<"STRICT_VFNMADD_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>; 275 def riscv_strict_vfmsub_vl : RVSDNode<"STRICT_VFMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>; 276 def riscv_strict_vfnmsub_vl : RVSDNode<"STRICT_VFNMSUB_VL", SDT_RISCVVecFMA_VL, [SDNPCommutative, SDNPHasChain]>; 277 } // let IsStrictFP = true 278} // let HasMaskOp = true 279 280def any_riscv_vfmadd_vl : PatFrags<(ops node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl), 281 [(riscv_vfmadd_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl), 282 (riscv_strict_vfmadd_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl)]>; 283def any_riscv_vfnmadd_vl : PatFrags<(ops node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl), 284 [(riscv_vfnmadd_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl), 285 (riscv_strict_vfnmadd_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl)]>; 286def any_riscv_vfmsub_vl : PatFrags<(ops node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl), 287 [(riscv_vfmsub_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl), 288 (riscv_strict_vfmsub_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl)]>; 289def any_riscv_vfnmsub_vl : PatFrags<(ops node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl), 290 [(riscv_vfnmsub_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl), 291 (riscv_strict_vfnmsub_vl node:$rs1, node:$rs2, node:$rs3, node:$mask, node:$vl)]>; 292 293def SDT_RISCVFPRoundOp_VL : SDTypeProfile<1, 3, [ 294 SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1>, 295 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT> 296]>; 297def SDT_RISCVFPExtendOp_VL : SDTypeProfile<1, 3, [ 298 SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1>, 299 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT> 300]>; 301 302let HasMaskOp = true in { 303 def riscv_fpround_vl : RVSDNode<"FP_ROUND_VL", SDT_RISCVFPRoundOp_VL>; 304 def riscv_fpextend_vl : RVSDNode<"FP_EXTEND_VL", SDT_RISCVFPExtendOp_VL>; 305 306 // Matches the semantics of the vfcnvt.rod function (Convert double-width 307 // float to single-width float, rounding towards odd). Takes a double-width 308 // float vector and produces a single-width float vector. Also has a mask and 309 // VL operand. 310 def riscv_fncvt_rod_vl : RVSDNode<"VFNCVT_ROD_VL", SDT_RISCVFPRoundOp_VL>; 311 312 let IsStrictFP = true in { 313 def riscv_strict_fpround_vl : RVSDNode<"STRICT_FP_ROUND_VL", SDT_RISCVFPRoundOp_VL, [SDNPHasChain]>; 314 def riscv_strict_fpextend_vl : RVSDNode<"STRICT_FP_EXTEND_VL", SDT_RISCVFPExtendOp_VL, [SDNPHasChain]>; 315 def riscv_strict_fncvt_rod_vl : RVSDNode<"STRICT_VFNCVT_ROD_VL", SDT_RISCVFPRoundOp_VL, [SDNPHasChain]>; 316 } // let IsStrictFP = true 317} // let HasMaskOp = true 318 319def any_riscv_fpround_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 320 [(riscv_fpround_vl node:$src, node:$mask, node:$vl), 321 (riscv_strict_fpround_vl node:$src, node:$mask, node:$vl)]>; 322def any_riscv_fpextend_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 323 [(riscv_fpextend_vl node:$src, node:$mask, node:$vl), 324 (riscv_strict_fpextend_vl node:$src, node:$mask, node:$vl)]>; 325def any_riscv_fncvt_rod_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 326 [(riscv_fncvt_rod_vl node:$src, node:$mask, node:$vl), 327 (riscv_strict_fncvt_rod_vl node:$src, node:$mask, node:$vl)]>; 328 329def SDT_RISCVFP2IOp_VL : SDTypeProfile<1, 3, [ 330 SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>, 331 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT> 332]>; 333def SDT_RISCVFP2IOp_RM_VL : SDTypeProfile<1, 4, [ 334 SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>, 335 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT>, 336 SDTCisVT<4, XLenVT> // Rounding mode 337]>; 338 339def SDT_RISCVI2FPOp_VL : SDTypeProfile<1, 3, [ 340 SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1>, 341 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT> 342]>; 343def SDT_RISCVI2FPOp_RM_VL : SDTypeProfile<1, 4, [ 344 SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1>, 345 SDTCVecEltisVT<2, i1>, SDTCisSameNumEltsAs<1, 2>, SDTCisVT<3, XLenVT>, 346 SDTCisVT<4, XLenVT> // Rounding mode 347]>; 348 349def SDT_RISCVSETCCOP_VL : SDTypeProfile<1, 6, [ 350 SDTCVecEltisVT<0, i1>, SDTCisVec<1>, SDTCisSameNumEltsAs<0, 1>, 351 SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>, SDTCisSameAs<0, 4>, 352 SDTCisSameAs<0, 5>, SDTCisVT<6, XLenVT>]>; 353 354// Float -> Int 355 356let HasMaskOp = true in { 357 def riscv_vfcvt_rm_xu_f_vl : RVSDNode<"VFCVT_RM_XU_F_VL", SDT_RISCVFP2IOp_RM_VL>; 358 def riscv_vfcvt_rm_x_f_vl : RVSDNode<"VFCVT_RM_X_F_VL", SDT_RISCVFP2IOp_RM_VL>; 359 360 def riscv_vfcvt_rtz_xu_f_vl : RVSDNode<"VFCVT_RTZ_XU_F_VL", SDT_RISCVFP2IOp_VL>; 361 def riscv_vfcvt_rtz_x_f_vl : RVSDNode<"VFCVT_RTZ_X_F_VL", SDT_RISCVFP2IOp_VL>; 362 363 let IsStrictFP = true in { 364 def riscv_strict_vfcvt_rm_x_f_vl : RVSDNode<"STRICT_VFCVT_RM_X_F_VL", SDT_RISCVFP2IOp_RM_VL, [SDNPHasChain]>; 365 def riscv_strict_vfcvt_rtz_xu_f_vl : RVSDNode<"STRICT_VFCVT_RTZ_XU_F_VL", SDT_RISCVFP2IOp_VL, [SDNPHasChain]>; 366 def riscv_strict_vfcvt_rtz_x_f_vl : RVSDNode<"STRICT_VFCVT_RTZ_X_F_VL", SDT_RISCVFP2IOp_VL, [SDNPHasChain]>; 367 } // let IsStrictFP = true 368} // let HasMaskOp = true 369 370def any_riscv_vfcvt_rm_x_f_vl : PatFrags<(ops node:$src, node:$mask, node:$vl, node:$rm), 371 [(riscv_vfcvt_rm_x_f_vl node:$src, node:$mask, node:$vl, node:$rm), 372 (riscv_strict_vfcvt_rm_x_f_vl node:$src, node:$mask, node:$vl, node:$rm)]>; 373def any_riscv_vfcvt_rtz_xu_f_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 374 [(riscv_vfcvt_rtz_xu_f_vl node:$src, node:$mask, node:$vl), 375 (riscv_strict_vfcvt_rtz_xu_f_vl node:$src, node:$mask, node:$vl)]>; 376def any_riscv_vfcvt_rtz_x_f_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 377 [(riscv_vfcvt_rtz_x_f_vl node:$src, node:$mask, node:$vl), 378 (riscv_strict_vfcvt_rtz_x_f_vl node:$src, node:$mask, node:$vl)]>; 379 380// Int -> Float 381 382let HasMaskOp = true in { 383 def riscv_sint_to_fp_vl : RVSDNode<"SINT_TO_FP_VL", SDT_RISCVI2FPOp_VL>; 384 def riscv_uint_to_fp_vl : RVSDNode<"UINT_TO_FP_VL", SDT_RISCVI2FPOp_VL>; 385 def riscv_vfcvt_rm_f_xu_vl : RVSDNode<"VFCVT_RM_F_XU_VL", SDT_RISCVI2FPOp_RM_VL>; 386 def riscv_vfcvt_rm_f_x_vl : RVSDNode<"VFCVT_RM_F_X_VL", SDT_RISCVI2FPOp_RM_VL>; 387 388 let IsStrictFP = true in { 389 def riscv_strict_sint_to_fp_vl : RVSDNode<"STRICT_SINT_TO_FP_VL", SDT_RISCVI2FPOp_VL, [SDNPHasChain]>; 390 def riscv_strict_uint_to_fp_vl : RVSDNode<"STRICT_UINT_TO_FP_VL", SDT_RISCVI2FPOp_VL, [SDNPHasChain]>; 391 } // let IsStrictFP = true 392} // let HasMaskOp = true 393 394def any_riscv_sint_to_fp_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 395 [(riscv_sint_to_fp_vl node:$src, node:$mask, node:$vl), 396 (riscv_strict_sint_to_fp_vl node:$src, node:$mask, node:$vl)]>; 397def any_riscv_uint_to_fp_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 398 [(riscv_uint_to_fp_vl node:$src, node:$mask, node:$vl), 399 (riscv_strict_uint_to_fp_vl node:$src, node:$mask, node:$vl)]>; 400 401let HasMaskOp = true in { 402 def riscv_vfround_noexcept_vl: RVSDNode<"VFROUND_NOEXCEPT_VL", SDT_RISCVFPUnOp_VL>; 403 404 let IsStrictFP = true in 405 def riscv_strict_vfround_noexcept_vl: RVSDNode<"STRICT_VFROUND_NOEXCEPT_VL", SDT_RISCVFPUnOp_VL, [SDNPHasChain]>; 406} 407 408def any_riscv_vfround_noexcept_vl : PatFrags<(ops node:$src, node:$mask, node:$vl), 409 [(riscv_vfround_noexcept_vl node:$src, node:$mask, node:$vl), 410 (riscv_strict_vfround_noexcept_vl node:$src, node:$mask, node:$vl)]>; 411 412// Vector compare producing a mask. Fourth operand is input mask. Fifth 413// operand is VL. 414let HasPassthruOp = true, HasMaskOp = true in 415def riscv_setcc_vl : RVSDNode<"SETCC_VL", SDT_RISCVSETCCOP_VL>; 416 417let IsStrictFP = true, HasMaskOp = true in { 418 def riscv_strict_fsetcc_vl : RVSDNode<"STRICT_FSETCC_VL", SDT_RISCVSETCCOP_VL, [SDNPHasChain]>; 419 def riscv_strict_fsetccs_vl : RVSDNode<"STRICT_FSETCCS_VL", SDT_RISCVSETCCOP_VL, [SDNPHasChain]>; 420} // let IsStrictFP = true, HasMaskOp = true 421 422def any_riscv_fsetcc_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl), 423 [(riscv_setcc_vl node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl), 424 (riscv_strict_fsetcc_vl node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl)]>; 425def any_riscv_fsetccs_vl : PatFrags<(ops node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl), 426 [(riscv_setcc_vl node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl), 427 (riscv_strict_fsetccs_vl node:$lhs, node:$rhs, node:$cc, node:$passthru, node:$mask, node:$vl)]>; 428 429let HasMaskOp = true in { 430 // Matches the semantics of vrgather.vx and vrgather.vv with extra operands 431 // for passthru and VL, except that out of bound indices result in a poison 432 // result not zero. Operands are (src, index, mask, passthru, vl). 433 def riscv_vrgather_vx_vl : RVSDNode<"VRGATHER_VX_VL", 434 SDTypeProfile<1, 5, [SDTCisVec<0>, 435 SDTCisSameAs<0, 1>, 436 SDTCisVT<2, XLenVT>, 437 SDTCisSameAs<0, 3>, 438 SDTCVecEltisVT<4, i1>, 439 SDTCisSameNumEltsAs<0, 4>, 440 SDTCisVT<5, XLenVT>]>>; 441 def riscv_vrgather_vv_vl : RVSDNode<"VRGATHER_VV_VL", 442 SDTypeProfile<1, 5, [SDTCisVec<0>, 443 SDTCisSameAs<0, 1>, 444 SDTCisInt<2>, 445 SDTCisSameNumEltsAs<0, 2>, 446 SDTCisSameSizeAs<0, 2>, 447 SDTCisSameAs<0, 3>, 448 SDTCVecEltisVT<4, i1>, 449 SDTCisSameNumEltsAs<0, 4>, 450 SDTCisVT<5, XLenVT>]>>; 451 def riscv_vrgatherei16_vv_vl : RVSDNode<"VRGATHEREI16_VV_VL", 452 SDTypeProfile<1, 5, [SDTCisVec<0>, 453 SDTCisSameAs<0, 1>, 454 SDTCisInt<2>, 455 SDTCVecEltisVT<2, i16>, 456 SDTCisSameNumEltsAs<0, 2>, 457 SDTCisSameAs<0, 3>, 458 SDTCVecEltisVT<4, i1>, 459 SDTCisSameNumEltsAs<0, 4>, 460 SDTCisVT<5, XLenVT>]>>; 461} // let HasMaskOp = true 462 463def SDT_RISCVVMERGE_VL : SDTypeProfile<1, 5, [ 464 SDTCisVec<0>, SDTCisVec<1>, SDTCisSameNumEltsAs<0, 1>, SDTCVecEltisVT<1, i1>, 465 SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameAs<0, 4>, 466 SDTCisVT<5, XLenVT> 467]>; 468 469// General vmerge node with mask, true, false, passthru, and vl operands. 470// Tail agnostic vselect can be implemented by setting passthru to undef. 471let HasPassthruOp = true in 472def riscv_vmerge_vl : RVSDNode<"VMERGE_VL", SDT_RISCVVMERGE_VL>; 473 474def SDT_RISCVVMSETCLR_VL : SDTypeProfile<1, 1, [SDTCVecEltisVT<0, i1>, 475 SDTCisVT<1, XLenVT>]>; 476 477// Set mask vector to all zeros or ones. 478def riscv_vmclr_vl : RVSDNode<"VMCLR_VL", SDT_RISCVVMSETCLR_VL>; 479def riscv_vmset_vl : RVSDNode<"VMSET_VL", SDT_RISCVVMSETCLR_VL>; 480 481def SDT_RISCVMaskBinOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 482 SDTCisSameAs<0, 2>, 483 SDTCVecEltisVT<0, i1>, 484 SDTCisVT<3, XLenVT>]>; 485 486// Mask binary operators. 487def riscv_vmand_vl : RVSDNode<"VMAND_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 488def riscv_vmor_vl : RVSDNode<"VMOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 489def riscv_vmxor_vl : RVSDNode<"VMXOR_VL", SDT_RISCVMaskBinOp_VL, [SDNPCommutative]>; 490 491def true_mask : PatLeaf<(riscv_vmset_vl (XLenVT srcvalue))>; 492 493def riscv_vmnot_vl : PatFrag<(ops node:$rs, node:$vl), 494 (riscv_vmxor_vl node:$rs, true_mask, node:$vl)>; 495 496let HasMaskOp = true in { 497 // vcpop.m with additional mask and VL operands. 498 def riscv_vcpop_vl : RVSDNode<"VCPOP_VL", 499 SDTypeProfile<1, 3, [SDTCisVT<0, XLenVT>, 500 SDTCisVec<1>, SDTCisInt<1>, 501 SDTCVecEltisVT<2, i1>, 502 SDTCisSameNumEltsAs<1, 2>, 503 SDTCisVT<3, XLenVT>]>>; 504 505 // vfirst.m with additional mask and VL operands. 506 def riscv_vfirst_vl : RVSDNode<"VFIRST_VL", 507 SDTypeProfile<1, 3, [SDTCisVT<0, XLenVT>, 508 SDTCisVec<1>, SDTCisInt<1>, 509 SDTCVecEltisVT<2, i1>, 510 SDTCisSameNumEltsAs<1, 2>, 511 SDTCisVT<3, XLenVT>]>>; 512} // let HasMaskOp = true 513 514def SDT_RISCVVEXTEND_VL : SDTypeProfile<1, 3, [SDTCisVec<0>, 515 SDTCisSameNumEltsAs<0, 1>, 516 SDTCisSameNumEltsAs<1, 2>, 517 SDTCVecEltisVT<2, i1>, 518 SDTCisVT<3, XLenVT>]>; 519 520let HasMaskOp = true in { 521 // Vector sign/zero extend with additional mask & VL operands. 522 def riscv_sext_vl : RVSDNode<"VSEXT_VL", SDT_RISCVVEXTEND_VL>; 523 def riscv_zext_vl : RVSDNode<"VZEXT_VL", SDT_RISCVVEXTEND_VL>; 524} // let HasMaskOp = true 525 526def riscv_ext_vl : PatFrags<(ops node:$A, node:$B, node:$C), 527 [(riscv_sext_vl node:$A, node:$B, node:$C), 528 (riscv_zext_vl node:$A, node:$B, node:$C)]>; 529 530def SDT_RISCVVTRUNCATE_VL : SDTypeProfile<1, 3, [SDTCisVec<0>, 531 SDTCisSameNumEltsAs<0, 1>, 532 SDTCisSameNumEltsAs<0, 2>, 533 SDTCVecEltisVT<2, i1>, 534 SDTCisVT<3, XLenVT>]>; 535 536let HasMaskOp = true in { 537 // Truncates a RVV integer vector by one power-of-two. Carries both an extra 538 // mask and VL operand. 539 def riscv_trunc_vector_vl : RVSDNode<"TRUNCATE_VECTOR_VL", 540 SDT_RISCVVTRUNCATE_VL>; 541 542 // Truncates a RVV integer vector by one power-of-two. If the value doesn't 543 // fit in the destination type, the result is saturated. These correspond to 544 // vnclip and vnclipu with a shift of 0. Carries both an extra mask and VL 545 // operand. 546 def riscv_trunc_vector_vl_ssat : RVSDNode<"TRUNCATE_VECTOR_VL_SSAT", 547 SDT_RISCVVTRUNCATE_VL>; 548 def riscv_trunc_vector_vl_usat : RVSDNode<"TRUNCATE_VECTOR_VL_USAT", 549 SDT_RISCVVTRUNCATE_VL>; 550} // let HasMaskOp = true 551 552def SDT_RISCVVWIntBinOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>, 553 SDTCisInt<1>, 554 SDTCisSameNumEltsAs<0, 1>, 555 SDTCisOpSmallerThanOp<1, 0>, 556 SDTCisSameAs<1, 2>, 557 SDTCisSameAs<0, 3>, 558 SDTCisSameNumEltsAs<1, 4>, 559 SDTCVecEltisVT<4, i1>, 560 SDTCisVT<5, XLenVT>]>; 561 562let HasPassthruOp = true, HasMaskOp = true in { 563 // Widening instructions with a passthru value a third operand, a mask as a 564 // fourth operand, and VL as a fifth operand. 565 def riscv_vwmul_vl : RVSDNode<"VWMUL_VL", SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>; 566 def riscv_vwmulu_vl : RVSDNode<"VWMULU_VL", SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>; 567 def riscv_vwmulsu_vl : RVSDNode<"VWMULSU_VL", SDT_RISCVVWIntBinOp_VL>; 568 def riscv_vwadd_vl : RVSDNode<"VWADD_VL", SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>; 569 def riscv_vwaddu_vl : RVSDNode<"VWADDU_VL", SDT_RISCVVWIntBinOp_VL, [SDNPCommutative]>; 570 def riscv_vwsub_vl : RVSDNode<"VWSUB_VL", SDT_RISCVVWIntBinOp_VL, []>; 571 def riscv_vwsubu_vl : RVSDNode<"VWSUBU_VL", SDT_RISCVVWIntBinOp_VL, []>; 572 def riscv_vwsll_vl : RVSDNode<"VWSLL_VL", SDT_RISCVVWIntBinOp_VL, []>; 573} // let HasPassthruOp = true, HasMaskOp = true 574 575def SDT_RISCVVWIntTernOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>, 576 SDTCisInt<1>, 577 SDTCisSameNumEltsAs<0, 1>, 578 SDTCisOpSmallerThanOp<1, 0>, 579 SDTCisSameAs<1, 2>, 580 SDTCisSameAs<0, 3>, 581 SDTCisSameNumEltsAs<1, 4>, 582 SDTCVecEltisVT<4, i1>, 583 SDTCisVT<5, XLenVT>]>; 584 585let HasMaskOp = true in { 586 // Widening ternary operations with a mask as the fourth operand and VL as the 587 // fifth operand. 588 def riscv_vwmacc_vl : RVSDNode<"VWMACC_VL", SDT_RISCVVWIntTernOp_VL, [SDNPCommutative]>; 589 def riscv_vwmaccu_vl : RVSDNode<"VWMACCU_VL", SDT_RISCVVWIntTernOp_VL, [SDNPCommutative]>; 590 def riscv_vwmaccsu_vl : RVSDNode<"VWMACCSU_VL", SDT_RISCVVWIntTernOp_VL, []>; 591} // let HasMaskOp = true 592 593def SDT_RISCVVWFPBinOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>, 594 SDTCisFP<1>, 595 SDTCisSameNumEltsAs<0, 1>, 596 SDTCisOpSmallerThanOp<1, 0>, 597 SDTCisSameAs<1, 2>, 598 SDTCisSameAs<0, 3>, 599 SDTCisSameNumEltsAs<1, 4>, 600 SDTCVecEltisVT<4, i1>, 601 SDTCisVT<5, XLenVT>]>; 602 603let HasPassthruOp = true, HasMaskOp = true in { 604 def riscv_vfwmul_vl : RVSDNode<"VFWMUL_VL", SDT_RISCVVWFPBinOp_VL, [SDNPCommutative]>; 605 def riscv_vfwadd_vl : RVSDNode<"VFWADD_VL", SDT_RISCVVWFPBinOp_VL, [SDNPCommutative]>; 606 def riscv_vfwsub_vl : RVSDNode<"VFWSUB_VL", SDT_RISCVVWFPBinOp_VL, []>; 607} // let HasPassthruOp = true, HasMaskOp = true 608 609def SDT_RISCVVWIntBinOpW_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisInt<0>, 610 SDTCisSameAs<0, 1>, 611 SDTCisInt<2>, 612 SDTCisSameNumEltsAs<1, 2>, 613 SDTCisOpSmallerThanOp<2, 1>, 614 SDTCisSameAs<0, 3>, 615 SDTCisSameNumEltsAs<1, 4>, 616 SDTCVecEltisVT<4, i1>, 617 SDTCisVT<5, XLenVT>]>; 618 619let HasPassthruOp = true, HasMaskOp = true in { 620 def riscv_vwadd_w_vl : RVSDNode<"VWADD_W_VL", SDT_RISCVVWIntBinOpW_VL>; 621 def riscv_vwaddu_w_vl : RVSDNode<"VWADDU_W_VL", SDT_RISCVVWIntBinOpW_VL>; 622 def riscv_vwsub_w_vl : RVSDNode<"VWSUB_W_VL", SDT_RISCVVWIntBinOpW_VL>; 623 def riscv_vwsubu_w_vl : RVSDNode<"VWSUBU_W_VL", SDT_RISCVVWIntBinOpW_VL>; 624} // let HasPassthruOp = true, HasMaskOp = true 625 626def SDT_RISCVVWFPBinOpW_VL : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisFP<0>, 627 SDTCisSameAs<0, 1>, 628 SDTCisFP<2>, 629 SDTCisSameNumEltsAs<1, 2>, 630 SDTCisOpSmallerThanOp<2, 1>, 631 SDTCisSameAs<0, 3>, 632 SDTCisSameNumEltsAs<1, 4>, 633 SDTCVecEltisVT<4, i1>, 634 SDTCisVT<5, XLenVT>]>; 635 636let HasPassthruOp = true, HasMaskOp = true in { 637 def riscv_vfwadd_w_vl : RVSDNode<"VFWADD_W_VL", SDT_RISCVVWFPBinOpW_VL>; 638 def riscv_vfwsub_w_vl : RVSDNode<"VFWSUB_W_VL", SDT_RISCVVWFPBinOpW_VL>; 639} // let HasPassthruOp = true, HasMaskOp = true 640 641def SDTRVVVecReduce : SDTypeProfile<1, 6, [ 642 SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisSameAs<0, 3>, 643 SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<2, 4>, SDTCisVT<5, XLenVT>, 644 SDTCisVT<6, XLenVT> 645]>; 646 647let HasOneUse = 1 in { 648 def riscv_add_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 649 node:$E), 650 (riscv_add_vl node:$A, node:$B, node:$C, 651 node:$D, node:$E)>; 652 def riscv_or_vl_is_add_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 653 node:$E), 654 (riscv_or_vl node:$A, node:$B, node:$C, 655 node:$D, node:$E), [{ 656 return orDisjoint(N); 657 }]>; 658 def riscv_sub_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 659 node:$E), 660 (riscv_sub_vl node:$A, node:$B, node:$C, 661 node:$D, node:$E)>; 662 def riscv_mul_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 663 node:$E), 664 (riscv_mul_vl node:$A, node:$B, node:$C, 665 node:$D, node:$E)>; 666 def riscv_vwmul_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 667 node:$E), 668 (riscv_vwmul_vl node:$A, node:$B, node:$C, 669 node:$D, node:$E)>; 670 def riscv_vwmulu_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 671 node:$E), 672 (riscv_vwmulu_vl node:$A, node:$B, node:$C, 673 node:$D, node:$E)>; 674 def riscv_vwmulsu_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 675 node:$E), 676 (riscv_vwmulsu_vl node:$A, node:$B, node:$C, 677 node:$D, node:$E)>; 678 def riscv_sext_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C), 679 (riscv_sext_vl node:$A, node:$B, node:$C)>; 680 def riscv_zext_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C), 681 (riscv_zext_vl node:$A, node:$B, node:$C)>; 682 def riscv_ext_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C), 683 (riscv_ext_vl node:$A, node:$B, node:$C)>; 684 def riscv_fpextend_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C), 685 (riscv_fpextend_vl node:$A, node:$B, node:$C)>; 686 def riscv_vfmadd_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 687 node:$E), 688 (riscv_vfmadd_vl node:$A, node:$B, 689 node:$C, node:$D, node:$E)>; 690 def riscv_vfnmadd_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 691 node:$E), 692 (riscv_vfnmadd_vl node:$A, node:$B, 693 node:$C, node:$D, node:$E)>; 694 def riscv_vfmsub_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 695 node:$E), 696 (riscv_vfmsub_vl node:$A, node:$B, 697 node:$C, node:$D, node:$E)>; 698 def riscv_vfnmsub_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, 699 node:$E), 700 (riscv_vfnmsub_vl node:$A, node:$B, 701 node:$C, node:$D, node:$E)>; 702} // HasOneUse = 1 703 704def riscv_fpextend_vl_sameuser : PatFrag<(ops node:$A, node:$B, node:$C), 705 (riscv_fpextend_vl node:$A, node:$B, node:$C), [{ 706 return !N->use_empty() && all_equal(N->users()); 707}]>; 708 709// These nodes match the semantics of the corresponding RVV vector reduction 710// instructions. They produce a vector result which is the reduction 711// performed over the second vector operand plus the first element of the 712// third vector operand. The first operand is the pass-thru operand. The 713// second operand is an unconstrained vector type, and the result, first, and 714// third operand's types are expected to be the corresponding full-width 715// LMUL=1 type for the second operand: 716// nxv8i8 = vecreduce_add nxv8i8, nxv32i8, nxv8i8 717// nxv2i32 = vecreduce_add nxv2i32, nxv8i32, nxv2i32 718// The different in types does introduce extra vsetvli instructions but 719// similarly it reduces the number of registers consumed per reduction. 720// Also has a mask and VL operand. 721let HasMaskOp = true in 722foreach kind = ["ADD", "UMAX", "SMAX", "UMIN", "SMIN", "AND", "OR", "XOR", 723 "FADD", "SEQ_FADD", "FMIN", "FMAX"] in 724 def rvv_vecreduce_#kind#_vl : RVSDNode<"VECREDUCE_"#kind#"_VL", SDTRVVVecReduce>; 725 726// Give explicit Complexity to prefer simm5/uimm5. 727def SplatPat : ComplexPattern<vAny, 1, "selectVSplat", [], [], 1>; 728def SplatPat_simm5 : ComplexPattern<vAny, 1, "selectVSplatSimm5", [], [], 3>; 729def SplatPat_uimm5 : ComplexPattern<vAny, 1, "selectVSplatUimmBits<5>", [], [], 3>; 730def SplatPat_uimm6 : ComplexPattern<vAny, 1, "selectVSplatUimmBits<6>", [], [], 3>; 731def SplatPat_simm5_plus1 732 : ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1", [], [], 3>; 733def SplatPat_simm5_plus1_nodec 734 : ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1NoDec", [], [], 3>; 735def SplatPat_simm5_plus1_nonzero 736 : ComplexPattern<vAny, 1, "selectVSplatSimm5Plus1NonZero", [], [], 3>; 737def SplatPat_imm64_neg : ComplexPattern<vAny, 1, "selectVSplatImm64Neg", [], [], 3>; 738 739// Selects extends or truncates of splats where we only care about the lowest 8 740// bits of each element. 741def Low8BitsSplatPat 742 : ComplexPattern<vAny, 1, "selectLow8BitsVSplat", [], [], 2>; 743 744// Ignore the vl operand on vmv_v_f, and vmv_s_f. 745def SplatFPOp : PatFrags<(ops node:$op), 746 [(riscv_vfmv_v_f_vl undef, node:$op, srcvalue), 747 (riscv_vfmv_s_f_vl undef, node:$op, srcvalue)]>; 748 749def sew8simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<8>", []>; 750def sew16simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<16>", []>; 751def sew32simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<32>", []>; 752def sew64simm5 : ComplexPattern<XLenVT, 1, "selectRVVSimm5<64>", []>; 753 754class VPatBinaryVL_V<SDPatternOperator vop, 755 string instruction_name, 756 string suffix, 757 ValueType result_type, 758 ValueType op1_type, 759 ValueType op2_type, 760 ValueType mask_type, 761 int log2sew, 762 LMULInfo vlmul, 763 VReg result_reg_class, 764 VReg op1_reg_class, 765 VReg op2_reg_class, 766 bit isSEWAware = 0> 767 : Pat<(result_type (vop 768 (op1_type op1_reg_class:$rs1), 769 (op2_type op2_reg_class:$rs2), 770 (result_type result_reg_class:$passthru), 771 (mask_type VMV0:$vm), 772 VLOpFrag)), 773 (!cast<Instruction>( 774 !if(isSEWAware, 775 instruction_name#"_"#suffix#"_"#vlmul.MX#"_E"#!shl(1, log2sew)#"_MASK", 776 instruction_name#"_"#suffix#"_"#vlmul.MX#"_MASK")) 777 result_reg_class:$passthru, 778 op1_reg_class:$rs1, 779 op2_reg_class:$rs2, 780 (mask_type VMV0:$vm), GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 781 782class VPatBinaryVL_V_RM<SDPatternOperator vop, 783 string instruction_name, 784 string suffix, 785 ValueType result_type, 786 ValueType op1_type, 787 ValueType op2_type, 788 ValueType mask_type, 789 int log2sew, 790 LMULInfo vlmul, 791 VReg result_reg_class, 792 VReg op1_reg_class, 793 VReg op2_reg_class, 794 bit isSEWAware = 0> 795 : Pat<(result_type (vop 796 (op1_type op1_reg_class:$rs1), 797 (op2_type op2_reg_class:$rs2), 798 (result_type result_reg_class:$passthru), 799 (mask_type VMV0:$vm), 800 VLOpFrag)), 801 (!cast<Instruction>( 802 !if(isSEWAware, 803 instruction_name#"_"#suffix#"_"#vlmul.MX#"_E"#!shl(1, log2sew)#"_MASK", 804 instruction_name#"_"#suffix#"_"#vlmul.MX#"_MASK")) 805 result_reg_class:$passthru, 806 op1_reg_class:$rs1, 807 op2_reg_class:$rs2, 808 (mask_type VMV0:$vm), 809 // Value to indicate no rounding mode change in 810 // RISCVInsertReadWriteCSR 811 FRM_DYN, 812 GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 813 814multiclass VPatTiedBinaryNoMaskVL_V<SDNode vop, 815 string instruction_name, 816 string suffix, 817 ValueType result_type, 818 ValueType op2_type, 819 int sew, 820 LMULInfo vlmul, 821 VReg result_reg_class, 822 VReg op2_reg_class> { 823 def : Pat<(result_type (vop 824 (result_type result_reg_class:$rs1), 825 (op2_type op2_reg_class:$rs2), 826 srcvalue, 827 true_mask, 828 VLOpFrag)), 829 (!cast<Instruction>(instruction_name#"_"#suffix#"_"# vlmul.MX#"_TIED") 830 result_reg_class:$rs1, 831 op2_reg_class:$rs2, 832 GPR:$vl, sew, TAIL_AGNOSTIC)>; 833 // Tail undisturbed 834 def : Pat<(riscv_vmerge_vl true_mask, 835 (result_type (vop 836 result_reg_class:$rs1, 837 (op2_type op2_reg_class:$rs2), 838 srcvalue, 839 true_mask, 840 VLOpFrag)), 841 result_reg_class:$rs1, result_reg_class:$rs1, VLOpFrag), 842 (!cast<Instruction>(instruction_name#"_"#suffix#"_"# vlmul.MX#"_TIED") 843 result_reg_class:$rs1, 844 op2_reg_class:$rs2, 845 GPR:$vl, sew, TU_MU)>; 846} 847 848class VPatTiedBinaryMaskVL_V<SDNode vop, 849 string instruction_name, 850 string suffix, 851 ValueType result_type, 852 ValueType op2_type, 853 ValueType mask_type, 854 int sew, 855 LMULInfo vlmul, 856 VReg result_reg_class, 857 VReg op2_reg_class> : 858 Pat<(result_type (vop 859 (result_type result_reg_class:$rs1), 860 (op2_type op2_reg_class:$rs2), 861 (result_type result_reg_class:$rs1), 862 (mask_type VMV0:$vm), 863 VLOpFrag)), 864 (!cast<Instruction>(instruction_name#"_"#suffix#"_"# vlmul.MX#"_MASK_TIED") 865 result_reg_class:$rs1, 866 op2_reg_class:$rs2, 867 (mask_type VMV0:$vm), GPR:$vl, sew, TU_MU)>; 868 869multiclass VPatTiedBinaryNoMaskVL_V_RM<SDNode vop, 870 string instruction_name, 871 string suffix, 872 ValueType result_type, 873 ValueType op2_type, 874 int log2sew, 875 LMULInfo vlmul, 876 VReg result_reg_class, 877 VReg op2_reg_class, 878 bit isSEWAware = 0> { 879 defvar name = !if(isSEWAware, 880 instruction_name#"_"#suffix#"_"#vlmul.MX#"_E"#!shl(1, log2sew)#"_TIED", 881 instruction_name#"_"#suffix#"_"#vlmul.MX#"_TIED"); 882 def : Pat<(result_type (vop 883 (result_type result_reg_class:$rs1), 884 (op2_type op2_reg_class:$rs2), 885 srcvalue, 886 true_mask, 887 VLOpFrag)), 888 (!cast<Instruction>(name) 889 result_reg_class:$rs1, 890 op2_reg_class:$rs2, 891 // Value to indicate no rounding mode change in 892 // RISCVInsertReadWriteCSR 893 FRM_DYN, 894 GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 895 // Tail undisturbed 896 def : Pat<(riscv_vmerge_vl true_mask, 897 (result_type (vop 898 result_reg_class:$rs1, 899 (op2_type op2_reg_class:$rs2), 900 srcvalue, 901 true_mask, 902 VLOpFrag)), 903 result_reg_class:$rs1, result_reg_class:$rs1, VLOpFrag), 904 (!cast<Instruction>(name) 905 result_reg_class:$rs1, 906 op2_reg_class:$rs2, 907 // Value to indicate no rounding mode change in 908 // RISCVInsertReadWriteCSR 909 FRM_DYN, 910 GPR:$vl, log2sew, TU_MU)>; 911} 912 913class VPatBinaryVL_XI<SDPatternOperator vop, 914 string instruction_name, 915 string suffix, 916 ValueType result_type, 917 ValueType vop1_type, 918 ValueType vop2_type, 919 ValueType mask_type, 920 int log2sew, 921 LMULInfo vlmul, 922 VReg result_reg_class, 923 VReg vop_reg_class, 924 ComplexPattern SplatPatKind, 925 DAGOperand xop_kind, 926 bit isSEWAware = 0> 927 : Pat<(result_type (vop 928 (vop1_type vop_reg_class:$rs1), 929 (vop2_type (SplatPatKind (XLenVT xop_kind:$rs2))), 930 (result_type result_reg_class:$passthru), 931 (mask_type VMV0:$vm), 932 VLOpFrag)), 933 (!cast<Instruction>( 934 !if(isSEWAware, 935 instruction_name#_#suffix#_#vlmul.MX#"_E"#!shl(1, log2sew)#"_MASK", 936 instruction_name#_#suffix#_#vlmul.MX#"_MASK")) 937 result_reg_class:$passthru, 938 vop_reg_class:$rs1, 939 xop_kind:$rs2, 940 (mask_type VMV0:$vm), GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 941 942multiclass VPatBinaryVL_VV_VX<SDPatternOperator vop, string instruction_name, 943 list<VTypeInfo> vtilist = AllIntegerVectors, 944 bit isSEWAware = 0> { 945 foreach vti = vtilist in { 946 let Predicates = GetVTypePredicates<vti>.Predicates in { 947 def : VPatBinaryVL_V<vop, instruction_name, "VV", 948 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 949 vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass, 950 vti.RegClass, isSEWAware>; 951 def : VPatBinaryVL_XI<vop, instruction_name, "VX", 952 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 953 vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass, 954 SplatPat, GPR, isSEWAware>; 955 } 956 } 957} 958 959multiclass VPatBinaryVL_VV_VX_VI<SDPatternOperator vop, string instruction_name, 960 Operand ImmType = simm5> 961 : VPatBinaryVL_VV_VX<vop, instruction_name> { 962 foreach vti = AllIntegerVectors in { 963 let Predicates = GetVTypePredicates<vti>.Predicates in 964 def : VPatBinaryVL_XI<vop, instruction_name, "VI", 965 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 966 vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass, 967 !cast<ComplexPattern>(SplatPat#_#ImmType), 968 ImmType>; 969 } 970} 971 972multiclass VPatBinaryWVL_VV_VX<SDPatternOperator vop, string instruction_name> { 973 foreach VtiToWti = AllWidenableIntVectors in { 974 defvar vti = VtiToWti.Vti; 975 defvar wti = VtiToWti.Wti; 976 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 977 GetVTypePredicates<wti>.Predicates) in { 978 def : VPatBinaryVL_V<vop, instruction_name, "VV", 979 wti.Vector, vti.Vector, vti.Vector, vti.Mask, 980 vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass, 981 vti.RegClass>; 982 def : VPatBinaryVL_XI<vop, instruction_name, "VX", 983 wti.Vector, vti.Vector, vti.Vector, vti.Mask, 984 vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass, 985 SplatPat, GPR>; 986 } 987 } 988} 989 990multiclass VPatBinaryWVL_VV_VX_WV_WX<SDPatternOperator vop, SDNode vop_w, 991 string instruction_name> 992 : VPatBinaryWVL_VV_VX<vop, instruction_name> { 993 foreach VtiToWti = AllWidenableIntVectors in { 994 defvar vti = VtiToWti.Vti; 995 defvar wti = VtiToWti.Wti; 996 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 997 GetVTypePredicates<wti>.Predicates) in { 998 defm : VPatTiedBinaryNoMaskVL_V<vop_w, instruction_name, "WV", 999 wti.Vector, vti.Vector, vti.Log2SEW, 1000 vti.LMul, wti.RegClass, vti.RegClass>; 1001 def : VPatTiedBinaryMaskVL_V<vop_w, instruction_name, "WV", 1002 wti.Vector, vti.Vector, wti.Mask, 1003 vti.Log2SEW, vti.LMul, wti.RegClass, 1004 vti.RegClass>; 1005 def : VPatBinaryVL_V<vop_w, instruction_name, "WV", 1006 wti.Vector, wti.Vector, vti.Vector, vti.Mask, 1007 vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass, 1008 vti.RegClass>; 1009 def : VPatBinaryVL_XI<vop_w, instruction_name, "WX", 1010 wti.Vector, wti.Vector, vti.Vector, vti.Mask, 1011 vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass, 1012 SplatPat, GPR>; 1013 } 1014 } 1015} 1016 1017class VPatBinaryVL_VF<SDPatternOperator vop, 1018 string instruction_name, 1019 ValueType result_type, 1020 ValueType vop1_type, 1021 ValueType vop2_type, 1022 ValueType mask_type, 1023 int log2sew, 1024 LMULInfo vlmul, 1025 VReg result_reg_class, 1026 VReg vop_reg_class, 1027 RegisterClass scalar_reg_class, 1028 bit isSEWAware = 0> 1029 : Pat<(result_type (vop (vop1_type vop_reg_class:$rs1), 1030 (vop2_type (SplatFPOp scalar_reg_class:$rs2)), 1031 (result_type result_reg_class:$passthru), 1032 (mask_type VMV0:$vm), 1033 VLOpFrag)), 1034 (!cast<Instruction>( 1035 !if(isSEWAware, 1036 instruction_name#"_"#vlmul.MX#"_E"#!shl(1, log2sew)#"_MASK", 1037 instruction_name#"_"#vlmul.MX#"_MASK")) 1038 result_reg_class:$passthru, 1039 vop_reg_class:$rs1, 1040 scalar_reg_class:$rs2, 1041 (mask_type VMV0:$vm), GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 1042 1043class VPatBinaryVL_VF_RM<SDPatternOperator vop, 1044 string instruction_name, 1045 ValueType result_type, 1046 ValueType vop1_type, 1047 ValueType vop2_type, 1048 ValueType mask_type, 1049 int log2sew, 1050 LMULInfo vlmul, 1051 VReg result_reg_class, 1052 VReg vop_reg_class, 1053 RegisterClass scalar_reg_class, 1054 bit isSEWAware = 0> 1055 : Pat<(result_type (vop (vop1_type vop_reg_class:$rs1), 1056 (vop2_type (SplatFPOp scalar_reg_class:$rs2)), 1057 (result_type result_reg_class:$passthru), 1058 (mask_type VMV0:$vm), 1059 VLOpFrag)), 1060 (!cast<Instruction>( 1061 !if(isSEWAware, 1062 instruction_name#"_"#vlmul.MX#"_E"#!shl(1, log2sew)#"_MASK", 1063 instruction_name#"_"#vlmul.MX#"_MASK")) 1064 result_reg_class:$passthru, 1065 vop_reg_class:$rs1, 1066 scalar_reg_class:$rs2, 1067 (mask_type VMV0:$vm), 1068 // Value to indicate no rounding mode change in 1069 // RISCVInsertReadWriteCSR 1070 FRM_DYN, 1071 GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 1072 1073multiclass VPatBinaryFPVL_VV_VF<SDPatternOperator vop, string instruction_name, 1074 bit isSEWAware = 0> { 1075 foreach vti = AllFloatVectors in { 1076 let Predicates = GetVTypePredicates<vti>.Predicates in { 1077 def : VPatBinaryVL_V<vop, instruction_name, "VV", 1078 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 1079 vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass, 1080 vti.RegClass, isSEWAware>; 1081 def : VPatBinaryVL_VF<vop, instruction_name#"_V"#vti.ScalarSuffix, 1082 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 1083 vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass, 1084 vti.ScalarRegClass, isSEWAware>; 1085 } 1086 } 1087} 1088 1089multiclass VPatBinaryFPVL_VV_VF_RM<SDPatternOperator vop, string instruction_name, 1090 bit isSEWAware = 0> { 1091 foreach vti = AllFloatVectors in { 1092 let Predicates = GetVTypePredicates<vti>.Predicates in { 1093 def : VPatBinaryVL_V_RM<vop, instruction_name, "VV", 1094 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 1095 vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass, 1096 vti.RegClass, isSEWAware>; 1097 def : VPatBinaryVL_VF_RM<vop, instruction_name#"_V"#vti.ScalarSuffix, 1098 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 1099 vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass, 1100 vti.ScalarRegClass, isSEWAware>; 1101 } 1102 } 1103} 1104 1105multiclass VPatBinaryFPVL_R_VF<SDPatternOperator vop, string instruction_name, 1106 bit isSEWAware = 0> { 1107 foreach fvti = AllFloatVectors in { 1108 let Predicates = GetVTypePredicates<fvti>.Predicates in 1109 def : Pat<(fvti.Vector (vop (SplatFPOp fvti.ScalarRegClass:$rs2), 1110 fvti.RegClass:$rs1, 1111 (fvti.Vector fvti.RegClass:$passthru), 1112 (fvti.Mask VMV0:$vm), 1113 VLOpFrag)), 1114 (!cast<Instruction>( 1115 !if(isSEWAware, 1116 instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK", 1117 instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_MASK")) 1118 fvti.RegClass:$passthru, 1119 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 1120 (fvti.Mask VMV0:$vm), GPR:$vl, fvti.Log2SEW, TAIL_AGNOSTIC)>; 1121 } 1122} 1123 1124multiclass VPatBinaryFPVL_R_VF_RM<SDPatternOperator vop, string instruction_name, 1125 bit isSEWAware = 0> { 1126 foreach fvti = AllFloatVectors in { 1127 let Predicates = GetVTypePredicates<fvti>.Predicates in 1128 def : Pat<(fvti.Vector (vop (SplatFPOp fvti.ScalarRegClass:$rs2), 1129 fvti.RegClass:$rs1, 1130 (fvti.Vector fvti.RegClass:$passthru), 1131 (fvti.Mask VMV0:$vm), 1132 VLOpFrag)), 1133 (!cast<Instruction>( 1134 !if(isSEWAware, 1135 instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK", 1136 instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_MASK")) 1137 fvti.RegClass:$passthru, 1138 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 1139 (fvti.Mask VMV0:$vm), 1140 // Value to indicate no rounding mode change in 1141 // RISCVInsertReadWriteCSR 1142 FRM_DYN, 1143 GPR:$vl, fvti.Log2SEW, TAIL_AGNOSTIC)>; 1144 } 1145} 1146 1147multiclass VPatIntegerSetCCVL_VV<VTypeInfo vti, string instruction_name, 1148 CondCode cc> { 1149 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 1150 vti.RegClass:$rs2, cc, 1151 VR:$passthru, 1152 (vti.Mask VMV0:$vm), 1153 VLOpFrag)), 1154 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX#"_MASK") 1155 VR:$passthru, 1156 vti.RegClass:$rs1, 1157 vti.RegClass:$rs2, 1158 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MU)>; 1159} 1160 1161// Inherits from VPatIntegerSetCCVL_VV and adds a pattern with operands swapped. 1162multiclass VPatIntegerSetCCVL_VV_Swappable<VTypeInfo vti, string instruction_name, 1163 CondCode cc, CondCode invcc> 1164 : VPatIntegerSetCCVL_VV<vti, instruction_name, cc> { 1165 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs2), 1166 vti.RegClass:$rs1, invcc, 1167 VR:$passthru, 1168 (vti.Mask VMV0:$vm), 1169 VLOpFrag)), 1170 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX#"_MASK") 1171 VR:$passthru, vti.RegClass:$rs1, 1172 vti.RegClass:$rs2, (vti.Mask VMV0:$vm), GPR:$vl, 1173 vti.Log2SEW, TA_MU)>; 1174} 1175 1176multiclass VPatIntegerSetCCVL_VX_Swappable<VTypeInfo vti, string instruction_name, 1177 CondCode cc, CondCode invcc> { 1178 defvar instruction_masked = !cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX#"_MASK"); 1179 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 1180 (SplatPat (XLenVT GPR:$rs2)), cc, 1181 VR:$passthru, 1182 (vti.Mask VMV0:$vm), 1183 VLOpFrag)), 1184 (instruction_masked VR:$passthru, vti.RegClass:$rs1, 1185 GPR:$rs2, (vti.Mask VMV0:$vm), GPR:$vl, 1186 vti.Log2SEW, TA_MU)>; 1187 def : Pat<(vti.Mask (riscv_setcc_vl (SplatPat (XLenVT GPR:$rs2)), 1188 (vti.Vector vti.RegClass:$rs1), invcc, 1189 VR:$passthru, 1190 (vti.Mask VMV0:$vm), 1191 VLOpFrag)), 1192 (instruction_masked VR:$passthru, vti.RegClass:$rs1, 1193 GPR:$rs2, (vti.Mask VMV0:$vm), GPR:$vl, 1194 vti.Log2SEW, TA_MU)>; 1195} 1196 1197multiclass VPatIntegerSetCCVL_VI_Swappable<VTypeInfo vti, string instruction_name, 1198 CondCode cc, CondCode invcc, 1199 ComplexPattern splatpat_kind = SplatPat_simm5> { 1200 defvar instruction_masked = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX#"_MASK"); 1201 def : Pat<(vti.Mask (riscv_setcc_vl (vti.Vector vti.RegClass:$rs1), 1202 (splatpat_kind simm5:$rs2), cc, 1203 VR:$passthru, 1204 (vti.Mask VMV0:$vm), 1205 VLOpFrag)), 1206 (instruction_masked VR:$passthru, vti.RegClass:$rs1, 1207 XLenVT:$rs2, (vti.Mask VMV0:$vm), GPR:$vl, 1208 vti.Log2SEW, TA_MU)>; 1209 1210 // FIXME: Can do some canonicalization to remove these patterns. 1211 def : Pat<(vti.Mask (riscv_setcc_vl (splatpat_kind simm5:$rs2), 1212 (vti.Vector vti.RegClass:$rs1), invcc, 1213 VR:$passthru, 1214 (vti.Mask VMV0:$vm), 1215 VLOpFrag)), 1216 (instruction_masked VR:$passthru, vti.RegClass:$rs1, 1217 simm5:$rs2, (vti.Mask VMV0:$vm), GPR:$vl, 1218 vti.Log2SEW, TA_MU)>; 1219} 1220 1221multiclass VPatFPSetCCVL_VV_VF_FV<SDPatternOperator vop, CondCode cc, 1222 string inst_name, 1223 string swapped_op_inst_name> { 1224 foreach fvti = AllFloatVectors in { 1225 let Predicates = GetVTypePredicates<fvti>.Predicates in { 1226 def : Pat<(fvti.Mask (vop (fvti.Vector fvti.RegClass:$rs1), 1227 fvti.RegClass:$rs2, 1228 cc, 1229 VR:$passthru, 1230 (fvti.Mask VMV0:$vm), 1231 VLOpFrag)), 1232 (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX#"_MASK") 1233 VR:$passthru, fvti.RegClass:$rs1, 1234 fvti.RegClass:$rs2, (fvti.Mask VMV0:$vm), 1235 GPR:$vl, fvti.Log2SEW, TA_MU)>; 1236 def : Pat<(fvti.Mask (vop (fvti.Vector fvti.RegClass:$rs1), 1237 (SplatFPOp fvti.ScalarRegClass:$rs2), 1238 cc, 1239 VR:$passthru, 1240 (fvti.Mask VMV0:$vm), 1241 VLOpFrag)), 1242 (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_MASK") 1243 VR:$passthru, fvti.RegClass:$rs1, 1244 fvti.ScalarRegClass:$rs2, (fvti.Mask VMV0:$vm), 1245 GPR:$vl, fvti.Log2SEW, TA_MU)>; 1246 def : Pat<(fvti.Mask (vop (SplatFPOp fvti.ScalarRegClass:$rs2), 1247 (fvti.Vector fvti.RegClass:$rs1), 1248 cc, 1249 VR:$passthru, 1250 (fvti.Mask VMV0:$vm), 1251 VLOpFrag)), 1252 (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_MASK") 1253 VR:$passthru, fvti.RegClass:$rs1, 1254 fvti.ScalarRegClass:$rs2, (fvti.Mask VMV0:$vm), 1255 GPR:$vl, fvti.Log2SEW, TA_MU)>; 1256 } 1257 } 1258} 1259 1260multiclass VPatExtendVL_V<SDNode vop, string inst_name, string suffix, 1261 list <VTypeInfoToFraction> fraction_list> { 1262 foreach vtiTofti = fraction_list in { 1263 defvar vti = vtiTofti.Vti; 1264 defvar fti = vtiTofti.Fti; 1265 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1266 GetVTypePredicates<fti>.Predicates) in 1267 def : Pat<(vti.Vector (vop (fti.Vector fti.RegClass:$rs2), 1268 (fti.Mask VMV0:$vm), VLOpFrag)), 1269 (!cast<Instruction>(inst_name#"_"#suffix#"_"#vti.LMul.MX#"_MASK") 1270 (vti.Vector (IMPLICIT_DEF)), 1271 fti.RegClass:$rs2, 1272 (fti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 1273 } 1274} 1275 1276// Single width converting 1277 1278multiclass VPatConvertFP2IVL_V<SDPatternOperator vop, string instruction_name> { 1279 foreach fvti = AllFloatVectors in { 1280 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 1281 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 1282 GetVTypePredicates<ivti>.Predicates) in 1283 def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1), 1284 (fvti.Mask VMV0:$vm), 1285 VLOpFrag)), 1286 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX#"_MASK") 1287 (ivti.Vector (IMPLICIT_DEF)), fvti.RegClass:$rs1, 1288 (fvti.Mask VMV0:$vm), GPR:$vl, ivti.Log2SEW, TA_MA)>; 1289 } 1290} 1291 1292 1293multiclass VPatConvertFP2I_RM_VL_V<SDPatternOperator vop, string instruction_name> { 1294 foreach fvti = AllFloatVectors in { 1295 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 1296 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 1297 GetVTypePredicates<ivti>.Predicates) in 1298 def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1), 1299 (fvti.Mask VMV0:$vm), (XLenVT timm:$frm), 1300 VLOpFrag)), 1301 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX#"_MASK") 1302 (ivti.Vector (IMPLICIT_DEF)), fvti.RegClass:$rs1, 1303 (fvti.Mask VMV0:$vm), timm:$frm, GPR:$vl, ivti.Log2SEW, 1304 TA_MA)>; 1305 } 1306} 1307 1308multiclass VPatConvertI2FPVL_V_RM<SDPatternOperator vop, string instruction_name> { 1309 foreach fvti = AllFloatVectors in { 1310 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 1311 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 1312 GetVTypePredicates<ivti>.Predicates) in 1313 def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1), 1314 (ivti.Mask VMV0:$vm), 1315 VLOpFrag)), 1316 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 1317 (fvti.Vector (IMPLICIT_DEF)), ivti.RegClass:$rs1, 1318 (ivti.Mask VMV0:$vm), 1319 // Value to indicate no rounding mode change in 1320 // RISCVInsertReadWriteCSR 1321 FRM_DYN, 1322 GPR:$vl, fvti.Log2SEW, TA_MA)>; 1323 } 1324} 1325 1326multiclass VPatConvertI2FP_RM_VL_V<SDNode vop, string instruction_name> { 1327 foreach fvti = AllFloatVectors in { 1328 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 1329 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 1330 GetVTypePredicates<ivti>.Predicates) in 1331 def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1), 1332 (ivti.Mask VMV0:$vm), (XLenVT timm:$frm), 1333 VLOpFrag)), 1334 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 1335 (fvti.Vector (IMPLICIT_DEF)), ivti.RegClass:$rs1, 1336 (ivti.Mask VMV0:$vm), timm:$frm, GPR:$vl, fvti.Log2SEW, TA_MA)>; 1337 } 1338} 1339 1340// Widening converting 1341 1342multiclass VPatWConvertFP2IVL_V<SDPatternOperator vop, string instruction_name> { 1343 foreach fvtiToFWti = AllWidenableFloatVectors in { 1344 defvar fvti = fvtiToFWti.Vti; 1345 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 1346 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 1347 GetVTypePredicates<iwti>.Predicates) in 1348 def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1), 1349 (fvti.Mask VMV0:$vm), 1350 VLOpFrag)), 1351 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_MASK") 1352 (iwti.Vector (IMPLICIT_DEF)), fvti.RegClass:$rs1, 1353 (fvti.Mask VMV0:$vm), GPR:$vl, fvti.Log2SEW, TA_MA)>; 1354 } 1355} 1356 1357 1358multiclass VPatWConvertFP2I_RM_VL_V<SDNode vop, string instruction_name> { 1359 foreach fvtiToFWti = AllWidenableFloatVectors in { 1360 defvar fvti = fvtiToFWti.Vti; 1361 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 1362 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 1363 GetVTypePredicates<iwti>.Predicates) in 1364 def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1), 1365 (fvti.Mask VMV0:$vm), (XLenVT timm:$frm), 1366 VLOpFrag)), 1367 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_MASK") 1368 (iwti.Vector (IMPLICIT_DEF)), fvti.RegClass:$rs1, 1369 (fvti.Mask VMV0:$vm), timm:$frm, GPR:$vl, fvti.Log2SEW, TA_MA)>; 1370 } 1371} 1372 1373multiclass VPatWConvertI2FPVL_V<SDPatternOperator vop, 1374 string instruction_name> { 1375 foreach vtiToWti = AllWidenableIntToFloatVectors in { 1376 defvar ivti = vtiToWti.Vti; 1377 defvar fwti = vtiToWti.Wti; 1378 let Predicates = !listconcat(GetVTypePredicates<ivti>.Predicates, 1379 GetVTypePredicates<fwti>.Predicates) in 1380 def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1), 1381 (ivti.Mask VMV0:$vm), 1382 VLOpFrag)), 1383 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX#"_E"#ivti.SEW#"_MASK") 1384 (fwti.Vector (IMPLICIT_DEF)), ivti.RegClass:$rs1, 1385 (ivti.Mask VMV0:$vm), 1386 GPR:$vl, ivti.Log2SEW, TA_MA)>; 1387 } 1388} 1389 1390// Narrowing converting 1391 1392multiclass VPatNConvertFP2IVL_W<SDPatternOperator vop, 1393 string instruction_name> { 1394 // Reuse the same list of types used in the widening nodes, but just swap the 1395 // direction of types around so we're converting from Wti -> Vti 1396 foreach vtiToWti = AllWidenableIntToFloatVectors in { 1397 defvar vti = vtiToWti.Vti; 1398 defvar fwti = vtiToWti.Wti; 1399 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1400 GetVTypePredicates<fwti>.Predicates) in 1401 def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1), 1402 (fwti.Mask VMV0:$vm), 1403 VLOpFrag)), 1404 (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX#"_MASK") 1405 (vti.Vector (IMPLICIT_DEF)), fwti.RegClass:$rs1, 1406 (fwti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 1407 } 1408} 1409 1410multiclass VPatNConvertFP2I_RM_VL_W<SDNode vop, string instruction_name> { 1411 foreach vtiToWti = AllWidenableIntToFloatVectors in { 1412 defvar vti = vtiToWti.Vti; 1413 defvar fwti = vtiToWti.Wti; 1414 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1415 GetVTypePredicates<fwti>.Predicates) in 1416 def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1), 1417 (fwti.Mask VMV0:$vm), (XLenVT timm:$frm), 1418 VLOpFrag)), 1419 (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX#"_MASK") 1420 (vti.Vector (IMPLICIT_DEF)), fwti.RegClass:$rs1, 1421 (fwti.Mask VMV0:$vm), timm:$frm, GPR:$vl, vti.Log2SEW, TA_MA)>; 1422 } 1423} 1424 1425multiclass VPatNConvertI2FPVL_W_RM<SDPatternOperator vop, 1426 string instruction_name> { 1427 foreach fvtiToFWti = AllWidenableFloatVectors in { 1428 defvar fvti = fvtiToFWti.Vti; 1429 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 1430 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 1431 GetVTypePredicates<iwti>.Predicates) in 1432 def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1), 1433 (iwti.Mask VMV0:$vm), 1434 VLOpFrag)), 1435 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 1436 (fvti.Vector (IMPLICIT_DEF)), iwti.RegClass:$rs1, 1437 (iwti.Mask VMV0:$vm), 1438 // Value to indicate no rounding mode change in 1439 // RISCVInsertReadWriteCSR 1440 FRM_DYN, 1441 GPR:$vl, fvti.Log2SEW, TA_MA)>; 1442 } 1443} 1444 1445multiclass VPatNConvertI2FP_RM_VL_W<SDNode vop, string instruction_name> { 1446 foreach fvtiToFWti = AllWidenableFloatVectors in { 1447 defvar fvti = fvtiToFWti.Vti; 1448 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 1449 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 1450 GetVTypePredicates<iwti>.Predicates) in 1451 def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1), 1452 (iwti.Mask VMV0:$vm), (XLenVT timm:$frm), 1453 VLOpFrag)), 1454 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 1455 (fvti.Vector (IMPLICIT_DEF)), iwti.RegClass:$rs1, 1456 (iwti.Mask VMV0:$vm), timm:$frm, GPR:$vl, fvti.Log2SEW, TA_MA)>; 1457 } 1458} 1459 1460multiclass VPatReductionVL<SDNode vop, string instruction_name, bit is_float> { 1461 foreach vti = !if(is_float, AllFloatVectors, AllIntegerVectors) in { 1462 defvar vti_m1 = !cast<VTypeInfo>(!if(is_float, "VF", "VI") # vti.SEW # "M1"); 1463 let Predicates = GetVTypePredicates<vti>.Predicates in { 1464 def: Pat<(vti_m1.Vector (vop (vti_m1.Vector VR:$passthru), 1465 (vti.Vector vti.RegClass:$rs1), VR:$rs2, 1466 (vti.Mask VMV0:$vm), VLOpFrag, 1467 (XLenVT timm:$policy))), 1468 (!cast<Instruction>(instruction_name#"_VS_"#vti.LMul.MX#"_E"#vti.SEW#"_MASK") 1469 (vti_m1.Vector VR:$passthru), 1470 (vti.Vector vti.RegClass:$rs1), 1471 (vti_m1.Vector VR:$rs2), 1472 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, (XLenVT timm:$policy))>; 1473 } 1474 } 1475} 1476 1477multiclass VPatReductionVL_RM<SDNode vop, string instruction_name, bit is_float> { 1478 foreach vti = !if(is_float, AllFloatVectors, AllIntegerVectors) in { 1479 defvar vti_m1 = !cast<VTypeInfo>(!if(is_float, "VF", "VI") # vti.SEW # "M1"); 1480 let Predicates = GetVTypePredicates<vti>.Predicates in { 1481 def: Pat<(vti_m1.Vector (vop (vti_m1.Vector VR:$passthru), 1482 (vti.Vector vti.RegClass:$rs1), VR:$rs2, 1483 (vti.Mask VMV0:$vm), VLOpFrag, 1484 (XLenVT timm:$policy))), 1485 (!cast<Instruction>(instruction_name#"_VS_"#vti.LMul.MX#"_E"#vti.SEW#"_MASK") 1486 (vti_m1.Vector VR:$passthru), 1487 (vti.Vector vti.RegClass:$rs1), 1488 (vti_m1.Vector VR:$rs2), 1489 (vti.Mask VMV0:$vm), 1490 // Value to indicate no rounding mode change in 1491 // RISCVInsertReadWriteCSR 1492 FRM_DYN, 1493 GPR:$vl, vti.Log2SEW, (XLenVT timm:$policy))>; 1494 } 1495 } 1496} 1497 1498multiclass VPatBinaryVL_WV_WX_WI<SDNode op, string instruction_name> { 1499 foreach vtiToWti = AllWidenableIntVectors in { 1500 defvar vti = vtiToWti.Vti; 1501 defvar wti = vtiToWti.Wti; 1502 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1503 GetVTypePredicates<wti>.Predicates) in { 1504 def : Pat< 1505 (vti.Vector 1506 (riscv_trunc_vector_vl 1507 (op (wti.Vector wti.RegClass:$rs2), 1508 (wti.Vector (ext_oneuse (vti.Vector vti.RegClass:$rs1)))), 1509 (vti.Mask true_mask), 1510 VLOpFrag)), 1511 (!cast<Instruction>(instruction_name#"_WV_"#vti.LMul.MX) 1512 (vti.Vector (IMPLICIT_DEF)), 1513 wti.RegClass:$rs2, vti.RegClass:$rs1, GPR:$vl, vti.Log2SEW, TA_MA)>; 1514 1515 def : Pat< 1516 (vti.Vector 1517 (riscv_trunc_vector_vl 1518 (op (wti.Vector wti.RegClass:$rs2), 1519 (wti.Vector (Low8BitsSplatPat (XLenVT GPR:$rs1)))), 1520 (vti.Mask true_mask), 1521 VLOpFrag)), 1522 (!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX) 1523 (vti.Vector (IMPLICIT_DEF)), 1524 wti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.Log2SEW, TA_MA)>; 1525 1526 def : Pat< 1527 (vti.Vector 1528 (riscv_trunc_vector_vl 1529 (op (wti.Vector wti.RegClass:$rs2), 1530 (wti.Vector (SplatPat_uimm5 uimm5:$rs1))), (vti.Mask true_mask), 1531 VLOpFrag)), 1532 (!cast<Instruction>(instruction_name#"_WI_"#vti.LMul.MX) 1533 (vti.Vector (IMPLICIT_DEF)), 1534 wti.RegClass:$rs2, uimm5:$rs1, GPR:$vl, vti.Log2SEW, TA_MA)>; 1535 } 1536 } 1537} 1538 1539multiclass VPatWidenReductionVL<SDNode vop, PatFrags extop, string instruction_name, bit is_float> { 1540 foreach vtiToWti = !if(is_float, AllWidenableFloatVectors, AllWidenableIntVectors) in { 1541 defvar vti = vtiToWti.Vti; 1542 defvar wti = vtiToWti.Wti; 1543 defvar wti_m1 = !cast<VTypeInfo>(!if(is_float, "VF", "VI") # wti.SEW # "M1"); 1544 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1545 GetVTypePredicates<wti>.Predicates) in { 1546 def: Pat<(wti_m1.Vector (vop (wti_m1.Vector VR:$passthru), 1547 (wti.Vector (extop (vti.Vector vti.RegClass:$rs1))), 1548 VR:$rs2, (vti.Mask VMV0:$vm), VLOpFrag, 1549 (XLenVT timm:$policy))), 1550 (!cast<Instruction>(instruction_name#"_VS_"#vti.LMul.MX#"_E"#vti.SEW#"_MASK") 1551 (wti_m1.Vector VR:$passthru), (vti.Vector vti.RegClass:$rs1), 1552 (wti_m1.Vector VR:$rs2), (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 1553 (XLenVT timm:$policy))>; 1554 } 1555 } 1556} 1557 1558multiclass VPatWidenReductionVL_Ext_VL<SDNode vop, PatFrags extop, string instruction_name, bit is_float> { 1559 foreach vtiToWti = !if(is_float, AllWidenableFloatVectors, AllWidenableIntVectors) in { 1560 defvar vti = vtiToWti.Vti; 1561 defvar wti = vtiToWti.Wti; 1562 defvar wti_m1 = !cast<VTypeInfo>(!if(is_float, "VF", "VI") # wti.SEW # "M1"); 1563 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1564 GetVTypePredicates<wti>.Predicates) in { 1565 def: Pat<(wti_m1.Vector (vop (wti_m1.Vector VR:$passthru), 1566 (wti.Vector (extop (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), (XLenVT srcvalue))), 1567 VR:$rs2, (vti.Mask VMV0:$vm), VLOpFrag, 1568 (XLenVT timm:$policy))), 1569 (!cast<Instruction>(instruction_name#"_VS_"#vti.LMul.MX#"_E"#vti.SEW#"_MASK") 1570 (wti_m1.Vector VR:$passthru), (vti.Vector vti.RegClass:$rs1), 1571 (wti_m1.Vector VR:$rs2), (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 1572 (XLenVT timm:$policy))>; 1573 } 1574 } 1575} 1576 1577multiclass VPatWidenReductionVL_Ext_VL_RM<SDNode vop, PatFrags extop, string instruction_name, bit is_float> { 1578 foreach vtiToWti = !if(is_float, AllWidenableFloatVectors, AllWidenableIntVectors) in { 1579 defvar vti = vtiToWti.Vti; 1580 defvar wti = vtiToWti.Wti; 1581 defvar wti_m1 = !cast<VTypeInfo>(!if(is_float, "VF", "VI") # wti.SEW # "M1"); 1582 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1583 GetVTypePredicates<wti>.Predicates) in { 1584 def: Pat<(wti_m1.Vector (vop (wti_m1.Vector VR:$passthru), 1585 (wti.Vector (extop (vti.Vector vti.RegClass:$rs1), (vti.Mask true_mask), (XLenVT srcvalue))), 1586 VR:$rs2, (vti.Mask VMV0:$vm), VLOpFrag, 1587 (XLenVT timm:$policy))), 1588 (!cast<Instruction>(instruction_name#"_VS_"#vti.LMul.MX#"_E"#vti.SEW#"_MASK") 1589 (wti_m1.Vector VR:$passthru), (vti.Vector vti.RegClass:$rs1), 1590 (wti_m1.Vector VR:$rs2), (vti.Mask VMV0:$vm), 1591 // Value to indicate no rounding mode change in 1592 // RISCVInsertReadWriteCSR 1593 FRM_DYN, 1594 GPR:$vl, vti.Log2SEW, 1595 (XLenVT timm:$policy))>; 1596 } 1597 } 1598} 1599 1600multiclass VPatBinaryFPWVL_VV_VF<SDNode vop, string instruction_name> { 1601 foreach fvtiToFWti = AllWidenableFloatVectors in { 1602 defvar vti = fvtiToFWti.Vti; 1603 defvar wti = fvtiToFWti.Wti; 1604 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1605 GetVTypePredicates<wti>.Predicates) in { 1606 def : VPatBinaryVL_V<vop, instruction_name, "VV", 1607 wti.Vector, vti.Vector, vti.Vector, vti.Mask, 1608 vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass, 1609 vti.RegClass>; 1610 def : VPatBinaryVL_VF<vop, instruction_name#"_V"#vti.ScalarSuffix, 1611 wti.Vector, vti.Vector, vti.Vector, vti.Mask, 1612 vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass, 1613 vti.ScalarRegClass>; 1614 } 1615 } 1616} 1617 1618multiclass VPatBinaryFPWVL_VV_VF_RM<SDNode vop, string instruction_name, 1619 bit isSEWAware = 0> { 1620 foreach fvtiToFWti = AllWidenableFloatVectors in { 1621 defvar vti = fvtiToFWti.Vti; 1622 defvar wti = fvtiToFWti.Wti; 1623 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1624 GetVTypePredicates<wti>.Predicates) in { 1625 def : VPatBinaryVL_V_RM<vop, instruction_name, "VV", 1626 wti.Vector, vti.Vector, vti.Vector, vti.Mask, 1627 vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass, 1628 vti.RegClass, isSEWAware>; 1629 def : VPatBinaryVL_VF_RM<vop, instruction_name#"_V"#vti.ScalarSuffix, 1630 wti.Vector, vti.Vector, vti.Vector, vti.Mask, 1631 vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass, 1632 vti.ScalarRegClass, isSEWAware>; 1633 } 1634 } 1635} 1636 1637multiclass VPatBinaryFPWVL_VV_VF_WV_WF<SDNode vop, SDNode vop_w, string instruction_name> 1638 : VPatBinaryFPWVL_VV_VF<vop, instruction_name> { 1639 foreach fvtiToFWti = AllWidenableFloatVectors in { 1640 defvar vti = fvtiToFWti.Vti; 1641 defvar wti = fvtiToFWti.Wti; 1642 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1643 GetVTypePredicates<wti>.Predicates) in { 1644 defm : VPatTiedBinaryNoMaskVL_V<vop_w, instruction_name, "WV", 1645 wti.Vector, vti.Vector, vti.Log2SEW, 1646 vti.LMul, wti.RegClass, vti.RegClass>; 1647 def : VPatBinaryVL_V<vop_w, instruction_name, "WV", 1648 wti.Vector, wti.Vector, vti.Vector, vti.Mask, 1649 vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass, 1650 vti.RegClass>; 1651 def : VPatBinaryVL_VF<vop_w, instruction_name#"_W"#vti.ScalarSuffix, 1652 wti.Vector, wti.Vector, vti.Vector, vti.Mask, 1653 vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass, 1654 vti.ScalarRegClass>; 1655 } 1656 } 1657} 1658 1659multiclass VPatBinaryFPWVL_VV_VF_WV_WF_RM< 1660 SDNode vop, SDNode vop_w, string instruction_name, bit isSEWAware = 0> 1661 : VPatBinaryFPWVL_VV_VF_RM<vop, instruction_name, isSEWAware> { 1662 foreach fvtiToFWti = AllWidenableFloatVectors in { 1663 defvar vti = fvtiToFWti.Vti; 1664 defvar wti = fvtiToFWti.Wti; 1665 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1666 GetVTypePredicates<wti>.Predicates) in { 1667 defm : VPatTiedBinaryNoMaskVL_V_RM<vop_w, instruction_name, "WV", 1668 wti.Vector, vti.Vector, vti.Log2SEW, 1669 vti.LMul, wti.RegClass, vti.RegClass, 1670 isSEWAware>; 1671 def : VPatBinaryVL_V_RM<vop_w, instruction_name, "WV", 1672 wti.Vector, wti.Vector, vti.Vector, vti.Mask, 1673 vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass, 1674 vti.RegClass, isSEWAware>; 1675 def : VPatBinaryVL_VF_RM<vop_w, instruction_name#"_W"#vti.ScalarSuffix, 1676 wti.Vector, wti.Vector, vti.Vector, vti.Mask, 1677 vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass, 1678 vti.ScalarRegClass, isSEWAware>; 1679 } 1680 } 1681} 1682 1683multiclass VPatNarrowShiftSplatExt_WX<SDNode op, PatFrags extop, string instruction_name> { 1684 foreach vtiToWti = AllWidenableIntVectors in { 1685 defvar vti = vtiToWti.Vti; 1686 defvar wti = vtiToWti.Wti; 1687 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1688 GetVTypePredicates<wti>.Predicates) in 1689 def : Pat< 1690 (vti.Vector 1691 (riscv_trunc_vector_vl 1692 (op (wti.Vector wti.RegClass:$rs2), 1693 (wti.Vector (extop (vti.Vector (SplatPat (XLenVT GPR:$rs1))), 1694 (vti.Mask true_mask), VLOpFrag)), 1695 srcvalue, (wti.Mask true_mask), VLOpFrag), 1696 (vti.Mask true_mask), VLOpFrag)), 1697 (!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX) 1698 (vti.Vector (IMPLICIT_DEF)), 1699 wti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.Log2SEW, TA_MA)>; 1700 } 1701} 1702 1703multiclass VPatNarrowShiftExtVL_WV<SDNode op, PatFrags extop, string instruction_name> { 1704 foreach vtiToWti = AllWidenableIntVectors in { 1705 defvar vti = vtiToWti.Vti; 1706 defvar wti = vtiToWti.Wti; 1707 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1708 GetVTypePredicates<wti>.Predicates) in 1709 def : Pat< 1710 (vti.Vector 1711 (riscv_trunc_vector_vl 1712 (op (wti.Vector wti.RegClass:$rs2), 1713 (wti.Vector (extop (vti.Vector vti.RegClass:$rs1), 1714 (vti.Mask true_mask), VLOpFrag)), 1715 srcvalue, (vti.Mask true_mask), VLOpFrag), 1716 (vti.Mask VMV0:$vm), VLOpFrag)), 1717 (!cast<Instruction>(instruction_name#"_WV_"#vti.LMul.MX#"_MASK") 1718 (vti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2, vti.RegClass:$rs1, 1719 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 1720 } 1721} 1722 1723multiclass VPatNarrowShiftVL_WV<SDNode op, string instruction_name> { 1724 defm : VPatNarrowShiftExtVL_WV<op, riscv_sext_vl_oneuse, instruction_name>; 1725 defm : VPatNarrowShiftExtVL_WV<op, riscv_zext_vl_oneuse, instruction_name>; 1726} 1727 1728multiclass VPatMultiplyAddVL_VV_VX<SDNode op, string instruction_name> { 1729 foreach vti = AllIntegerVectors in { 1730 defvar suffix = vti.LMul.MX; 1731 let Predicates = GetVTypePredicates<vti>.Predicates in { 1732 // NOTE: We choose VMADD because it has the most commuting freedom. So it 1733 // works best with how TwoAddressInstructionPass tries commuting. 1734 def : Pat<(vti.Vector 1735 (op vti.RegClass:$rs2, 1736 (riscv_mul_vl_oneuse vti.RegClass:$rs1, 1737 vti.RegClass:$rd, 1738 srcvalue, (vti.Mask true_mask), VLOpFrag), 1739 srcvalue, (vti.Mask true_mask), VLOpFrag)), 1740 (!cast<Instruction>(instruction_name#"_VV_"# suffix) 1741 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1742 GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 1743 // The choice of VMADD here is arbitrary, vmadd.vx and vmacc.vx are equally 1744 // commutable. 1745 def : Pat<(vti.Vector 1746 (op vti.RegClass:$rs2, 1747 (riscv_mul_vl_oneuse (SplatPat XLenVT:$rs1), 1748 vti.RegClass:$rd, 1749 srcvalue, (vti.Mask true_mask), VLOpFrag), 1750 srcvalue, (vti.Mask true_mask), VLOpFrag)), 1751 (!cast<Instruction>(instruction_name#"_VX_" # suffix) 1752 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 1753 GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 1754 } 1755 } 1756} 1757 1758multiclass VPatMultiplyAccVL_VV_VX<PatFrag op, string instruction_name> { 1759 foreach vti = AllIntegerVectors in { 1760 defvar suffix = vti.LMul.MX; 1761 let Predicates = GetVTypePredicates<vti>.Predicates in { 1762 def : Pat<(riscv_vmerge_vl (vti.Mask VMV0:$vm), 1763 (vti.Vector (op vti.RegClass:$rd, 1764 (riscv_mul_vl_oneuse vti.RegClass:$rs1, vti.RegClass:$rs2, 1765 srcvalue, (vti.Mask true_mask), VLOpFrag), 1766 srcvalue, (vti.Mask true_mask), VLOpFrag)), 1767 vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag), 1768 (!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK") 1769 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1770 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TU_MU)>; 1771 def : Pat<(riscv_vmerge_vl (vti.Mask VMV0:$vm), 1772 (vti.Vector (op vti.RegClass:$rd, 1773 (riscv_mul_vl_oneuse (SplatPat XLenVT:$rs1), vti.RegClass:$rs2, 1774 srcvalue, (vti.Mask true_mask), VLOpFrag), 1775 srcvalue, (vti.Mask true_mask), VLOpFrag)), 1776 vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag), 1777 (!cast<Instruction>(instruction_name#"_VX_"# suffix #"_MASK") 1778 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 1779 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TU_MU)>; 1780 def : Pat<(riscv_vmerge_vl (vti.Mask VMV0:$vm), 1781 (vti.Vector (op vti.RegClass:$rd, 1782 (riscv_mul_vl_oneuse vti.RegClass:$rs1, vti.RegClass:$rs2, 1783 srcvalue, (vti.Mask true_mask), VLOpFrag), 1784 srcvalue, (vti.Mask true_mask), VLOpFrag)), 1785 vti.RegClass:$rd, undef, VLOpFrag), 1786 (!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK") 1787 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1788 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 1789 def : Pat<(riscv_vmerge_vl (vti.Mask VMV0:$vm), 1790 (vti.Vector (op vti.RegClass:$rd, 1791 (riscv_mul_vl_oneuse (SplatPat XLenVT:$rs1), vti.RegClass:$rs2, 1792 srcvalue, (vti.Mask true_mask), VLOpFrag), 1793 srcvalue, (vti.Mask true_mask), VLOpFrag)), 1794 vti.RegClass:$rd, undef, VLOpFrag), 1795 (!cast<Instruction>(instruction_name#"_VX_"# suffix #"_MASK") 1796 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 1797 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 1798 } 1799 } 1800} 1801 1802multiclass VPatWidenMultiplyAddVL_VV_VX<SDNode vwmacc_op, string instr_name> { 1803 foreach vtiTowti = AllWidenableIntVectors in { 1804 defvar vti = vtiTowti.Vti; 1805 defvar wti = vtiTowti.Wti; 1806 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1807 GetVTypePredicates<wti>.Predicates) in { 1808 def : Pat<(vwmacc_op (vti.Vector vti.RegClass:$rs1), 1809 (vti.Vector vti.RegClass:$rs2), 1810 (wti.Vector wti.RegClass:$rd), 1811 (vti.Mask VMV0:$vm), VLOpFrag), 1812 (!cast<Instruction>(instr_name#"_VV_"#vti.LMul.MX#"_MASK") 1813 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1814 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 1815 def : Pat<(vwmacc_op (SplatPat XLenVT:$rs1), 1816 (vti.Vector vti.RegClass:$rs2), 1817 (wti.Vector wti.RegClass:$rd), 1818 (vti.Mask VMV0:$vm), VLOpFrag), 1819 (!cast<Instruction>(instr_name#"_VX_"#vti.LMul.MX#"_MASK") 1820 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, 1821 vti.RegClass:$rs2, (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 1822 TAIL_AGNOSTIC)>; 1823 } 1824 } 1825} 1826 1827multiclass VPatNarrowShiftSplat_WX_WI<SDNode op, string instruction_name> { 1828 foreach vtiTowti = AllWidenableIntVectors in { 1829 defvar vti = vtiTowti.Vti; 1830 defvar wti = vtiTowti.Wti; 1831 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1832 GetVTypePredicates<wti>.Predicates) in { 1833 def : Pat<(vti.Vector (riscv_trunc_vector_vl 1834 (wti.Vector (op wti.RegClass:$rs1, (SplatPat XLenVT:$rs2), 1835 srcvalue, true_mask, VLOpFrag)), true_mask, VLOpFrag)), 1836 (!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX) 1837 (vti.Vector (IMPLICIT_DEF)), 1838 wti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW, TA_MA)>; 1839 def : Pat<(vti.Vector (riscv_trunc_vector_vl 1840 (wti.Vector (op wti.RegClass:$rs1, (SplatPat_uimm5 uimm5:$rs2), 1841 srcvalue, true_mask, VLOpFrag)), true_mask, VLOpFrag)), 1842 (!cast<Instruction>(instruction_name#"_WI_"#vti.LMul.MX) 1843 (vti.Vector (IMPLICIT_DEF)), 1844 wti.RegClass:$rs1, uimm5:$rs2, GPR:$vl, vti.Log2SEW, TA_MA)>; 1845 } 1846 } 1847} 1848 1849multiclass VPatFPMulAddVL_VV_VF<SDPatternOperator vop, string instruction_name> { 1850 foreach vti = AllFloatVectors in { 1851 defvar suffix = vti.LMul.MX; 1852 let Predicates = GetVTypePredicates<vti>.Predicates in { 1853 def : Pat<(vti.Vector (vop vti.RegClass:$rs1, vti.RegClass:$rd, 1854 vti.RegClass:$rs2, (vti.Mask VMV0:$vm), 1855 VLOpFrag)), 1856 (!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK") 1857 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1858 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 1859 1860 def : Pat<(vti.Vector (vop (SplatFPOp vti.ScalarRegClass:$rs1), 1861 vti.RegClass:$rd, vti.RegClass:$rs2, 1862 (vti.Mask VMV0:$vm), 1863 VLOpFrag)), 1864 (!cast<Instruction>(instruction_name#"_V" # vti.ScalarSuffix # "_" # suffix # "_MASK") 1865 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 1866 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 1867 } 1868 } 1869} 1870 1871multiclass VPatFPMulAddVL_VV_VF_RM<SDPatternOperator vop, string instruction_name> { 1872 foreach vti = AllFloatVectors in { 1873 defvar suffix = vti.LMul.MX # "_E" # vti.SEW; 1874 let Predicates = GetVTypePredicates<vti>.Predicates in { 1875 def : Pat<(vti.Vector (vop vti.RegClass:$rs1, vti.RegClass:$rd, 1876 vti.RegClass:$rs2, (vti.Mask VMV0:$vm), 1877 VLOpFrag)), 1878 (!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK") 1879 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1880 (vti.Mask VMV0:$vm), 1881 // Value to indicate no rounding mode change in 1882 // RISCVInsertReadWriteCSR 1883 FRM_DYN, 1884 GPR:$vl, vti.Log2SEW, TA_MA)>; 1885 1886 def : Pat<(vti.Vector (vop (SplatFPOp vti.ScalarRegClass:$rs1), 1887 vti.RegClass:$rd, vti.RegClass:$rs2, 1888 (vti.Mask VMV0:$vm), 1889 VLOpFrag)), 1890 (!cast<Instruction>(instruction_name#"_V" # vti.ScalarSuffix # "_" # suffix # "_MASK") 1891 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 1892 (vti.Mask VMV0:$vm), 1893 // Value to indicate no rounding mode change in 1894 // RISCVInsertReadWriteCSR 1895 FRM_DYN, 1896 GPR:$vl, vti.Log2SEW, TA_MA)>; 1897 } 1898 } 1899} 1900 1901multiclass VPatFPMulAccVL_VV_VF_RM<PatFrag vop, string instruction_name> { 1902 foreach vti = AllFloatVectors in { 1903 defvar suffix = vti.LMul.MX # "_E" # vti.SEW; 1904 let Predicates = GetVTypePredicates<vti>.Predicates in { 1905 def : Pat<(riscv_vmerge_vl (vti.Mask VMV0:$vm), 1906 (vti.Vector (vop vti.RegClass:$rs1, vti.RegClass:$rs2, 1907 vti.RegClass:$rd, (vti.Mask true_mask), VLOpFrag)), 1908 vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag), 1909 (!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK") 1910 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1911 (vti.Mask VMV0:$vm), 1912 // Value to indicate no rounding mode change in 1913 // RISCVInsertReadWriteCSR 1914 FRM_DYN, 1915 GPR:$vl, vti.Log2SEW, TU_MU)>; 1916 def : Pat<(riscv_vmerge_vl (vti.Mask VMV0:$vm), 1917 (vti.Vector (vop (SplatFPOp vti.ScalarRegClass:$rs1), vti.RegClass:$rs2, 1918 vti.RegClass:$rd, (vti.Mask true_mask), VLOpFrag)), 1919 vti.RegClass:$rd, vti.RegClass:$rd, VLOpFrag), 1920 (!cast<Instruction>(instruction_name#"_V" # vti.ScalarSuffix # "_" # suffix # "_MASK") 1921 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 1922 (vti.Mask VMV0:$vm), 1923 // Value to indicate no rounding mode change in 1924 // RISCVInsertReadWriteCSR 1925 FRM_DYN, 1926 GPR:$vl, vti.Log2SEW, TU_MU)>; 1927 def : Pat<(riscv_vmerge_vl (vti.Mask VMV0:$vm), 1928 (vti.Vector (vop vti.RegClass:$rs1, vti.RegClass:$rs2, 1929 vti.RegClass:$rd, (vti.Mask true_mask), VLOpFrag)), 1930 vti.RegClass:$rd, undef, VLOpFrag), 1931 (!cast<Instruction>(instruction_name#"_VV_"# suffix #"_MASK") 1932 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1933 (vti.Mask VMV0:$vm), 1934 // Value to indicate no rounding mode change in 1935 // RISCVInsertReadWriteCSR 1936 FRM_DYN, 1937 GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 1938 def : Pat<(riscv_vmerge_vl (vti.Mask VMV0:$vm), 1939 (vti.Vector (vop (SplatFPOp vti.ScalarRegClass:$rs1), vti.RegClass:$rs2, 1940 vti.RegClass:$rd, (vti.Mask true_mask), VLOpFrag)), 1941 vti.RegClass:$rd, undef, VLOpFrag), 1942 (!cast<Instruction>(instruction_name#"_V" # vti.ScalarSuffix # "_" # suffix # "_MASK") 1943 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 1944 (vti.Mask VMV0:$vm), 1945 // Value to indicate no rounding mode change in 1946 // RISCVInsertReadWriteCSR 1947 FRM_DYN, 1948 GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 1949 } 1950 } 1951} 1952 1953multiclass VPatWidenFPMulAccVL_VV_VF<SDNode vop, string instruction_name> { 1954 foreach vtiToWti = AllWidenableFloatVectors in { 1955 defvar vti = vtiToWti.Vti; 1956 defvar wti = vtiToWti.Wti; 1957 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1958 GetVTypePredicates<wti>.Predicates) in { 1959 def : Pat<(vop (vti.Vector vti.RegClass:$rs1), 1960 (vti.Vector vti.RegClass:$rs2), 1961 (wti.Vector wti.RegClass:$rd), (vti.Mask VMV0:$vm), 1962 VLOpFrag), 1963 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX #"_MASK") 1964 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1965 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 1966 def : Pat<(vop (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 1967 (vti.Vector vti.RegClass:$rs2), 1968 (wti.Vector wti.RegClass:$rd), (vti.Mask VMV0:$vm), 1969 VLOpFrag), 1970 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX #"_MASK") 1971 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 1972 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 1973 } 1974 } 1975} 1976 1977multiclass VPatWidenFPMulAccVL_VV_VF_RM<SDNode vop, string instruction_name, 1978 list<VTypeInfoToWide> vtiToWtis = 1979 AllWidenableFloatVectors> { 1980 foreach vtiToWti = vtiToWtis in { 1981 defvar vti = vtiToWti.Vti; 1982 defvar wti = vtiToWti.Wti; 1983 defvar suffix = vti.LMul.MX # "_E" # vti.SEW; 1984 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 1985 GetVTypePredicates<wti>.Predicates, 1986 !if(!eq(vti.Scalar, bf16), 1987 [HasStdExtZvfbfwma], 1988 [])) in { 1989 def : Pat<(vop (vti.Vector vti.RegClass:$rs1), 1990 (vti.Vector vti.RegClass:$rs2), 1991 (wti.Vector wti.RegClass:$rd), (vti.Mask VMV0:$vm), 1992 VLOpFrag), 1993 (!cast<Instruction>(instruction_name#"_VV_"#suffix#"_MASK") 1994 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 1995 (vti.Mask VMV0:$vm), 1996 // Value to indicate no rounding mode change in 1997 // RISCVInsertReadWriteCSR 1998 FRM_DYN, 1999 GPR:$vl, vti.Log2SEW, TA_MA)>; 2000 def : Pat<(vop (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 2001 (vti.Vector vti.RegClass:$rs2), 2002 (wti.Vector wti.RegClass:$rd), (vti.Mask VMV0:$vm), 2003 VLOpFrag), 2004 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix#"_MASK") 2005 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 2006 (vti.Mask VMV0:$vm), 2007 // Value to indicate no rounding mode change in 2008 // RISCVInsertReadWriteCSR 2009 FRM_DYN, 2010 GPR:$vl, vti.Log2SEW, TA_MA)>; 2011 } 2012 } 2013} 2014 2015multiclass VPatSlideVL_VX_VI<SDNode vop, string instruction_name> { 2016 foreach vti = AllVectors in { 2017 defvar ivti = GetIntVTypeInfo<vti>.Vti; 2018 let Predicates = GetVTypePredicates<ivti>.Predicates in { 2019 def : Pat<(vti.Vector (vop (vti.Vector vti.RegClass:$rd), 2020 (vti.Vector vti.RegClass:$rs1), 2021 uimm5:$rs2, (vti.Mask VMV0:$vm), 2022 VLOpFrag, (XLenVT timm:$policy))), 2023 (!cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX#"_MASK") 2024 vti.RegClass:$rd, vti.RegClass:$rs1, uimm5:$rs2, 2025 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 2026 (XLenVT timm:$policy))>; 2027 2028 def : Pat<(vti.Vector (vop (vti.Vector vti.RegClass:$rd), 2029 (vti.Vector vti.RegClass:$rs1), 2030 GPR:$rs2, (vti.Mask VMV0:$vm), 2031 VLOpFrag, (XLenVT timm:$policy))), 2032 (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX#"_MASK") 2033 vti.RegClass:$rd, vti.RegClass:$rs1, GPR:$rs2, 2034 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 2035 (XLenVT timm:$policy))>; 2036 } 2037 } 2038} 2039 2040multiclass VPatSlide1VL_VX<SDNode vop, string instruction_name> { 2041 foreach vti = AllIntegerVectors in { 2042 let Predicates = GetVTypePredicates<vti>.Predicates in { 2043 def : Pat<(vti.Vector (vop (vti.Vector vti.RegClass:$rs3), 2044 (vti.Vector vti.RegClass:$rs1), 2045 GPR:$rs2, (vti.Mask VMV0:$vm), VLOpFrag)), 2046 (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX#"_MASK") 2047 vti.RegClass:$rs3, vti.RegClass:$rs1, GPR:$rs2, 2048 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TU_MU)>; 2049 } 2050 } 2051} 2052 2053multiclass VPatSlide1VL_VF<SDNode vop, string instruction_name> { 2054 foreach vti = AllFloatVectors in { 2055 let Predicates = GetVTypePredicates<vti>.Predicates in { 2056 def : Pat<(vti.Vector (vop (vti.Vector vti.RegClass:$rs3), 2057 (vti.Vector vti.RegClass:$rs1), 2058 vti.Scalar:$rs2, (vti.Mask VMV0:$vm), VLOpFrag)), 2059 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_MASK") 2060 vti.RegClass:$rs3, vti.RegClass:$rs1, vti.Scalar:$rs2, 2061 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TU_MU)>; 2062 } 2063 } 2064} 2065 2066multiclass VPatAVGADDVL_VV_VX_RM<SDNode vop, int vxrm, string suffix = ""> { 2067 foreach vti = AllIntegerVectors in { 2068 let Predicates = GetVTypePredicates<vti>.Predicates in { 2069 def : Pat<(vop (vti.Vector vti.RegClass:$rs1), 2070 (vti.Vector vti.RegClass:$rs2), 2071 vti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag), 2072 (!cast<Instruction>("PseudoVAADD"#suffix#"_VV_"#vti.LMul.MX#"_MASK") 2073 vti.RegClass:$passthru, vti.RegClass:$rs1, vti.RegClass:$rs2, 2074 (vti.Mask VMV0:$vm), vxrm, GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2075 def : Pat<(vop (vti.Vector vti.RegClass:$rs1), 2076 (vti.Vector (SplatPat (XLenVT GPR:$rs2))), 2077 vti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag), 2078 (!cast<Instruction>("PseudoVAADD"#suffix#"_VX_"#vti.LMul.MX#"_MASK") 2079 vti.RegClass:$passthru, vti.RegClass:$rs1, GPR:$rs2, 2080 (vti.Mask VMV0:$vm), vxrm, GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2081 } 2082 } 2083} 2084 2085//===----------------------------------------------------------------------===// 2086// Patterns. 2087//===----------------------------------------------------------------------===// 2088 2089// 11. Vector Integer Arithmetic Instructions 2090 2091// 11.1. Vector Single-Width Integer Add and Subtract 2092defm : VPatBinaryVL_VV_VX_VI<riscv_add_vl, "PseudoVADD">; 2093defm : VPatBinaryVL_VV_VX<riscv_sub_vl, "PseudoVSUB">; 2094foreach vti = AllIntegerVectors in { 2095 let Predicates = GetVTypePredicates<vti>.Predicates in { 2096 // Handle VRSUB specially since it's the only integer binary op with 2097 // reversed pattern operands 2098 def : Pat<(riscv_sub_vl (vti.Vector (SplatPat (XLenVT GPR:$rs2))), 2099 (vti.Vector vti.RegClass:$rs1), 2100 vti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag), 2101 (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX#"_MASK") 2102 vti.RegClass:$passthru, vti.RegClass:$rs1, GPR:$rs2, 2103 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2104 def : Pat<(riscv_sub_vl (vti.Vector (SplatPat_simm5 simm5:$rs2)), 2105 (vti.Vector vti.RegClass:$rs1), 2106 vti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag), 2107 (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX#"_MASK") 2108 vti.RegClass:$passthru, vti.RegClass:$rs1, simm5:$rs2, 2109 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2110 2111 // Match VSUB with a small immediate to vadd.vi by negating the immediate. 2112 def : Pat<(riscv_sub_vl (vti.Vector vti.RegClass:$rs1), 2113 (vti.Vector (SplatPat_simm5_plus1_nodec simm5_plus1:$rs2)), 2114 vti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag), 2115 (!cast<Instruction>("PseudoVADD_VI_"#vti.LMul.MX#"_MASK") 2116 vti.RegClass:$passthru, vti.RegClass:$rs1, 2117 (NegImm simm5_plus1:$rs2), (vti.Mask VMV0:$vm), 2118 GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2119 } 2120} 2121 2122// (add v, C) -> (sub v, -C) if -C cheaper to materialize 2123foreach vti = I64IntegerVectors in { 2124 let Predicates = [HasVInstructionsI64] in { 2125 def : Pat<(riscv_add_vl (vti.Vector vti.RegClass:$rs1), 2126 (vti.Vector (SplatPat_imm64_neg i64:$rs2)), 2127 vti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag), 2128 (!cast<Instruction>("PseudoVSUB_VX_"#vti.LMul.MX#"_MASK") 2129 vti.RegClass:$passthru, vti.RegClass:$rs1, 2130 negImm:$rs2, (vti.Mask VMV0:$vm), 2131 GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2132 } 2133} 2134 2135// 11.2. Vector Widening Integer Add/Subtract 2136defm : VPatBinaryWVL_VV_VX_WV_WX<riscv_vwadd_vl, riscv_vwadd_w_vl, "PseudoVWADD">; 2137defm : VPatBinaryWVL_VV_VX_WV_WX<riscv_vwaddu_vl, riscv_vwaddu_w_vl, "PseudoVWADDU">; 2138defm : VPatBinaryWVL_VV_VX_WV_WX<riscv_vwsub_vl, riscv_vwsub_w_vl, "PseudoVWSUB">; 2139defm : VPatBinaryWVL_VV_VX_WV_WX<riscv_vwsubu_vl, riscv_vwsubu_w_vl, "PseudoVWSUBU">; 2140 2141// shl_vl (ext_vl v, splat 1) is a special case of widening add. 2142foreach vtiToWti = AllWidenableIntVectors in { 2143 defvar vti = vtiToWti.Vti; 2144 defvar wti = vtiToWti.Wti; 2145 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 2146 GetVTypePredicates<wti>.Predicates) in { 2147 def : Pat<(riscv_shl_vl (wti.Vector (riscv_sext_vl_oneuse 2148 (vti.Vector vti.RegClass:$rs1), 2149 (vti.Mask VMV0:$vm), VLOpFrag)), 2150 (wti.Vector (riscv_vmv_v_x_vl 2151 (wti.Vector undef), 1, VLOpFrag)), 2152 wti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag), 2153 (!cast<Instruction>("PseudoVWADD_VV_"#vti.LMul.MX#"_MASK") 2154 wti.RegClass:$passthru, vti.RegClass:$rs1, vti.RegClass:$rs1, 2155 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2156 def : Pat<(riscv_shl_vl (wti.Vector (riscv_zext_vl_oneuse 2157 (vti.Vector vti.RegClass:$rs1), 2158 (vti.Mask VMV0:$vm), VLOpFrag)), 2159 (wti.Vector (riscv_vmv_v_x_vl 2160 (wti.Vector undef), 1, VLOpFrag)), 2161 wti.RegClass:$passthru, (vti.Mask VMV0:$vm), VLOpFrag), 2162 (!cast<Instruction>("PseudoVWADDU_VV_"#vti.LMul.MX#"_MASK") 2163 wti.RegClass:$passthru, vti.RegClass:$rs1, vti.RegClass:$rs1, 2164 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2165 } 2166} 2167 2168// DAGCombiner::hoistLogicOpWithSameOpcodeHands may hoist disjoint ors 2169// to (ext (or disjoint (a, b))) 2170multiclass VPatWidenOrDisjointVL_VV_VX<SDNode extop, string instruction_name> { 2171 foreach vtiToWti = AllWidenableIntVectors in { 2172 defvar vti = vtiToWti.Vti; 2173 defvar wti = vtiToWti.Wti; 2174 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 2175 GetVTypePredicates<wti>.Predicates) in { 2176 def : Pat<(wti.Vector 2177 (extop 2178 (vti.Vector 2179 (riscv_or_vl_is_add_oneuse 2180 vti.RegClass:$rs2, vti.RegClass:$rs1, 2181 undef, srcvalue, srcvalue)), 2182 VMV0:$vm, VLOpFrag)), 2183 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX#"_MASK") 2184 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 2185 vti.RegClass:$rs1, VMV0:$vm, GPR:$vl, vti.Log2SEW, TA_MA)>; 2186 def : Pat<(wti.Vector 2187 (extop 2188 (vti.Vector 2189 (riscv_or_vl_is_add_oneuse 2190 vti.RegClass:$rs2, (SplatPat (XLenVT GPR:$rs1)), 2191 undef, srcvalue, srcvalue)), 2192 VMV0:$vm, VLOpFrag)), 2193 (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX#"_MASK") 2194 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 2195 GPR:$rs1, VMV0:$vm, GPR:$vl, vti.Log2SEW, TA_MA)>; 2196 } 2197 } 2198} 2199 2200defm : VPatWidenOrDisjointVL_VV_VX<riscv_sext_vl, "PseudoVWADD">; 2201defm : VPatWidenOrDisjointVL_VV_VX<riscv_zext_vl, "PseudoVWADDU">; 2202 2203// 11.3. Vector Integer Extension 2204defm : VPatExtendVL_V<riscv_zext_vl, "PseudoVZEXT", "VF2", 2205 AllFractionableVF2IntVectors>; 2206defm : VPatExtendVL_V<riscv_sext_vl, "PseudoVSEXT", "VF2", 2207 AllFractionableVF2IntVectors>; 2208defm : VPatExtendVL_V<riscv_zext_vl, "PseudoVZEXT", "VF4", 2209 AllFractionableVF4IntVectors>; 2210defm : VPatExtendVL_V<riscv_sext_vl, "PseudoVSEXT", "VF4", 2211 AllFractionableVF4IntVectors>; 2212defm : VPatExtendVL_V<riscv_zext_vl, "PseudoVZEXT", "VF8", 2213 AllFractionableVF8IntVectors>; 2214defm : VPatExtendVL_V<riscv_sext_vl, "PseudoVSEXT", "VF8", 2215 AllFractionableVF8IntVectors>; 2216 2217// 11.5. Vector Bitwise Logical Instructions 2218defm : VPatBinaryVL_VV_VX_VI<riscv_and_vl, "PseudoVAND">; 2219defm : VPatBinaryVL_VV_VX_VI<riscv_or_vl, "PseudoVOR">; 2220defm : VPatBinaryVL_VV_VX_VI<riscv_xor_vl, "PseudoVXOR">; 2221 2222// 11.6. Vector Single-Width Bit Shift Instructions 2223defm : VPatBinaryVL_VV_VX_VI<riscv_shl_vl, "PseudoVSLL", uimm5>; 2224defm : VPatBinaryVL_VV_VX_VI<riscv_srl_vl, "PseudoVSRL", uimm5>; 2225defm : VPatBinaryVL_VV_VX_VI<riscv_sra_vl, "PseudoVSRA", uimm5>; 2226 2227foreach vti = AllIntegerVectors in { 2228 // Emit shift by 1 as an add since it might be faster. 2229 let Predicates = GetVTypePredicates<vti>.Predicates in 2230 def : Pat<(riscv_shl_vl (vti.Vector vti.RegClass:$rs1), 2231 (riscv_vmv_v_x_vl (vti.Vector undef), 1, (XLenVT srcvalue)), 2232 srcvalue, (vti.Mask true_mask), VLOpFrag), 2233 (!cast<Instruction>("PseudoVADD_VV_"# vti.LMul.MX) 2234 (vti.Vector (IMPLICIT_DEF)), 2235 vti.RegClass:$rs1, vti.RegClass:$rs1, GPR:$vl, vti.Log2SEW, TA_MA)>; 2236} 2237 2238// 11.7. Vector Narrowing Integer Right Shift Instructions 2239defm : VPatBinaryVL_WV_WX_WI<srl, "PseudoVNSRL">; 2240defm : VPatBinaryVL_WV_WX_WI<sra, "PseudoVNSRA">; 2241 2242defm : VPatNarrowShiftSplat_WX_WI<riscv_sra_vl, "PseudoVNSRA">; 2243defm : VPatNarrowShiftSplat_WX_WI<riscv_srl_vl, "PseudoVNSRL">; 2244defm : VPatNarrowShiftSplatExt_WX<riscv_sra_vl, riscv_sext_vl_oneuse, "PseudoVNSRA">; 2245defm : VPatNarrowShiftSplatExt_WX<riscv_sra_vl, riscv_zext_vl_oneuse, "PseudoVNSRA">; 2246defm : VPatNarrowShiftSplatExt_WX<riscv_srl_vl, riscv_sext_vl_oneuse, "PseudoVNSRL">; 2247defm : VPatNarrowShiftSplatExt_WX<riscv_srl_vl, riscv_zext_vl_oneuse, "PseudoVNSRL">; 2248 2249defm : VPatNarrowShiftVL_WV<riscv_srl_vl, "PseudoVNSRL">; 2250defm : VPatNarrowShiftVL_WV<riscv_sra_vl, "PseudoVNSRA">; 2251 2252foreach vtiTowti = AllWidenableIntVectors in { 2253 defvar vti = vtiTowti.Vti; 2254 defvar wti = vtiTowti.Wti; 2255 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 2256 GetVTypePredicates<wti>.Predicates) in 2257 def : Pat<(vti.Vector (riscv_trunc_vector_vl (wti.Vector wti.RegClass:$rs1), 2258 (vti.Mask VMV0:$vm), 2259 VLOpFrag)), 2260 (!cast<Instruction>("PseudoVNSRL_WI_"#vti.LMul.MX#"_MASK") 2261 (vti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs1, 0, 2262 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 2263} 2264 2265// 11.8. Vector Integer Comparison Instructions 2266foreach vti = AllIntegerVectors in { 2267 let Predicates = GetVTypePredicates<vti>.Predicates in { 2268 defm : VPatIntegerSetCCVL_VV<vti, "PseudoVMSEQ", SETEQ>; 2269 defm : VPatIntegerSetCCVL_VV<vti, "PseudoVMSNE", SETNE>; 2270 2271 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLT", SETLT, SETGT>; 2272 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>; 2273 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 2274 defm : VPatIntegerSetCCVL_VV_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 2275 2276 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>; 2277 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>; 2278 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLT", SETLT, SETGT>; 2279 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLTU", SETULT, SETUGT>; 2280 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 2281 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 2282 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGT", SETGT, SETLT>; 2283 defm : VPatIntegerSetCCVL_VX_Swappable<vti, "PseudoVMSGTU", SETUGT, SETULT>; 2284 // There is no VMSGE(U)_VX instruction 2285 2286 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSEQ", SETEQ, SETEQ>; 2287 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSNE", SETNE, SETNE>; 2288 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLE", SETLE, SETGE>; 2289 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLEU", SETULE, SETUGE>; 2290 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSGT", SETGT, SETLT>; 2291 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSGTU", SETUGT, SETULT>; 2292 2293 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLE", SETLT, SETGT, 2294 SplatPat_simm5_plus1>; 2295 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSLEU", SETULT, SETUGT, 2296 SplatPat_simm5_plus1_nonzero>; 2297 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSGT", SETGE, SETLE, 2298 SplatPat_simm5_plus1>; 2299 defm : VPatIntegerSetCCVL_VI_Swappable<vti, "PseudoVMSGTU", SETUGE, SETULE, 2300 SplatPat_simm5_plus1_nonzero>; 2301 } 2302} // foreach vti = AllIntegerVectors 2303 2304// 11.9. Vector Integer Min/Max Instructions 2305defm : VPatBinaryVL_VV_VX<riscv_umin_vl, "PseudoVMINU">; 2306defm : VPatBinaryVL_VV_VX<riscv_smin_vl, "PseudoVMIN">; 2307defm : VPatBinaryVL_VV_VX<riscv_umax_vl, "PseudoVMAXU">; 2308defm : VPatBinaryVL_VV_VX<riscv_smax_vl, "PseudoVMAX">; 2309 2310// 11.10. Vector Single-Width Integer Multiply Instructions 2311defm : VPatBinaryVL_VV_VX<riscv_mul_vl, "PseudoVMUL">; 2312defm : VPatBinaryVL_VV_VX<riscv_mulhs_vl, "PseudoVMULH", IntegerVectorsExceptI64>; 2313defm : VPatBinaryVL_VV_VX<riscv_mulhu_vl, "PseudoVMULHU", IntegerVectorsExceptI64>; 2314// vsmul.vv and vsmul.vx are not included in EEW=64 in Zve64*. 2315let Predicates = [HasVInstructionsFullMultiply] in { 2316 defm : VPatBinaryVL_VV_VX<riscv_mulhs_vl, "PseudoVMULH", I64IntegerVectors>; 2317 defm : VPatBinaryVL_VV_VX<riscv_mulhu_vl, "PseudoVMULHU", I64IntegerVectors>; 2318} 2319 2320// 11.11. Vector Integer Divide Instructions 2321defm : VPatBinaryVL_VV_VX<riscv_udiv_vl, "PseudoVDIVU", isSEWAware=1>; 2322defm : VPatBinaryVL_VV_VX<riscv_sdiv_vl, "PseudoVDIV", isSEWAware=1>; 2323defm : VPatBinaryVL_VV_VX<riscv_urem_vl, "PseudoVREMU", isSEWAware=1>; 2324defm : VPatBinaryVL_VV_VX<riscv_srem_vl, "PseudoVREM", isSEWAware=1>; 2325 2326// 11.12. Vector Widening Integer Multiply Instructions 2327defm : VPatBinaryWVL_VV_VX<riscv_vwmul_vl, "PseudoVWMUL">; 2328defm : VPatBinaryWVL_VV_VX<riscv_vwmulu_vl, "PseudoVWMULU">; 2329defm : VPatBinaryWVL_VV_VX<riscv_vwmulsu_vl, "PseudoVWMULSU">; 2330 2331// 11.13 Vector Single-Width Integer Multiply-Add Instructions 2332defm : VPatMultiplyAddVL_VV_VX<riscv_add_vl, "PseudoVMADD">; 2333defm : VPatMultiplyAddVL_VV_VX<riscv_sub_vl, "PseudoVNMSUB">; 2334defm : VPatMultiplyAccVL_VV_VX<riscv_add_vl_oneuse, "PseudoVMACC">; 2335defm : VPatMultiplyAccVL_VV_VX<riscv_sub_vl_oneuse, "PseudoVNMSAC">; 2336 2337// 11.14. Vector Widening Integer Multiply-Add Instructions 2338defm : VPatWidenMultiplyAddVL_VV_VX<riscv_vwmacc_vl, "PseudoVWMACC">; 2339defm : VPatWidenMultiplyAddVL_VV_VX<riscv_vwmaccu_vl, "PseudoVWMACCU">; 2340defm : VPatWidenMultiplyAddVL_VV_VX<riscv_vwmaccsu_vl, "PseudoVWMACCSU">; 2341foreach vtiTowti = AllWidenableIntVectors in { 2342 defvar vti = vtiTowti.Vti; 2343 defvar wti = vtiTowti.Wti; 2344 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 2345 GetVTypePredicates<wti>.Predicates) in 2346 def : Pat<(riscv_vwmaccsu_vl (vti.Vector vti.RegClass:$rs1), 2347 (SplatPat XLenVT:$rs2), 2348 (wti.Vector wti.RegClass:$rd), 2349 (vti.Mask VMV0:$vm), VLOpFrag), 2350 (!cast<Instruction>("PseudoVWMACCUS_VX_"#vti.LMul.MX#"_MASK") 2351 wti.RegClass:$rd, vti.ScalarRegClass:$rs2, vti.RegClass:$rs1, 2352 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2353} 2354 2355// 11.15. Vector Integer Merge Instructions 2356foreach vti = AllIntegerVectors in { 2357 let Predicates = GetVTypePredicates<vti>.Predicates in { 2358 def : Pat<(vti.Vector (riscv_vmerge_vl (vti.Mask VMV0:$vm), 2359 vti.RegClass:$rs1, 2360 vti.RegClass:$rs2, 2361 vti.RegClass:$passthru, 2362 VLOpFrag)), 2363 (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX) 2364 vti.RegClass:$passthru, vti.RegClass:$rs2, vti.RegClass:$rs1, 2365 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW)>; 2366 2367 def : Pat<(vti.Vector (riscv_vmerge_vl (vti.Mask VMV0:$vm), 2368 (SplatPat XLenVT:$rs1), 2369 vti.RegClass:$rs2, 2370 vti.RegClass:$passthru, 2371 VLOpFrag)), 2372 (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX) 2373 vti.RegClass:$passthru, vti.RegClass:$rs2, GPR:$rs1, 2374 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW)>; 2375 2376 def : Pat<(vti.Vector (riscv_vmerge_vl (vti.Mask VMV0:$vm), 2377 (SplatPat_simm5 simm5:$rs1), 2378 vti.RegClass:$rs2, 2379 vti.RegClass:$passthru, 2380 VLOpFrag)), 2381 (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX) 2382 vti.RegClass:$passthru, vti.RegClass:$rs2, simm5:$rs1, 2383 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW)>; 2384 } 2385} 2386 2387// 11.16. Vector Integer Move Instructions 2388foreach vti = AllVectors in { 2389 defvar ivti = GetIntVTypeInfo<vti>.Vti; 2390 let Predicates = GetVTypePredicates<ivti>.Predicates in { 2391 def : Pat<(vti.Vector (riscv_vmv_v_v_vl vti.RegClass:$passthru, 2392 vti.RegClass:$rs2, VLOpFrag)), 2393 (!cast<Instruction>("PseudoVMV_V_V_"#vti.LMul.MX) 2394 vti.RegClass:$passthru, vti.RegClass:$rs2, GPR:$vl, vti.Log2SEW, TU_MU)>; 2395} 2396 2397foreach vti = AllIntegerVectors in { 2398 let Predicates = GetVTypePredicates<vti>.Predicates in { 2399 def : Pat<(vti.Vector (riscv_vmv_v_x_vl vti.RegClass:$passthru, GPR:$rs2, VLOpFrag)), 2400 (!cast<Instruction>("PseudoVMV_V_X_"#vti.LMul.MX) 2401 vti.RegClass:$passthru, GPR:$rs2, GPR:$vl, vti.Log2SEW, TU_MU)>; 2402 defvar ImmPat = !cast<ComplexPattern>("sew"#vti.SEW#"simm5"); 2403 def : Pat<(vti.Vector (riscv_vmv_v_x_vl vti.RegClass:$passthru, (ImmPat simm5:$imm5), 2404 VLOpFrag)), 2405 (!cast<Instruction>("PseudoVMV_V_I_"#vti.LMul.MX) 2406 vti.RegClass:$passthru, simm5:$imm5, GPR:$vl, vti.Log2SEW, TU_MU)>; 2407 } 2408 } 2409} 2410 2411// 12. Vector Fixed-Point Arithmetic Instructions 2412 2413// 12.1. Vector Single-Width Saturating Add and Subtract 2414defm : VPatBinaryVL_VV_VX_VI<riscv_saddsat_vl, "PseudoVSADD">; 2415defm : VPatBinaryVL_VV_VX_VI<riscv_uaddsat_vl, "PseudoVSADDU">; 2416defm : VPatBinaryVL_VV_VX<riscv_ssubsat_vl, "PseudoVSSUB">; 2417defm : VPatBinaryVL_VV_VX<riscv_usubsat_vl, "PseudoVSSUBU">; 2418 2419// 12.2. Vector Single-Width Averaging Add and Subtract 2420defm : VPatAVGADDVL_VV_VX_RM<riscv_avgfloors_vl, 0b10>; 2421defm : VPatAVGADDVL_VV_VX_RM<riscv_avgflooru_vl, 0b10, suffix="U">; 2422defm : VPatAVGADDVL_VV_VX_RM<riscv_avgceils_vl, 0b00>; 2423defm : VPatAVGADDVL_VV_VX_RM<riscv_avgceilu_vl, 0b00, suffix="U">; 2424 2425// 12.5. Vector Narrowing Fixed-Point Clip Instructions 2426foreach vtiTowti = AllWidenableIntVectors in { 2427 defvar vti = vtiTowti.Vti; 2428 defvar wti = vtiTowti.Wti; 2429 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 2430 GetVTypePredicates<wti>.Predicates) in { 2431 // Rounding mode here is arbitrary since we aren't shifting out any bits. 2432 def : Pat<(vti.Vector (riscv_trunc_vector_vl_ssat (wti.Vector wti.RegClass:$rs1), 2433 (vti.Mask VMV0:$vm), 2434 VLOpFrag)), 2435 (!cast<Instruction>("PseudoVNCLIP_WI_"#vti.LMul.MX#"_MASK") 2436 (vti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs1, 0, 2437 (vti.Mask VMV0:$vm), /*RNU*/0, GPR:$vl, vti.Log2SEW, TA_MA)>; 2438 def : Pat<(vti.Vector (riscv_trunc_vector_vl_usat (wti.Vector wti.RegClass:$rs1), 2439 (vti.Mask VMV0:$vm), 2440 VLOpFrag)), 2441 (!cast<Instruction>("PseudoVNCLIPU_WI_"#vti.LMul.MX#"_MASK") 2442 (vti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs1, 0, 2443 (vti.Mask VMV0:$vm), /*RNU*/0, GPR:$vl, vti.Log2SEW, TA_MA)>; 2444 } 2445} 2446 2447// 13. Vector Floating-Point Instructions 2448 2449// 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions 2450defm : VPatBinaryFPVL_VV_VF_RM<any_riscv_fadd_vl, "PseudoVFADD", isSEWAware=1>; 2451defm : VPatBinaryFPVL_VV_VF_RM<any_riscv_fsub_vl, "PseudoVFSUB", isSEWAware=1>; 2452defm : VPatBinaryFPVL_R_VF_RM<any_riscv_fsub_vl, "PseudoVFRSUB", isSEWAware=1>; 2453 2454// 13.3. Vector Widening Floating-Point Add/Subtract Instructions 2455defm : VPatBinaryFPWVL_VV_VF_WV_WF_RM<riscv_vfwadd_vl, riscv_vfwadd_w_vl, 2456 "PseudoVFWADD", isSEWAware=1>; 2457defm : VPatBinaryFPWVL_VV_VF_WV_WF_RM<riscv_vfwsub_vl, riscv_vfwsub_w_vl, 2458 "PseudoVFWSUB", isSEWAware=1>; 2459 2460// 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 2461defm : VPatBinaryFPVL_VV_VF_RM<any_riscv_fmul_vl, "PseudoVFMUL", isSEWAware=1>; 2462defm : VPatBinaryFPVL_VV_VF_RM<any_riscv_fdiv_vl, "PseudoVFDIV", isSEWAware=1>; 2463defm : VPatBinaryFPVL_R_VF_RM<any_riscv_fdiv_vl, "PseudoVFRDIV", isSEWAware=1>; 2464 2465// 13.5. Vector Widening Floating-Point Multiply Instructions 2466defm : VPatBinaryFPWVL_VV_VF_RM<riscv_vfwmul_vl, "PseudoVFWMUL", isSEWAware=1>; 2467 2468// 13.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions. 2469defm : VPatFPMulAddVL_VV_VF_RM<any_riscv_vfmadd_vl, "PseudoVFMADD">; 2470defm : VPatFPMulAddVL_VV_VF_RM<any_riscv_vfmsub_vl, "PseudoVFMSUB">; 2471defm : VPatFPMulAddVL_VV_VF_RM<any_riscv_vfnmadd_vl, "PseudoVFNMADD">; 2472defm : VPatFPMulAddVL_VV_VF_RM<any_riscv_vfnmsub_vl, "PseudoVFNMSUB">; 2473defm : VPatFPMulAccVL_VV_VF_RM<riscv_vfmadd_vl_oneuse, "PseudoVFMACC">; 2474defm : VPatFPMulAccVL_VV_VF_RM<riscv_vfmsub_vl_oneuse, "PseudoVFMSAC">; 2475defm : VPatFPMulAccVL_VV_VF_RM<riscv_vfnmadd_vl_oneuse, "PseudoVFNMACC">; 2476defm : VPatFPMulAccVL_VV_VF_RM<riscv_vfnmsub_vl_oneuse, "PseudoVFNMSAC">; 2477 2478// 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions 2479defm : VPatWidenFPMulAccVL_VV_VF_RM<riscv_vfwmadd_vl, "PseudoVFWMACC">; 2480defm : VPatWidenFPMulAccVL_VV_VF_RM<riscv_vfwmadd_vl, "PseudoVFWMACCBF16", 2481 AllWidenableBFloatToFloatVectors>; 2482defm : VPatWidenFPMulAccVL_VV_VF_RM<riscv_vfwnmadd_vl, "PseudoVFWNMACC">; 2483defm : VPatWidenFPMulAccVL_VV_VF_RM<riscv_vfwmsub_vl, "PseudoVFWMSAC">; 2484defm : VPatWidenFPMulAccVL_VV_VF_RM<riscv_vfwnmsub_vl, "PseudoVFWNMSAC">; 2485 2486// 13.11. Vector Floating-Point MIN/MAX Instructions 2487defm : VPatBinaryFPVL_VV_VF<riscv_vfmin_vl, "PseudoVFMIN", isSEWAware=1>; 2488defm : VPatBinaryFPVL_VV_VF<riscv_vfmax_vl, "PseudoVFMAX", isSEWAware=1>; 2489 2490// 13.13. Vector Floating-Point Compare Instructions 2491defm : VPatFPSetCCVL_VV_VF_FV<any_riscv_fsetcc_vl, SETEQ, 2492 "PseudoVMFEQ", "PseudoVMFEQ">; 2493defm : VPatFPSetCCVL_VV_VF_FV<any_riscv_fsetcc_vl, SETOEQ, 2494 "PseudoVMFEQ", "PseudoVMFEQ">; 2495defm : VPatFPSetCCVL_VV_VF_FV<any_riscv_fsetcc_vl, SETNE, 2496 "PseudoVMFNE", "PseudoVMFNE">; 2497defm : VPatFPSetCCVL_VV_VF_FV<any_riscv_fsetcc_vl, SETUNE, 2498 "PseudoVMFNE", "PseudoVMFNE">; 2499defm : VPatFPSetCCVL_VV_VF_FV<any_riscv_fsetccs_vl, SETLT, 2500 "PseudoVMFLT", "PseudoVMFGT">; 2501defm : VPatFPSetCCVL_VV_VF_FV<any_riscv_fsetccs_vl, SETOLT, 2502 "PseudoVMFLT", "PseudoVMFGT">; 2503defm : VPatFPSetCCVL_VV_VF_FV<any_riscv_fsetccs_vl, SETLE, 2504 "PseudoVMFLE", "PseudoVMFGE">; 2505defm : VPatFPSetCCVL_VV_VF_FV<any_riscv_fsetccs_vl, SETOLE, 2506 "PseudoVMFLE", "PseudoVMFGE">; 2507 2508foreach vti = AllFloatVectors in { 2509 let Predicates = GetVTypePredicates<vti>.Predicates in { 2510 // 13.8. Vector Floating-Point Square-Root Instruction 2511 def : Pat<(any_riscv_fsqrt_vl (vti.Vector vti.RegClass:$rs2), (vti.Mask VMV0:$vm), 2512 VLOpFrag), 2513 (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX # "_E" # vti.SEW # "_MASK") 2514 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 2515 (vti.Mask VMV0:$vm), 2516 // Value to indicate no rounding mode change in 2517 // RISCVInsertReadWriteCSR 2518 FRM_DYN, 2519 GPR:$vl, vti.Log2SEW, TA_MA)>; 2520 2521 // 13.12. Vector Floating-Point Sign-Injection Instructions 2522 def : Pat<(riscv_fabs_vl (vti.Vector vti.RegClass:$rs), (vti.Mask VMV0:$vm), 2523 VLOpFrag), 2524 (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX #"_E"#vti.SEW#"_MASK") 2525 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs, 2526 vti.RegClass:$rs, (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 2527 TA_MA)>; 2528 // Handle fneg with VFSGNJN using the same input for both operands. 2529 def : Pat<(riscv_fneg_vl (vti.Vector vti.RegClass:$rs), (vti.Mask VMV0:$vm), 2530 VLOpFrag), 2531 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX#"_E"#vti.SEW #"_MASK") 2532 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs, 2533 vti.RegClass:$rs, (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 2534 TA_MA)>; 2535 2536 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 2537 (vti.Vector vti.RegClass:$rs2), 2538 vti.RegClass:$passthru, 2539 (vti.Mask VMV0:$vm), 2540 VLOpFrag), 2541 (!cast<Instruction>("PseudoVFSGNJ_VV_"# vti.LMul.MX#"_E"#vti.SEW#"_MASK") 2542 vti.RegClass:$passthru, vti.RegClass:$rs1, 2543 vti.RegClass:$rs2, (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 2544 TAIL_AGNOSTIC)>; 2545 2546 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 2547 (riscv_fneg_vl vti.RegClass:$rs2, 2548 (vti.Mask true_mask), 2549 VLOpFrag), 2550 srcvalue, 2551 (vti.Mask true_mask), 2552 VLOpFrag), 2553 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX#"_E"#vti.SEW) 2554 (vti.Vector (IMPLICIT_DEF)), 2555 vti.RegClass:$rs1, vti.RegClass:$rs2, GPR:$vl, vti.Log2SEW, TA_MA)>; 2556 2557 def : Pat<(riscv_fcopysign_vl (vti.Vector vti.RegClass:$rs1), 2558 (SplatFPOp vti.ScalarRegClass:$rs2), 2559 vti.RegClass:$passthru, 2560 (vti.Mask VMV0:$vm), 2561 VLOpFrag), 2562 (!cast<Instruction>("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"# vti.LMul.MX#"_E"#vti.SEW#"_MASK") 2563 vti.RegClass:$passthru, vti.RegClass:$rs1, 2564 vti.ScalarRegClass:$rs2, (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 2565 TAIL_AGNOSTIC)>; 2566 2567 // Rounding without exception to implement nearbyint. 2568 def : Pat<(any_riscv_vfround_noexcept_vl (vti.Vector vti.RegClass:$rs1), 2569 (vti.Mask VMV0:$vm), VLOpFrag), 2570 (!cast<Instruction>("PseudoVFROUND_NOEXCEPT_V_" # vti.LMul.MX #"_MASK") 2571 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, 2572 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 2573 2574 // 14.14. Vector Floating-Point Classify Instruction 2575 def : Pat<(riscv_fclass_vl (vti.Vector vti.RegClass:$rs2), 2576 (vti.Mask VMV0:$vm), VLOpFrag), 2577 (!cast<Instruction>("PseudoVFCLASS_V_"# vti.LMul.MX #"_MASK") 2578 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, 2579 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TA_MA)>; 2580 } 2581} 2582 2583foreach fvti = AllFloatVectors in { 2584 // Floating-point vselects: 2585 // 11.15. Vector Integer Merge Instructions 2586 // 13.15. Vector Floating-Point Merge Instruction 2587 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 2588 let Predicates = GetVTypePredicates<ivti>.Predicates in { 2589 def : Pat<(fvti.Vector (riscv_vmerge_vl (fvti.Mask VMV0:$vm), 2590 fvti.RegClass:$rs1, 2591 fvti.RegClass:$rs2, 2592 fvti.RegClass:$passthru, 2593 VLOpFrag)), 2594 (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX) 2595 fvti.RegClass:$passthru, fvti.RegClass:$rs2, fvti.RegClass:$rs1, (fvti.Mask VMV0:$vm), 2596 GPR:$vl, fvti.Log2SEW)>; 2597 2598 def : Pat<(fvti.Vector (riscv_vmerge_vl (fvti.Mask VMV0:$vm), 2599 (SplatFPOp (SelectScalarFPAsInt (XLenVT GPR:$imm))), 2600 fvti.RegClass:$rs2, 2601 fvti.RegClass:$passthru, 2602 VLOpFrag)), 2603 (!cast<Instruction>("PseudoVMERGE_VXM_"#fvti.LMul.MX) 2604 fvti.RegClass:$passthru, fvti.RegClass:$rs2, GPR:$imm, (fvti.Mask VMV0:$vm), 2605 GPR:$vl, fvti.Log2SEW)>; 2606 2607 2608 def : Pat<(fvti.Vector (riscv_vmerge_vl (fvti.Mask VMV0:$vm), 2609 (SplatFPOp (fvti.Scalar fpimm0)), 2610 fvti.RegClass:$rs2, 2611 fvti.RegClass:$passthru, 2612 VLOpFrag)), 2613 (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX) 2614 fvti.RegClass:$passthru, fvti.RegClass:$rs2, 0, (fvti.Mask VMV0:$vm), 2615 GPR:$vl, fvti.Log2SEW)>; 2616 } 2617} 2618 2619foreach fvti = AllFloatVectors in { 2620 let Predicates = GetVTypePredicates<fvti>.Predicates in { 2621 def : Pat<(fvti.Vector (riscv_vmerge_vl (fvti.Mask VMV0:$vm), 2622 (SplatFPOp fvti.ScalarRegClass:$rs1), 2623 fvti.RegClass:$rs2, 2624 fvti.RegClass:$passthru, 2625 VLOpFrag)), 2626 (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX) 2627 fvti.RegClass:$passthru, fvti.RegClass:$rs2, 2628 (fvti.Scalar fvti.ScalarRegClass:$rs1), 2629 (fvti.Mask VMV0:$vm), GPR:$vl, fvti.Log2SEW)>; 2630 } 2631} 2632 2633foreach fvti = AllFloatVectors in { 2634 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 2635 let Predicates = GetVTypePredicates<ivti>.Predicates in { 2636 // 13.16. Vector Floating-Point Move Instruction 2637 // If we're splatting fpimm0, use vmv.v.x vd, x0. 2638 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 2639 fvti.Vector:$passthru, (fvti.Scalar (fpimm0)), VLOpFrag)), 2640 (!cast<Instruction>("PseudoVMV_V_I_"#fvti.LMul.MX) 2641 $passthru, 0, GPR:$vl, fvti.Log2SEW, TU_MU)>; 2642 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 2643 fvti.Vector:$passthru, (fvti.Scalar (SelectScalarFPAsInt (XLenVT GPR:$imm))), VLOpFrag)), 2644 (!cast<Instruction>("PseudoVMV_V_X_"#fvti.LMul.MX) 2645 $passthru, GPR:$imm, GPR:$vl, fvti.Log2SEW, TU_MU)>; 2646 } 2647} 2648 2649foreach fvti = AllFloatVectors in { 2650 let Predicates = GetVTypePredicates<fvti>.Predicates in { 2651 def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl 2652 fvti.Vector:$passthru, (fvti.Scalar fvti.ScalarRegClass:$rs2), VLOpFrag)), 2653 (!cast<Instruction>("PseudoVFMV_V_" # fvti.ScalarSuffix # "_" # 2654 fvti.LMul.MX) 2655 $passthru, (fvti.Scalar fvti.ScalarRegClass:$rs2), 2656 GPR:$vl, fvti.Log2SEW, TU_MU)>; 2657 } 2658} 2659 2660// 13.17. Vector Single-Width Floating-Point/Integer Type-Convert Instructions 2661defm : VPatConvertFP2I_RM_VL_V<riscv_vfcvt_rm_xu_f_vl, "PseudoVFCVT_XU_F_V">; 2662defm : VPatConvertFP2I_RM_VL_V<any_riscv_vfcvt_rm_x_f_vl, "PseudoVFCVT_X_F_V">; 2663 2664defm : VPatConvertFP2IVL_V<any_riscv_vfcvt_rtz_xu_f_vl, "PseudoVFCVT_RTZ_XU_F_V">; 2665defm : VPatConvertFP2IVL_V<any_riscv_vfcvt_rtz_x_f_vl, "PseudoVFCVT_RTZ_X_F_V">; 2666 2667defm : VPatConvertI2FPVL_V_RM<any_riscv_uint_to_fp_vl, "PseudoVFCVT_F_XU_V">; 2668defm : VPatConvertI2FPVL_V_RM<any_riscv_sint_to_fp_vl, "PseudoVFCVT_F_X_V">; 2669 2670defm : VPatConvertI2FP_RM_VL_V<riscv_vfcvt_rm_f_xu_vl, "PseudoVFCVT_F_XU_V">; 2671defm : VPatConvertI2FP_RM_VL_V<riscv_vfcvt_rm_f_x_vl, "PseudoVFCVT_F_X_V">; 2672 2673// 13.18. Widening Floating-Point/Integer Type-Convert Instructions 2674defm : VPatWConvertFP2I_RM_VL_V<riscv_vfcvt_rm_xu_f_vl, "PseudoVFWCVT_XU_F_V">; 2675defm : VPatWConvertFP2I_RM_VL_V<riscv_vfcvt_rm_x_f_vl, "PseudoVFWCVT_X_F_V">; 2676 2677defm : VPatWConvertFP2IVL_V<any_riscv_vfcvt_rtz_xu_f_vl, "PseudoVFWCVT_RTZ_XU_F_V">; 2678defm : VPatWConvertFP2IVL_V<any_riscv_vfcvt_rtz_x_f_vl, "PseudoVFWCVT_RTZ_X_F_V">; 2679 2680defm : VPatWConvertI2FPVL_V<any_riscv_uint_to_fp_vl, "PseudoVFWCVT_F_XU_V">; 2681defm : VPatWConvertI2FPVL_V<any_riscv_sint_to_fp_vl, "PseudoVFWCVT_F_X_V">; 2682 2683foreach fvtiToFWti = AllWidenableFloatVectors in { 2684 defvar fvti = fvtiToFWti.Vti; 2685 defvar fwti = fvtiToFWti.Wti; 2686 // Define vfwcvt.f.f.v for f16 when Zvfhmin is enable. 2687 let Predicates = !listconcat(GetVTypeMinimalPredicates<fvti>.Predicates, 2688 GetVTypeMinimalPredicates<fwti>.Predicates) in 2689 def : Pat<(fwti.Vector (any_riscv_fpextend_vl 2690 (fvti.Vector fvti.RegClass:$rs1), 2691 (fvti.Mask VMV0:$vm), 2692 VLOpFrag)), 2693 (!cast<Instruction>("PseudoVFWCVT_F_F_V_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 2694 (fwti.Vector (IMPLICIT_DEF)), fvti.RegClass:$rs1, 2695 (fvti.Mask VMV0:$vm), 2696 GPR:$vl, fvti.Log2SEW, TA_MA)>; 2697} 2698 2699foreach fvtiToFWti = AllWidenableBFloatToFloatVectors in { 2700 defvar fvti = fvtiToFWti.Vti; 2701 defvar fwti = fvtiToFWti.Wti; 2702 let Predicates = [HasVInstructionsBF16Minimal] in 2703 def : Pat<(fwti.Vector (any_riscv_fpextend_vl 2704 (fvti.Vector fvti.RegClass:$rs1), 2705 (fvti.Mask VMV0:$vm), 2706 VLOpFrag)), 2707 (!cast<Instruction>("PseudoVFWCVTBF16_F_F_V_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 2708 (fwti.Vector (IMPLICIT_DEF)), fvti.RegClass:$rs1, 2709 (fvti.Mask VMV0:$vm), 2710 GPR:$vl, fvti.Log2SEW, TA_MA)>; 2711} 2712 2713// 13.19 Narrowing Floating-Point/Integer Type-Convert Instructions 2714defm : VPatNConvertFP2I_RM_VL_W<riscv_vfcvt_rm_xu_f_vl, "PseudoVFNCVT_XU_F_W">; 2715defm : VPatNConvertFP2I_RM_VL_W<riscv_vfcvt_rm_x_f_vl, "PseudoVFNCVT_X_F_W">; 2716 2717defm : VPatNConvertFP2IVL_W<any_riscv_vfcvt_rtz_xu_f_vl, "PseudoVFNCVT_RTZ_XU_F_W">; 2718defm : VPatNConvertFP2IVL_W<any_riscv_vfcvt_rtz_x_f_vl, "PseudoVFNCVT_RTZ_X_F_W">; 2719 2720defm : VPatNConvertI2FPVL_W_RM<any_riscv_uint_to_fp_vl, "PseudoVFNCVT_F_XU_W">; 2721defm : VPatNConvertI2FPVL_W_RM<any_riscv_sint_to_fp_vl, "PseudoVFNCVT_F_X_W">; 2722 2723defm : VPatNConvertI2FP_RM_VL_W<riscv_vfcvt_rm_f_xu_vl, "PseudoVFNCVT_F_XU_W">; 2724defm : VPatNConvertI2FP_RM_VL_W<riscv_vfcvt_rm_f_x_vl, "PseudoVFNCVT_F_X_W">; 2725 2726foreach fvtiToFWti = AllWidenableFloatVectors in { 2727 defvar fvti = fvtiToFWti.Vti; 2728 defvar fwti = fvtiToFWti.Wti; 2729 // Define vfncvt.f.f.w for f16 when Zvfhmin is enable. 2730 let Predicates = !listconcat(GetVTypeMinimalPredicates<fvti>.Predicates, 2731 GetVTypeMinimalPredicates<fwti>.Predicates) in { 2732 def : Pat<(fvti.Vector (any_riscv_fpround_vl 2733 (fwti.Vector fwti.RegClass:$rs1), 2734 (fwti.Mask VMV0:$vm), VLOpFrag)), 2735 (!cast<Instruction>("PseudoVFNCVT_F_F_W_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 2736 (fvti.Vector (IMPLICIT_DEF)), fwti.RegClass:$rs1, 2737 (fwti.Mask VMV0:$vm), 2738 // Value to indicate no rounding mode change in 2739 // RISCVInsertReadWriteCSR 2740 FRM_DYN, 2741 GPR:$vl, fvti.Log2SEW, TA_MA)>; 2742 2743 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 2744 GetVTypePredicates<fwti>.Predicates) in 2745 def : Pat<(fvti.Vector (any_riscv_fncvt_rod_vl 2746 (fwti.Vector fwti.RegClass:$rs1), 2747 (fwti.Mask VMV0:$vm), VLOpFrag)), 2748 (!cast<Instruction>("PseudoVFNCVT_ROD_F_F_W_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 2749 (fvti.Vector (IMPLICIT_DEF)), fwti.RegClass:$rs1, 2750 (fwti.Mask VMV0:$vm), GPR:$vl, fvti.Log2SEW, TA_MA)>; 2751 } 2752} 2753 2754foreach fvtiToFWti = AllWidenableBFloatToFloatVectors in { 2755 defvar fvti = fvtiToFWti.Vti; 2756 defvar fwti = fvtiToFWti.Wti; 2757 let Predicates = [HasVInstructionsBF16Minimal] in 2758 def : Pat<(fvti.Vector (any_riscv_fpround_vl 2759 (fwti.Vector fwti.RegClass:$rs1), 2760 (fwti.Mask VMV0:$vm), VLOpFrag)), 2761 (!cast<Instruction>("PseudoVFNCVTBF16_F_F_W_"#fvti.LMul.MX#"_E"#fvti.SEW#"_MASK") 2762 (fvti.Vector (IMPLICIT_DEF)), fwti.RegClass:$rs1, 2763 (fwti.Mask VMV0:$vm), 2764 // Value to indicate no rounding mode change in 2765 // RISCVInsertReadWriteCSR 2766 FRM_DYN, 2767 GPR:$vl, fvti.Log2SEW, TA_MA)>; 2768} 2769 2770// 14. Vector Reduction Operations 2771 2772// 14.1. Vector Single-Width Integer Reduction Instructions 2773defm : VPatReductionVL<rvv_vecreduce_ADD_vl, "PseudoVREDSUM", is_float=0>; 2774defm : VPatReductionVL<rvv_vecreduce_UMAX_vl, "PseudoVREDMAXU", is_float=0>; 2775defm : VPatReductionVL<rvv_vecreduce_SMAX_vl, "PseudoVREDMAX", is_float=0>; 2776defm : VPatReductionVL<rvv_vecreduce_UMIN_vl, "PseudoVREDMINU", is_float=0>; 2777defm : VPatReductionVL<rvv_vecreduce_SMIN_vl, "PseudoVREDMIN", is_float=0>; 2778defm : VPatReductionVL<rvv_vecreduce_AND_vl, "PseudoVREDAND", is_float=0>; 2779defm : VPatReductionVL<rvv_vecreduce_OR_vl, "PseudoVREDOR", is_float=0>; 2780defm : VPatReductionVL<rvv_vecreduce_XOR_vl, "PseudoVREDXOR", is_float=0>; 2781 2782// 14.2. Vector Widening Integer Reduction Instructions 2783defm : VPatWidenReductionVL<rvv_vecreduce_ADD_vl, anyext_oneuse, "PseudoVWREDSUMU", is_float=0>; 2784defm : VPatWidenReductionVL<rvv_vecreduce_ADD_vl, zext_oneuse, "PseudoVWREDSUMU", is_float=0>; 2785defm : VPatWidenReductionVL_Ext_VL<rvv_vecreduce_ADD_vl, riscv_zext_vl_oneuse, "PseudoVWREDSUMU", is_float=0>; 2786defm : VPatWidenReductionVL<rvv_vecreduce_ADD_vl, sext_oneuse, "PseudoVWREDSUM", is_float=0>; 2787defm : VPatWidenReductionVL_Ext_VL<rvv_vecreduce_ADD_vl, riscv_sext_vl_oneuse, "PseudoVWREDSUM", is_float=0>; 2788 2789// 14.3. Vector Single-Width Floating-Point Reduction Instructions 2790defm : VPatReductionVL_RM<rvv_vecreduce_SEQ_FADD_vl, "PseudoVFREDOSUM", is_float=1>; 2791defm : VPatReductionVL_RM<rvv_vecreduce_FADD_vl, "PseudoVFREDUSUM", is_float=1>; 2792defm : VPatReductionVL<rvv_vecreduce_FMIN_vl, "PseudoVFREDMIN", is_float=1>; 2793defm : VPatReductionVL<rvv_vecreduce_FMAX_vl, "PseudoVFREDMAX", is_float=1>; 2794 2795// 14.4. Vector Widening Floating-Point Reduction Instructions 2796defm : VPatWidenReductionVL_Ext_VL_RM<rvv_vecreduce_SEQ_FADD_vl, 2797 riscv_fpextend_vl_oneuse, 2798 "PseudoVFWREDOSUM", is_float=1>; 2799defm : VPatWidenReductionVL_Ext_VL_RM<rvv_vecreduce_FADD_vl, 2800 riscv_fpextend_vl_oneuse, 2801 "PseudoVFWREDUSUM", is_float=1>; 2802 2803// 15. Vector Mask Instructions 2804 2805foreach mti = AllMasks in { 2806 let Predicates = [HasVInstructions] in { 2807 // 15.1 Vector Mask-Register Logical Instructions 2808 def : Pat<(mti.Mask (riscv_vmset_vl VLOpFrag)), 2809 (!cast<Instruction>("PseudoVMSET_M_" # mti.BX) GPR:$vl, mti.Log2SEW)>; 2810 def : Pat<(mti.Mask (riscv_vmclr_vl VLOpFrag)), 2811 (!cast<Instruction>("PseudoVMCLR_M_" # mti.BX) GPR:$vl, mti.Log2SEW)>; 2812 2813 def : Pat<(mti.Mask (riscv_vmand_vl VR:$rs1, VR:$rs2, VLOpFrag)), 2814 (!cast<Instruction>("PseudoVMAND_MM_" # mti.BX) 2815 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2816 def : Pat<(mti.Mask (riscv_vmor_vl VR:$rs1, VR:$rs2, VLOpFrag)), 2817 (!cast<Instruction>("PseudoVMOR_MM_" # mti.BX) 2818 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2819 def : Pat<(mti.Mask (riscv_vmxor_vl VR:$rs1, VR:$rs2, VLOpFrag)), 2820 (!cast<Instruction>("PseudoVMXOR_MM_" # mti.BX) 2821 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2822 2823 def : Pat<(mti.Mask (riscv_vmand_vl VR:$rs1, 2824 (riscv_vmnot_vl VR:$rs2, VLOpFrag), 2825 VLOpFrag)), 2826 (!cast<Instruction>("PseudoVMANDN_MM_" # mti.BX) 2827 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2828 def : Pat<(mti.Mask (riscv_vmor_vl VR:$rs1, 2829 (riscv_vmnot_vl VR:$rs2, VLOpFrag), 2830 VLOpFrag)), 2831 (!cast<Instruction>("PseudoVMORN_MM_" # mti.BX) 2832 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2833 // XOR is associative so we need 2 patterns for VMXNOR. 2834 def : Pat<(mti.Mask (riscv_vmxor_vl (riscv_vmnot_vl VR:$rs1, 2835 VLOpFrag), 2836 VR:$rs2, VLOpFrag)), 2837 (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.BX) 2838 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2839 2840 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmand_vl VR:$rs1, VR:$rs2, 2841 VLOpFrag), 2842 VLOpFrag)), 2843 (!cast<Instruction>("PseudoVMNAND_MM_" # mti.BX) 2844 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2845 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmor_vl VR:$rs1, VR:$rs2, 2846 VLOpFrag), 2847 VLOpFrag)), 2848 (!cast<Instruction>("PseudoVMNOR_MM_" # mti.BX) 2849 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2850 def : Pat<(mti.Mask (riscv_vmnot_vl (riscv_vmxor_vl VR:$rs1, VR:$rs2, 2851 VLOpFrag), 2852 VLOpFrag)), 2853 (!cast<Instruction>("PseudoVMXNOR_MM_" # mti.BX) 2854 VR:$rs1, VR:$rs2, GPR:$vl, mti.Log2SEW)>; 2855 2856 // Match the not idiom to the vmnot.m pseudo. 2857 def : Pat<(mti.Mask (riscv_vmnot_vl VR:$rs, VLOpFrag)), 2858 (!cast<Instruction>("PseudoVMNAND_MM_" # mti.BX) 2859 VR:$rs, VR:$rs, GPR:$vl, mti.Log2SEW)>; 2860 2861 // 15.2 Vector count population in mask vcpop.m 2862 def : Pat<(XLenVT (riscv_vcpop_vl (mti.Mask VR:$rs2), (mti.Mask VMV0:$vm), 2863 VLOpFrag)), 2864 (!cast<Instruction>("PseudoVCPOP_M_" # mti.BX # "_MASK") 2865 VR:$rs2, (mti.Mask VMV0:$vm), GPR:$vl, mti.Log2SEW)>; 2866 2867 // 15.3 vfirst find-first-set mask bit 2868 def : Pat<(XLenVT (riscv_vfirst_vl (mti.Mask VR:$rs2), (mti.Mask VMV0:$vm), 2869 VLOpFrag)), 2870 (!cast<Instruction>("PseudoVFIRST_M_" # mti.BX # "_MASK") 2871 VR:$rs2, (mti.Mask VMV0:$vm), GPR:$vl, mti.Log2SEW)>; 2872 } 2873} 2874 2875// 16. Vector Permutation Instructions 2876 2877// 16.1. Integer Scalar Move Instructions 2878foreach vti = NoGroupIntegerVectors in { 2879 let Predicates = GetVTypePredicates<vti>.Predicates in { 2880 def : Pat<(vti.Vector (riscv_vmv_s_x_vl (vti.Vector vti.RegClass:$passthru), 2881 vti.ScalarRegClass:$rs1, 2882 VLOpFrag)), 2883 (PseudoVMV_S_X $passthru, vti.ScalarRegClass:$rs1, GPR:$vl, 2884 vti.Log2SEW)>; 2885 } 2886} 2887 2888// 16.4. Vector Register Gather Instruction 2889foreach vti = AllIntegerVectors in { 2890 let Predicates = GetVTypePredicates<vti>.Predicates in { 2891 def : Pat<(vti.Vector (riscv_vrgather_vv_vl vti.RegClass:$rs2, 2892 vti.RegClass:$rs1, 2893 vti.RegClass:$passthru, 2894 (vti.Mask VMV0:$vm), 2895 VLOpFrag)), 2896 (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX#"_E"# vti.SEW#"_MASK") 2897 vti.RegClass:$passthru, vti.RegClass:$rs2, vti.RegClass:$rs1, 2898 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2899 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1, 2900 vti.RegClass:$passthru, 2901 (vti.Mask VMV0:$vm), 2902 VLOpFrag)), 2903 (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX#"_MASK") 2904 vti.RegClass:$passthru, vti.RegClass:$rs2, GPR:$rs1, 2905 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2906 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, 2907 uimm5:$imm, 2908 vti.RegClass:$passthru, 2909 (vti.Mask VMV0:$vm), 2910 VLOpFrag)), 2911 (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX#"_MASK") 2912 vti.RegClass:$passthru, vti.RegClass:$rs2, uimm5:$imm, 2913 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2914 } 2915 2916 // emul = lmul * 16 / sew 2917 defvar vlmul = vti.LMul; 2918 defvar octuple_lmul = vlmul.octuple; 2919 defvar octuple_emul = !srl(!mul(octuple_lmul, 16), vti.Log2SEW); 2920 if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then { 2921 defvar emul_str = octuple_to_str<octuple_emul>.ret; 2922 defvar ivti = !cast<VTypeInfo>("VI16" # emul_str); 2923 defvar inst = "PseudoVRGATHEREI16_VV_" # vti.LMul.MX # "_E" # vti.SEW # "_" # emul_str; 2924 let Predicates = GetVTypePredicates<vti>.Predicates in 2925 def : Pat<(vti.Vector 2926 (riscv_vrgatherei16_vv_vl vti.RegClass:$rs2, 2927 (ivti.Vector ivti.RegClass:$rs1), 2928 vti.RegClass:$passthru, 2929 (vti.Mask VMV0:$vm), 2930 VLOpFrag)), 2931 (!cast<Instruction>(inst#"_MASK") 2932 vti.RegClass:$passthru, vti.RegClass:$rs2, ivti.RegClass:$rs1, 2933 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2934 } 2935} 2936 2937// 16.2. Floating-Point Scalar Move Instructions 2938foreach vti = NoGroupFloatVectors in { 2939 let Predicates = GetVTypePredicates<vti>.Predicates in { 2940 def : Pat<(vti.Vector (riscv_vfmv_s_f_vl (vti.Vector vti.RegClass:$passthru), 2941 (vti.Scalar (fpimm0)), 2942 VLOpFrag)), 2943 (PseudoVMV_S_X $passthru, (XLenVT X0), GPR:$vl, vti.Log2SEW)>; 2944 def : Pat<(vti.Vector (riscv_vfmv_s_f_vl (vti.Vector vti.RegClass:$passthru), 2945 (vti.Scalar (SelectScalarFPAsInt (XLenVT GPR:$imm))), 2946 VLOpFrag)), 2947 (PseudoVMV_S_X $passthru, GPR:$imm, GPR:$vl, vti.Log2SEW)>; 2948 def : Pat<(vti.Vector (riscv_vfmv_s_f_vl (vti.Vector vti.RegClass:$passthru), 2949 vti.ScalarRegClass:$rs1, 2950 VLOpFrag)), 2951 (!cast<Instruction>("PseudoVFMV_S_"#vti.ScalarSuffix) 2952 vti.RegClass:$passthru, 2953 (vti.Scalar vti.ScalarRegClass:$rs1), GPR:$vl, vti.Log2SEW)>; 2954 } 2955} 2956 2957foreach vti = AllFloatVectors in { 2958 defvar ivti = GetIntVTypeInfo<vti>.Vti; 2959 let Predicates = GetVTypePredicates<ivti>.Predicates in { 2960 def : Pat<(vti.Vector 2961 (riscv_vrgather_vv_vl vti.RegClass:$rs2, 2962 (ivti.Vector vti.RegClass:$rs1), 2963 vti.RegClass:$passthru, 2964 (vti.Mask VMV0:$vm), 2965 VLOpFrag)), 2966 (!cast<Instruction>("PseudoVRGATHER_VV_"# vti.LMul.MX#"_E"# vti.SEW#"_MASK") 2967 vti.RegClass:$passthru, vti.RegClass:$rs2, vti.RegClass:$rs1, 2968 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2969 def : Pat<(vti.Vector (riscv_vrgather_vx_vl vti.RegClass:$rs2, GPR:$rs1, 2970 vti.RegClass:$passthru, 2971 (vti.Mask VMV0:$vm), 2972 VLOpFrag)), 2973 (!cast<Instruction>("PseudoVRGATHER_VX_"# vti.LMul.MX#"_MASK") 2974 vti.RegClass:$passthru, vti.RegClass:$rs2, GPR:$rs1, 2975 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2976 def : Pat<(vti.Vector 2977 (riscv_vrgather_vx_vl vti.RegClass:$rs2, 2978 uimm5:$imm, 2979 vti.RegClass:$passthru, 2980 (vti.Mask VMV0:$vm), 2981 VLOpFrag)), 2982 (!cast<Instruction>("PseudoVRGATHER_VI_"# vti.LMul.MX#"_MASK") 2983 vti.RegClass:$passthru, vti.RegClass:$rs2, uimm5:$imm, 2984 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 2985 } 2986 2987 defvar vlmul = vti.LMul; 2988 defvar octuple_lmul = vlmul.octuple; 2989 defvar octuple_emul = !srl(!mul(octuple_lmul, 16), vti.Log2SEW); 2990 if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then { 2991 defvar emul_str = octuple_to_str<octuple_emul>.ret; 2992 defvar ivti = !cast<VTypeInfo>("VI16" # emul_str); 2993 defvar inst = "PseudoVRGATHEREI16_VV_" # vti.LMul.MX # "_E" # vti.SEW # "_" # emul_str; 2994 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 2995 GetVTypePredicates<ivti>.Predicates) in 2996 def : Pat<(vti.Vector 2997 (riscv_vrgatherei16_vv_vl vti.RegClass:$rs2, 2998 (ivti.Vector ivti.RegClass:$rs1), 2999 vti.RegClass:$passthru, 3000 (vti.Mask VMV0:$vm), 3001 VLOpFrag)), 3002 (!cast<Instruction>(inst#"_MASK") 3003 vti.RegClass:$passthru, vti.RegClass:$rs2, ivti.RegClass:$rs1, 3004 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; 3005 } 3006} 3007 3008//===----------------------------------------------------------------------===// 3009// Miscellaneous RISCVISD SDNodes 3010//===----------------------------------------------------------------------===// 3011 3012// Matches the semantics of the vid.v instruction, with a mask and VL 3013// operand. 3014let HasMaskOp = true in 3015def riscv_vid_vl : RVSDNode<"VID_VL", SDTypeProfile<1, 2, [SDTCisVec<0>, 3016 SDTCVecEltisVT<1, i1>, 3017 SDTCisSameNumEltsAs<0, 1>, 3018 SDTCisVT<2, XLenVT>]>>; 3019 3020def SDTRVVSlide : SDTypeProfile<1, 6, [ 3021 SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>, SDTCisVT<3, XLenVT>, 3022 SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<0, 4>, SDTCisVT<5, XLenVT>, 3023 SDTCisVT<6, XLenVT> 3024]>; 3025def SDTRVVSlide1 : SDTypeProfile<1, 5, [ 3026 SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>, SDTCisInt<0>, 3027 SDTCisVT<3, XLenVT>, SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<0, 4>, 3028 SDTCisVT<5, XLenVT> 3029]>; 3030def SDTRVVFSlide1 : SDTypeProfile<1, 5, [ 3031 SDTCisVec<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>, SDTCisFP<0>, 3032 SDTCisEltOfVec<3, 0>, SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<0, 4>, 3033 SDTCisVT<5, XLenVT> 3034]>; 3035 3036let HasMaskOp = true in { 3037 // Matches the semantics of vslideup/vslidedown. The first operand is the 3038 // pass-thru operand, the second is the source vector, the third is the XLenVT 3039 // index (either constant or non-constant), the fourth is the mask, the fifth 3040 // is the VL and the sixth is the policy. 3041 def riscv_slideup_vl : RVSDNode<"VSLIDEUP_VL", SDTRVVSlide, []>; 3042 def riscv_slidedown_vl : RVSDNode<"VSLIDEDOWN_VL", SDTRVVSlide, []>; 3043 3044 // Matches the semantics of vslide1up/slide1down. The first operand is 3045 // passthru operand, the second is source vector, third is the XLenVT scalar 3046 // value. The fourth and fifth operands are the mask and VL operands. 3047 def riscv_slide1up_vl : RVSDNode<"VSLIDE1UP_VL", SDTRVVSlide1, []>; 3048 def riscv_slide1down_vl : RVSDNode<"VSLIDE1DOWN_VL", SDTRVVSlide1, []>; 3049 3050 // Matches the semantics of vfslide1up/vfslide1down. The first operand is 3051 // passthru operand, the second is source vector, third is a scalar value 3052 // whose type matches the element type of the vectors. The fourth and fifth 3053 // operands are the mask and VL operands. 3054 def riscv_fslide1up_vl : RVSDNode<"VFSLIDE1UP_VL", SDTRVVFSlide1, []>; 3055 def riscv_fslide1down_vl : RVSDNode<"VFSLIDE1DOWN_VL", SDTRVVFSlide1, []>; 3056} // let HasMaskOp = true 3057 3058foreach vti = AllIntegerVectors in { 3059 let Predicates = GetVTypePredicates<vti>.Predicates in { 3060 def : Pat<(vti.Vector (riscv_vid_vl (vti.Mask VMV0:$vm), 3061 VLOpFrag)), 3062 (!cast<Instruction>("PseudoVID_V_"#vti.LMul.MX#"_MASK") 3063 (vti.Vector (IMPLICIT_DEF)), (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, 3064 TAIL_AGNOSTIC)>; 3065 } 3066} 3067 3068defm : VPatSlideVL_VX_VI<riscv_slideup_vl, "PseudoVSLIDEUP">; 3069defm : VPatSlideVL_VX_VI<riscv_slidedown_vl, "PseudoVSLIDEDOWN">; 3070defm : VPatSlide1VL_VX<riscv_slide1up_vl, "PseudoVSLIDE1UP">; 3071defm : VPatSlide1VL_VF<riscv_fslide1up_vl, "PseudoVFSLIDE1UP">; 3072defm : VPatSlide1VL_VX<riscv_slide1down_vl, "PseudoVSLIDE1DOWN">; 3073defm : VPatSlide1VL_VF<riscv_fslide1down_vl, "PseudoVFSLIDE1DOWN">; 3074