1478 lines · plain
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-exception6//7//===----------------------------------------------------------------------===//8///9/// This file contains the required infrastructure and SDNode patterns to10/// support code generation for the standard 'V' (Vector) extension, version11/// version 1.0.12///13/// This file is included from and depends upon RISCVInstrInfoVPseudos.td14///15/// Note: the patterns for RVV intrinsics are found in16/// 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 RegisterClass regclass,29 int log2sew,30 LMULInfo vlmul,31 OutPatFrag avl,32 VReg reg_class,33 int sew = !shl(1, log2sew)> {34 defvar load_instr = !cast<Instruction>("PseudoVLE"#sew#"_V_"#vlmul.MX);35 defvar store_instr = !cast<Instruction>("PseudoVSE"#sew#"_V_"#vlmul.MX);36 // Load37 def : Pat<(type (load (XLenVT GPR:$rs1))),38 (load_instr (type (IMPLICIT_DEF)), GPR:$rs1, avl,39 log2sew, TA_MA)>;40 // Store41 def : Pat<(store (type regclass:$rs2), (XLenVT GPR:$rs1)),42 (store_instr reg_class:$rs2, GPR:$rs1, avl, log2sew)>;43}44 45multiclass VPatUSLoadStoreMaskSDNode<MTypeInfo m> {46 defvar load_instr = !cast<Instruction>("PseudoVLM_V_"#m.BX);47 defvar store_instr = !cast<Instruction>("PseudoVSM_V_"#m.BX);48 // Load49 def : Pat<(m.Mask (load GPR:$rs1)),50 (load_instr (m.Mask (IMPLICIT_DEF)), GPR:$rs1, m.AVL,51 m.Log2SEW, TA_MA)>;52 // Store53 def : Pat<(store (m.Mask VR:$rs2), GPR:$rs1),54 (store_instr VR:$rs2, GPR:$rs1, m.AVL, m.Log2SEW)>;55}56 57class VPatBinarySDNode_VV<SDPatternOperator vop,58 string instruction_name,59 ValueType result_type,60 ValueType op_type,61 int log2sew,62 LMULInfo vlmul,63 OutPatFrag avl,64 VReg op_reg_class,65 bit isSEWAware = 0> :66 Pat<(result_type (vop67 (op_type op_reg_class:$rs1),68 (op_type op_reg_class:$rs2))),69 (!cast<Instruction>(70 !if(isSEWAware,71 instruction_name#"_VV_"# vlmul.MX#"_E"#!shl(1, log2sew),72 instruction_name#"_VV_"# vlmul.MX))73 (result_type (IMPLICIT_DEF)),74 op_reg_class:$rs1,75 op_reg_class:$rs2,76 avl, log2sew, TA_MA)>;77 78class VPatBinarySDNode_VV_RM<SDPatternOperator vop,79 string instruction_name,80 ValueType result_type,81 ValueType op_type,82 int log2sew,83 LMULInfo vlmul,84 OutPatFrag avl,85 VReg op_reg_class,86 bit isSEWAware = 0> :87 Pat<(result_type (vop88 (op_type op_reg_class:$rs1),89 (op_type op_reg_class:$rs2))),90 (!cast<Instruction>(91 !if(isSEWAware,92 instruction_name#"_VV_"# vlmul.MX#"_E"#!shl(1, log2sew),93 instruction_name#"_VV_"# vlmul.MX))94 (result_type (IMPLICIT_DEF)),95 op_reg_class:$rs1,96 op_reg_class:$rs2,97 // Value to indicate no rounding mode change in98 // RISCVInsertReadWriteCSR99 FRM_DYN,100 avl, log2sew, TA_MA)>;101 102class VPatBinarySDNode_XI<SDPatternOperator vop,103 string instruction_name,104 string suffix,105 ValueType result_type,106 ValueType vop_type,107 int log2sew,108 LMULInfo vlmul,109 OutPatFrag avl,110 VReg vop_reg_class,111 ComplexPattern SplatPatKind,112 DAGOperand xop_kind,113 bit isSEWAware = 0> :114 Pat<(result_type (vop115 (vop_type vop_reg_class:$rs1),116 (vop_type (SplatPatKind (XLenVT xop_kind:$rs2))))),117 (!cast<Instruction>(118 !if(isSEWAware,119 instruction_name#_#suffix#_# vlmul.MX#"_E"#!shl(1, log2sew),120 instruction_name#_#suffix#_# vlmul.MX))121 (result_type (IMPLICIT_DEF)),122 vop_reg_class:$rs1,123 xop_kind:$rs2,124 avl, log2sew, TA_MA)>;125 126multiclass VPatBinarySDNode_VV_VX<SDPatternOperator vop, string instruction_name,127 list<VTypeInfo> vtilist = AllIntegerVectors,128 bit isSEWAware = 0> {129 foreach vti = vtilist in {130 let Predicates = GetVTypePredicates<vti>.Predicates in {131 def : VPatBinarySDNode_VV<vop, instruction_name,132 vti.Vector, vti.Vector, vti.Log2SEW,133 vti.LMul, vti.AVL, vti.RegClass, isSEWAware>;134 def : VPatBinarySDNode_XI<vop, instruction_name, "VX",135 vti.Vector, vti.Vector, vti.Log2SEW,136 vti.LMul, vti.AVL, vti.RegClass,137 SplatPat, GPR, isSEWAware>;138 }139 }140}141 142multiclass VPatBinarySDNode_VV_VX_VI<SDPatternOperator vop, string instruction_name,143 Operand ImmType = simm5>144 : VPatBinarySDNode_VV_VX<vop, instruction_name> {145 foreach vti = AllIntegerVectors in {146 let Predicates = GetVTypePredicates<vti>.Predicates in147 def : VPatBinarySDNode_XI<vop, instruction_name, "VI",148 vti.Vector, vti.Vector, vti.Log2SEW,149 vti.LMul, vti.AVL, vti.RegClass,150 !cast<ComplexPattern>(SplatPat#_#ImmType),151 ImmType>;152 }153}154 155class VPatBinarySDNode_VF<SDPatternOperator vop,156 string instruction_name,157 ValueType result_type,158 ValueType vop_type,159 ValueType xop_type,160 int log2sew,161 LMULInfo vlmul,162 OutPatFrag avl,163 VReg vop_reg_class,164 DAGOperand xop_kind,165 bit isSEWAware = 0> :166 Pat<(result_type (vop (vop_type vop_reg_class:$rs1),167 (vop_type (SplatFPOp xop_kind:$rs2)))),168 (!cast<Instruction>(169 !if(isSEWAware,170 instruction_name#"_"#vlmul.MX#"_E"#!shl(1, log2sew),171 instruction_name#"_"#vlmul.MX))172 (result_type (IMPLICIT_DEF)),173 vop_reg_class:$rs1,174 (xop_type xop_kind:$rs2),175 avl, log2sew, TA_MA)>;176 177class VPatBinarySDNode_VF_RM<SDPatternOperator vop,178 string instruction_name,179 ValueType result_type,180 ValueType vop_type,181 ValueType xop_type,182 int log2sew,183 LMULInfo vlmul,184 OutPatFrag avl,185 VReg vop_reg_class,186 DAGOperand xop_kind,187 bit isSEWAware = 0> :188 Pat<(result_type (vop (vop_type vop_reg_class:$rs1),189 (vop_type (SplatFPOp xop_kind:$rs2)))),190 (!cast<Instruction>(191 !if(isSEWAware,192 instruction_name#"_"#vlmul.MX#"_E"#!shl(1, log2sew),193 instruction_name#"_"#vlmul.MX))194 (result_type (IMPLICIT_DEF)),195 vop_reg_class:$rs1,196 (xop_type xop_kind:$rs2),197 // Value to indicate no rounding mode change in198 // RISCVInsertReadWriteCSR199 FRM_DYN,200 avl, log2sew, TA_MA)>;201 202multiclass VPatBinaryFPSDNode_VV_VF<SDPatternOperator vop, string instruction_name,203 bit isSEWAware = 0> {204 foreach vti = AllFloatVectors in {205 let Predicates = GetVTypePredicates<vti>.Predicates in {206 def : VPatBinarySDNode_VV<vop, instruction_name,207 vti.Vector, vti.Vector, vti.Log2SEW,208 vti.LMul, vti.AVL, vti.RegClass, isSEWAware>;209 def : VPatBinarySDNode_VF<vop, instruction_name#"_V"#vti.ScalarSuffix,210 vti.Vector, vti.Vector, vti.Scalar,211 vti.Log2SEW, vti.LMul, vti.AVL, vti.RegClass,212 vti.ScalarRegClass, isSEWAware>;213 }214 }215}216 217multiclass VPatBinaryFPSDNode_VV_VF_RM<SDPatternOperator vop, string instruction_name,218 bit isSEWAware = 0> {219 foreach vti = AllFloatVectors in {220 let Predicates = GetVTypePredicates<vti>.Predicates in {221 def : VPatBinarySDNode_VV_RM<vop, instruction_name,222 vti.Vector, vti.Vector, vti.Log2SEW,223 vti.LMul, vti.AVL, vti.RegClass, isSEWAware>;224 def : VPatBinarySDNode_VF_RM<vop, instruction_name#"_V"#vti.ScalarSuffix,225 vti.Vector, vti.Vector, vti.Scalar,226 vti.Log2SEW, vti.LMul, vti.AVL, vti.RegClass,227 vti.ScalarRegClass, isSEWAware>;228 }229 }230}231 232multiclass VPatBinaryFPSDNode_R_VF<SDPatternOperator vop, string instruction_name,233 bit isSEWAware = 0> {234 foreach fvti = AllFloatVectors in235 let Predicates = GetVTypePredicates<fvti>.Predicates in236 def : Pat<(fvti.Vector (vop (fvti.Vector (SplatFPOp fvti.Scalar:$rs2)),237 (fvti.Vector fvti.RegClass:$rs1))),238 (!cast<Instruction>(239 !if(isSEWAware,240 instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_E"#fvti.SEW,241 instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX))242 (fvti.Vector (IMPLICIT_DEF)),243 fvti.RegClass:$rs1,244 (fvti.Scalar fvti.ScalarRegClass:$rs2),245 fvti.AVL, fvti.Log2SEW, TA_MA)>;246}247 248multiclass VPatBinaryFPSDNode_R_VF_RM<SDPatternOperator vop, string instruction_name,249 bit isSEWAware = 0> {250 foreach fvti = AllFloatVectors in251 let Predicates = GetVTypePredicates<fvti>.Predicates in252 def : Pat<(fvti.Vector (vop (fvti.Vector (SplatFPOp fvti.Scalar:$rs2)),253 (fvti.Vector fvti.RegClass:$rs1))),254 (!cast<Instruction>(255 !if(isSEWAware,256 instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_E"#fvti.SEW,257 instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX))258 (fvti.Vector (IMPLICIT_DEF)),259 fvti.RegClass:$rs1,260 (fvti.Scalar fvti.ScalarRegClass:$rs2),261 // Value to indicate no rounding mode change in262 // RISCVInsertReadWriteCSR263 FRM_DYN,264 fvti.AVL, fvti.Log2SEW, TA_MA)>;265}266 267multiclass VPatIntegerSetCCSDNode_VV<string instruction_name,268 CondCode cc> {269 foreach vti = AllIntegerVectors in {270 defvar instruction = !cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX);271 let Predicates = GetVTypePredicates<vti>.Predicates in272 def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1),273 (vti.Vector vti.RegClass:$rs2), cc)),274 (instruction vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL,275 vti.Log2SEW)>;276 }277}278 279multiclass VPatIntegerSetCCSDNode_VV_Swappable<string instruction_name,280 CondCode cc, CondCode invcc>281 : VPatIntegerSetCCSDNode_VV<instruction_name, cc> {282 foreach vti = AllIntegerVectors in {283 defvar instruction = !cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX);284 let Predicates = GetVTypePredicates<vti>.Predicates in285 def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs2),286 (vti.Vector vti.RegClass:$rs1), invcc)),287 (instruction vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL,288 vti.Log2SEW)>;289 }290}291 292multiclass VPatIntegerSetCCSDNode_XI_Swappable<string instruction_name,293 CondCode cc, CondCode invcc,294 string kind,295 ComplexPattern SplatPatKind,296 DAGOperand xop_kind> {297 foreach vti = AllIntegerVectors in {298 defvar instruction = !cast<Instruction>(instruction_name#_#kind#_#vti.LMul.MX);299 let Predicates = GetVTypePredicates<vti>.Predicates in {300 def : Pat<(vti.Mask (setcc (vti.Vector vti.RegClass:$rs1),301 (vti.Vector (SplatPatKind (XLenVT xop_kind:$rs2))), cc)),302 (instruction vti.RegClass:$rs1, xop_kind:$rs2, vti.AVL, vti.Log2SEW)>;303 def : Pat<(vti.Mask (setcc (vti.Vector (SplatPatKind (XLenVT xop_kind:$rs2))),304 (vti.Vector vti.RegClass:$rs1), invcc)),305 (instruction vti.RegClass:$rs1, xop_kind:$rs2, vti.AVL, vti.Log2SEW)>;306 }307 }308}309 310multiclass VPatIntegerSetCCSDNode_VX_Swappable<string instruction_name,311 CondCode cc, CondCode invcc>312 : VPatIntegerSetCCSDNode_XI_Swappable<instruction_name, cc, invcc, "VX",313 SplatPat, GPR>;314 315multiclass VPatIntegerSetCCSDNode_VI_Swappable<string instruction_name,316 CondCode cc, CondCode invcc,317 ComplexPattern splatpat_kind = SplatPat_simm5>318 : VPatIntegerSetCCSDNode_XI_Swappable<instruction_name, cc, invcc, "VI",319 splatpat_kind, simm5>;320 321multiclass VPatFPSetCCSDNode_VV_VF_FV<CondCode cc,322 string inst_name,323 string swapped_op_inst_name> {324 foreach fvti = AllFloatVectors in {325 let Predicates = GetVTypePredicates<fvti>.Predicates in {326 def : Pat<(fvti.Mask (setcc (fvti.Vector fvti.RegClass:$rs1),327 (fvti.Vector fvti.RegClass:$rs2),328 cc)),329 (!cast<Instruction>(inst_name#"_VV_"#fvti.LMul.MX)330 fvti.RegClass:$rs1, fvti.RegClass:$rs2, fvti.AVL, fvti.Log2SEW)>;331 def : Pat<(fvti.Mask (setcc (fvti.Vector fvti.RegClass:$rs1),332 (SplatFPOp fvti.ScalarRegClass:$rs2),333 cc)),334 (!cast<Instruction>(inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)335 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2,336 fvti.AVL, fvti.Log2SEW)>;337 def : Pat<(fvti.Mask (setcc (SplatFPOp fvti.ScalarRegClass:$rs2),338 (fvti.Vector fvti.RegClass:$rs1),339 cc)),340 (!cast<Instruction>(swapped_op_inst_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)341 fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2,342 fvti.AVL, fvti.Log2SEW)>;343 }344 }345}346 347multiclass VPatExtendSDNode_V<list<SDNode> ops, string inst_name, string suffix,348 list <VTypeInfoToFraction> fraction_list> {349 foreach vtiTofti = fraction_list in {350 defvar vti = vtiTofti.Vti;351 defvar fti = vtiTofti.Fti;352 foreach op = ops in353 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,354 GetVTypePredicates<fti>.Predicates) in355 def : Pat<(vti.Vector (op (fti.Vector fti.RegClass:$rs2))),356 (!cast<Instruction>(inst_name#"_"#suffix#"_"#vti.LMul.MX)357 (vti.Vector (IMPLICIT_DEF)),358 fti.RegClass:$rs2, fti.AVL, vti.Log2SEW, TA_MA)>;359 }360}361 362multiclass VPatConvertI2FPSDNode_V_RM<SDPatternOperator vop,363 string instruction_name> {364 foreach fvti = AllFloatVectors in {365 defvar ivti = GetIntVTypeInfo<fvti>.Vti;366 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates,367 GetVTypePredicates<ivti>.Predicates) in368 def : Pat<(fvti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))),369 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_E"#fvti.SEW)370 (fvti.Vector (IMPLICIT_DEF)),371 ivti.RegClass:$rs1,372 // Value to indicate no rounding mode change in373 // RISCVInsertReadWriteCSR374 FRM_DYN,375 fvti.AVL, fvti.Log2SEW, TA_MA)>;376 }377}378 379multiclass VPatConvertFP2ISDNode_V<SDPatternOperator vop,380 string instruction_name> {381 foreach fvti = AllFloatVectors in {382 defvar ivti = GetIntVTypeInfo<fvti>.Vti;383 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates,384 GetVTypePredicates<ivti>.Predicates) in385 def : Pat<(ivti.Vector (vop (fvti.Vector fvti.RegClass:$rs1))),386 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX)387 (ivti.Vector (IMPLICIT_DEF)),388 fvti.RegClass:$rs1, ivti.AVL, ivti.Log2SEW, TA_MA)>;389 }390}391 392multiclass VPatWConvertI2FPSDNode_V<SDPatternOperator vop,393 string instruction_name> {394 foreach vtiToWti = AllWidenableIntToFloatVectors in {395 defvar ivti = vtiToWti.Vti;396 defvar fwti = vtiToWti.Wti;397 let Predicates = !listconcat(GetVTypePredicates<ivti>.Predicates,398 GetVTypePredicates<fwti>.Predicates) in399 def : Pat<(fwti.Vector (vop (ivti.Vector ivti.RegClass:$rs1))),400 (!cast<Instruction>(instruction_name#"_"#ivti.LMul.MX#"_E"#ivti.SEW)401 (fwti.Vector (IMPLICIT_DEF)),402 ivti.RegClass:$rs1,403 ivti.AVL, ivti.Log2SEW, TA_MA)>;404 }405}406 407multiclass VPatWConvertFP2ISDNode_V<SDPatternOperator vop,408 string instruction_name> {409 foreach fvtiToFWti = AllWidenableFloatVectors in {410 defvar fvti = fvtiToFWti.Vti;411 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti;412 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates,413 GetVTypePredicates<iwti>.Predicates) in414 def : Pat<(iwti.Vector (vop (fvti.Vector fvti.RegClass:$rs1))),415 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX)416 (iwti.Vector (IMPLICIT_DEF)),417 fvti.RegClass:$rs1, fvti.AVL, fvti.Log2SEW, TA_MA)>;418 }419}420 421multiclass VPatNConvertI2FPSDNode_W_RM<SDPatternOperator vop,422 string instruction_name> {423 foreach fvtiToFWti = AllWidenableFloatVectors in {424 defvar fvti = fvtiToFWti.Vti;425 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti;426 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates,427 GetVTypePredicates<iwti>.Predicates) in428 def : Pat<(fvti.Vector (vop (iwti.Vector iwti.RegClass:$rs1))),429 (!cast<Instruction>(instruction_name#"_"#fvti.LMul.MX#"_E"#fvti.SEW)430 (fvti.Vector (IMPLICIT_DEF)),431 iwti.RegClass:$rs1,432 // Value to indicate no rounding mode change in433 // RISCVInsertReadWriteCSR434 FRM_DYN,435 fvti.AVL, fvti.Log2SEW, TA_MA)>;436 }437}438 439multiclass VPatNConvertFP2ISDNode_W<SDPatternOperator vop,440 string instruction_name> {441 foreach vtiToWti = AllWidenableIntToFloatVectors in {442 defvar vti = vtiToWti.Vti;443 defvar fwti = vtiToWti.Wti;444 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,445 GetVTypePredicates<fwti>.Predicates) in446 def : Pat<(vti.Vector (vop (fwti.Vector fwti.RegClass:$rs1))),447 (!cast<Instruction>(instruction_name#"_"#vti.LMul.MX)448 (vti.Vector (IMPLICIT_DEF)),449 fwti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;450 }451}452 453multiclass VPatWidenBinarySDNode_VV_VX<SDNode op, PatFrags extop1, PatFrags extop2,454 string instruction_name> {455 foreach vtiToWti = AllWidenableIntVectors in {456 defvar vti = vtiToWti.Vti;457 defvar wti = vtiToWti.Wti;458 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,459 GetVTypePredicates<wti>.Predicates) in {460 def : Pat<(op (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs2))),461 (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs1)))),462 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX)463 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,464 vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;465 def : Pat<(op (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs2))),466 (wti.Vector (extop2 (vti.Vector (SplatPat (XLenVT GPR:$rs1)))))),467 (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX)468 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,469 GPR:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;470 }471 }472}473 474multiclass VPatWidenBinarySDNode_WV_WX<SDNode op, PatFrags extop,475 string instruction_name> {476 foreach vtiToWti = AllWidenableIntVectors in {477 defvar vti = vtiToWti.Vti;478 defvar wti = vtiToWti.Wti;479 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,480 GetVTypePredicates<wti>.Predicates) in {481 def : Pat<(op (wti.Vector wti.RegClass:$rs2),482 (wti.Vector (extop (vti.Vector vti.RegClass:$rs1)))),483 (!cast<Instruction>(instruction_name#"_WV_"#vti.LMul.MX#"_TIED")484 wti.RegClass:$rs2, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW,485 TAIL_AGNOSTIC)>;486 def : Pat<(op (wti.Vector wti.RegClass:$rs2),487 (wti.Vector (extop (vti.Vector (SplatPat (XLenVT GPR:$rs1)))))),488 (!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX)489 (wti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2, GPR:$rs1,490 vti.AVL, vti.Log2SEW, TA_MA)>;491 }492 }493}494 495multiclass VPatWidenBinarySDNode_VV_VX_WV_WX<SDNode op, PatFrags extop,496 string instruction_name>497 : VPatWidenBinarySDNode_VV_VX<op, extop, extop, instruction_name>,498 VPatWidenBinarySDNode_WV_WX<op, extop, instruction_name>;499 500multiclass VPatWidenMulAddSDNode_VV<PatFrags extop1, PatFrags extop2, string instruction_name> {501 foreach vtiToWti = AllWidenableIntVectors in {502 defvar vti = vtiToWti.Vti;503 defvar wti = vtiToWti.Wti;504 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,505 GetVTypePredicates<wti>.Predicates) in506 def : Pat<507 (add (wti.Vector wti.RegClass:$rd),508 (mul_oneuse (wti.Vector (extop1 (vti.Vector vti.RegClass:$rs1))),509 (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs2))))),510 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX)511 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,512 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC513 )>;514 }515}516multiclass VPatWidenMulAddSDNode_VX<PatFrags extop1, PatFrags extop2, string instruction_name> {517 foreach vtiToWti = AllWidenableIntVectors in {518 defvar vti = vtiToWti.Vti;519 defvar wti = vtiToWti.Wti;520 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,521 GetVTypePredicates<wti>.Predicates) in522 def : Pat<523 (add (wti.Vector wti.RegClass:$rd),524 (mul_oneuse (wti.Vector (extop1 (vti.Vector (SplatPat (XLenVT GPR:$rs1))))),525 (wti.Vector (extop2 (vti.Vector vti.RegClass:$rs2))))),526 (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX)527 wti.RegClass:$rd, GPR:$rs1, vti.RegClass:$rs2,528 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC529 )>;530 }531}532 533multiclass VPatWidenBinaryFPSDNode_VV_VF<SDNode op, string instruction_name> {534 foreach vtiToWti = AllWidenableFloatVectors in {535 defvar vti = vtiToWti.Vti;536 defvar wti = vtiToWti.Wti;537 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,538 GetVTypePredicates<wti>.Predicates) in {539 def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser540 (vti.Vector vti.RegClass:$rs2),541 (vti.Mask true_mask), (XLenVT srcvalue))),542 (wti.Vector (riscv_fpextend_vl_sameuser543 (vti.Vector vti.RegClass:$rs1),544 (vti.Mask true_mask), (XLenVT srcvalue)))),545 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX)546 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,547 vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;548 def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser549 (vti.Vector vti.RegClass:$rs2),550 (vti.Mask true_mask), (XLenVT srcvalue))),551 (wti.Vector (riscv_fpextend_vl_sameuser552 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)),553 (vti.Mask true_mask), (XLenVT srcvalue)))),554 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX)555 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,556 vti.ScalarRegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;557 def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse558 (vti.Vector vti.RegClass:$rs2),559 (vti.Mask true_mask), (XLenVT srcvalue))),560 (wti.Vector (SplatFPOp (fpext_oneuse vti.ScalarRegClass:$rs1)))),561 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX)562 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,563 vti.ScalarRegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;564 }565 }566}567 568multiclass VPatWidenBinaryFPSDNode_VV_VF_RM<SDNode op, string instruction_name> {569 foreach vtiToWti = AllWidenableFloatVectors in {570 defvar vti = vtiToWti.Vti;571 defvar wti = vtiToWti.Wti;572 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,573 GetVTypePredicates<wti>.Predicates) in {574 def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser575 (vti.Vector vti.RegClass:$rs2),576 (vti.Mask true_mask), (XLenVT srcvalue))),577 (wti.Vector (riscv_fpextend_vl_sameuser578 (vti.Vector vti.RegClass:$rs1),579 (vti.Mask true_mask), (XLenVT srcvalue)))),580 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX#"_E"#vti.SEW)581 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,582 vti.RegClass:$rs1,583 // Value to indicate no rounding mode change in584 // RISCVInsertReadWriteCSR585 FRM_DYN,586 vti.AVL, vti.Log2SEW, TA_MA)>;587 def : Pat<(op (wti.Vector (riscv_fpextend_vl_sameuser588 (vti.Vector vti.RegClass:$rs2),589 (vti.Mask true_mask), (XLenVT srcvalue))),590 (wti.Vector (riscv_fpextend_vl_sameuser591 (vti.Vector (SplatFPOp (vti.Scalar vti.ScalarRegClass:$rs1))),592 (vti.Mask true_mask), (XLenVT srcvalue)))),593 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW)594 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,595 vti.ScalarRegClass:$rs1,596 // Value to indicate no rounding mode change in597 // RISCVInsertReadWriteCSR598 FRM_DYN,599 vti.AVL, vti.Log2SEW, TA_MA)>;600 def : Pat<(op (wti.Vector (riscv_fpextend_vl_oneuse601 (vti.Vector vti.RegClass:$rs2),602 (vti.Mask true_mask), (XLenVT srcvalue))),603 (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))),604 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW)605 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,606 vti.ScalarRegClass:$rs1,607 // Value to indicate no rounding mode change in608 // RISCVInsertReadWriteCSR609 FRM_DYN,610 vti.AVL, vti.Log2SEW, TA_MA)>;611 }612 }613}614 615multiclass VPatWidenBinaryFPSDNode_WV_WF_RM<SDNode op, string instruction_name> {616 foreach vtiToWti = AllWidenableFloatVectors in {617 defvar vti = vtiToWti.Vti;618 defvar wti = vtiToWti.Wti;619 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,620 GetVTypePredicates<wti>.Predicates) in {621 def : Pat<(op (wti.Vector wti.RegClass:$rs2),622 (wti.Vector (riscv_fpextend_vl_oneuse623 (vti.Vector vti.RegClass:$rs1),624 (vti.Mask true_mask), (XLenVT srcvalue)))),625 (!cast<Instruction>(instruction_name#"_WV_"#vti.LMul.MX#"_E"#vti.SEW#"_TIED")626 wti.RegClass:$rs2, vti.RegClass:$rs1,627 // Value to indicate no rounding mode change in628 // RISCVInsertReadWriteCSR629 FRM_DYN,630 vti.AVL, vti.Log2SEW,631 TAIL_AGNOSTIC)>;632 def : Pat<(op (wti.Vector wti.RegClass:$rs2),633 (wti.Vector (riscv_fpextend_vl_oneuse634 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs1)),635 (vti.Mask true_mask), (XLenVT srcvalue)))),636 (!cast<Instruction>(instruction_name#"_W"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW)637 (wti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2,638 vti.ScalarRegClass:$rs1,639 // Value to indicate no rounding mode change in640 // RISCVInsertReadWriteCSR641 FRM_DYN,642 vti.AVL, vti.Log2SEW, TA_MA)>;643 def : Pat<(op (wti.Vector wti.RegClass:$rs2),644 (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))),645 (!cast<Instruction>(instruction_name#"_W"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW)646 (wti.Vector (IMPLICIT_DEF)), wti.RegClass:$rs2,647 vti.ScalarRegClass:$rs1,648 // Value to indicate no rounding mode change in649 // RISCVInsertReadWriteCSR650 FRM_DYN,651 vti.AVL, vti.Log2SEW, TA_MA)>;652 }653 }654}655 656multiclass VPatWidenBinaryFPSDNode_VV_VF_WV_WF_RM<SDNode op,657 string instruction_name>658 : VPatWidenBinaryFPSDNode_VV_VF_RM<op, instruction_name>,659 VPatWidenBinaryFPSDNode_WV_WF_RM<op, instruction_name>;660 661multiclass VPatWidenFPMulAccSDNode_VV_VF_RM<string instruction_name,662 list <VTypeInfoToWide> vtiToWtis> {663 foreach vtiToWti = vtiToWtis in {664 defvar vti = vtiToWti.Vti;665 defvar wti = vtiToWti.Wti;666 defvar suffix = vti.LMul.MX # "_E" # vti.SEW;667 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,668 GetVTypePredicates<wti>.Predicates,669 !if(!eq(vti.Scalar, bf16),670 [HasStdExtZvfbfwma],671 [])) in {672 def : Pat<(fma (wti.Vector (riscv_fpextend_vl_sameuser673 (vti.Vector vti.RegClass:$rs1),674 (vti.Mask true_mask), (XLenVT srcvalue))),675 (wti.Vector (riscv_fpextend_vl_sameuser676 (vti.Vector vti.RegClass:$rs2),677 (vti.Mask true_mask), (XLenVT srcvalue))),678 (wti.Vector wti.RegClass:$rd)),679 (!cast<Instruction>(instruction_name#"_VV_"#suffix)680 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,681 // Value to indicate no rounding mode change in682 // RISCVInsertReadWriteCSR683 FRM_DYN,684 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;685 def : Pat<(fma (wti.Vector (SplatFPOp686 (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1)))),687 (wti.Vector (riscv_fpextend_vl_oneuse688 (vti.Vector vti.RegClass:$rs2),689 (vti.Mask true_mask), (XLenVT srcvalue))),690 (wti.Vector wti.RegClass:$rd)),691 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix)692 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,693 // Value to indicate no rounding mode change in694 // RISCVInsertReadWriteCSR695 FRM_DYN,696 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;697 }698 }699}700 701multiclass VPatWidenFPNegMulAccSDNode_VV_VF_RM<string instruction_name> {702 foreach vtiToWti = AllWidenableFloatVectors in {703 defvar vti = vtiToWti.Vti;704 defvar wti = vtiToWti.Wti;705 defvar suffix = vti.LMul.MX # "_E" # vti.SEW;706 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,707 GetVTypePredicates<wti>.Predicates) in {708 def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse709 (vti.Vector vti.RegClass:$rs1),710 (vti.Mask true_mask), (XLenVT srcvalue)))),711 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2),712 (vti.Mask true_mask), (XLenVT srcvalue)),713 (fneg wti.RegClass:$rd)),714 (!cast<Instruction>(instruction_name#"_VV_"#suffix)715 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,716 // Value to indicate no rounding mode change in717 // RISCVInsertReadWriteCSR718 FRM_DYN,719 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;720 def : Pat<(fma (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))),721 (fneg (wti.Vector (riscv_fpextend_vl_oneuse722 (vti.Vector vti.RegClass:$rs2),723 (vti.Mask true_mask), (XLenVT srcvalue)))),724 (fneg wti.RegClass:$rd)),725 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix)726 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,727 // Value to indicate no rounding mode change in728 // RISCVInsertReadWriteCSR729 FRM_DYN,730 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;731 def : Pat<(fma (fneg (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))),732 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2),733 (vti.Mask true_mask), (XLenVT srcvalue)),734 (fneg wti.RegClass:$rd)),735 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix)736 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,737 // Value to indicate no rounding mode change in738 // RISCVInsertReadWriteCSR739 FRM_DYN,740 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;741 }742 }743}744 745multiclass VPatWidenFPMulSacSDNode_VV_VF_RM<string instruction_name> {746 foreach vtiToWti = AllWidenableFloatVectors in {747 defvar vti = vtiToWti.Vti;748 defvar wti = vtiToWti.Wti;749 defvar suffix = vti.LMul.MX # "_E" # vti.SEW;750 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,751 GetVTypePredicates<wti>.Predicates) in {752 def : Pat<(fma (wti.Vector (riscv_fpextend_vl_sameuser753 (vti.Vector vti.RegClass:$rs1),754 (vti.Mask true_mask), (XLenVT srcvalue))),755 (riscv_fpextend_vl_sameuser (vti.Vector vti.RegClass:$rs2),756 (vti.Mask true_mask), (XLenVT srcvalue)),757 (fneg wti.RegClass:$rd)),758 (!cast<Instruction>(instruction_name#"_VV_"#suffix)759 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,760 // Value to indicate no rounding mode change in761 // RISCVInsertReadWriteCSR762 FRM_DYN,763 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;764 def : Pat<(fma (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1)))),765 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2),766 (vti.Mask true_mask), (XLenVT srcvalue)),767 (fneg wti.RegClass:$rd)),768 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix)769 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,770 // Value to indicate no rounding mode change in771 // RISCVInsertReadWriteCSR772 FRM_DYN,773 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;774 }775 }776}777 778multiclass VPatWidenFPNegMulSacSDNode_VV_VF_RM<string instruction_name> {779 foreach vtiToWti = AllWidenableFloatVectors in {780 defvar vti = vtiToWti.Vti;781 defvar wti = vtiToWti.Wti;782 defvar suffix = vti.LMul.MX # "_E" # vti.SEW;783 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,784 GetVTypePredicates<wti>.Predicates) in {785 def : Pat<(fma (fneg (wti.Vector (riscv_fpextend_vl_oneuse786 (vti.Vector vti.RegClass:$rs1),787 (vti.Mask true_mask), (XLenVT srcvalue)))),788 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2),789 (vti.Mask true_mask), (XLenVT srcvalue)),790 wti.RegClass:$rd),791 (!cast<Instruction>(instruction_name#"_VV_"#suffix)792 wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,793 // Value to indicate no rounding mode change in794 // RISCVInsertReadWriteCSR795 FRM_DYN,796 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;797 def : Pat<(fma (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1)))),798 (fneg (wti.Vector (riscv_fpextend_vl_oneuse799 (vti.Vector vti.RegClass:$rs2),800 (vti.Mask true_mask), (XLenVT srcvalue)))),801 wti.RegClass:$rd),802 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix)803 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,804 // Value to indicate no rounding mode change in805 // RISCVInsertReadWriteCSR806 FRM_DYN,807 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;808 def : Pat<(fma (fneg (wti.Vector (SplatFPOp (fpext_oneuse (vti.Scalar vti.ScalarRegClass:$rs1))))),809 (riscv_fpextend_vl_oneuse (vti.Vector vti.RegClass:$rs2),810 (vti.Mask true_mask), (XLenVT srcvalue)),811 wti.RegClass:$rd),812 (!cast<Instruction>(instruction_name#"_V"#vti.ScalarSuffix#"_"#suffix)813 wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,814 // Value to indicate no rounding mode change in815 // RISCVInsertReadWriteCSR816 FRM_DYN,817 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;818 }819 }820}821 822multiclass VPatMultiplyAddSDNode_VV_VX<SDNode op, string instruction_name> {823 foreach vti = AllIntegerVectors in {824 defvar suffix = vti.LMul.MX;825 let Predicates = GetVTypePredicates<vti>.Predicates in {826 // NOTE: We choose VMADD because it has the most commuting freedom. So it827 // works best with how TwoAddressInstructionPass tries commuting.828 def : Pat<(vti.Vector (op vti.RegClass:$rs2,829 (mul_oneuse vti.RegClass:$rs1, vti.RegClass:$rd))),830 (!cast<Instruction>(instruction_name#"_VV_"# suffix)831 vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,832 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;833 // The choice of VMADD here is arbitrary, vmadd.vx and vmacc.vx are equally834 // commutable.835 def : Pat<(vti.Vector (op vti.RegClass:$rs2,836 (mul_oneuse (SplatPat XLenVT:$rs1), vti.RegClass:$rd))),837 (!cast<Instruction>(instruction_name#"_VX_" # suffix)838 vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,839 vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>;840 }841 }842}843 844multiclass VPatAVGADD_VV_VX_RM<SDNode vop, int vxrm, string suffix = ""> {845 foreach vti = AllIntegerVectors in {846 let Predicates = GetVTypePredicates<vti>.Predicates in {847 def : Pat<(vop (vti.Vector vti.RegClass:$rs1),848 (vti.Vector vti.RegClass:$rs2)),849 (!cast<Instruction>("PseudoVAADD"#suffix#"_VV_"#vti.LMul.MX)850 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs2,851 vxrm, vti.AVL, vti.Log2SEW, TA_MA)>;852 def : Pat<(vop (vti.Vector vti.RegClass:$rs1),853 (vti.Vector (SplatPat (XLenVT GPR:$rs2)))),854 (!cast<Instruction>("PseudoVAADD"#suffix#"_VX_"#vti.LMul.MX)855 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, GPR:$rs2,856 vxrm, vti.AVL, vti.Log2SEW, TA_MA)>;857 }858 }859}860 861//===----------------------------------------------------------------------===//862// Patterns.863//===----------------------------------------------------------------------===//864 865// 7.4. Vector Unit-Stride Instructions866foreach vti = AllVectors in867 let Predicates = GetVTypeMinimalPredicates<vti>.Predicates in868 defm : VPatUSLoadStoreSDNode<vti.Vector, vti.RegClass, vti.Log2SEW, vti.LMul,869 vti.AVL, vti.RegClass>;870foreach mti = AllMasks in871 let Predicates = [HasVInstructions] in872 defm : VPatUSLoadStoreMaskSDNode<mti>;873 874// 11. Vector Integer Arithmetic Instructions875 876// 11.1. Vector Single-Width Integer Add and Subtract877defm : VPatBinarySDNode_VV_VX_VI<add, "PseudoVADD">;878defm : VPatBinarySDNode_VV_VX<sub, "PseudoVSUB">;879foreach vti = AllIntegerVectors in {880 // Handle VRSUB specially since it's the only integer binary op with reversed881 // pattern operands882 // FIXME: The AddedComplexity here is covering up a missing matcher for883 // widening vwsub.vx which can recognize a extended folded into the884 // scalar of the splat.885 let AddedComplexity = 20 in886 let Predicates = GetVTypePredicates<vti>.Predicates in {887 def : Pat<(sub (vti.Vector (SplatPat (XLenVT GPR:$rs2))),888 (vti.Vector vti.RegClass:$rs1)),889 (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX)890 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, GPR:$rs2,891 vti.AVL, vti.Log2SEW, TA_MA)>;892 def : Pat<(sub (vti.Vector (SplatPat_simm5 simm5:$rs2)),893 (vti.Vector vti.RegClass:$rs1)),894 (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX)895 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1,896 simm5:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>;897 }898 899 let Predicates = GetVTypePredicates<vti>.Predicates in {900 // Match VSUB with a small immediate to vadd.vi by negating the immediate.901 def : Pat<(sub (vti.Vector vti.RegClass:$rs1),902 (vti.Vector (SplatPat_simm5_plus1_nodec simm5_plus1:$rs2))),903 (!cast<Instruction>("PseudoVADD_VI_"#vti.LMul.MX)904 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1,905 (NegImm simm5_plus1:$rs2), vti.AVL, vti.Log2SEW, TA_MA)>;906 }907}908 909// (add v, C) -> (sub v, -C) if -C cheaper to materialize910foreach vti = I64IntegerVectors in {911 let Predicates = [HasVInstructionsI64] in {912 def : Pat<(add (vti.Vector vti.RegClass:$rs1),913 (vti.Vector (SplatPat_imm64_neg (i64 GPR:$rs2)))),914 (!cast<Instruction>("PseudoVSUB_VX_"#vti.LMul.MX)915 (vti.Vector (IMPLICIT_DEF)),916 vti.RegClass:$rs1,917 negImm:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>;918 }919}920 921// 11.2. Vector Widening Integer Add and Subtract922defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, sext_oneuse, "PseudoVWADD">;923defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, zext_oneuse, "PseudoVWADDU">;924defm : VPatWidenBinarySDNode_VV_VX_WV_WX<add, anyext_oneuse, "PseudoVWADDU">;925 926// DAGCombiner::hoistLogicOpWithSameOpcodeHands may hoist disjoint ors927// to (ext (or disjoint (a, b)))928multiclass VPatWidenOrDisjoint_VV_VX<SDNode extop, string instruction_name> {929 foreach vtiToWti = AllWidenableIntVectors in {930 defvar vti = vtiToWti.Vti;931 defvar wti = vtiToWti.Wti;932 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,933 GetVTypePredicates<wti>.Predicates) in {934 def : Pat<(wti.Vector (extop (vti.Vector (riscv_or_disjoint vti.RegClass:$rs2, vti.RegClass:$rs1)))),935 (!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX)936 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,937 vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;938 def : Pat<(wti.Vector (extop (vti.Vector (riscv_or_disjoint vti.RegClass:$rs2, (SplatPat (XLenVT GPR:$rs1)))))),939 (!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX)940 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,941 GPR:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;942 }943 }944}945defm : VPatWidenOrDisjoint_VV_VX<sext, "PseudoVWADD">;946defm : VPatWidenOrDisjoint_VV_VX<zext, "PseudoVWADDU">;947defm : VPatWidenOrDisjoint_VV_VX<anyext, "PseudoVWADDU">;948 949defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, sext_oneuse, "PseudoVWSUB">;950defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, zext_oneuse, "PseudoVWSUBU">;951defm : VPatWidenBinarySDNode_VV_VX_WV_WX<sub, anyext_oneuse, "PseudoVWSUBU">;952 953// shl (ext v, splat 1) is a special case of widening add.954foreach vtiToWti = AllWidenableIntVectors in {955 defvar vti = vtiToWti.Vti;956 defvar wti = vtiToWti.Wti;957 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,958 GetVTypePredicates<wti>.Predicates) in {959 def : Pat<(shl (wti.Vector (sext_oneuse (vti.Vector vti.RegClass:$rs1))),960 (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))),961 (!cast<Instruction>("PseudoVWADD_VV_"#vti.LMul.MX)962 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1,963 vti.AVL, vti.Log2SEW, TA_MA)>;964 def : Pat<(shl (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs1))),965 (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))),966 (!cast<Instruction>("PseudoVWADDU_VV_"#vti.LMul.MX)967 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1,968 vti.AVL, vti.Log2SEW, TA_MA)>;969 def : Pat<(shl (wti.Vector (anyext_oneuse (vti.Vector vti.RegClass:$rs1))),970 (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))),971 (!cast<Instruction>("PseudoVWADDU_VV_"#vti.LMul.MX)972 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1,973 vti.AVL, vti.Log2SEW, TA_MA)>;974 def : Pat<(shl (wti.Vector (riscv_sext_vl_oneuse (vti.Vector vti.RegClass:$rs1), (vti.Mask VMV0:$vm), VLOpFrag)),975 (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))),976 (!cast<Instruction>("PseudoVWADD_VV_"#vti.LMul.MX#"_MASK")977 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1,978 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;979 def : Pat<(shl (wti.Vector (riscv_zext_vl_oneuse (vti.Vector vti.RegClass:$rs1), (vti.Mask VMV0:$vm), VLOpFrag)),980 (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))),981 (!cast<Instruction>("PseudoVWADDU_VV_"#vti.LMul.MX#"_MASK")982 (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, vti.RegClass:$rs1,983 (vti.Mask VMV0:$vm), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;984 }985}986 987// 11.3. Vector Integer Extension988defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF2",989 AllFractionableVF2IntVectors>;990defm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF2",991 AllFractionableVF2IntVectors>;992defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF4",993 AllFractionableVF4IntVectors>;994defm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF4",995 AllFractionableVF4IntVectors>;996defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF8",997 AllFractionableVF8IntVectors>;998defm : VPatExtendSDNode_V<[sext], "PseudoVSEXT", "VF8",999 AllFractionableVF8IntVectors>;1000 1001// 11.5. Vector Bitwise Logical Instructions1002defm : VPatBinarySDNode_VV_VX_VI<and, "PseudoVAND">;1003defm : VPatBinarySDNode_VV_VX_VI<or, "PseudoVOR">;1004defm : VPatBinarySDNode_VV_VX_VI<xor, "PseudoVXOR">;1005 1006// 11.6. Vector Single-Width Bit Shift Instructions1007defm : VPatBinarySDNode_VV_VX_VI<shl, "PseudoVSLL", uimm5>;1008defm : VPatBinarySDNode_VV_VX_VI<srl, "PseudoVSRL", uimm5>;1009defm : VPatBinarySDNode_VV_VX_VI<sra, "PseudoVSRA", uimm5>;1010 1011foreach vti = AllIntegerVectors in {1012 // Emit shift by 1 as an add since it might be faster.1013 let Predicates = GetVTypePredicates<vti>.Predicates in1014 def : Pat<(shl (vti.Vector vti.RegClass:$rs1),1015 (vti.Vector (riscv_vmv_v_x_vl (vti.Vector undef), 1, (XLenVT srcvalue)))),1016 (!cast<Instruction>("PseudoVADD_VV_"# vti.LMul.MX)1017 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1,1018 vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;1019 1020}1021 1022// 11.8. Vector Integer Comparison Instructions1023defm : VPatIntegerSetCCSDNode_VV<"PseudoVMSEQ", SETEQ>;1024defm : VPatIntegerSetCCSDNode_VV<"PseudoVMSNE", SETNE>;1025 1026defm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLT", SETLT, SETGT>;1027defm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLTU", SETULT, SETUGT>;1028defm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLE", SETLE, SETGE>;1029defm : VPatIntegerSetCCSDNode_VV_Swappable<"PseudoVMSLEU", SETULE, SETUGE>;1030 1031defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSEQ", SETEQ, SETEQ>;1032defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSNE", SETNE, SETNE>;1033defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLT", SETLT, SETGT>;1034defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLTU", SETULT, SETUGT>;1035defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLE", SETLE, SETGE>;1036defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSLEU", SETULE, SETUGE>;1037defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSGT", SETGT, SETLT>;1038defm : VPatIntegerSetCCSDNode_VX_Swappable<"PseudoVMSGTU", SETUGT, SETULT>;1039// There is no VMSGE(U)_VX instruction1040 1041defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSEQ", SETEQ, SETEQ>;1042defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSNE", SETNE, SETNE>;1043defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSLE", SETLE, SETGE>;1044defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSLEU", SETULE, SETUGE>;1045defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSGT", SETGT, SETLT>;1046defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSGTU", SETUGT, SETULT>;1047 1048defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSLE", SETLT, SETGT,1049 SplatPat_simm5_plus1>;1050defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSLEU", SETULT, SETUGT,1051 SplatPat_simm5_plus1_nonzero>;1052defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSGT", SETGE, SETLE,1053 SplatPat_simm5_plus1>;1054defm : VPatIntegerSetCCSDNode_VI_Swappable<"PseudoVMSGTU", SETUGE, SETULE,1055 SplatPat_simm5_plus1_nonzero>;1056 1057// 11.9. Vector Integer Min/Max Instructions1058defm : VPatBinarySDNode_VV_VX<umin, "PseudoVMINU">;1059defm : VPatBinarySDNode_VV_VX<smin, "PseudoVMIN">;1060defm : VPatBinarySDNode_VV_VX<umax, "PseudoVMAXU">;1061defm : VPatBinarySDNode_VV_VX<smax, "PseudoVMAX">;1062 1063// 11.10. Vector Single-Width Integer Multiply Instructions1064defm : VPatBinarySDNode_VV_VX<mul, "PseudoVMUL">;1065 1066defm : VPatBinarySDNode_VV_VX<mulhs, "PseudoVMULH", IntegerVectorsExceptI64>;1067defm : VPatBinarySDNode_VV_VX<mulhu, "PseudoVMULHU", IntegerVectorsExceptI64>;1068 1069let Predicates = [HasVInstructionsFullMultiply] in {1070 defm : VPatBinarySDNode_VV_VX<mulhs, "PseudoVMULH", I64IntegerVectors>;1071 defm : VPatBinarySDNode_VV_VX<mulhu, "PseudoVMULHU", I64IntegerVectors>;1072}1073 1074// 11.11. Vector Integer Divide Instructions1075defm : VPatBinarySDNode_VV_VX<udiv, "PseudoVDIVU", isSEWAware=1>;1076defm : VPatBinarySDNode_VV_VX<sdiv, "PseudoVDIV", isSEWAware=1>;1077defm : VPatBinarySDNode_VV_VX<urem, "PseudoVREMU", isSEWAware=1>;1078defm : VPatBinarySDNode_VV_VX<srem, "PseudoVREM", isSEWAware=1>;1079 1080foreach vtiTowti = AllWidenableIntVectors in {1081 defvar vti = vtiTowti.Vti;1082 defvar wti = vtiTowti.Wti;1083 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,1084 GetVTypePredicates<wti>.Predicates) in {1085 def : Pat<1086 (vti.Vector1087 (riscv_trunc_vector_vl1088 (srem (wti.Vector (sext_oneuse (vti.Vector vti.RegClass:$rs1))),1089 (wti.Vector (sext_oneuse (vti.Vector vti.RegClass:$rs2)))),1090 (vti.Mask true_mask), (XLenVT srcvalue))),1091 (!cast<Instruction>("PseudoVREM_VV_"#vti.LMul.MX#"_E"#!shl(1, vti.Log2SEW))1092 (vti.Vector (IMPLICIT_DEF)),1093 vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>;1094 }1095}1096 1097// 11.12. Vector Widening Integer Multiply Instructions1098defm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, sext_oneuse,1099 "PseudoVWMUL">;1100defm : VPatWidenBinarySDNode_VV_VX<mul, zext_oneuse, zext_oneuse,1101 "PseudoVWMULU">;1102defm : VPatWidenBinarySDNode_VV_VX<mul, anyext_oneuse, anyext_oneuse,1103 "PseudoVWMULU">;1104defm : VPatWidenBinarySDNode_VV_VX<mul, zext_oneuse, anyext_oneuse,1105 "PseudoVWMULU">;1106defm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, zext_oneuse,1107 "PseudoVWMULSU">;1108defm : VPatWidenBinarySDNode_VV_VX<mul, sext_oneuse, anyext_oneuse,1109 "PseudoVWMULSU">;1110 1111// 11.13 Vector Single-Width Integer Multiply-Add Instructions.1112defm : VPatMultiplyAddSDNode_VV_VX<add, "PseudoVMADD">;1113defm : VPatMultiplyAddSDNode_VV_VX<sub, "PseudoVNMSUB">;1114 1115// 11.14 Vector Widening Integer Multiply-Add Instructions1116defm : VPatWidenMulAddSDNode_VV<sext_oneuse, sext_oneuse, "PseudoVWMACC">;1117defm : VPatWidenMulAddSDNode_VX<sext_oneuse, sext_oneuse, "PseudoVWMACC">;1118defm : VPatWidenMulAddSDNode_VV<zext_oneuse, zext_oneuse, "PseudoVWMACCU">;1119defm : VPatWidenMulAddSDNode_VX<zext_oneuse, zext_oneuse, "PseudoVWMACCU">;1120defm : VPatWidenMulAddSDNode_VV<sext_oneuse, zext_oneuse, "PseudoVWMACCSU">;1121defm : VPatWidenMulAddSDNode_VX<sext_oneuse, zext_oneuse, "PseudoVWMACCSU">;1122defm : VPatWidenMulAddSDNode_VX<zext_oneuse, sext_oneuse, "PseudoVWMACCUS">;1123 1124// 11.15. Vector Integer Merge Instructions1125foreach vti = AllIntegerVectors in {1126 let Predicates = GetVTypePredicates<vti>.Predicates in {1127 def : Pat<(vti.Vector (vselect (vti.Mask VMV0:$vm), vti.RegClass:$rs1,1128 vti.RegClass:$rs2)),1129 (!cast<Instruction>("PseudoVMERGE_VVM_"#vti.LMul.MX)1130 (vti.Vector (IMPLICIT_DEF)),1131 vti.RegClass:$rs2, vti.RegClass:$rs1, (vti.Mask VMV0:$vm),1132 vti.AVL, vti.Log2SEW)>;1133 1134 def : Pat<(vti.Vector (vselect (vti.Mask VMV0:$vm), (SplatPat XLenVT:$rs1),1135 vti.RegClass:$rs2)),1136 (!cast<Instruction>("PseudoVMERGE_VXM_"#vti.LMul.MX)1137 (vti.Vector (IMPLICIT_DEF)),1138 vti.RegClass:$rs2, GPR:$rs1, (vti.Mask VMV0:$vm), vti.AVL, vti.Log2SEW)>;1139 1140 def : Pat<(vti.Vector (vselect (vti.Mask VMV0:$vm), (SplatPat_simm5 simm5:$rs1),1141 vti.RegClass:$rs2)),1142 (!cast<Instruction>("PseudoVMERGE_VIM_"#vti.LMul.MX)1143 (vti.Vector (IMPLICIT_DEF)),1144 vti.RegClass:$rs2, simm5:$rs1, (vti.Mask VMV0:$vm), vti.AVL, vti.Log2SEW)>;1145 }1146}1147 1148// 12. Vector Fixed-Point Arithmetic Instructions1149 1150// 12.1. Vector Single-Width Saturating Add and Subtract1151defm : VPatBinarySDNode_VV_VX_VI<saddsat, "PseudoVSADD">;1152defm : VPatBinarySDNode_VV_VX_VI<uaddsat, "PseudoVSADDU">;1153defm : VPatBinarySDNode_VV_VX<ssubsat, "PseudoVSSUB">;1154defm : VPatBinarySDNode_VV_VX<usubsat, "PseudoVSSUBU">;1155 1156// 12.2. Vector Single-Width Averaging Add and Subtract1157defm : VPatAVGADD_VV_VX_RM<avgfloors, 0b10>;1158defm : VPatAVGADD_VV_VX_RM<avgflooru, 0b10, suffix = "U">;1159defm : VPatAVGADD_VV_VX_RM<avgceils, 0b00>;1160defm : VPatAVGADD_VV_VX_RM<avgceilu, 0b00, suffix = "U">;1161 1162// 15. Vector Mask Instructions1163 1164// 15.1. Vector Mask-Register Logical Instructions1165foreach mti = AllMasks in {1166 let Predicates = [HasVInstructions] in {1167 def : Pat<(mti.Mask (and VR:$rs1, VR:$rs2)),1168 (!cast<Instruction>("PseudoVMAND_MM_"#mti.BX)1169 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;1170 def : Pat<(mti.Mask (or VR:$rs1, VR:$rs2)),1171 (!cast<Instruction>("PseudoVMOR_MM_"#mti.BX)1172 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;1173 def : Pat<(mti.Mask (xor VR:$rs1, VR:$rs2)),1174 (!cast<Instruction>("PseudoVMXOR_MM_"#mti.BX)1175 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;1176 1177 def : Pat<(mti.Mask (rvv_vnot (and VR:$rs1, VR:$rs2))),1178 (!cast<Instruction>("PseudoVMNAND_MM_"#mti.BX)1179 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;1180 def : Pat<(mti.Mask (rvv_vnot (or VR:$rs1, VR:$rs2))),1181 (!cast<Instruction>("PseudoVMNOR_MM_"#mti.BX)1182 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;1183 def : Pat<(mti.Mask (rvv_vnot (xor VR:$rs1, VR:$rs2))),1184 (!cast<Instruction>("PseudoVMXNOR_MM_"#mti.BX)1185 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;1186 1187 def : Pat<(mti.Mask (and VR:$rs1, (rvv_vnot VR:$rs2))),1188 (!cast<Instruction>("PseudoVMANDN_MM_"#mti.BX)1189 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;1190 def : Pat<(mti.Mask (or VR:$rs1, (rvv_vnot VR:$rs2))),1191 (!cast<Instruction>("PseudoVMORN_MM_"#mti.BX)1192 VR:$rs1, VR:$rs2, mti.AVL, mti.Log2SEW)>;1193 1194 // Handle rvv_vnot the same as the vmnot.m pseudoinstruction.1195 def : Pat<(mti.Mask (rvv_vnot VR:$rs)),1196 (!cast<Instruction>("PseudoVMNAND_MM_"#mti.BX)1197 VR:$rs, VR:$rs, mti.AVL, mti.Log2SEW)>;1198 }1199}1200 1201// 13. Vector Floating-Point Instructions1202 1203// 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions1204defm : VPatBinaryFPSDNode_VV_VF_RM<any_fadd, "PseudoVFADD", isSEWAware=1>;1205defm : VPatBinaryFPSDNode_VV_VF_RM<any_fsub, "PseudoVFSUB", isSEWAware=1>;1206defm : VPatBinaryFPSDNode_R_VF_RM<any_fsub, "PseudoVFRSUB", isSEWAware=1>;1207 1208// 13.3. Vector Widening Floating-Point Add/Subtract Instructions1209defm : VPatWidenBinaryFPSDNode_VV_VF_WV_WF_RM<fadd, "PseudoVFWADD">;1210defm : VPatWidenBinaryFPSDNode_VV_VF_WV_WF_RM<fsub, "PseudoVFWSUB">;1211 1212// 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions1213defm : VPatBinaryFPSDNode_VV_VF_RM<any_fmul, "PseudoVFMUL", isSEWAware=1>;1214defm : VPatBinaryFPSDNode_VV_VF_RM<any_fdiv, "PseudoVFDIV", isSEWAware=1>;1215defm : VPatBinaryFPSDNode_R_VF_RM<any_fdiv, "PseudoVFRDIV", isSEWAware=1>;1216 1217// 13.5. Vector Widening Floating-Point Multiply Instructions1218defm : VPatWidenBinaryFPSDNode_VV_VF_RM<fmul, "PseudoVFWMUL">;1219 1220// 13.6 Vector Single-Width Floating-Point Fused Multiply-Add Instructions.1221foreach fvti = AllFloatVectors in {1222 // NOTE: We choose VFMADD because it has the most commuting freedom. So it1223 // works best with how TwoAddressInstructionPass tries commuting.1224 defvar suffix = fvti.LMul.MX # "_E" # fvti.SEW;1225 let Predicates = GetVTypePredicates<fvti>.Predicates in {1226 def : Pat<(fvti.Vector (any_fma fvti.RegClass:$rs1, fvti.RegClass:$rd,1227 fvti.RegClass:$rs2)),1228 (!cast<Instruction>("PseudoVFMADD_VV_"# suffix)1229 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2,1230 // Value to indicate no rounding mode change in1231 // RISCVInsertReadWriteCSR1232 FRM_DYN,1233 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1234 def : Pat<(fvti.Vector (any_fma fvti.RegClass:$rs1, fvti.RegClass:$rd,1235 (fneg fvti.RegClass:$rs2))),1236 (!cast<Instruction>("PseudoVFMSUB_VV_"# suffix)1237 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2,1238 // Value to indicate no rounding mode change in1239 // RISCVInsertReadWriteCSR1240 FRM_DYN,1241 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1242 def : Pat<(fvti.Vector (any_fma (fneg fvti.RegClass:$rs1), fvti.RegClass:$rd,1243 (fneg fvti.RegClass:$rs2))),1244 (!cast<Instruction>("PseudoVFNMADD_VV_"# suffix)1245 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2,1246 // Value to indicate no rounding mode change in1247 // RISCVInsertReadWriteCSR1248 FRM_DYN,1249 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1250 def : Pat<(fvti.Vector (any_fma (fneg fvti.RegClass:$rs1), fvti.RegClass:$rd,1251 fvti.RegClass:$rs2)),1252 (!cast<Instruction>("PseudoVFNMSUB_VV_"# suffix)1253 fvti.RegClass:$rd, fvti.RegClass:$rs1, fvti.RegClass:$rs2,1254 // Value to indicate no rounding mode change in1255 // RISCVInsertReadWriteCSR1256 FRM_DYN,1257 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1258 1259 // The choice of VFMADD here is arbitrary, vfmadd.vf and vfmacc.vf are equally1260 // commutable.1261 def : Pat<(fvti.Vector (any_fma (SplatFPOp fvti.ScalarRegClass:$rs1),1262 fvti.RegClass:$rd, fvti.RegClass:$rs2)),1263 (!cast<Instruction>("PseudoVFMADD_V" # fvti.ScalarSuffix # "_" # suffix)1264 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,1265 // Value to indicate no rounding mode change in1266 // RISCVInsertReadWriteCSR1267 FRM_DYN,1268 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1269 def : Pat<(fvti.Vector (any_fma (SplatFPOp fvti.ScalarRegClass:$rs1),1270 fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))),1271 (!cast<Instruction>("PseudoVFMSUB_V" # fvti.ScalarSuffix # "_" # suffix)1272 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,1273 // Value to indicate no rounding mode change in1274 // RISCVInsertReadWriteCSR1275 FRM_DYN,1276 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1277 1278 def : Pat<(fvti.Vector (any_fma (SplatFPOp fvti.ScalarRegClass:$rs1),1279 (fneg fvti.RegClass:$rd), (fneg fvti.RegClass:$rs2))),1280 (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix)1281 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,1282 // Value to indicate no rounding mode change in1283 // RISCVInsertReadWriteCSR1284 FRM_DYN,1285 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1286 def : Pat<(fvti.Vector (any_fma (SplatFPOp fvti.ScalarRegClass:$rs1),1287 (fneg fvti.RegClass:$rd), fvti.RegClass:$rs2)),1288 (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix)1289 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,1290 // Value to indicate no rounding mode change in1291 // RISCVInsertReadWriteCSR1292 FRM_DYN,1293 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1294 1295 // The splat might be negated.1296 def : Pat<(fvti.Vector (any_fma (fneg (SplatFPOp fvti.ScalarRegClass:$rs1)),1297 fvti.RegClass:$rd, (fneg fvti.RegClass:$rs2))),1298 (!cast<Instruction>("PseudoVFNMADD_V" # fvti.ScalarSuffix # "_" # suffix)1299 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,1300 // Value to indicate no rounding mode change in1301 // RISCVInsertReadWriteCSR1302 FRM_DYN,1303 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1304 def : Pat<(fvti.Vector (any_fma (fneg (SplatFPOp fvti.ScalarRegClass:$rs1)),1305 fvti.RegClass:$rd, fvti.RegClass:$rs2)),1306 (!cast<Instruction>("PseudoVFNMSUB_V" # fvti.ScalarSuffix # "_" # suffix)1307 fvti.RegClass:$rd, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2,1308 // Value to indicate no rounding mode change in1309 // RISCVInsertReadWriteCSR1310 FRM_DYN,1311 fvti.AVL, fvti.Log2SEW, TAIL_AGNOSTIC)>;1312 }1313}1314 1315// 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions1316defm : VPatWidenFPMulAccSDNode_VV_VF_RM<"PseudoVFWMACC",1317 AllWidenableFloatVectors>;1318defm : VPatWidenFPNegMulAccSDNode_VV_VF_RM<"PseudoVFWNMACC">;1319defm : VPatWidenFPMulSacSDNode_VV_VF_RM<"PseudoVFWMSAC">;1320defm : VPatWidenFPNegMulSacSDNode_VV_VF_RM<"PseudoVFWNMSAC">;1321 1322foreach vti = AllFloatVectors in {1323 let Predicates = GetVTypePredicates<vti>.Predicates in {1324 // 13.8. Vector Floating-Point Square-Root Instruction1325 def : Pat<(any_fsqrt (vti.Vector vti.RegClass:$rs2)),1326 (!cast<Instruction>("PseudoVFSQRT_V_"# vti.LMul.MX#"_E"#vti.SEW)1327 (vti.Vector (IMPLICIT_DEF)),1328 vti.RegClass:$rs2,1329 // Value to indicate no rounding mode change in1330 // RISCVInsertReadWriteCSR1331 FRM_DYN,1332 vti.AVL, vti.Log2SEW, TA_MA)>;1333 1334 // 13.12. Vector Floating-Point Sign-Injection Instructions1335 def : Pat<(fabs (vti.Vector vti.RegClass:$rs)),1336 (!cast<Instruction>("PseudoVFSGNJX_VV_"# vti.LMul.MX#"_E"#vti.SEW)1337 (vti.Vector (IMPLICIT_DEF)),1338 vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.Log2SEW, TA_MA)>;1339 // Handle fneg with VFSGNJN using the same input for both operands.1340 def : Pat<(fneg (vti.Vector vti.RegClass:$rs)),1341 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX#"_E"#vti.SEW)1342 (vti.Vector (IMPLICIT_DEF)),1343 vti.RegClass:$rs, vti.RegClass:$rs, vti.AVL, vti.Log2SEW, TA_MA)>;1344 1345 def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1),1346 (vti.Vector vti.RegClass:$rs2))),1347 (!cast<Instruction>("PseudoVFSGNJ_VV_"# vti.LMul.MX#"_E"#vti.SEW)1348 (vti.Vector (IMPLICIT_DEF)),1349 vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>;1350 def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1),1351 (vti.Vector (SplatFPOp vti.ScalarRegClass:$rs2)))),1352 (!cast<Instruction>("PseudoVFSGNJ_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW)1353 (vti.Vector (IMPLICIT_DEF)),1354 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>;1355 1356 def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1),1357 (vti.Vector (fneg vti.RegClass:$rs2)))),1358 (!cast<Instruction>("PseudoVFSGNJN_VV_"# vti.LMul.MX#"_E"#vti.SEW)1359 (vti.Vector (IMPLICIT_DEF)),1360 vti.RegClass:$rs1, vti.RegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>;1361 def : Pat<(vti.Vector (fcopysign (vti.Vector vti.RegClass:$rs1),1362 (vti.Vector (fneg (SplatFPOp vti.ScalarRegClass:$rs2))))),1363 (!cast<Instruction>("PseudoVFSGNJN_V"#vti.ScalarSuffix#"_"#vti.LMul.MX#"_E"#vti.SEW)1364 (vti.Vector (IMPLICIT_DEF)),1365 vti.RegClass:$rs1, vti.ScalarRegClass:$rs2, vti.AVL, vti.Log2SEW, TA_MA)>;1366 }1367}1368 1369// 13.11. Vector Floating-Point MIN/MAX Instructions1370defm : VPatBinaryFPSDNode_VV_VF<fminnum, "PseudoVFMIN", isSEWAware=1>;1371defm : VPatBinaryFPSDNode_VV_VF<fmaxnum, "PseudoVFMAX", isSEWAware=1>;1372defm : VPatBinaryFPSDNode_VV_VF<fminimumnum, "PseudoVFMIN", isSEWAware=1>;1373defm : VPatBinaryFPSDNode_VV_VF<fmaximumnum, "PseudoVFMAX", isSEWAware=1>;1374 1375// 13.13. Vector Floating-Point Compare Instructions1376defm : VPatFPSetCCSDNode_VV_VF_FV<SETEQ, "PseudoVMFEQ", "PseudoVMFEQ">;1377defm : VPatFPSetCCSDNode_VV_VF_FV<SETOEQ, "PseudoVMFEQ", "PseudoVMFEQ">;1378 1379defm : VPatFPSetCCSDNode_VV_VF_FV<SETNE, "PseudoVMFNE", "PseudoVMFNE">;1380defm : VPatFPSetCCSDNode_VV_VF_FV<SETUNE, "PseudoVMFNE", "PseudoVMFNE">;1381 1382defm : VPatFPSetCCSDNode_VV_VF_FV<SETLT, "PseudoVMFLT", "PseudoVMFGT">;1383defm : VPatFPSetCCSDNode_VV_VF_FV<SETOLT, "PseudoVMFLT", "PseudoVMFGT">;1384 1385defm : VPatFPSetCCSDNode_VV_VF_FV<SETLE, "PseudoVMFLE", "PseudoVMFGE">;1386defm : VPatFPSetCCSDNode_VV_VF_FV<SETOLE, "PseudoVMFLE", "PseudoVMFGE">;1387 1388// Floating-point vselects:1389// 11.15. Vector Integer Merge Instructions1390// 13.15. Vector Floating-Point Merge Instruction1391foreach fvti = AllFloatAndBF16Vectors in {1392 defvar ivti = GetIntVTypeInfo<fvti>.Vti;1393 let Predicates = GetVTypePredicates<ivti>.Predicates in {1394 def : Pat<(fvti.Vector (vselect (fvti.Mask VMV0:$vm), fvti.RegClass:$rs1,1395 fvti.RegClass:$rs2)),1396 (!cast<Instruction>("PseudoVMERGE_VVM_"#fvti.LMul.MX)1397 (fvti.Vector (IMPLICIT_DEF)),1398 fvti.RegClass:$rs2, fvti.RegClass:$rs1, (fvti.Mask VMV0:$vm),1399 fvti.AVL, fvti.Log2SEW)>;1400 }1401}1402 1403foreach fvti = AllFloatVectors in {1404 defvar ivti = GetIntVTypeInfo<fvti>.Vti;1405 let Predicates = GetVTypePredicates<ivti>.Predicates in {1406 def : Pat<(fvti.Vector (vselect (fvti.Mask VMV0:$vm),1407 (SplatFPOp (SelectScalarFPAsInt (XLenVT GPR:$imm))),1408 fvti.RegClass:$rs2)),1409 (!cast<Instruction>("PseudoVMERGE_VXM_"#fvti.LMul.MX)1410 (fvti.Vector (IMPLICIT_DEF)),1411 fvti.RegClass:$rs2, GPR:$imm, (fvti.Mask VMV0:$vm), fvti.AVL, fvti.Log2SEW)>;1412 1413 def : Pat<(fvti.Vector (vselect (fvti.Mask VMV0:$vm),1414 (SplatFPOp (fvti.Scalar fpimm0)),1415 fvti.RegClass:$rs2)),1416 (!cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX)1417 (fvti.Vector (IMPLICIT_DEF)),1418 fvti.RegClass:$rs2, 0, (fvti.Mask VMV0:$vm), fvti.AVL, fvti.Log2SEW)>;1419 }1420 1421 let Predicates = GetVTypePredicates<fvti>.Predicates in1422 def : Pat<(fvti.Vector (vselect (fvti.Mask VMV0:$vm),1423 (SplatFPOp fvti.ScalarRegClass:$rs1),1424 fvti.RegClass:$rs2)),1425 (!cast<Instruction>("PseudoVFMERGE_V"#fvti.ScalarSuffix#"M_"#fvti.LMul.MX)1426 (fvti.Vector (IMPLICIT_DEF)),1427 fvti.RegClass:$rs2,1428 (fvti.Scalar fvti.ScalarRegClass:$rs1),1429 (fvti.Mask VMV0:$vm), fvti.AVL, fvti.Log2SEW)>;1430}1431 1432// 13.17. Vector Single-Width Floating-Point/Integer Type-Convert Instructions1433defm : VPatConvertFP2ISDNode_V<any_fp_to_sint, "PseudoVFCVT_RTZ_X_F_V">;1434defm : VPatConvertFP2ISDNode_V<any_fp_to_uint, "PseudoVFCVT_RTZ_XU_F_V">;1435defm : VPatConvertI2FPSDNode_V_RM<any_sint_to_fp, "PseudoVFCVT_F_X_V">;1436defm : VPatConvertI2FPSDNode_V_RM<any_uint_to_fp, "PseudoVFCVT_F_XU_V">;1437 1438// 13.18. Widening Floating-Point/Integer Type-Convert Instructions1439defm : VPatWConvertFP2ISDNode_V<any_fp_to_sint, "PseudoVFWCVT_RTZ_X_F_V">;1440defm : VPatWConvertFP2ISDNode_V<any_fp_to_uint, "PseudoVFWCVT_RTZ_XU_F_V">;1441defm : VPatWConvertI2FPSDNode_V<any_sint_to_fp, "PseudoVFWCVT_F_X_V">;1442defm : VPatWConvertI2FPSDNode_V<any_uint_to_fp, "PseudoVFWCVT_F_XU_V">;1443 1444// 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions1445defm : VPatNConvertFP2ISDNode_W<any_fp_to_sint, "PseudoVFNCVT_RTZ_X_F_W">;1446defm : VPatNConvertFP2ISDNode_W<any_fp_to_uint, "PseudoVFNCVT_RTZ_XU_F_W">;1447defm : VPatNConvertI2FPSDNode_W_RM<any_sint_to_fp, "PseudoVFNCVT_F_X_W">;1448defm : VPatNConvertI2FPSDNode_W_RM<any_uint_to_fp, "PseudoVFNCVT_F_XU_W">;1449foreach fvtiToFWti = AllWidenableFloatVectors in {1450 defvar fvti = fvtiToFWti.Vti;1451 defvar fwti = fvtiToFWti.Wti;1452 let Predicates = !listconcat(GetVTypeMinimalPredicates<fvti>.Predicates,1453 GetVTypeMinimalPredicates<fwti>.Predicates) in1454 def : Pat<(fvti.Vector (fpround (fwti.Vector fwti.RegClass:$rs1))),1455 (!cast<Instruction>("PseudoVFNCVT_F_F_W_"#fvti.LMul.MX#"_E"#fvti.SEW)1456 (fvti.Vector (IMPLICIT_DEF)),1457 fwti.RegClass:$rs1,1458 // Value to indicate no rounding mode change in1459 // RISCVInsertReadWriteCSR1460 FRM_DYN,1461 fvti.AVL, fvti.Log2SEW, TA_MA)>;1462}1463 1464//===----------------------------------------------------------------------===//1465// Vector Element Extracts1466//===----------------------------------------------------------------------===//1467foreach vti = NoGroupFloatVectors in {1468 defvar vfmv_f_s_inst = !cast<Instruction>(!strconcat("PseudoVFMV_",1469 vti.ScalarSuffix,1470 "_S"));1471 // Only pattern-match extract-element operations where the index is 0. Any1472 // other index will have been custom-lowered to slide the vector correctly1473 // into place.1474 let Predicates = GetVTypePredicates<vti>.Predicates in1475 def : Pat<(vti.Scalar (extractelt (vti.Vector vti.RegClass:$rs2), 0)),1476 (vfmv_f_s_inst vti.RegClass:$rs2, vti.Log2SEW)>;1477}1478