1//===- RISCVInstrInfoVSDPatterns.td - RVV SDNode 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 SDNode 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//===----------------------------------------------------------------------===// 21// Helpers to define the SDNode patterns. 22//===----------------------------------------------------------------------===// 23 24def rvv_vnot : PatFrag<(ops node:$in), 25 (xor node:$in, (riscv_vmset_vl (XLenVT srcvalue)))>; 26 27multiclass VPatUSLoadStoreSDNode<ValueType type, 28 int log2sew, 29 LMULInfo vlmul, 30 OutPatFrag avl, 31 VReg reg_class, 32 int sew = !shl(1, log2sew)> 33{ 34 defvar load_instr = !cast<Instruction>("PseudoVLE"#sew#"_V_"#vlmul.MX); 35 defvar store_instr = !cast<Instruction>("PseudoVSE"#sew#"_V_"#vlmul.MX); 36 // Load 37 def : Pat<(type (load GPR:$rs1)), 38 (load_instr GPR:$rs1, avl, log2sew)>; 39 // Store 40 def : Pat<(store type:$rs2, GPR:$rs1), 41 (store_instr reg_class:$rs2, GPR:$rs1, avl, log2sew)>; 42} 43 44multiclass VPatUSLoadStoreWholeVRSDNode<ValueType type, 45 int log2sew, 46 LMULInfo vlmul, 47 VReg reg_class, 48 int sew = !shl(1, log2sew)> 49{ 50 defvar load_instr = 51 !cast<Instruction>("VL"#!substr(vlmul.MX, 1)#"RE"#sew#"_V"); 52 defvar store_instr = 53 !cast<Instruction>("VS"#!substr(vlmul.MX, 1)#"R_V"); 54 55 // Load 56 def : Pat<(type (load GPR:$rs1)), 57 (load_instr GPR:$rs1)>; 58 // Store 59 def : Pat<(store type:$rs2, GPR:$rs1), 60 (store_instr reg_class:$rs2, GPR:$rs1)>; 61} 62 63multiclass VPatUSLoadStoreMaskSDNode<MTypeInfo m> 64{ 65 defvar load_instr = !cast<Instruction>("PseudoVLM_V_"#m.BX); 66 defvar store_instr = !cast<Instruction>("PseudoVSM_V_"#m.BX); 67 // Load 68 def : Pat<(m.Mask (load GPR:$rs1)), 69 (load_instr GPR:$rs1, m.AVL, m.Log2SEW)>; 70 // Store 71 def : Pat<(store m.Mask:$rs2, GPR:$rs1), 72 (store_instr VR:$rs2, GPR:$rs1, m.AVL, m.Log2SEW)>; 73} 74 75class VPatBinarySDNode_VV<SDNode vop, 76 string instruction_name, 77 ValueType result_type, 78 ValueType op_type, 79 int sew, 80 LMULInfo vlmul, 81 OutPatFrag avl, 82 VReg op_reg_class> : 83 Pat<(result_type (vop 84 (op_type op_reg_class:$rs1), 85 (op_type op_reg_class:$rs2))), 86 (!cast<Instruction>(instruction_name#"_VV_"# vlmul.MX) 87 op_reg_class:$rs1, 88 op_reg_class:$rs2, 89 avl, sew)>; 90 91class VPatBinarySDNode_XI<SDNode vop, 92 string instruction_name, 93 string suffix, 94 ValueType result_type, 95 ValueType vop_type, 96 int sew, 97 LMULInfo vlmul, 98 OutPatFrag avl, 99 VReg vop_reg_class, 100 ComplexPattern SplatPatKind, 101 DAGOperand xop_kind> : 102 Pat<(result_type (vop 103 (vop_type vop_reg_class:$rs1), 104 (vop_type (SplatPatKind xop_kind:$rs2)))), 105 (!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX) 106 vop_reg_class:$rs1, 107 xop_kind:$rs2, 108 avl, sew)>; 109 110multiclass VPatBinarySDNode_VV_VX<SDNode vop, string instruction_name> { 111 foreach vti = AllIntegerVectors in { 112 def : VPatBinarySDNode_VV<vop, instruction_name, 113 vti.Vector, vti.Vector, vti.Log2SEW, 114 vti.LMul, vti.AVL, vti.RegClass>; 115 def : VPatBinarySDNode_XI<vop, instruction_name, "VX", 116 vti.Vector, vti.Vector, vti.Log2SEW, 117 vti.LMul, vti.AVL, vti.RegClass, 118 SplatPat, GPR>; 119 } 120} 121 122multiclass VPatBinarySDNode_VV_VX_VI<SDNode vop, string instruction_name, 123 Operand ImmType = simm5> 124 : VPatBinarySDNode_VV_VX<vop, instruction_name> { 125 foreach vti = AllIntegerVectors in { 126 def : VPatBinarySDNode_XI<vop, instruction_name, "VI", 127 vti.Vector, vti.Vector, vti.Log2SEW, 128 vti.LMul, vti.AVL, vti.RegClass, 129 !cast<ComplexPattern>(SplatPat#_#ImmType), 130 ImmType>; 131 } 132} 133 134class VPatBinarySDNode_VF<SDNode vop, 135 string instruction_name, 136 ValueType result_type, 137 ValueType vop_type, 138 ValueType xop_type, 139 int sew, 140 LMULInfo vlmul, 141 OutPatFrag avl, 142 VReg vop_reg_class, 143 DAGOperand xop_kind> : 144 Pat<(result_type (vop (vop_type vop_reg_class:$rs1), 145 (vop_type (SplatFPOp xop_kind:$rs2)))), 146 (!cast<Instruction>(instruction_name#"_"#vlmul.MX) 147 vop_reg_class:$rs1, 148 (xop_type xop_kind:$rs2), 149 avl, sew)>; 150 151multiclass VPatBinaryFPSDNode_VV_VF<SDNode vop, string instruction_name> { 152 foreach vti = AllFloatVectors in { 153 def : VPatBinarySDNode_VV<vop, instruction_name, 154 vti.Vector, vti.Vector, vti.Log2SEW, 155 vti.LMul, vti.AVL, vti.RegClass>; 156 def : VPatBinarySDNode_VF<vop, instruction_name#"_V"#vti.ScalarSuffix, 157 vti.Vector, vti.Vector, vti.Scalar, 158 vti.Log2SEW, vti.LMul, vti.AVL, vti.RegClass, 159 vti.ScalarRegClass>; 160 } 161} 162 163multiclass VPatBinaryFPSDNode_R_VF<SDNode vop, string instruction_name> { 164 foreach fvti = AllFloatVectors in 165 def : Pat<(fvti.Vector (vop (fvti.Vector (SplatFPOp fvti.Scalar:$rs2)), 166 (fvti.Vector fvti.RegClass:$rs1))), 167 (!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 168 fvti.RegClass:$rs1, 169 (fvti.Scalar fvti.ScalarRegClass:$rs2), 170 fvti.AVL, fvti.Log2SEW)>; 171} 172 173multiclass VPatIntegerSetCCSDNode_VV<string instruction_name, 174 CondCode cc> { 175 foreach vti = AllIntegerVectors in { 176 defvar instruction = !cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX); 177 def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1), 178 (vti.Vector vti.RegClass:$rs2), cc)), 179 (instruction vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, 180 vti.Log2SEW)>; 181 } 182} 183 184multiclass VPatIntegerSetCCSDNode_VV_Swappable<string instruction_name, 185 CondCode cc, CondCode invcc> 186 : VPatIntegerSetCCSDNode_VV<instruction_name, cc> { 187 foreach vti = AllIntegerVectors in { 188 defvar instruction = !cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX); 189 def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs2), 190 (vti.Vector vti.RegClass:$rs1), invcc)), 191 (instruction vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, 192 vti.Log2SEW)>; 193 } 194} 195 196multiclass VPatIntegerSetCCSDNode_XI< 197 string instruction_name, 198 CondCode cc, 199 string kind, 200 ComplexPattern SplatPatKind, 201 DAGOperand xop_kind> { 202 foreach vti = AllIntegerVectors in { 203 defvar instruction = !cast<Instruction>(instruction_name#_#kind#_#vti.LMul.MX); 204 def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1), 205 (vti.Vector (SplatPatKind xop_kind:$rs2)), cc)), 206 (instruction vti.RegClass:$rs1, xop_kind:$rs2, vti.AVL, vti.Log2SEW)>; 207 } 208} 209 210multiclass VPatIntegerSetCCSDNode_XI_Swappable<string instruction_name, 211 CondCode cc, CondCode invcc, 212 string kind, 213 ComplexPattern SplatPatKind, 214 DAGOperand xop_kind> 215 : VPatIntegerSetCCSDNode_XI<instruction_name, cc, kind, SplatPatKind, 216 xop_kind> { 217 foreach vti = AllIntegerVectors in { 218 defvar instruction = !cast<Instruction>(instruction_name#_#kind#_#vti.LMul.MX); 219 def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1), 220 (vti.Vector (SplatPatKind xop_kind:$rs2)), cc)), 221 (instruction vti.RegClass:$rs1, xop_kind:$rs2, vti.AVL, vti.Log2SEW)>; 222 def : Pat<(vti.Mask (setcc (vti.Vector (SplatPatKind xop_kind:$rs2)), 223 (vti.Vector vti.RegClass:$rs1), invcc)), 224 (instruction vti.RegClass:$rs1, xop_kind:$rs2, vti.AVL, vti.Log2SEW)>; 225 } 226} 227 228multiclass VPatIntegerSetCCSDNode_VX_Swappable<string instruction_name, 229 CondCode cc, CondCode invcc> 230 : VPatIntegerSetCCSDNode_XI_Swappable<instruction_name, cc, invcc, "VX", 231 SplatPat, GPR>; 232 233multiclass VPatIntegerSetCCSDNode_VI<string instruction_name, CondCode cc> 234 : VPatIntegerSetCCSDNode_XI<instruction_name, cc, "VI", SplatPat_simm5, simm5>; 235 236multiclass VPatIntegerSetCCSDNode_VIPlus1<string instruction_name, CondCode cc, 237 ComplexPattern splatpat_kind> { 238 foreach vti = AllIntegerVectors in { 239 defvar instruction = !cast<Instruction>(instruction_name#"_VI_"#vti.LMul.MX); 240 def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1), 241 (vti.Vector (splatpat_kind simm5:$rs2)), 242 cc)), 243 (instruction vti.RegClass:$rs1, (DecImm simm5:$rs2), 244 vti.AVL, vti.Log2SEW)>; 245 } 246} 247 248multiclass VPatFPSetCCSDNode_VV_VF_FV<CondCode cc, 249 string inst_name, 250 string swapped_op_inst_name> { 251 foreach fvti = AllFloatVectors in { 252 def : Pat<(fvti.Mask (setcc (fvti.Vector fvti.RegClass:$rs1), 253 (fvti.Vector fvti.RegClass:$rs2), 254 cc)), 255 (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX) 256 fvti.RegClass:$rs1, fvti.RegClass:$rs2, fvti.AVL, fvti.Log2SEW)>; 257 def : Pat<(fvti.Mask (setcc (fvti.Vector fvti.RegClass:$rs1), 258 (SplatFPOp fvti.ScalarRegClass:$rs2), 259 cc)), 260 (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 261 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 262 fvti.AVL, fvti.Log2SEW)>; 263 def : Pat<(fvti.Mask (setcc (SplatFPOp fvti.ScalarRegClass:$rs2), 264 (fvti.Vector fvti.RegClass:$rs1), 265 cc)), 266 (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 267 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, 268 fvti.AVL, fvti.Log2SEW)>; 269 } 270} 271 272multiclass VPatExtendSDNode_V<list<SDNode> ops, string inst_name, string suffix, 273 list <VTypeInfoToFraction> fraction_list> { 274 foreach vtiTofti = fraction_list in { 275 defvar vti = vtiTofti.Vti; 276 defvar fti = vtiTofti.Fti; 277 foreach op = ops in 278 def : Pat<(vti.Vector (op (fti.Vector fti.RegClass:$rs2))), 279 (!cast<Instruction>(inst_name#"_"#suffix#"_"#vti.LMul.MX) 280 fti.RegClass:$rs2, fti.AVL, vti.Log2SEW)>; 281 } 282} 283 284multiclass VPatConvertI2FPSDNode_V<SDNode vop, string instruction_name> { 285 foreach fvti = AllFloatVectors in { 286 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 287 def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))), 288 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 289 ivti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>; 290 } 291} 292 293multiclass VPatConvertFP2ISDNode_V<SDNode vop, string instruction_name> { 294 foreach fvti = AllFloatVectors in { 295 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 296 def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1))), 297 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX) 298 fvti.RegClass:$rs1, ivti.AVL, ivti.Log2SEW)>; 299 } 300} 301 302multiclass VPatWConvertI2FPSDNode_V<SDNode vop, string instruction_name> { 303 foreach vtiToWti = AllWidenableIntToFloatVectors in { 304 defvar ivti = vtiToWti.Vti; 305 defvar fwti = vtiToWti.Wti; 306 def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))), 307 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX) 308 ivti.RegClass:$rs1, ivti.AVL, ivti.Log2SEW)>; 309 } 310} 311 312multiclass VPatWConvertFP2ISDNode_V<SDNode vop, string instruction_name> { 313 foreach fvtiToFWti = AllWidenableFloatVectors in { 314 defvar fvti = fvtiToFWti.Vti; 315 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 316 def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1))), 317 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 318 fvti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>; 319 } 320} 321 322multiclass VPatNConvertI2FPSDNode_V<SDNode vop, string instruction_name> { 323 foreach fvtiToFWti = AllWidenableFloatVectors in { 324 defvar fvti = fvtiToFWti.Vti; 325 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 326 def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1))), 327 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX) 328 iwti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>; 329 } 330} 331 332multiclass VPatNConvertFP2ISDNode_V<SDNode vop, string instruction_name> { 333 foreach vtiToWti = AllWidenableIntToFloatVectors in { 334 defvar vti = vtiToWti.Vti; 335 defvar fwti = vtiToWti.Wti; 336 def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1))), 337 (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX) 338 fwti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; 339 } 340} 341 342multiclass VPatWidenBinarySDNode_VV_VX<SDNode op, PatFrags extop1, PatFrags extop2, 343 string instruction_name> { 344 foreach vtiToWti = AllWidenableIntVectors in { 345 defvar vti = vtiToWti.Vti; 346 defvar wti = vtiToWti.Wti; 347 def : Pat<(op (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs2))), 348 (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs1)))), 349 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 350 vti.RegClass:$rs2, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; 351 def : Pat<(op (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs2))), 352 (wti.Vector (extop2 (vti.Vector (SplatPat GPR:$rs1))))), 353 (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX) 354 vti.RegClass:$rs2, GPR:$rs1, vti.AVL, vti.Log2SEW)>; 355 } 356} 357 358multiclass VPatWidenBinarySDNode_WV_WX<SDNode op, PatFrags extop, 359 string instruction_name> { 360 foreach vtiToWti = AllWidenableIntVectors in { 361 defvar vti = vtiToWti.Vti; 362 defvar wti = vtiToWti.Wti; 363 def : Pat<(op (wti.Vector wti.RegClass:$rs2), 364 (wti.Vector (extop (vti.Vector vti.RegClass:$rs1)))), 365 (!cast<Instruction>(instruction_name#"_WV_"#vti.LMul.MX) 366 wti.RegClass:$rs2, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; 367 def : Pat<(op (wti.Vector wti.RegClass:$rs2), 368 (wti.Vector (extop (vti.Vector (SplatPat GPR:$rs1))))), 369 (!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX) 370 wti.RegClass:$rs2, GPR:$rs1, vti.AVL, vti.Log2SEW)>; 371 } 372} 373 374multiclass VPatWidenBinarySDNode_VV_VX_WV_WX<SDNode op, PatFrags extop, 375 string instruction_name> { 376 defm : VPatWidenBinarySDNode_VV_VX<op, extop, extop, instruction_name>; 377 defm : VPatWidenBinarySDNode_WV_WX<op, extop, instruction_name>; 378} 379 380multiclass VPatWidenMulAddSDNode_VV<PatFrags extop1, PatFrags extop2, string instruction_name> { 381 foreach vtiToWti = AllWidenableIntVectors in { 382 defvar vti = vtiToWti.Vti; 383 defvar wti = vtiToWti.Wti; 384 def : Pat< 385 (add (wti.Vector wti.RegClass:$rd), 386 (mul_oneuse (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs1))), 387 (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs2))))), 388 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 389 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 390 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC 391 )>; 392 } 393} 394multiclass VPatWidenMulAddSDNode_VX<PatFrags extop1, PatFrags extop2, string instruction_name> { 395 foreach vtiToWti = AllWidenableIntVectors in { 396 defvar vti = vtiToWti.Vti; 397 defvar wti = vtiToWti.Wti; 398 def : Pat< 399 (add (wti.Vector wti.RegClass:$rd), 400 (mul_oneuse (wti.Vector (extop1 (vti.Vector (SplatPat GPR:$rs1)))), 401 (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs2))))), 402 (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX) 403 wti.RegClass:$rd, GPR:$rs1, vti.RegClass:$rs2, 404 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC 405 )>; 406 } 407} 408 409multiclass VPatWidenBinaryFPSDNode_VV_VF<SDNode op, string instruction_name> { 410 foreach vtiToWti = AllWidenableFloatVectors in { 411 defvar vti = vtiToWti.Vti; 412 defvar wti = vtiToWti.Wti; 413 def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 414 (vti.Vector vti.RegClass:$rs2), 415 (vti.Mask true_mask), (XLenVT srcvalue))), 416 (wti.Vector (riscv_fpextend_vl_oneuse 417 (vti.Vector vti.RegClass:$rs1), 418 (vti.Mask true_mask), (XLenVT srcvalue)))), 419 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 420 vti.RegClass:$rs2, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; 421 def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 422 (vti.Vector vti.RegClass:$rs2), 423 (vti.Mask true_mask), (XLenVT srcvalue))), 424 (wti.Vector (riscv_fpextend_vl_oneuse 425 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 426 (vti.Mask true_mask), (XLenVT srcvalue)))), 427 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 428 vti.RegClass:$rs2, vti.ScalarRegClass:$rs1, vti.AVL, vti.Log2SEW)>; 429 def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse 430 (vti.Vector vti.RegClass:$rs2), 431 (vti.Mask true_mask), (XLenVT srcvalue))), 432 (wti.Vector (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1)))), 433 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 434 vti.RegClass:$rs2, vti.ScalarRegClass:$rs1, vti.AVL, vti.Log2SEW)>; 435 } 436} 437 438multiclass VPatWidenBinaryFPSDNode_WV_WF<SDNode op, string instruction_name> { 439 foreach vtiToWti = AllWidenableFloatVectors in { 440 defvar vti = vtiToWti.Vti; 441 defvar wti = vtiToWti.Wti; 442 def : Pat<(op (wti.Vector wti.RegClass:$rs2), 443 (wti.Vector (riscv_fpextend_vl_oneuse 444 (vti.Vector vti.RegClass:$rs1), 445 (vti.Mask true_mask), (XLenVT srcvalue)))), 446 (!cast<Instruction>(instruction_name#"_WV_"#vti.LMul.MX) 447 wti.RegClass:$rs2, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; 448 def : Pat<(op (wti.Vector wti.RegClass:$rs2), 449 (wti.Vector (riscv_fpextend_vl_oneuse 450 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 451 (vti.Mask true_mask), (XLenVT srcvalue)))), 452 (!cast<Instruction>(instruction_name#"_W"#vti.ScalarSuffix#"_"#vti.LMul.MX) 453 wti.RegClass:$rs2, vti.ScalarRegClass:$rs1, vti.AVL, vti.Log2SEW)>; 454 def : Pat<(op (wti.Vector wti.RegClass:$rs2), 455 (wti.Vector (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1)))), 456 (!cast<Instruction>(instruction_name#"_W"#vti.ScalarSuffix#"_"#vti.LMul.MX) 457 wti.RegClass:$rs2, vti.ScalarRegClass:$rs1, vti.AVL, vti.Log2SEW)>; 458 } 459} 460 461multiclass VPatWidenBinaryFPSDNode_VV_VF_WV_WF<SDNode op, string instruction_name> { 462 defm : VPatWidenBinaryFPSDNode_VV_VF<op, instruction_name>; 463 defm : VPatWidenBinaryFPSDNode_WV_WF<op, instruction_name>; 464} 465 466multiclass VPatWidenFPMulAccSDNode_VV_VF<string instruction_name> { 467 foreach vtiToWti = AllWidenableFloatVectors in { 468 defvar vti = vtiToWti.Vti; 469 defvar wti = vtiToWti.Wti; 470 def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse 471 (vti.Vector vti.RegClass:$rs1), 472 (vti.Mask true_mask), (XLenVT srcvalue))), 473 (wti.Vector (riscv_fpextend_vl_oneuse 474 (vti.Vector vti.RegClass:$rs2), 475 (vti.Mask true_mask), (XLenVT srcvalue))), 476 (wti.Vector wti.RegClass:$rd)), 477 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 478 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 479 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 480 def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse 481 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 482 (vti.Mask true_mask), (XLenVT srcvalue))), 483 (wti.Vector (riscv_fpextend_vl_oneuse 484 (vti.Vector vti.RegClass:$rs2), 485 (vti.Mask true_mask), (XLenVT srcvalue))), 486 (wti.Vector wti.RegClass:$rd)), 487 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 488 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 489 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 490 } 491} 492 493multiclass VPatWidenFPNegMulAccSDNode_VV_VF<string instruction_name> { 494 foreach vtiToWti = AllWidenableFloatVectors in { 495 defvar vti = vtiToWti.Vti; 496 defvar wti = vtiToWti.Wti; 497 def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse 498 (vti.Vector vti.RegClass:$rs1), 499 (vti.Mask true_mask), (XLenVT srcvalue)))), 500 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 501 (vti.Mask true_mask), (XLenVT srcvalue)), 502 (fneg wti.RegClass:$rd)), 503 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 504 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 505 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 506 def : Pat<(fma (riscv_fpextend_vl_oneuse 507 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 508 (vti.Mask true_mask), (XLenVT srcvalue)), 509 (fneg (wti.Vector (riscv_fpextend_vl_oneuse 510 (vti.Vector vti.RegClass:$rs2), 511 (vti.Mask true_mask), (XLenVT srcvalue)))), 512 (fneg wti.RegClass:$rd)), 513 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 514 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 515 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 516 def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse 517 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 518 (vti.Mask true_mask), (XLenVT srcvalue)))), 519 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 520 (vti.Mask true_mask), (XLenVT srcvalue)), 521 (fneg wti.RegClass:$rd)), 522 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 523 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 524 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 525 } 526} 527 528multiclass VPatWidenFPMulSacSDNode_VV_VF<string instruction_name> { 529 foreach vtiToWti = AllWidenableFloatVectors in { 530 defvar vti = vtiToWti.Vti; 531 defvar wti = vtiToWti.Wti; 532 def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse 533 (vti.Vector vti.RegClass:$rs1), 534 (vti.Mask true_mask), (XLenVT srcvalue))), 535 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 536 (vti.Mask true_mask), (XLenVT srcvalue)), 537 (fneg wti.RegClass:$rd)), 538 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 539 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 540 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 541 def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse 542 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 543 (vti.Mask true_mask), (XLenVT srcvalue))), 544 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 545 (vti.Mask true_mask), (XLenVT srcvalue)), 546 (fneg wti.RegClass:$rd)), 547 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 548 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 549 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 550 } 551} 552 553multiclass VPatWidenFPNegMulSacSDNode_VV_VF<string instruction_name> { 554 foreach vtiToWti = AllWidenableFloatVectors in { 555 defvar vti = vtiToWti.Vti; 556 defvar wti = vtiToWti.Wti; 557 def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse 558 (vti.Vector vti.RegClass:$rs1), 559 (vti.Mask true_mask), (XLenVT srcvalue)))), 560 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 561 (vti.Mask true_mask), (XLenVT srcvalue)), 562 wti.RegClass:$rd), 563 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX) 564 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 565 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 566 def : Pat<(fma (wti.Vector (riscv_fpextend_vl_oneuse 567 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 568 (vti.Mask true_mask), (XLenVT srcvalue))), 569 (fneg (wti.Vector (riscv_fpextend_vl_oneuse 570 (vti.Vector vti.RegClass:$rs2), 571 (vti.Mask true_mask), (XLenVT srcvalue)))), 572 wti.RegClass:$rd), 573 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 574 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 575 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 576 def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse 577 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)), 578 (vti.Mask true_mask), (XLenVT srcvalue)))), 579 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2), 580 (vti.Mask true_mask), (XLenVT srcvalue)), 581 wti.RegClass:$rd), 582 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 583 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 584 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 585 } 586} 587 588multiclass VPatMultiplyAddSDNode_VV_VX<SDNode op, string instruction_name> { 589 foreach vti = AllIntegerVectors in { 590 defvar suffix = vti.LMul.MX; 591 // NOTE: We choose VMADD because it has the most commuting freedom. So it 592 // works best with how TwoAddressInstructionPass tries commuting. 593 def : Pat<(vti.Vector (op vti.RegClass:$rs2, 594 (mul_oneuse vti.RegClass:$rs1, vti.RegClass:$rd))), 595 (!cast<Instruction>(instruction_name#"_VV_"# suffix) 596 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, 597 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 598 // The choice of VMADD here is arbitrary, vmadd.vx and vmacc.vx are equally 599 // commutable. 600 def : Pat<(vti.Vector (op vti.RegClass:$rs2, 601 (mul_oneuse (SplatPat XLenVT:$rs1), vti.RegClass:$rd))), 602 (!cast<Instruction>(instruction_name#"_VX_" # suffix) 603 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, 604 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; 605 } 606} 607 608//===----------------------------------------------------------------------===// 609// Patterns. 610//===----------------------------------------------------------------------===// 611 612let Predicates = [HasVInstructions] in { 613 614// 7.4. Vector Unit-Stride Instructions 615foreach vti = !listconcat(FractionalGroupIntegerVectors, 616 FractionalGroupFloatVectors) in 617 defm : VPatUSLoadStoreSDNode<vti.Vector, vti.Log2SEW, vti.LMul, 618 vti.AVL, vti.RegClass>; 619foreach vti = [VI8M1, VI16M1, VI32M1, VI64M1, VF16M1, VF32M1, VF64M1] in 620 defm : VPatUSLoadStoreWholeVRSDNode<vti.Vector, vti.Log2SEW, vti.LMul, 621 vti.RegClass>; 622foreach vti = !listconcat(GroupIntegerVectors, GroupFloatVectors) in 623 defm : VPatUSLoadStoreWholeVRSDNode<vti.Vector, vti.Log2SEW, vti.LMul, 624 vti.RegClass>; 625foreach mti = AllMasks in 626 defm : VPatUSLoadStoreMaskSDNode<mti>; 627 628// 12.1. Vector Single-Width Integer Add and Subtract 629defm : VPatBinarySDNode_VV_VX_VI<add, "PseudoVADD">; 630defm : VPatBinarySDNode_VV_VX<sub, "PseudoVSUB">; 631// Handle VRSUB specially since it's the only integer binary op with reversed 632// pattern operands 633foreach vti = AllIntegerVectors in { 634 def : Pat<(sub (vti.Vector (SplatPat GPR:$rs2)), 635 (vti.Vector vti.RegClass:$rs1)), 636 (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX) 637 vti.RegClass:$rs1, GPR:$rs2, vti.AVL, vti.Log2SEW)>; 638 def : Pat<(sub (vti.Vector (SplatPat_simm5 simm5:$rs2)), 639 (vti.Vector vti.RegClass:$rs1)), 640 (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX) 641 vti.RegClass:$rs1, simm5:$rs2, vti.AVL, vti.Log2SEW)>; 642} 643 644// 12.2. Vector Widening Integer Add and Subtract 645defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, sext_oneuse, "PseudoVWADD">; 646defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, zext_oneuse, "PseudoVWADDU">; 647defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, anyext_oneuse, "PseudoVWADDU">; 648 649defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, sext_oneuse, "PseudoVWSUB">; 650defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, zext_oneuse, "PseudoVWSUBU">; 651defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, anyext_oneuse, "PseudoVWSUBU">; 652 653// 12.3. Vector Integer Extension 654defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF2", 655 AllFractionableVF2IntVectors>; 656defm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF2", 657 AllFractionableVF2IntVectors>; 658defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF4", 659 AllFractionableVF4IntVectors>; 660defm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF4", 661 AllFractionableVF4IntVectors>; 662defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF8", 663 AllFractionableVF8IntVectors>; 664defm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF8", 665 AllFractionableVF8IntVectors>; 666 667// 12.5. Vector Bitwise Logical Instructions 668defm : VPatBinarySDNode_VV_VX_VI<and, "PseudoVAND">; 669defm : VPatBinarySDNode_VV_VX_VI<or, "PseudoVOR">; 670defm : VPatBinarySDNode_VV_VX_VI<xor, "PseudoVXOR">; 671 672// 12.6. Vector Single-Width Bit Shift Instructions 673defm : VPatBinarySDNode_VV_VX_VI<shl, "PseudoVSLL", uimm5>; 674defm : VPatBinarySDNode_VV_VX_VI<srl, "PseudoVSRL", uimm5>; 675defm : VPatBinarySDNode_VV_VX_VI<sra, "PseudoVSRA", uimm5>; 676 677foreach vti = AllIntegerVectors in { 678 // Emit shift by 1 as an add since it might be faster. 679 def : Pat<(shl (vti.Vector vti.RegClass:$rs1), 680 (vti.Vector (riscv_vmv_v_x_vl (vti.Vector undef), 1, (XLenVT srcvalue)))), 681 (!cast<Instruction>("PseudoVADD_VV_"# vti.LMul.MX) 682 vti.RegClass:$rs1, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; 683 684} 685 686// 12.8. Vector Integer Comparison Instructions 687defm : VPatIntegerSetCCSDNode_VV<"PseudoVMSEQ", SETEQ>; 688defm : VPatIntegerSetCCSDNode_VV<"PseudoVMSNE", SETNE>; 689 690defm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLT", SETLT, SETGT>; 691defm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLTU", SETULT, SETUGT>; 692defm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLE", SETLE, SETGE>; 693defm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLEU", SETULE, SETUGE>; 694 695defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSEQ", SETEQ, SETEQ>; 696defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSNE", SETNE, SETNE>; 697defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLT", SETLT, SETGT>; 698defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLTU", SETULT, SETUGT>; 699defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLE", SETLE, SETGE>; 700defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLEU", SETULE, SETUGE>; 701defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSGT", SETGT, SETLT>; 702defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSGTU", SETUGT, SETULT>; 703// There is no VMSGE(U)_VX instruction 704 705defm : VPatIntegerSetCCSDNode_VI<"PseudoVMSEQ", SETEQ>; 706defm : VPatIntegerSetCCSDNode_VI<"PseudoVMSNE", SETNE>; 707defm : VPatIntegerSetCCSDNode_VI<"PseudoVMSLE", SETLE>; 708defm : VPatIntegerSetCCSDNode_VI<"PseudoVMSLEU", SETULE>; 709defm : VPatIntegerSetCCSDNode_VI<"PseudoVMSGT", SETGT>; 710defm : VPatIntegerSetCCSDNode_VI<"PseudoVMSGTU", SETUGT>; 711 712defm : VPatIntegerSetCCSDNode_VIPlus1<"PseudoVMSLE", SETLT, 713 SplatPat_simm5_plus1_nonzero>; 714defm : VPatIntegerSetCCSDNode_VIPlus1<"PseudoVMSLEU", SETULT, 715 SplatPat_simm5_plus1_nonzero>; 716defm : VPatIntegerSetCCSDNode_VIPlus1<"PseudoVMSGT", SETGE, 717 SplatPat_simm5_plus1>; 718defm : VPatIntegerSetCCSDNode_VIPlus1<"PseudoVMSGTU", SETUGE, 719 SplatPat_simm5_plus1_nonzero>; 720 721// 12.9. Vector Integer Min/Max Instructions 722defm : VPatBinarySDNode_VV_VX<umin, "PseudoVMINU">; 723defm : VPatBinarySDNode_VV_VX<smin, "PseudoVMIN">; 724defm : VPatBinarySDNode_VV_VX<umax, "PseudoVMAXU">; 725defm : VPatBinarySDNode_VV_VX<smax, "PseudoVMAX">; 726 727// 12.10. Vector Single-Width Integer Multiply Instructions 728defm : VPatBinarySDNode_VV_VX<mul, "PseudoVMUL">; 729defm : VPatBinarySDNode_VV_VX<mulhs, "PseudoVMULH">; 730defm : VPatBinarySDNode_VV_VX<mulhu, "PseudoVMULHU">; 731 732// 12.11. Vector Integer Divide Instructions 733defm : VPatBinarySDNode_VV_VX<udiv, "PseudoVDIVU">; 734defm : VPatBinarySDNode_VV_VX<sdiv, "PseudoVDIV">; 735defm : VPatBinarySDNode_VV_VX<urem, "PseudoVREMU">; 736defm : VPatBinarySDNode_VV_VX<srem, "PseudoVREM">; 737 738// 12.12. Vector Widening Integer Multiply Instructions 739defm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, sext_oneuse, 740 "PseudoVWMUL">; 741defm : VPatWidenBinarySDNode_VV_VX<mul, zext_oneuse, zext_oneuse, 742 "PseudoVWMULU">; 743defm : VPatWidenBinarySDNode_VV_VX<mul, anyext_oneuse, anyext_oneuse, 744 "PseudoVWMULU">; 745defm : VPatWidenBinarySDNode_VV_VX<mul, zext_oneuse, anyext_oneuse, 746 "PseudoVWMULU">; 747defm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, zext_oneuse, 748 "PseudoVWMULSU">; 749defm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, anyext_oneuse, 750 "PseudoVWMULSU">; 751 752// 12.13 Vector Single-Width Integer Multiply-Add Instructions. 753defm : VPatMultiplyAddSDNode_VV_VX<add, "PseudoVMADD">; 754defm : VPatMultiplyAddSDNode_VV_VX<sub, "PseudoVNMSUB">; 755 756// 12.14 Vector Widening Integer Multiply-Add Instructions 757defm : VPatWidenMulAddSDNode_VV<sext_oneuse, sext_oneuse, "PseudoVWMACC">; 758defm : VPatWidenMulAddSDNode_VX<sext_oneuse, sext_oneuse, "PseudoVWMACC">; 759defm : VPatWidenMulAddSDNode_VV<zext_oneuse, zext_oneuse, "PseudoVWMACCU">; 760defm : VPatWidenMulAddSDNode_VX<zext_oneuse, zext_oneuse, "PseudoVWMACCU">; 761defm : VPatWidenMulAddSDNode_VV<sext_oneuse, zext_oneuse, "PseudoVWMACCSU">; 762defm : VPatWidenMulAddSDNode_VX<sext_oneuse, zext_oneuse, "PseudoVWMACCSU">; 763defm : VPatWidenMulAddSDNode_VX<zext_oneuse, sext_oneuse, "PseudoVWMACCUS">; 764 765// 12.15. Vector Integer Merge Instructions 766foreach vti = AllIntegerVectors in { 767 def : Pat<(vti.Vector (vselect (vti.Mask V0), vti.RegClass:$rs1, 768 vti.RegClass:$rs2)), 769 (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX) 770 vti.RegClass:$rs2, vti.RegClass:$rs1, (vti.Mask V0), 771 vti.AVL, vti.Log2SEW)>; 772 773 def : Pat<(vti.Vector (vselect (vti.Mask V0), (SplatPat XLenVT:$rs1), 774 vti.RegClass:$rs2)), 775 (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX) 776 vti.RegClass:$rs2, GPR:$rs1, (vti.Mask V0), vti.AVL, vti.Log2SEW)>; 777 778 def : Pat<(vti.Vector (vselect (vti.Mask V0), (SplatPat_simm5 simm5:$rs1), 779 vti.RegClass:$rs2)), 780 (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX) 781 vti.RegClass:$rs2, simm5:$rs1, (vti.Mask V0), vti.AVL, vti.Log2SEW)>; 782} 783 784// 12.1. Vector Single-Width Saturating Add and Subtract 785defm : VPatBinarySDNode_VV_VX_VI<saddsat, "PseudoVSADD">; 786defm : VPatBinarySDNode_VV_VX_VI<uaddsat, "PseudoVSADDU">; 787defm : VPatBinarySDNode_VV_VX<ssubsat, "PseudoVSSUB">; 788defm : VPatBinarySDNode_VV_VX<usubsat, "PseudoVSSUBU">; 789 790// 16.1. Vector Mask-Register Logical Instructions 791foreach mti = AllMasks in { 792 def : Pat<(mti.Mask (and VR:$rs1, VR:$rs2)), 793 (!cast<Instruction>("PseudoVMAND_MM_"#mti.LMul.MX) 794 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 795 def : Pat<(mti.Mask (or VR:$rs1, VR:$rs2)), 796 (!cast<Instruction>("PseudoVMOR_MM_"#mti.LMul.MX) 797 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 798 def : Pat<(mti.Mask (xor VR:$rs1, VR:$rs2)), 799 (!cast<Instruction>("PseudoVMXOR_MM_"#mti.LMul.MX) 800 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 801 802 def : Pat<(mti.Mask (rvv_vnot (and VR:$rs1, VR:$rs2))), 803 (!cast<Instruction>("PseudoVMNAND_MM_"#mti.LMul.MX) 804 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 805 def : Pat<(mti.Mask (rvv_vnot (or VR:$rs1, VR:$rs2))), 806 (!cast<Instruction>("PseudoVMNOR_MM_"#mti.LMul.MX) 807 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 808 def : Pat<(mti.Mask (rvv_vnot (xor VR:$rs1, VR:$rs2))), 809 (!cast<Instruction>("PseudoVMXNOR_MM_"#mti.LMul.MX) 810 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 811 812 def : Pat<(mti.Mask (and VR:$rs1, (rvv_vnot VR:$rs2))), 813 (!cast<Instruction>("PseudoVMANDN_MM_"#mti.LMul.MX) 814 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 815 def : Pat<(mti.Mask (or VR:$rs1, (rvv_vnot VR:$rs2))), 816 (!cast<Instruction>("PseudoVMORN_MM_"#mti.LMul.MX) 817 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>; 818 819 // Handle rvv_vnot the same as the vmnot.m pseudoinstruction. 820 def : Pat<(mti.Mask (rvv_vnot VR:$rs)), 821 (!cast<Instruction>("PseudoVMNAND_MM_"#mti.LMul.MX) 822 VR:$rs, VR:$rs, mti.AVL, mti.Log2SEW)>; 823} 824 825} // Predicates = [HasVInstructions] 826 827let Predicates = [HasVInstructionsAnyF] in { 828 829// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions 830defm : VPatBinaryFPSDNode_VV_VF<fadd, "PseudoVFADD">; 831defm : VPatBinaryFPSDNode_VV_VF<fsub, "PseudoVFSUB">; 832defm : VPatBinaryFPSDNode_R_VF<fsub, "PseudoVFRSUB">; 833 834// 14.3. Vector Widening Floating-Point Add/Subtract Instructions 835defm : VPatWidenBinaryFPSDNode_VV_VF_WV_WF<fadd, "PseudoVFWADD">; 836defm : VPatWidenBinaryFPSDNode_VV_VF_WV_WF<fsub, "PseudoVFWSUB">; 837 838// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 839defm : VPatBinaryFPSDNode_VV_VF<fmul, "PseudoVFMUL">; 840defm : VPatBinaryFPSDNode_VV_VF<fdiv, "PseudoVFDIV">; 841defm : VPatBinaryFPSDNode_R_VF<fdiv, "PseudoVFRDIV">; 842 843// 14.5. Vector Widening Floating-Point Multiply Instructions 844defm : VPatWidenBinaryFPSDNode_VV_VF<fmul, "PseudoVFWMUL">; 845 846// 14.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions. 847foreach fvti = AllFloatVectors in { 848 // NOTE: We choose VFMADD because it has the most commuting freedom. So it 849 // works best with how TwoAddressInstructionPass tries commuting. 850 defvar suffix = fvti.LMul.MX; 851 def : Pat<(fvti.Vector (fma fvti.RegClass:$rs1, fvti.RegClass:$rd, 852 fvti.RegClass:$rs2)), 853 (!cast<Instruction>("PseudoVFMADD_VV_"# suffix) 854 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2, 855 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 856 def : Pat<(fvti.Vector (fma fvti.RegClass:$rs1, fvti.RegClass:$rd, 857 (fneg fvti.RegClass:$rs2))), 858 (!cast<Instruction>("PseudoVFMSUB_VV_"# suffix) 859 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2, 860 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 861 def : Pat<(fvti.Vector (fma (fneg fvti.RegClass:$rs1), fvti.RegClass:$rd, 862 (fneg fvti.RegClass:$rs2))), 863 (!cast<Instruction>("PseudoVFNMADD_VV_"# suffix) 864 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2, 865 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 866 def : Pat<(fvti.Vector (fma (fneg fvti.RegClass:$rs1), fvti.RegClass:$rd, 867 fvti.RegClass:$rs2)), 868 (!cast<Instruction>("PseudoVFNMSUB_VV_"# suffix) 869 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2, 870 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 871 872 // The choice of VFMADD here is arbitrary, vfmadd.vf and vfmacc.vf are equally 873 // commutable. 874 def : Pat<(fvti.Vector (fma (SplatFPOp fvti.ScalarRegClass:$rs1), 875 fvti.RegClass:$rd, fvti.RegClass:$rs2)), 876 (!cast<Instruction>("PseudoVFMADD_V" # fvti.ScalarSuffix # "_" # suffix) 877 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 878 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 879 def : Pat<(fvti.Vector (fma (SplatFPOp fvti.ScalarRegClass:$rs1), 880 fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))), 881 (!cast<Instruction>("PseudoVFMSUB_V" # fvti.ScalarSuffix # "_" # suffix) 882 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 883 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 884 885 def : Pat<(fvti.Vector (fma (SplatFPOp fvti.ScalarRegClass:$rs1), 886 (fneg fvti.RegClass:$rd), (fneg fvti.RegClass:$rs2))), 887 (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix) 888 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 889 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 890 def : Pat<(fvti.Vector (fma (SplatFPOp fvti.ScalarRegClass:$rs1), 891 (fneg fvti.RegClass:$rd), fvti.RegClass:$rs2)), 892 (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix) 893 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 894 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 895 896 // The splat might be negated. 897 def : Pat<(fvti.Vector (fma (fneg (SplatFPOp fvti.ScalarRegClass:$rs1)), 898 fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))), 899 (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix) 900 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 901 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 902 def : Pat<(fvti.Vector (fma (fneg (SplatFPOp fvti.ScalarRegClass:$rs1)), 903 fvti.RegClass:$rd, fvti.RegClass:$rs2)), 904 (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix) 905 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, 906 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>; 907} 908 909// 14.7. Vector Widening Floating-Point Fused Multiply-Add Instructions 910defm : VPatWidenFPMulAccSDNode_VV_VF<"PseudoVFWMACC">; 911defm : VPatWidenFPNegMulAccSDNode_VV_VF<"PseudoVFWNMACC">; 912defm : VPatWidenFPMulSacSDNode_VV_VF<"PseudoVFWMSAC">; 913defm : VPatWidenFPNegMulSacSDNode_VV_VF<"PseudoVFWNMSAC">; 914 915foreach vti = AllFloatVectors in { 916 // 14.8. Vector Floating-Point Square-Root Instruction 917 def : Pat<(fsqrt (vti.Vector vti.RegClass:$rs2)), 918 (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX) 919 vti.RegClass:$rs2, vti.AVL, vti.Log2SEW)>; 920 921 // 14.12. Vector Floating-Point Sign-Injection Instructions 922 def : Pat<(fabs (vti.Vector vti.RegClass:$rs)), 923 (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX) 924 vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.Log2SEW)>; 925 // Handle fneg with VFSGNJN using the same input for both operands. 926 def : Pat<(fneg (vti.Vector vti.RegClass:$rs)), 927 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX) 928 vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.Log2SEW)>; 929 930 def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1), 931 (vti.Vector vti.RegClass:$rs2))), 932 (!cast<Instruction>("PseudoVFSGNJ_VV_"# vti.LMul.MX) 933 vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW)>; 934 def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1), 935 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs2)))), 936 (!cast<Instruction>("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 937 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.Log2SEW)>; 938 939 def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1), 940 (vti.Vector (fneg vti.RegClass:$rs2)))), 941 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX) 942 vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW)>; 943 def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1), 944 (vti.Vector (fneg (SplatFPOp vti.ScalarRegClass:$rs2))))), 945 (!cast<Instruction>("PseudoVFSGNJN_V"#vti.ScalarSuffix#"_"#vti.LMul.MX) 946 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.Log2SEW)>; 947} 948 949// 14.11. Vector Floating-Point MIN/MAX Instructions 950defm : VPatBinaryFPSDNode_VV_VF<fminnum, "PseudoVFMIN">; 951defm : VPatBinaryFPSDNode_VV_VF<fmaxnum, "PseudoVFMAX">; 952 953// 14.13. Vector Floating-Point Compare Instructions 954defm : VPatFPSetCCSDNode_VV_VF_FV<SETEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 955defm : VPatFPSetCCSDNode_VV_VF_FV<SETOEQ, "PseudoVMFEQ", "PseudoVMFEQ">; 956 957defm : VPatFPSetCCSDNode_VV_VF_FV<SETNE, "PseudoVMFNE", "PseudoVMFNE">; 958defm : VPatFPSetCCSDNode_VV_VF_FV<SETUNE, "PseudoVMFNE", "PseudoVMFNE">; 959 960defm : VPatFPSetCCSDNode_VV_VF_FV<SETLT, "PseudoVMFLT", "PseudoVMFGT">; 961defm : VPatFPSetCCSDNode_VV_VF_FV<SETOLT, "PseudoVMFLT", "PseudoVMFGT">; 962 963defm : VPatFPSetCCSDNode_VV_VF_FV<SETLE, "PseudoVMFLE", "PseudoVMFGE">; 964defm : VPatFPSetCCSDNode_VV_VF_FV<SETOLE, "PseudoVMFLE", "PseudoVMFGE">; 965 966// Floating-point vselects: 967// 12.15. Vector Integer Merge Instructions 968// 14.15. Vector Floating-Point Merge Instruction 969foreach fvti = AllFloatVectors in { 970 def : Pat<(fvti.Vector (vselect (fvti.Mask V0), fvti.RegClass:$rs1, 971 fvti.RegClass:$rs2)), 972 (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX) 973 fvti.RegClass:$rs2, fvti.RegClass:$rs1, (fvti.Mask V0), 974 fvti.AVL, fvti.Log2SEW)>; 975 976 def : Pat<(fvti.Vector (vselect (fvti.Mask V0), 977 (SplatFPOp fvti.ScalarRegClass:$rs1), 978 fvti.RegClass:$rs2)), 979 (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX) 980 fvti.RegClass:$rs2, 981 (fvti.Scalar fvti.ScalarRegClass:$rs1), 982 (fvti.Mask V0), fvti.AVL, fvti.Log2SEW)>; 983 984 def : Pat<(fvti.Vector (vselect (fvti.Mask V0), 985 (SplatFPOp (fvti.Scalar fpimm0)), 986 fvti.RegClass:$rs2)), 987 (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX) 988 fvti.RegClass:$rs2, 0, (fvti.Mask V0), fvti.AVL, fvti.Log2SEW)>; 989} 990 991// 14.17. Vector Single-Width Floating-Point/Integer Type-Convert Instructions 992defm : VPatConvertFP2ISDNode_V<fp_to_sint, "PseudoVFCVT_RTZ_X_F_V">; 993defm : VPatConvertFP2ISDNode_V<fp_to_uint, "PseudoVFCVT_RTZ_XU_F_V">; 994defm : VPatConvertI2FPSDNode_V<sint_to_fp, "PseudoVFCVT_F_X_V">; 995defm : VPatConvertI2FPSDNode_V<uint_to_fp, "PseudoVFCVT_F_XU_V">; 996 997// 14.18. Widening Floating-Point/Integer Type-Convert Instructions 998defm : VPatWConvertFP2ISDNode_V<fp_to_sint, "PseudoVFWCVT_RTZ_X_F_V">; 999defm : VPatWConvertFP2ISDNode_V<fp_to_uint, "PseudoVFWCVT_RTZ_XU_F_V">; 1000defm : VPatWConvertI2FPSDNode_V<sint_to_fp, "PseudoVFWCVT_F_X_V">; 1001defm : VPatWConvertI2FPSDNode_V<uint_to_fp, "PseudoVFWCVT_F_XU_V">; 1002 1003// 14.19. Narrowing Floating-Point/Integer Type-Convert Instructions 1004defm : VPatNConvertFP2ISDNode_V<fp_to_sint, "PseudoVFNCVT_RTZ_X_F_W">; 1005defm : VPatNConvertFP2ISDNode_V<fp_to_uint, "PseudoVFNCVT_RTZ_XU_F_W">; 1006defm : VPatNConvertI2FPSDNode_V<sint_to_fp, "PseudoVFNCVT_F_X_W">; 1007defm : VPatNConvertI2FPSDNode_V<uint_to_fp, "PseudoVFNCVT_F_XU_W">; 1008foreach fvtiToFWti = AllWidenableFloatVectors in { 1009 defvar fvti = fvtiToFWti.Vti; 1010 defvar fwti = fvtiToFWti.Wti; 1011 def : Pat<(fvti.Vector (fpround (fwti.Vector fwti.RegClass:$rs1))), 1012 (!cast<Instruction>("PseudoVFNCVT_F_F_W_"#fvti.LMul.MX) 1013 fwti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW)>; 1014} 1015} // Predicates = [HasVInstructionsAnyF] 1016 1017//===----------------------------------------------------------------------===// 1018// Vector Splats 1019//===----------------------------------------------------------------------===// 1020 1021let Predicates = [HasVInstructionsAnyF] in { 1022foreach fvti = AllFloatVectors in { 1023 def : Pat<(fvti.Vector (SplatFPOp fvti.ScalarRegClass:$rs1)), 1024 (!cast<Instruction>("PseudoVFMV_V_"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) 1025 (fvti.Scalar fvti.ScalarRegClass:$rs1), 1026 fvti.AVL, fvti.Log2SEW)>; 1027 1028 def : Pat<(fvti.Vector (SplatFPOp (fvti.Scalar fpimm0))), 1029 (!cast<Instruction>("PseudoVMV_V_I_"#fvti.LMul.MX) 1030 0, fvti.AVL, fvti.Log2SEW)>; 1031} 1032} // Predicates = [HasVInstructionsAnyF] 1033 1034//===----------------------------------------------------------------------===// 1035// Vector Element Extracts 1036//===----------------------------------------------------------------------===// 1037let Predicates = [HasVInstructionsAnyF] in 1038foreach vti = AllFloatVectors in { 1039 // Fold store of vmv.f.s to a vse with VL=1. 1040 defvar store_instr = !cast<Instruction>("PseudoVSE"#vti.SEW#"_V_"#vti.LMul.MX); 1041 1042 let AddedComplexity = 2 in { 1043 // Add complexity to increase the priority of this pattern being matched. 1044 def : Pat<(store (vti.Scalar (int_riscv_vfmv_f_s (vti.Vector vti.RegClass:$rs2))), GPR:$rs1), 1045 (store_instr vti.RegClass:$rs2, GPR:$rs1, 1, vti.Log2SEW)>; 1046 def : Pat<(store (extractelt (vti.Vector vti.RegClass:$rs2), 0), GPR:$rs1), 1047 (store_instr vti.RegClass:$rs2, GPR:$rs1, 1, vti.Log2SEW)>; 1048 } 1049 1050 defvar vmv_f_s_inst = !cast<Instruction>(!strconcat("PseudoVFMV_", 1051 vti.ScalarSuffix, 1052 "_S_", vti.LMul.MX)); 1053 // Only pattern-match extract-element operations where the index is 0. Any 1054 // other index will have been custom-lowered to slide the vector correctly 1055 // into place. 1056 def : Pat<(vti.Scalar (extractelt (vti.Vector vti.RegClass:$rs2), 0)), 1057 (vmv_f_s_inst vti.RegClass:$rs2, vti.Log2SEW)>; 1058} 1059