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