1//===- TargetSelectionDAG.td - Common code for DAG isels ---*- 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 defines the target-independent interfaces used by SelectionDAG 10// instruction selection generators. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15// Selection DAG Type Constraint definitions. 16// 17// Note that the semantics of these constraints are hard coded into tblgen. To 18// modify or add constraints, you have to hack tblgen. 19// 20 21class SDTypeConstraint<int opnum> { 22 int OperandNum = opnum; 23} 24 25// SDTCisVT - The specified operand has exactly this VT. 26class SDTCisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> { 27 ValueType VT = vt; 28} 29 30class SDTCisPtrTy<int OpNum> : SDTypeConstraint<OpNum>; 31 32// SDTCisInt - The specified operand has integer type. 33class SDTCisInt<int OpNum> : SDTypeConstraint<OpNum>; 34 35// SDTCisFP - The specified operand has floating-point type. 36class SDTCisFP<int OpNum> : SDTypeConstraint<OpNum>; 37 38// SDTCisVec - The specified operand has a vector type. 39class SDTCisVec<int OpNum> : SDTypeConstraint<OpNum>; 40 41// SDTCisSameAs - The two specified operands have identical types. 42class SDTCisSameAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { 43 int OtherOperandNum = OtherOp; 44} 45 46// SDTCisVTSmallerThanOp - The specified operand is a VT SDNode, and its type is 47// smaller than the 'Other' operand. 48class SDTCisVTSmallerThanOp<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { 49 int OtherOperandNum = OtherOp; 50} 51 52class SDTCisOpSmallerThanOp<int SmallOp, int BigOp> : SDTypeConstraint<SmallOp>{ 53 int BigOperandNum = BigOp; 54} 55 56/// SDTCisEltOfVec - This indicates that ThisOp is a scalar type of the same 57/// type as the element type of OtherOp, which is a vector type. 58class SDTCisEltOfVec<int ThisOp, int OtherOp> 59 : SDTypeConstraint<ThisOp> { 60 int OtherOpNum = OtherOp; 61} 62 63/// SDTCisSubVecOfVec - This indicates that ThisOp is a vector type 64/// with length less that of OtherOp, which is a vector type. 65class SDTCisSubVecOfVec<int ThisOp, int OtherOp> 66 : SDTypeConstraint<ThisOp> { 67 int OtherOpNum = OtherOp; 68} 69 70// SDTCVecEltisVT - The specified operand is vector type with element type 71// of VT. 72class SDTCVecEltisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> { 73 ValueType VT = vt; 74} 75 76// SDTCisSameNumEltsAs - The two specified operands have identical number 77// of elements. 78class SDTCisSameNumEltsAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { 79 int OtherOperandNum = OtherOp; 80} 81 82// SDTCisSameSizeAs - The two specified operands have identical size. 83class SDTCisSameSizeAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> { 84 int OtherOperandNum = OtherOp; 85} 86 87//===----------------------------------------------------------------------===// 88// Selection DAG Type Profile definitions. 89// 90// These use the constraints defined above to describe the type requirements of 91// the various nodes. These are not hard coded into tblgen, allowing targets to 92// add their own if needed. 93// 94 95// SDTypeProfile - This profile describes the type requirements of a Selection 96// DAG node. 97class SDTypeProfile<int numresults, int numoperands, 98 list<SDTypeConstraint> constraints> { 99 int NumResults = numresults; 100 int NumOperands = numoperands; 101 list<SDTypeConstraint> Constraints = constraints; 102} 103 104// Builtin profiles. 105def SDTIntLeaf: SDTypeProfile<1, 0, [SDTCisInt<0>]>; // for 'imm'. 106def SDTFPLeaf : SDTypeProfile<1, 0, [SDTCisFP<0>]>; // for 'fpimm'. 107def SDTPtrLeaf: SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>; // for '&g'. 108def SDTOther : SDTypeProfile<1, 0, [SDTCisVT<0, OtherVT>]>; // for 'vt'. 109def SDTUNDEF : SDTypeProfile<1, 0, []>; // for 'undef'. 110def SDTUnaryOp : SDTypeProfile<1, 1, []>; // for bitconvert. 111 112def SDTPtrAddOp : SDTypeProfile<1, 2, [ // ptradd 113 SDTCisSameAs<0, 1>, SDTCisInt<2>, SDTCisPtrTy<1> 114]>; 115def SDTIntBinOp : SDTypeProfile<1, 2, [ // add, and, or, xor, udiv, etc. 116 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0> 117]>; 118def SDTIntShiftOp : SDTypeProfile<1, 2, [ // shl, sra, srl 119 SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisInt<2> 120]>; 121def SDTIntShiftDOp: SDTypeProfile<1, 3, [ // fshl, fshr 122 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3> 123]>; 124def SDTIntSatNoShOp : SDTypeProfile<1, 2, [ // ssat with no shift 125 SDTCisSameAs<0, 1>, SDTCisInt<2> 126]>; 127def SDTIntBinHiLoOp : SDTypeProfile<2, 2, [ // mulhi, mullo, sdivrem, udivrem 128 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,SDTCisInt<0> 129]>; 130def SDTIntScaledBinOp : SDTypeProfile<1, 3, [ // smulfix, sdivfix, etc 131 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisInt<0>, SDTCisInt<3> 132]>; 133 134def SDTFPBinOp : SDTypeProfile<1, 2, [ // fadd, fmul, etc. 135 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0> 136]>; 137def SDTFPSignOp : SDTypeProfile<1, 2, [ // fcopysign. 138 SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisFP<2> 139]>; 140def SDTFPTernaryOp : SDTypeProfile<1, 3, [ // fmadd, fnmsub, etc. 141 SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisFP<0> 142]>; 143def SDTIntUnaryOp : SDTypeProfile<1, 1, [ // bitreverse 144 SDTCisSameAs<0, 1>, SDTCisInt<0> 145]>; 146def SDTIntBitCountUnaryOp : SDTypeProfile<1, 1, [ // ctlz, cttz 147 SDTCisInt<0>, SDTCisInt<1> 148]>; 149def SDTIntExtendOp : SDTypeProfile<1, 1, [ // sext, zext, anyext 150 SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1> 151]>; 152def SDTIntTruncOp : SDTypeProfile<1, 1, [ // trunc 153 SDTCisInt<0>, SDTCisInt<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1> 154]>; 155def SDTFPUnaryOp : SDTypeProfile<1, 1, [ // fneg, fsqrt, etc 156 SDTCisSameAs<0, 1>, SDTCisFP<0> 157]>; 158def SDTFPRoundOp : SDTypeProfile<1, 1, [ // fpround 159 SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<0, 1>, SDTCisSameNumEltsAs<0, 1> 160]>; 161def SDTFPExtendOp : SDTypeProfile<1, 1, [ // fpextend 162 SDTCisFP<0>, SDTCisFP<1>, SDTCisOpSmallerThanOp<1, 0>, SDTCisSameNumEltsAs<0, 1> 163]>; 164def SDIsFPClassOp : SDTypeProfile<1, 2, [ // is_fpclass 165 SDTCisInt<0>, SDTCisFP<1>, SDTCisInt<2>, SDTCisSameNumEltsAs<0, 1> 166]>; 167def SDTIntToFPOp : SDTypeProfile<1, 1, [ // [su]int_to_fp 168 SDTCisFP<0>, SDTCisInt<1>, SDTCisSameNumEltsAs<0, 1> 169]>; 170def SDTFPToIntOp : SDTypeProfile<1, 1, [ // fp_to_[su]int 171 SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1> 172]>; 173def SDTFPToIntSatOp : SDTypeProfile<1, 2, [ // fp_to_[su]int_sat 174 SDTCisInt<0>, SDTCisFP<1>, SDTCisSameNumEltsAs<0, 1>, SDTCisVT<2, OtherVT> 175]>; 176def SDTFPExpOp : SDTypeProfile<1, 2, [ // ldexp 177 SDTCisSameAs<0, 1>, SDTCisFP<0>, SDTCisInt<2> 178]>; 179def SDTGetFPStateOp : SDTypeProfile<1, 0, [ // get_fpenv, get_fpmode 180 SDTCisInt<0> 181]>; 182def SDTSetFPStateOp : SDTypeProfile<0, 1, [ // set_fpenv, set_fpmode 183 SDTCisInt<0> 184]>; 185def SDTExtInreg : SDTypeProfile<1, 2, [ // sext_inreg 186 SDTCisSameAs<0, 1>, SDTCisInt<0>, SDTCisVT<2, OtherVT>, 187 SDTCisVTSmallerThanOp<2, 1> 188]>; 189def SDTExtInvec : SDTypeProfile<1, 1, [ // sext_invec 190 SDTCisInt<0>, SDTCisVec<0>, SDTCisInt<1>, SDTCisVec<1>, 191 SDTCisOpSmallerThanOp<1, 0> 192]>; 193def SDTFreeze : SDTypeProfile<1, 1, [ 194 SDTCisSameAs<0, 1> 195]>; 196 197def SDTSetCC : SDTypeProfile<1, 3, [ // setcc 198 SDTCisInt<0>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> 199]>; 200 201def SDTSelect : SDTypeProfile<1, 3, [ // select 202 SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3> 203]>; 204 205def SDTVSelect : SDTypeProfile<1, 3, [ // vselect 206 SDTCisVec<0>, SDTCisInt<1>, SDTCisSameAs<0, 2>, SDTCisSameAs<2, 3>, SDTCisSameNumEltsAs<0, 1> 207]>; 208 209def SDTSelectCC : SDTypeProfile<1, 5, [ // select_cc 210 SDTCisSameAs<1, 2>, SDTCisSameAs<3, 4>, SDTCisSameAs<0, 3>, 211 SDTCisVT<5, OtherVT> 212]>; 213 214def SDTBr : SDTypeProfile<0, 1, [ // br 215 SDTCisVT<0, OtherVT> 216]>; 217 218def SDTBrCC : SDTypeProfile<0, 4, [ // brcc 219 SDTCisVT<0, OtherVT>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT> 220]>; 221 222def SDTBrcond : SDTypeProfile<0, 2, [ // brcond 223 SDTCisInt<0>, SDTCisVT<1, OtherVT> 224]>; 225 226def SDTBrind : SDTypeProfile<0, 1, [ // brind 227 SDTCisPtrTy<0> 228]>; 229 230def SDTCatchret : SDTypeProfile<0, 2, [ // catchret 231 SDTCisVT<0, OtherVT>, SDTCisVT<1, OtherVT> 232]>; 233 234def SDTCleanupret : SDTypeProfile<0, 1, [ // cleanupret 235 SDTCisVT<0, OtherVT> 236]>; 237 238def SDTNone : SDTypeProfile<0, 0, []>; // ret, trap 239 240def SDTUBSANTrap : SDTypeProfile<0, 1, []>; // ubsantrap 241 242def SDTLoad : SDTypeProfile<1, 1, [ // load 243 SDTCisPtrTy<1> 244]>; 245 246def SDTStore : SDTypeProfile<0, 2, [ // store 247 SDTCisPtrTy<1> 248]>; 249 250def SDTIStore : SDTypeProfile<1, 3, [ // indexed store 251 SDTCisSameAs<0, 2>, SDTCisPtrTy<0>, SDTCisPtrTy<3> 252]>; 253 254def SDTMaskedStore: SDTypeProfile<0, 4, [ // masked store 255 SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisPtrTy<2>, SDTCisVec<3>, SDTCisSameNumEltsAs<0, 3> 256]>; 257 258def SDTMaskedLoad: SDTypeProfile<1, 4, [ // masked load 259 SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisPtrTy<2>, SDTCisVec<3>, SDTCisSameAs<0, 4>, 260 SDTCisSameNumEltsAs<0, 3> 261]>; 262 263def SDTMaskedGather : SDTypeProfile<1, 4, [ 264 SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisVec<2>, SDTCisPtrTy<3>, SDTCisVec<4>, 265 SDTCisSameNumEltsAs<0, 2>, SDTCisSameNumEltsAs<0, 4> 266]>; 267 268def SDTMaskedScatter : SDTypeProfile<0, 4, [ 269 SDTCisVec<0>, SDTCisVec<1>, SDTCisPtrTy<2>, SDTCisVec<3>, 270 SDTCisSameNumEltsAs<0, 1>, SDTCisSameNumEltsAs<0, 3> 271]>; 272 273def SDTVectorCompress : SDTypeProfile<1, 3, [ 274 SDTCisVec<0>, SDTCisSameAs<0, 1>, 275 SDTCisVec<2>, SDTCisSameNumEltsAs<1, 2>, 276 SDTCisSameAs<1, 3> 277]>; 278 279def SDTVecShuffle : SDTypeProfile<1, 2, [ 280 SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> 281]>; 282def SDTVecSlice : SDTypeProfile<1, 3, [ // vector splice 283 SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisInt<3> 284]>; 285def SDTVecExtract : SDTypeProfile<1, 2, [ // vector extract 286 SDTCisEltOfVec<0, 1>, SDTCisPtrTy<2> 287]>; 288def SDTVecInsert : SDTypeProfile<1, 3, [ // vector insert 289 SDTCisEltOfVec<2, 1>, SDTCisSameAs<0, 1>, SDTCisPtrTy<3> 290]>; 291def SDTVecReduce : SDTypeProfile<1, 1, [ // vector reduction 292 SDTCisInt<0>, SDTCisVec<1> 293]>; 294def SDTFPVecReduce : SDTypeProfile<1, 1, [ // FP vector reduction 295 SDTCisFP<0>, SDTCisVec<1> 296]>; 297 298def SDTVecReverse : SDTypeProfile<1, 1, [ // vector reverse 299 SDTCisVec<0>, SDTCisSameAs<0,1> 300]>; 301 302def SDTSubVecExtract : SDTypeProfile<1, 2, [// subvector extract 303 SDTCisSubVecOfVec<0,1>, SDTCisInt<2> 304]>; 305def SDTSubVecInsert : SDTypeProfile<1, 3, [ // subvector insert 306 SDTCisSubVecOfVec<2, 1>, SDTCisSameAs<0,1>, SDTCisInt<3> 307]>; 308 309def SDTPrefetch : SDTypeProfile<0, 4, [ // prefetch 310 SDTCisPtrTy<0>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisInt<1> 311]>; 312 313def SDTAtomicFence : SDTypeProfile<0, 2, [ 314 SDTCisSameAs<0,1>, SDTCisPtrTy<0> 315]>; 316def SDTAtomic3 : SDTypeProfile<1, 3, [ 317 SDTCisSameAs<0,2>, SDTCisSameAs<0,3>, SDTCisInt<0>, SDTCisPtrTy<1> 318]>; 319def SDTAtomic2 : SDTypeProfile<1, 2, [ 320 SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1> 321]>; 322 323def SDTFPAtomic2 : SDTypeProfile<1, 2, [ 324 SDTCisSameAs<0,2>, SDTCisFP<0>, SDTCisPtrTy<1> 325]>; 326 327def SDTAtomicStore : SDTypeProfile<0, 2, [ 328 SDTCisInt<0>, SDTCisPtrTy<1> 329]>; 330def SDTAtomicLoad : SDTypeProfile<1, 1, [ 331 SDTCisPtrTy<1> 332]>; 333 334class SDCallSeqStart<list<SDTypeConstraint> constraints> : 335 SDTypeProfile<0, 2, constraints>; 336class SDCallSeqEnd<list<SDTypeConstraint> constraints> : 337 SDTypeProfile<0, 2, constraints>; 338 339//===----------------------------------------------------------------------===// 340// Selection DAG Node definitions. 341// 342class SDNode<string opcode, SDTypeProfile typeprof, 343 list<SDNodeProperty> props = [], string sdclass = "SDNode"> 344 : SDPatternOperator { 345 string Opcode = opcode; 346 string SDClass = sdclass; 347 let Properties = props; 348 SDTypeProfile TypeProfile = typeprof; 349} 350 351// Special TableGen-recognized dag nodes 352def set; 353def implicit; 354def node; 355def srcvalue; 356 357def imm : SDNode<"ISD::Constant" , SDTIntLeaf , [], "ConstantSDNode">; 358def timm : SDNode<"ISD::TargetConstant",SDTIntLeaf, [], "ConstantSDNode">; 359def fpimm : SDNode<"ISD::ConstantFP", SDTFPLeaf , [], "ConstantFPSDNode">; 360def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">; 361def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">; 362def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">; 363def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>; 364def vscale : SDNode<"ISD::VSCALE" , SDTIntUnaryOp, []>; 365def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [], 366 "GlobalAddressSDNode">; 367def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [], 368 "GlobalAddressSDNode">; 369def globaltlsaddr : SDNode<"ISD::GlobalTLSAddress", SDTPtrLeaf, [], 370 "GlobalAddressSDNode">; 371def tglobaltlsaddr : SDNode<"ISD::TargetGlobalTLSAddress", SDTPtrLeaf, [], 372 "GlobalAddressSDNode">; 373def constpool : SDNode<"ISD::ConstantPool", SDTPtrLeaf, [], 374 "ConstantPoolSDNode">; 375def tconstpool : SDNode<"ISD::TargetConstantPool", SDTPtrLeaf, [], 376 "ConstantPoolSDNode">; 377def jumptable : SDNode<"ISD::JumpTable", SDTPtrLeaf, [], 378 "JumpTableSDNode">; 379def tjumptable : SDNode<"ISD::TargetJumpTable", SDTPtrLeaf, [], 380 "JumpTableSDNode">; 381def frameindex : SDNode<"ISD::FrameIndex", SDTPtrLeaf, [], 382 "FrameIndexSDNode">; 383def tframeindex : SDNode<"ISD::TargetFrameIndex", SDTPtrLeaf, [], 384 "FrameIndexSDNode">; 385def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [], 386 "ExternalSymbolSDNode">; 387def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [], 388 "ExternalSymbolSDNode">; 389def mcsym: SDNode<"ISD::MCSymbol", SDTPtrLeaf, [], "MCSymbolSDNode">; 390def blockaddress : SDNode<"ISD::BlockAddress", SDTPtrLeaf, [], 391 "BlockAddressSDNode">; 392def tblockaddress: SDNode<"ISD::TargetBlockAddress", SDTPtrLeaf, [], 393 "BlockAddressSDNode">; 394 395def add : SDNode<"ISD::ADD" , SDTIntBinOp , 396 [SDNPCommutative, SDNPAssociative]>; 397def ptradd : SDNode<"ISD::ADD" , SDTPtrAddOp, []>; 398def sub : SDNode<"ISD::SUB" , SDTIntBinOp>; 399def mul : SDNode<"ISD::MUL" , SDTIntBinOp, 400 [SDNPCommutative, SDNPAssociative]>; 401def mulhs : SDNode<"ISD::MULHS" , SDTIntBinOp, [SDNPCommutative]>; 402def mulhu : SDNode<"ISD::MULHU" , SDTIntBinOp, [SDNPCommutative]>; 403def avgfloors : SDNode<"ISD::AVGFLOORS" , SDTIntBinOp, [SDNPCommutative]>; 404def avgflooru : SDNode<"ISD::AVGFLOORU" , SDTIntBinOp, [SDNPCommutative]>; 405def avgceils : SDNode<"ISD::AVGCEILS" , SDTIntBinOp, [SDNPCommutative]>; 406def avgceilu : SDNode<"ISD::AVGCEILU" , SDTIntBinOp, [SDNPCommutative]>; 407def abds : SDNode<"ISD::ABDS" , SDTIntBinOp, [SDNPCommutative]>; 408def abdu : SDNode<"ISD::ABDU" , SDTIntBinOp, [SDNPCommutative]>; 409def smullohi : SDNode<"ISD::SMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>; 410def umullohi : SDNode<"ISD::UMUL_LOHI" , SDTIntBinHiLoOp, [SDNPCommutative]>; 411def sdiv : SDNode<"ISD::SDIV" , SDTIntBinOp>; 412def udiv : SDNode<"ISD::UDIV" , SDTIntBinOp>; 413def srem : SDNode<"ISD::SREM" , SDTIntBinOp>; 414def urem : SDNode<"ISD::UREM" , SDTIntBinOp>; 415def sdivrem : SDNode<"ISD::SDIVREM" , SDTIntBinHiLoOp>; 416def udivrem : SDNode<"ISD::UDIVREM" , SDTIntBinHiLoOp>; 417def srl : SDNode<"ISD::SRL" , SDTIntShiftOp>; 418def sra : SDNode<"ISD::SRA" , SDTIntShiftOp>; 419def shl : SDNode<"ISD::SHL" , SDTIntShiftOp>; 420def rotl : SDNode<"ISD::ROTL" , SDTIntShiftOp>; 421def rotr : SDNode<"ISD::ROTR" , SDTIntShiftOp>; 422def fshl : SDNode<"ISD::FSHL" , SDTIntShiftDOp>; 423def fshr : SDNode<"ISD::FSHR" , SDTIntShiftDOp>; 424def and : SDNode<"ISD::AND" , SDTIntBinOp, 425 [SDNPCommutative, SDNPAssociative]>; 426def or : SDNode<"ISD::OR" , SDTIntBinOp, 427 [SDNPCommutative, SDNPAssociative]>; 428def xor : SDNode<"ISD::XOR" , SDTIntBinOp, 429 [SDNPCommutative, SDNPAssociative]>; 430def addc : SDNode<"ISD::ADDC" , SDTIntBinOp, 431 [SDNPCommutative, SDNPOutGlue]>; 432def adde : SDNode<"ISD::ADDE" , SDTIntBinOp, 433 [SDNPCommutative, SDNPOutGlue, SDNPInGlue]>; 434def subc : SDNode<"ISD::SUBC" , SDTIntBinOp, 435 [SDNPOutGlue]>; 436def sube : SDNode<"ISD::SUBE" , SDTIntBinOp, 437 [SDNPOutGlue, SDNPInGlue]>; 438def smin : SDNode<"ISD::SMIN" , SDTIntBinOp, 439 [SDNPCommutative, SDNPAssociative]>; 440def smax : SDNode<"ISD::SMAX" , SDTIntBinOp, 441 [SDNPCommutative, SDNPAssociative]>; 442def umin : SDNode<"ISD::UMIN" , SDTIntBinOp, 443 [SDNPCommutative, SDNPAssociative]>; 444def umax : SDNode<"ISD::UMAX" , SDTIntBinOp, 445 [SDNPCommutative, SDNPAssociative]>; 446 447def scmp : SDNode<"ISD::SCMP" , SDTIntBinOp, 448 []>; 449def ucmp : SDNode<"ISD::UCMP" , SDTIntBinOp, 450 []>; 451 452def saddsat : SDNode<"ISD::SADDSAT" , SDTIntBinOp, [SDNPCommutative]>; 453def uaddsat : SDNode<"ISD::UADDSAT" , SDTIntBinOp, [SDNPCommutative]>; 454def ssubsat : SDNode<"ISD::SSUBSAT" , SDTIntBinOp>; 455def usubsat : SDNode<"ISD::USUBSAT" , SDTIntBinOp>; 456def sshlsat : SDNode<"ISD::SSHLSAT" , SDTIntBinOp>; 457def ushlsat : SDNode<"ISD::USHLSAT" , SDTIntBinOp>; 458 459def smulfix : SDNode<"ISD::SMULFIX" , SDTIntScaledBinOp, [SDNPCommutative]>; 460def smulfixsat : SDNode<"ISD::SMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>; 461def umulfix : SDNode<"ISD::UMULFIX" , SDTIntScaledBinOp, [SDNPCommutative]>; 462def umulfixsat : SDNode<"ISD::UMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>; 463def sdivfix : SDNode<"ISD::SDIVFIX" , SDTIntScaledBinOp>; 464def sdivfixsat : SDNode<"ISD::SDIVFIXSAT", SDTIntScaledBinOp>; 465def udivfix : SDNode<"ISD::UDIVFIX" , SDTIntScaledBinOp>; 466def udivfixsat : SDNode<"ISD::UDIVFIXSAT", SDTIntScaledBinOp>; 467 468def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>; 469def sext_invec : SDNode<"ISD::SIGN_EXTEND_VECTOR_INREG", SDTExtInvec>; 470def zext_invec : SDNode<"ISD::ZERO_EXTEND_VECTOR_INREG", SDTExtInvec>; 471 472def abs : SDNode<"ISD::ABS" , SDTIntUnaryOp>; 473def bitreverse : SDNode<"ISD::BITREVERSE" , SDTIntUnaryOp>; 474def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>; 475def ctlz : SDNode<"ISD::CTLZ" , SDTIntBitCountUnaryOp>; 476def cttz : SDNode<"ISD::CTTZ" , SDTIntBitCountUnaryOp>; 477def ctpop : SDNode<"ISD::CTPOP" , SDTIntBitCountUnaryOp>; 478def ctlz_zero_undef : SDNode<"ISD::CTLZ_ZERO_UNDEF", SDTIntBitCountUnaryOp>; 479def cttz_zero_undef : SDNode<"ISD::CTTZ_ZERO_UNDEF", SDTIntBitCountUnaryOp>; 480def sext : SDNode<"ISD::SIGN_EXTEND", SDTIntExtendOp>; 481def zext : SDNode<"ISD::ZERO_EXTEND", SDTIntExtendOp>; 482def anyext : SDNode<"ISD::ANY_EXTEND" , SDTIntExtendOp>; 483def trunc : SDNode<"ISD::TRUNCATE" , SDTIntTruncOp>; 484def bitconvert : SDNode<"ISD::BITCAST" , SDTUnaryOp>; 485def addrspacecast : SDNode<"ISD::ADDRSPACECAST", SDTUnaryOp>; 486def freeze : SDNode<"ISD::FREEZE" , SDTFreeze>; 487def extractelt : SDNode<"ISD::EXTRACT_VECTOR_ELT", SDTVecExtract>; 488def insertelt : SDNode<"ISD::INSERT_VECTOR_ELT", SDTVecInsert>; 489 490def vecreduce_add : SDNode<"ISD::VECREDUCE_ADD", SDTVecReduce>; 491def vecreduce_smax : SDNode<"ISD::VECREDUCE_SMAX", SDTVecReduce>; 492def vecreduce_umax : SDNode<"ISD::VECREDUCE_UMAX", SDTVecReduce>; 493def vecreduce_smin : SDNode<"ISD::VECREDUCE_SMIN", SDTVecReduce>; 494def vecreduce_umin : SDNode<"ISD::VECREDUCE_UMIN", SDTVecReduce>; 495def vecreduce_fadd : SDNode<"ISD::VECREDUCE_FADD", SDTFPVecReduce>; 496def vecreduce_fmin : SDNode<"ISD::VECREDUCE_FMIN", SDTFPVecReduce>; 497def vecreduce_fmax : SDNode<"ISD::VECREDUCE_FMAX", SDTFPVecReduce>; 498def vecreduce_fminimum : SDNode<"ISD::VECREDUCE_FMINIMUM", SDTFPVecReduce>; 499def vecreduce_fmaximum : SDNode<"ISD::VECREDUCE_FMAXIMUM", SDTFPVecReduce>; 500 501def fadd : SDNode<"ISD::FADD" , SDTFPBinOp, [SDNPCommutative]>; 502def fsub : SDNode<"ISD::FSUB" , SDTFPBinOp>; 503def fmul : SDNode<"ISD::FMUL" , SDTFPBinOp, [SDNPCommutative]>; 504def fdiv : SDNode<"ISD::FDIV" , SDTFPBinOp>; 505def frem : SDNode<"ISD::FREM" , SDTFPBinOp>; 506def fma : SDNode<"ISD::FMA" , SDTFPTernaryOp, [SDNPCommutative]>; 507def fmad : SDNode<"ISD::FMAD" , SDTFPTernaryOp, [SDNPCommutative]>; 508def fabs : SDNode<"ISD::FABS" , SDTFPUnaryOp>; 509def fminnum : SDNode<"ISD::FMINNUM" , SDTFPBinOp, 510 [SDNPCommutative, SDNPAssociative]>; 511def fmaxnum : SDNode<"ISD::FMAXNUM" , SDTFPBinOp, 512 [SDNPCommutative, SDNPAssociative]>; 513def fminnum_ieee : SDNode<"ISD::FMINNUM_IEEE", SDTFPBinOp, 514 [SDNPCommutative]>; 515def fmaxnum_ieee : SDNode<"ISD::FMAXNUM_IEEE", SDTFPBinOp, 516 [SDNPCommutative]>; 517def fminimum : SDNode<"ISD::FMINIMUM" , SDTFPBinOp, 518 [SDNPCommutative, SDNPAssociative]>; 519def fmaximum : SDNode<"ISD::FMAXIMUM" , SDTFPBinOp, 520 [SDNPCommutative, SDNPAssociative]>; 521def fgetsign : SDNode<"ISD::FGETSIGN" , SDTFPToIntOp>; 522def fcanonicalize : SDNode<"ISD::FCANONICALIZE", SDTFPUnaryOp>; 523def fneg : SDNode<"ISD::FNEG" , SDTFPUnaryOp>; 524def fsqrt : SDNode<"ISD::FSQRT" , SDTFPUnaryOp>; 525def fsin : SDNode<"ISD::FSIN" , SDTFPUnaryOp>; 526def fcos : SDNode<"ISD::FCOS" , SDTFPUnaryOp>; 527def ftan : SDNode<"ISD::FTAN" , SDTFPUnaryOp>; 528def fasin : SDNode<"ISD::FASIN" , SDTFPUnaryOp>; 529def facos : SDNode<"ISD::FACOS" , SDTFPUnaryOp>; 530def fatan : SDNode<"ISD::FATAN" , SDTFPUnaryOp>; 531def fsinh : SDNode<"ISD::FSINH" , SDTFPUnaryOp>; 532def fcosh : SDNode<"ISD::FCOSH" , SDTFPUnaryOp>; 533def ftanh : SDNode<"ISD::FTANH" , SDTFPUnaryOp>; 534def fexp2 : SDNode<"ISD::FEXP2" , SDTFPUnaryOp>; 535def fexp10 : SDNode<"ISD::FEXP10" , SDTFPUnaryOp>; 536def fpow : SDNode<"ISD::FPOW" , SDTFPBinOp>; 537def flog2 : SDNode<"ISD::FLOG2" , SDTFPUnaryOp>; 538def fldexp : SDNode<"ISD::FLDEXP" , SDTFPExpOp>; 539def frint : SDNode<"ISD::FRINT" , SDTFPUnaryOp>; 540def ftrunc : SDNode<"ISD::FTRUNC" , SDTFPUnaryOp>; 541def fceil : SDNode<"ISD::FCEIL" , SDTFPUnaryOp>; 542def ffloor : SDNode<"ISD::FFLOOR" , SDTFPUnaryOp>; 543def fnearbyint : SDNode<"ISD::FNEARBYINT" , SDTFPUnaryOp>; 544def fround : SDNode<"ISD::FROUND" , SDTFPUnaryOp>; 545def froundeven : SDNode<"ISD::FROUNDEVEN" , SDTFPUnaryOp>; 546 547def lround : SDNode<"ISD::LROUND" , SDTFPToIntOp>; 548def llround : SDNode<"ISD::LLROUND" , SDTFPToIntOp>; 549def lrint : SDNode<"ISD::LRINT" , SDTFPToIntOp>; 550def llrint : SDNode<"ISD::LLRINT" , SDTFPToIntOp>; 551 552def fpround : SDNode<"ISD::FP_ROUND" , SDTFPRoundOp>; 553def fpextend : SDNode<"ISD::FP_EXTEND" , SDTFPExtendOp>; 554def fcopysign : SDNode<"ISD::FCOPYSIGN" , SDTFPSignOp>; 555 556def is_fpclass : SDNode<"ISD::IS_FPCLASS" , SDIsFPClassOp>; 557 558def sint_to_fp : SDNode<"ISD::SINT_TO_FP" , SDTIntToFPOp>; 559def uint_to_fp : SDNode<"ISD::UINT_TO_FP" , SDTIntToFPOp>; 560def fp_to_sint : SDNode<"ISD::FP_TO_SINT" , SDTFPToIntOp>; 561def fp_to_uint : SDNode<"ISD::FP_TO_UINT" , SDTFPToIntOp>; 562def fp_to_sint_sat : SDNode<"ISD::FP_TO_SINT_SAT" , SDTFPToIntSatOp>; 563def fp_to_uint_sat : SDNode<"ISD::FP_TO_UINT_SAT" , SDTFPToIntSatOp>; 564def f16_to_fp : SDNode<"ISD::FP16_TO_FP" , SDTIntToFPOp>; 565def fp_to_f16 : SDNode<"ISD::FP_TO_FP16" , SDTFPToIntOp>; 566def bf16_to_fp : SDNode<"ISD::BF16_TO_FP" , SDTIntToFPOp>; 567def fp_to_bf16 : SDNode<"ISD::FP_TO_BF16" , SDTFPToIntOp>; 568 569def strict_fadd : SDNode<"ISD::STRICT_FADD", 570 SDTFPBinOp, [SDNPHasChain, SDNPCommutative]>; 571def strict_fsub : SDNode<"ISD::STRICT_FSUB", 572 SDTFPBinOp, [SDNPHasChain]>; 573def strict_fmul : SDNode<"ISD::STRICT_FMUL", 574 SDTFPBinOp, [SDNPHasChain, SDNPCommutative]>; 575def strict_fdiv : SDNode<"ISD::STRICT_FDIV", 576 SDTFPBinOp, [SDNPHasChain]>; 577def strict_frem : SDNode<"ISD::STRICT_FREM", 578 SDTFPBinOp, [SDNPHasChain]>; 579def strict_fma : SDNode<"ISD::STRICT_FMA", 580 SDTFPTernaryOp, [SDNPHasChain, SDNPCommutative]>; 581def strict_fsqrt : SDNode<"ISD::STRICT_FSQRT", 582 SDTFPUnaryOp, [SDNPHasChain]>; 583def strict_fsin : SDNode<"ISD::STRICT_FSIN", 584 SDTFPUnaryOp, [SDNPHasChain]>; 585def strict_fcos : SDNode<"ISD::STRICT_FCOS", 586 SDTFPUnaryOp, [SDNPHasChain]>; 587def strict_ftan : SDNode<"ISD::STRICT_FTAN", 588 SDTFPUnaryOp, [SDNPHasChain]>; 589def strict_fasin : SDNode<"ISD::STRICT_FASIN", 590 SDTFPUnaryOp, [SDNPHasChain]>; 591def strict_facos : SDNode<"ISD::STRICT_FACOS", 592 SDTFPUnaryOp, [SDNPHasChain]>; 593def strict_fatan : SDNode<"ISD::STRICT_FATAN", 594 SDTFPUnaryOp, [SDNPHasChain]>; 595def strict_fsinh : SDNode<"ISD::STRICT_FSINH", 596 SDTFPUnaryOp, [SDNPHasChain]>; 597def strict_fcosh : SDNode<"ISD::STRICT_FCOSH", 598 SDTFPUnaryOp, [SDNPHasChain]>; 599def strict_ftanh : SDNode<"ISD::STRICT_FTANH", 600 SDTFPUnaryOp, [SDNPHasChain]>; 601def strict_fexp2 : SDNode<"ISD::STRICT_FEXP2", 602 SDTFPUnaryOp, [SDNPHasChain]>; 603def strict_fpow : SDNode<"ISD::STRICT_FPOW", 604 SDTFPBinOp, [SDNPHasChain]>; 605def strict_fldexp : SDNode<"ISD::STRICT_FLDEXP", 606 SDTFPExpOp, [SDNPHasChain]>; 607def strict_flog2 : SDNode<"ISD::STRICT_FLOG2", 608 SDTFPUnaryOp, [SDNPHasChain]>; 609def strict_frint : SDNode<"ISD::STRICT_FRINT", 610 SDTFPUnaryOp, [SDNPHasChain]>; 611def strict_lrint : SDNode<"ISD::STRICT_LRINT", 612 SDTFPToIntOp, [SDNPHasChain]>; 613def strict_llrint : SDNode<"ISD::STRICT_LLRINT", 614 SDTFPToIntOp, [SDNPHasChain]>; 615def strict_fnearbyint : SDNode<"ISD::STRICT_FNEARBYINT", 616 SDTFPUnaryOp, [SDNPHasChain]>; 617def strict_fceil : SDNode<"ISD::STRICT_FCEIL", 618 SDTFPUnaryOp, [SDNPHasChain]>; 619def strict_ffloor : SDNode<"ISD::STRICT_FFLOOR", 620 SDTFPUnaryOp, [SDNPHasChain]>; 621def strict_lround : SDNode<"ISD::STRICT_LROUND", 622 SDTFPToIntOp, [SDNPHasChain]>; 623def strict_llround : SDNode<"ISD::STRICT_LLROUND", 624 SDTFPToIntOp, [SDNPHasChain]>; 625def strict_fround : SDNode<"ISD::STRICT_FROUND", 626 SDTFPUnaryOp, [SDNPHasChain]>; 627def strict_froundeven : SDNode<"ISD::STRICT_FROUNDEVEN", 628 SDTFPUnaryOp, [SDNPHasChain]>; 629def strict_ftrunc : SDNode<"ISD::STRICT_FTRUNC", 630 SDTFPUnaryOp, [SDNPHasChain]>; 631def strict_fminnum : SDNode<"ISD::STRICT_FMINNUM", 632 SDTFPBinOp, [SDNPHasChain, 633 SDNPCommutative, SDNPAssociative]>; 634def strict_fmaxnum : SDNode<"ISD::STRICT_FMAXNUM", 635 SDTFPBinOp, [SDNPHasChain, 636 SDNPCommutative, SDNPAssociative]>; 637def strict_fminimum : SDNode<"ISD::STRICT_FMINIMUM", 638 SDTFPBinOp, [SDNPHasChain, 639 SDNPCommutative, SDNPAssociative]>; 640def strict_fmaximum : SDNode<"ISD::STRICT_FMAXIMUM", 641 SDTFPBinOp, [SDNPHasChain, 642 SDNPCommutative, SDNPAssociative]>; 643def strict_fpround : SDNode<"ISD::STRICT_FP_ROUND", 644 SDTFPRoundOp, [SDNPHasChain]>; 645def strict_fpextend : SDNode<"ISD::STRICT_FP_EXTEND", 646 SDTFPExtendOp, [SDNPHasChain]>; 647def strict_fp_to_sint : SDNode<"ISD::STRICT_FP_TO_SINT", 648 SDTFPToIntOp, [SDNPHasChain]>; 649def strict_fp_to_uint : SDNode<"ISD::STRICT_FP_TO_UINT", 650 SDTFPToIntOp, [SDNPHasChain]>; 651def strict_sint_to_fp : SDNode<"ISD::STRICT_SINT_TO_FP", 652 SDTIntToFPOp, [SDNPHasChain]>; 653def strict_uint_to_fp : SDNode<"ISD::STRICT_UINT_TO_FP", 654 SDTIntToFPOp, [SDNPHasChain]>; 655 656def strict_f16_to_fp : SDNode<"ISD::STRICT_FP16_TO_FP", 657 SDTIntToFPOp, [SDNPHasChain]>; 658def strict_fp_to_f16 : SDNode<"ISD::STRICT_FP_TO_FP16", 659 SDTFPToIntOp, [SDNPHasChain]>; 660 661def strict_bf16_to_fp : SDNode<"ISD::STRICT_BF16_TO_FP", 662 SDTIntToFPOp, [SDNPHasChain]>; 663def strict_fp_to_bf16 : SDNode<"ISD::STRICT_FP_TO_BF16", 664 SDTFPToIntOp, [SDNPHasChain]>; 665 666def strict_fsetcc : SDNode<"ISD::STRICT_FSETCC", SDTSetCC, [SDNPHasChain]>; 667def strict_fsetccs : SDNode<"ISD::STRICT_FSETCCS", SDTSetCC, [SDNPHasChain]>; 668 669def get_fpenv : SDNode<"ISD::GET_FPENV", SDTGetFPStateOp, [SDNPHasChain]>; 670def set_fpenv : SDNode<"ISD::SET_FPENV", SDTSetFPStateOp, [SDNPHasChain]>; 671def reset_fpenv : SDNode<"ISD::RESET_FPENV", SDTNone, [SDNPHasChain]>; 672def get_fpmode : SDNode<"ISD::GET_FPMODE", SDTGetFPStateOp, [SDNPHasChain]>; 673def set_fpmode : SDNode<"ISD::SET_FPMODE", SDTSetFPStateOp, [SDNPHasChain]>; 674def reset_fpmode : SDNode<"ISD::RESET_FPMODE", SDTNone, [SDNPHasChain]>; 675 676def setcc : SDNode<"ISD::SETCC" , SDTSetCC>; 677def select : SDNode<"ISD::SELECT" , SDTSelect>; 678def vselect : SDNode<"ISD::VSELECT" , SDTVSelect>; 679def selectcc : SDNode<"ISD::SELECT_CC" , SDTSelectCC>; 680 681def brcc : SDNode<"ISD::BR_CC" , SDTBrCC, [SDNPHasChain]>; 682def brcond : SDNode<"ISD::BRCOND" , SDTBrcond, [SDNPHasChain]>; 683def brind : SDNode<"ISD::BRIND" , SDTBrind, [SDNPHasChain]>; 684def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>; 685def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret, 686 [SDNPHasChain, SDNPSideEffect]>; 687def cleanupret : SDNode<"ISD::CLEANUPRET" , SDTCleanupret, [SDNPHasChain]>; 688 689def trap : SDNode<"ISD::TRAP" , SDTNone, 690 [SDNPHasChain, SDNPSideEffect]>; 691def debugtrap : SDNode<"ISD::DEBUGTRAP" , SDTNone, 692 [SDNPHasChain, SDNPSideEffect]>; 693def ubsantrap : SDNode<"ISD::UBSANTRAP" , SDTUBSANTrap, 694 [SDNPHasChain, SDNPSideEffect]>; 695 696def prefetch : SDNode<"ISD::PREFETCH" , SDTPrefetch, 697 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 698 SDNPMemOperand]>; 699 700def readcyclecounter : SDNode<"ISD::READCYCLECOUNTER", SDTIntLeaf, 701 [SDNPHasChain, SDNPSideEffect]>; 702 703def readsteadycounter : SDNode<"ISD::READSTEADYCOUNTER", SDTIntLeaf, 704 [SDNPHasChain, SDNPSideEffect]>; 705 706def membarrier : SDNode<"ISD::MEMBARRIER", SDTNone, 707 [SDNPHasChain, SDNPSideEffect]>; 708 709def jump_table_debug_info : SDNode<"ISD::JUMP_TABLE_DEBUG_INFO", SDTNone, 710 [SDNPHasChain]>; 711 712def atomic_fence : SDNode<"ISD::ATOMIC_FENCE" , SDTAtomicFence, 713 [SDNPHasChain, SDNPSideEffect]>; 714 715def atomic_cmp_swap : SDNode<"ISD::ATOMIC_CMP_SWAP" , SDTAtomic3, 716 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 717def atomic_load_add : SDNode<"ISD::ATOMIC_LOAD_ADD" , SDTAtomic2, 718 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 719def atomic_swap : SDNode<"ISD::ATOMIC_SWAP", SDTAtomic2, 720 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 721def atomic_load_sub : SDNode<"ISD::ATOMIC_LOAD_SUB" , SDTAtomic2, 722 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 723def atomic_load_and : SDNode<"ISD::ATOMIC_LOAD_AND" , SDTAtomic2, 724 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 725def atomic_load_clr : SDNode<"ISD::ATOMIC_LOAD_CLR" , SDTAtomic2, 726 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 727def atomic_load_or : SDNode<"ISD::ATOMIC_LOAD_OR" , SDTAtomic2, 728 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 729def atomic_load_xor : SDNode<"ISD::ATOMIC_LOAD_XOR" , SDTAtomic2, 730 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 731def atomic_load_nand: SDNode<"ISD::ATOMIC_LOAD_NAND", SDTAtomic2, 732 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 733def atomic_load_min : SDNode<"ISD::ATOMIC_LOAD_MIN", SDTAtomic2, 734 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 735def atomic_load_max : SDNode<"ISD::ATOMIC_LOAD_MAX", SDTAtomic2, 736 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 737def atomic_load_umin : SDNode<"ISD::ATOMIC_LOAD_UMIN", SDTAtomic2, 738 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 739def atomic_load_umax : SDNode<"ISD::ATOMIC_LOAD_UMAX", SDTAtomic2, 740 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 741def atomic_load_fadd : SDNode<"ISD::ATOMIC_LOAD_FADD" , SDTFPAtomic2, 742 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 743def atomic_load_fsub : SDNode<"ISD::ATOMIC_LOAD_FSUB" , SDTFPAtomic2, 744 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 745def atomic_load_fmax : SDNode<"ISD::ATOMIC_LOAD_FMAX", SDTFPAtomic2, 746 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 747def atomic_load_fmin : SDNode<"ISD::ATOMIC_LOAD_FMIN", SDTFPAtomic2, 748 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 749def atomic_load_uinc_wrap : SDNode<"ISD::ATOMIC_LOAD_UINC_WRAP", SDTAtomic2, 750 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 751def atomic_load_udec_wrap : SDNode<"ISD::ATOMIC_LOAD_UDEC_WRAP", SDTAtomic2, 752 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 753 754def atomic_load : SDNode<"ISD::ATOMIC_LOAD", SDTAtomicLoad, 755 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 756def atomic_store : SDNode<"ISD::ATOMIC_STORE", SDTAtomicStore, 757 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 758 759def masked_st : SDNode<"ISD::MSTORE", SDTMaskedStore, 760 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 761def masked_ld : SDNode<"ISD::MLOAD", SDTMaskedLoad, 762 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 763 764def masked_gather : SDNode<"ISD::MGATHER", SDTMaskedGather, 765 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 766 767def masked_scatter : SDNode<"ISD::MSCATTER", SDTMaskedScatter, 768 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 769 770def vector_compress : SDNode<"ISD::VECTOR_COMPRESS", SDTVectorCompress>; 771 772// Do not use ld, st directly. Use load, extload, sextload, zextload, store, 773// and truncst (see below). 774def ld : SDNode<"ISD::LOAD" , SDTLoad, 775 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>; 776def st : SDNode<"ISD::STORE" , SDTStore, 777 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 778def ist : SDNode<"ISD::STORE" , SDTIStore, 779 [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>; 780 781def vector_shuffle : SDNode<"ISD::VECTOR_SHUFFLE", SDTVecShuffle, []>; 782def vector_reverse : SDNode<"ISD::VECTOR_REVERSE", SDTVecReverse>; 783def vector_splice : SDNode<"ISD::VECTOR_SPLICE", SDTVecSlice, []>; 784def build_vector : SDNode<"ISD::BUILD_VECTOR", SDTypeProfile<1, -1, []>, []>; 785def splat_vector : SDNode<"ISD::SPLAT_VECTOR", SDTypeProfile<1, 1, []>, []>; 786def step_vector : SDNode<"ISD::STEP_VECTOR", SDTypeProfile<1, 1, 787 [SDTCisVec<0>, SDTCisInt<1>]>, []>; 788def scalar_to_vector : SDNode<"ISD::SCALAR_TO_VECTOR", SDTypeProfile<1, 1, []>, 789 []>; 790 791// vector_extract/vector_insert are deprecated. extractelt/insertelt 792// are preferred. 793def vector_extract : SDNode<"ISD::EXTRACT_VECTOR_ELT", 794 SDTypeProfile<1, 2, [SDTCisPtrTy<2>]>, []>; 795def vector_insert : SDNode<"ISD::INSERT_VECTOR_ELT", 796 SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisPtrTy<3>]>, []>; 797def concat_vectors : SDNode<"ISD::CONCAT_VECTORS", 798 SDTypeProfile<1, 2, [SDTCisSubVecOfVec<1, 0>, SDTCisSameAs<1, 2>]>,[]>; 799 800// This operator does not do subvector type checking. The ARM 801// backend, at least, needs it. 802def vector_extract_subvec : SDNode<"ISD::EXTRACT_SUBVECTOR", 803 SDTypeProfile<1, 2, [SDTCisInt<2>, SDTCisVec<1>, SDTCisVec<0>]>, 804 []>; 805def vector_insert_subvec : SDNode<"ISD::INSERT_SUBVECTOR", 806 SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisVec<2>, SDTCisInt<3>]>, 807 []>; 808 809// This operator does subvector type checking. 810def extract_subvector : SDNode<"ISD::EXTRACT_SUBVECTOR", SDTSubVecExtract, []>; 811def insert_subvector : SDNode<"ISD::INSERT_SUBVECTOR", SDTSubVecInsert, []>; 812 813// Nodes for intrinsics, you should use the intrinsic itself and let tblgen use 814// these internally. Don't reference these directly. 815def intrinsic_void : SDNode<"ISD::INTRINSIC_VOID", 816 SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>, 817 [SDNPHasChain]>; 818def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN", 819 SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, 820 [SDNPHasChain]>; 821def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN", 822 SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>; 823 824def SDT_assert : SDTypeProfile<1, 1, 825 [SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>; 826def assertsext : SDNode<"ISD::AssertSext", SDT_assert>; 827def assertzext : SDNode<"ISD::AssertZext", SDT_assert>; 828def assertalign : SDNode<"ISD::AssertAlign", SDT_assert>; 829 830def convergencectrl_anchor : SDNode<"ISD::CONVERGENCECTRL_ANCHOR", 831 SDTypeProfile<1, 0, [SDTCisVT<0,untyped>]>>; 832def convergencectrl_entry : SDNode<"ISD::CONVERGENCECTRL_ENTRY", 833 SDTypeProfile<1, 0, [SDTCisVT<0,untyped>]>>; 834def convergencectrl_loop : SDNode<"ISD::CONVERGENCECTRL_LOOP", 835 SDTypeProfile<1, 1, 836 [SDTCisVT<0,untyped>, SDTCisVT<1,untyped>]>>; 837def convergencectrl_glue : SDNode<"ISD::CONVERGENCECTRL_GLUE", 838 SDTypeProfile<0, 1, [SDTCisVT<0, untyped>]>>; 839 840//===----------------------------------------------------------------------===// 841// Selection DAG Condition Codes 842 843class CondCode<string fcmpName = "", string icmpName = ""> { 844 string ICmpPredicate = icmpName; 845 string FCmpPredicate = fcmpName; 846} 847 848// ISD::CondCode enums, and mapping to CmpInst::Predicate names 849def SETOEQ : CondCode<"FCMP_OEQ">; 850def SETOGT : CondCode<"FCMP_OGT">; 851def SETOGE : CondCode<"FCMP_OGE">; 852def SETOLT : CondCode<"FCMP_OLT">; 853def SETOLE : CondCode<"FCMP_OLE">; 854def SETONE : CondCode<"FCMP_ONE">; 855def SETO : CondCode<"FCMP_ORD">; 856def SETUO : CondCode<"FCMP_UNO">; 857def SETUEQ : CondCode<"FCMP_UEQ">; 858def SETUGT : CondCode<"FCMP_UGT", "ICMP_UGT">; 859def SETUGE : CondCode<"FCMP_UGE", "ICMP_UGE">; 860def SETULT : CondCode<"FCMP_ULT", "ICMP_ULT">; 861def SETULE : CondCode<"FCMP_ULE", "ICMP_ULE">; 862def SETUNE : CondCode<"FCMP_UNE">; 863def SETEQ : CondCode<"", "ICMP_EQ">; 864def SETGT : CondCode<"", "ICMP_SGT">; 865def SETGE : CondCode<"", "ICMP_SGE">; 866def SETLT : CondCode<"", "ICMP_SLT">; 867def SETLE : CondCode<"", "ICMP_SLE">; 868def SETNE : CondCode<"", "ICMP_NE">; 869 870//===----------------------------------------------------------------------===// 871// Selection DAG Node Transformation Functions. 872// 873// This mechanism allows targets to manipulate nodes in the output DAG once a 874// match has been formed. This is typically used to manipulate immediate 875// values. 876// 877class SDNodeXForm<SDNode opc, code xformFunction> { 878 SDNode Opcode = opc; 879 code XFormFunction = xformFunction; 880} 881 882def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>; 883 884//===----------------------------------------------------------------------===// 885// Selection DAG Pattern Fragments. 886// 887// Pattern fragments are reusable chunks of dags that match specific things. 888// They can take arguments and have C++ predicates that control whether they 889// match. They are intended to make the patterns for common instructions more 890// compact and readable. 891// 892 893/// PatFrags - Represents a set of pattern fragments. Each single fragment 894/// can match something on the DAG, from a single node to multiple nested other 895/// fragments. The whole set of fragments matches if any of the single 896/// fragments match. This allows e.g. matching and "add with overflow" and 897/// a regular "add" with the same fragment set. 898/// 899class PatFrags<dag ops, list<dag> frags, code pred = [{}], 900 SDNodeXForm xform = NOOP_SDNodeXForm> : SDPatternOperator { 901 dag Operands = ops; 902 list<dag> Fragments = frags; 903 code PredicateCode = pred; 904 code GISelPredicateCode = [{}]; 905 code ImmediateCode = [{}]; 906 SDNodeXForm OperandTransform = xform; 907 908 // When this is set, the PredicateCode may refer to a constant Operands 909 // vector which contains the captured nodes of the DAG, in the order listed 910 // by the Operands field above. 911 // 912 // This is useful when Fragments involves associative / commutative 913 // operators: a single piece of code can easily refer to all operands even 914 // when re-associated / commuted variants of the fragment are matched. 915 bit PredicateCodeUsesOperands = false; 916 917 // Define a few pre-packaged predicates. This helps GlobalISel import 918 // existing rules from SelectionDAG for many common cases. 919 // They will be tested prior to the code in pred and must not be used in 920 // ImmLeaf and its subclasses. 921 922 // If set to true, a predicate is added that checks for the absence of use of 923 // the first result. 924 bit HasNoUse = ?; 925 // If set to true, a predicate is added that checks for the sole use of 926 // the first result. 927 bit HasOneUse = ?; 928 929 // Is the desired pre-packaged predicate for a load? 930 bit IsLoad = ?; 931 // Is the desired pre-packaged predicate for a store? 932 bit IsStore = ?; 933 // Is the desired pre-packaged predicate for an atomic? 934 bit IsAtomic = ?; 935 936 // cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; 937 // cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED; 938 bit IsUnindexed = ?; 939 940 // cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD 941 bit IsNonExtLoad = ?; 942 // cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD; 943 bit IsAnyExtLoad = ?; 944 // cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD; 945 bit IsSignExtLoad = ?; 946 // cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD; 947 bit IsZeroExtLoad = ?; 948 // !cast<StoreSDNode>(N)->isTruncatingStore(); 949 // cast<StoreSDNode>(N)->isTruncatingStore(); 950 bit IsTruncStore = ?; 951 952 // cast<MemSDNode>(N)->getAddressSpace() == 953 // If this empty, accept any address space. 954 list<int> AddressSpaces = ?; 955 956 // cast<MemSDNode>(N)->getAlign() >= 957 // If this is empty, accept any alignment. 958 int MinAlignment = ?; 959 960 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Monotonic 961 bit IsAtomicOrderingMonotonic = ?; 962 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Acquire 963 bit IsAtomicOrderingAcquire = ?; 964 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::Release 965 bit IsAtomicOrderingRelease = ?; 966 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::AcquireRelease 967 bit IsAtomicOrderingAcquireRelease = ?; 968 // cast<AtomicSDNode>(N)->getOrdering() == AtomicOrdering::SequentiallyConsistent 969 bit IsAtomicOrderingSequentiallyConsistent = ?; 970 971 // isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering()) 972 // !isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering()) 973 bit IsAtomicOrderingAcquireOrStronger = ?; 974 975 // isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering()) 976 // !isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering()) 977 bit IsAtomicOrderingReleaseOrStronger = ?; 978 979 // cast<LoadSDNode>(N)->getMemoryVT() == MVT::<VT>; 980 // cast<StoreSDNode>(N)->getMemoryVT() == MVT::<VT>; 981 ValueType MemoryVT = ?; 982 // cast<LoadSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>; 983 // cast<StoreSDNode>(N)->getMemoryVT().getScalarType() == MVT::<VT>; 984 ValueType ScalarMemoryVT = ?; 985} 986 987// Patterns and PatFrags can also subclass GISelFlags to set flags that affect 988// how GlobalISel behaves when matching them. 989class GISelFlags { 990 bit GIIgnoreCopies = ?; 991} 992 993// PatFrag - A version of PatFrags matching only a single fragment. 994class PatFrag<dag ops, dag frag, code pred = [{}], 995 SDNodeXForm xform = NOOP_SDNodeXForm> 996 : PatFrags<ops, [frag], pred, xform>; 997 998// OutPatFrag is a pattern fragment that is used as part of an output pattern 999// (not an input pattern). These do not have predicates or transforms, but are 1000// used to avoid repeated subexpressions in output patterns. 1001class OutPatFrag<dag ops, dag frag> 1002 : PatFrag<ops, frag, [{}], NOOP_SDNodeXForm>; 1003 1004// PatLeaf's are pattern fragments that have no operands. This is just a helper 1005// to define immediates and other common things concisely. 1006class PatLeaf<dag frag, code pred = [{}], SDNodeXForm xform = NOOP_SDNodeXForm> 1007 : PatFrag<(ops), frag, pred, xform>; 1008 1009 1010// ImmLeaf is a pattern fragment with a constraint on the immediate. The 1011// constraint is a function that is run on the immediate (always with the value 1012// sign extended out to an int64_t) as Imm. For example: 1013// 1014// def immSExt8 : ImmLeaf<i16, [{ return (char)Imm == Imm; }]>; 1015// 1016// this is a more convenient form to match 'imm' nodes in than PatLeaf and also 1017// is preferred over using PatLeaf because it allows the code generator to 1018// reason more about the constraint. 1019// 1020// If FastIsel should ignore all instructions that have an operand of this type, 1021// the FastIselShouldIgnore flag can be set. This is an optimization to reduce 1022// the code size of the generated fast instruction selector. 1023class ImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm, 1024 SDNode ImmNode = imm> 1025 : PatFrag<(ops), (vt ImmNode), [{}], xform> { 1026 let ImmediateCode = pred; 1027 bit FastIselShouldIgnore = false; 1028 1029 // Is the data type of the immediate an APInt? 1030 bit IsAPInt = false; 1031 1032 // Is the data type of the immediate an APFloat? 1033 bit IsAPFloat = false; 1034} 1035 1036// Convenience wrapper for ImmLeaf to use timm/TargetConstant instead 1037// of imm/Constant. 1038class TImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm, 1039 SDNode ImmNode = timm> : ImmLeaf<vt, pred, xform, ImmNode>; 1040 1041// An ImmLeaf except that Imm is an APInt. This is useful when you need to 1042// zero-extend the immediate instead of sign-extend it. 1043// 1044// Note that FastISel does not currently understand IntImmLeaf and will not 1045// generate code for rules that make use of it. As such, it does not make sense 1046// to replace ImmLeaf with IntImmLeaf. However, replacing PatLeaf with an 1047// IntImmLeaf will allow GlobalISel to import the rule. 1048class IntImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm> 1049 : ImmLeaf<vt, pred, xform> { 1050 let IsAPInt = true; 1051 let FastIselShouldIgnore = true; 1052} 1053 1054// An ImmLeaf except that Imm is an APFloat. 1055// 1056// Note that FastISel does not currently understand FPImmLeaf and will not 1057// generate code for rules that make use of it. 1058class FPImmLeaf<ValueType vt, code pred, SDNodeXForm xform = NOOP_SDNodeXForm> 1059 : ImmLeaf<vt, pred, xform, fpimm> { 1060 let IsAPFloat = true; 1061 let FastIselShouldIgnore = true; 1062} 1063 1064// Leaf fragments. 1065 1066def vtInt : PatLeaf<(vt), [{ return N->getVT().isInteger(); }]>; 1067def vtFP : PatLeaf<(vt), [{ return N->getVT().isFloatingPoint(); }]>; 1068 1069// Use ISD::isConstantSplatVectorAllOnes or ISD::isConstantSplatVectorAllZeros 1070// to look for the corresponding build_vector or splat_vector. Will look through 1071// bitcasts and check for either opcode, except when used as a pattern root. 1072// When used as a pattern root, only fixed-length build_vector and scalable 1073// splat_vector are supported. 1074def immAllOnesV : SDPatternOperator; // ISD::isConstantSplatVectorAllOnes 1075def immAllZerosV : SDPatternOperator; // ISD::isConstantSplatVectorAllZeros 1076 1077// Other helper fragments. 1078def not : PatFrag<(ops node:$in), (xor node:$in, -1)>; 1079def vnot : PatFrag<(ops node:$in), (xor node:$in, immAllOnesV)>; 1080def ineg : PatFrag<(ops node:$in), (sub 0, node:$in)>; 1081 1082def zanyext : PatFrags<(ops node:$op), 1083 [(zext node:$op), 1084 (anyext node:$op)]>; 1085 1086// null_frag - The null pattern operator is used in multiclass instantiations 1087// which accept an SDPatternOperator for use in matching patterns for internal 1088// definitions. When expanding a pattern, if the null fragment is referenced 1089// in the expansion, the pattern is discarded and it is as-if '[]' had been 1090// specified. This allows multiclasses to have the isel patterns be optional. 1091def null_frag : SDPatternOperator; 1092 1093// load fragments. 1094def unindexedload : PatFrag<(ops node:$ptr), (ld node:$ptr)> { 1095 let IsLoad = true; 1096 let IsUnindexed = true; 1097} 1098def load : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { 1099 let IsLoad = true; 1100 let IsNonExtLoad = true; 1101} 1102 1103// extending load fragments. 1104def extload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { 1105 let IsLoad = true; 1106 let IsAnyExtLoad = true; 1107} 1108def sextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { 1109 let IsLoad = true; 1110 let IsSignExtLoad = true; 1111} 1112def zextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr)> { 1113 let IsLoad = true; 1114 let IsZeroExtLoad = true; 1115} 1116 1117def extloadi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1118 let IsLoad = true; 1119 let MemoryVT = i1; 1120} 1121def extloadi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1122 let IsLoad = true; 1123 let MemoryVT = i8; 1124} 1125def extloadi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1126 let IsLoad = true; 1127 let MemoryVT = i16; 1128} 1129def extloadi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1130 let IsLoad = true; 1131 let MemoryVT = i32; 1132} 1133def extloadi64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1134 let IsLoad = true; 1135 let MemoryVT = i64; 1136} 1137def extloadf16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1138 let IsLoad = true; 1139 let MemoryVT = f16; 1140} 1141def extloadf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1142 let IsLoad = true; 1143 let MemoryVT = f32; 1144} 1145def extloadf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1146 let IsLoad = true; 1147 let MemoryVT = f64; 1148} 1149 1150def sextloadi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1151 let IsLoad = true; 1152 let MemoryVT = i1; 1153} 1154def sextloadi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1155 let IsLoad = true; 1156 let MemoryVT = i8; 1157} 1158def sextloadi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1159 let IsLoad = true; 1160 let MemoryVT = i16; 1161} 1162def sextloadi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1163 let IsLoad = true; 1164 let MemoryVT = i32; 1165} 1166def sextloadi64 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1167 let IsLoad = true; 1168 let MemoryVT = i64; 1169} 1170 1171def zextloadi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1172 let IsLoad = true; 1173 let MemoryVT = i1; 1174} 1175def zextloadi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1176 let IsLoad = true; 1177 let MemoryVT = i8; 1178} 1179def zextloadi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1180 let IsLoad = true; 1181 let MemoryVT = i16; 1182} 1183def zextloadi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1184 let IsLoad = true; 1185 let MemoryVT = i32; 1186} 1187def zextloadi64 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1188 let IsLoad = true; 1189 let MemoryVT = i64; 1190} 1191 1192def extloadvi1 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1193 let IsLoad = true; 1194 let ScalarMemoryVT = i1; 1195} 1196def extloadvi8 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1197 let IsLoad = true; 1198 let ScalarMemoryVT = i8; 1199} 1200def extloadvi16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1201 let IsLoad = true; 1202 let ScalarMemoryVT = i16; 1203} 1204def extloadvi32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1205 let IsLoad = true; 1206 let ScalarMemoryVT = i32; 1207} 1208def extloadvf16 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1209 let IsLoad = true; 1210 let ScalarMemoryVT = f16; 1211} 1212def extloadvf32 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1213 let IsLoad = true; 1214 let ScalarMemoryVT = f32; 1215} 1216def extloadvf64 : PatFrag<(ops node:$ptr), (extload node:$ptr)> { 1217 let IsLoad = true; 1218 let ScalarMemoryVT = f64; 1219} 1220 1221def sextloadvi1 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1222 let IsLoad = true; 1223 let ScalarMemoryVT = i1; 1224} 1225def sextloadvi8 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1226 let IsLoad = true; 1227 let ScalarMemoryVT = i8; 1228} 1229def sextloadvi16 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1230 let IsLoad = true; 1231 let ScalarMemoryVT = i16; 1232} 1233def sextloadvi32 : PatFrag<(ops node:$ptr), (sextload node:$ptr)> { 1234 let IsLoad = true; 1235 let ScalarMemoryVT = i32; 1236} 1237 1238def zextloadvi1 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1239 let IsLoad = true; 1240 let ScalarMemoryVT = i1; 1241} 1242def zextloadvi8 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1243 let IsLoad = true; 1244 let ScalarMemoryVT = i8; 1245} 1246def zextloadvi16 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1247 let IsLoad = true; 1248 let ScalarMemoryVT = i16; 1249} 1250def zextloadvi32 : PatFrag<(ops node:$ptr), (zextload node:$ptr)> { 1251 let IsLoad = true; 1252 let ScalarMemoryVT = i32; 1253} 1254 1255// store fragments. 1256def unindexedstore : PatFrag<(ops node:$val, node:$ptr), 1257 (st node:$val, node:$ptr)> { 1258 let IsStore = true; 1259 let IsUnindexed = true; 1260} 1261def store : PatFrag<(ops node:$val, node:$ptr), 1262 (unindexedstore node:$val, node:$ptr)> { 1263 let IsStore = true; 1264 let IsTruncStore = false; 1265} 1266 1267// truncstore fragments. 1268def truncstore : PatFrag<(ops node:$val, node:$ptr), 1269 (unindexedstore node:$val, node:$ptr)> { 1270 let IsStore = true; 1271 let IsTruncStore = true; 1272} 1273def truncstorei8 : PatFrag<(ops node:$val, node:$ptr), 1274 (truncstore node:$val, node:$ptr)> { 1275 let IsStore = true; 1276 let MemoryVT = i8; 1277 let IsTruncStore = true; 1278} 1279def truncstorei16 : PatFrag<(ops node:$val, node:$ptr), 1280 (truncstore node:$val, node:$ptr)> { 1281 let IsStore = true; 1282 let MemoryVT = i16; 1283 let IsTruncStore = true; 1284} 1285def truncstorei32 : PatFrag<(ops node:$val, node:$ptr), 1286 (truncstore node:$val, node:$ptr)> { 1287 let IsStore = true; 1288 let MemoryVT = i32; 1289 let IsTruncStore = true; 1290} 1291def truncstorei64 : PatFrag<(ops node:$val, node:$ptr), 1292 (truncstore node:$val, node:$ptr)> { 1293 let IsStore = true; 1294 let MemoryVT = i64; 1295 let IsTruncStore = true; 1296} 1297def truncstoref16 : PatFrag<(ops node:$val, node:$ptr), 1298 (truncstore node:$val, node:$ptr)> { 1299 let IsStore = true; 1300 let MemoryVT = f16; 1301} 1302def truncstoref32 : PatFrag<(ops node:$val, node:$ptr), 1303 (truncstore node:$val, node:$ptr)> { 1304 let IsStore = true; 1305 let MemoryVT = f32; 1306} 1307def truncstoref64 : PatFrag<(ops node:$val, node:$ptr), 1308 (truncstore node:$val, node:$ptr)> { 1309 let IsStore = true; 1310 let MemoryVT = f64; 1311} 1312 1313def truncstorevi8 : PatFrag<(ops node:$val, node:$ptr), 1314 (truncstore node:$val, node:$ptr)> { 1315 let IsStore = true; 1316 let ScalarMemoryVT = i8; 1317} 1318 1319def truncstorevi16 : PatFrag<(ops node:$val, node:$ptr), 1320 (truncstore node:$val, node:$ptr)> { 1321 let IsStore = true; 1322 let ScalarMemoryVT = i16; 1323} 1324 1325def truncstorevi32 : PatFrag<(ops node:$val, node:$ptr), 1326 (truncstore node:$val, node:$ptr)> { 1327 let IsStore = true; 1328 let ScalarMemoryVT = i32; 1329} 1330 1331// indexed store fragments. 1332def istore : PatFrag<(ops node:$val, node:$base, node:$offset), 1333 (ist node:$val, node:$base, node:$offset)> { 1334 let IsStore = true; 1335 let IsTruncStore = false; 1336} 1337 1338def pre_store : PatFrag<(ops node:$val, node:$base, node:$offset), 1339 (istore node:$val, node:$base, node:$offset), [{ 1340 ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); 1341 return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; 1342}]>; 1343 1344def itruncstore : PatFrag<(ops node:$val, node:$base, node:$offset), 1345 (ist node:$val, node:$base, node:$offset)> { 1346 let IsStore = true; 1347 let IsTruncStore = true; 1348} 1349def pre_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), 1350 (itruncstore node:$val, node:$base, node:$offset), [{ 1351 ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); 1352 return AM == ISD::PRE_INC || AM == ISD::PRE_DEC; 1353}]>; 1354def pre_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), 1355 (pre_truncst node:$val, node:$base, node:$offset)> { 1356 let IsStore = true; 1357 let MemoryVT = i1; 1358} 1359def pre_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), 1360 (pre_truncst node:$val, node:$base, node:$offset)> { 1361 let IsStore = true; 1362 let MemoryVT = i8; 1363} 1364def pre_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), 1365 (pre_truncst node:$val, node:$base, node:$offset)> { 1366 let IsStore = true; 1367 let MemoryVT = i16; 1368} 1369def pre_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), 1370 (pre_truncst node:$val, node:$base, node:$offset)> { 1371 let IsStore = true; 1372 let MemoryVT = i32; 1373} 1374def pre_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), 1375 (pre_truncst node:$val, node:$base, node:$offset)> { 1376 let IsStore = true; 1377 let MemoryVT = f32; 1378} 1379def pre_truncstvi8 : PatFrag<(ops node:$val, node:$base, node:$offset), 1380 (pre_truncst node:$val, node:$base, node:$offset)> { 1381 let IsStore = true; 1382 let ScalarMemoryVT = i8; 1383} 1384def pre_truncstvi16 : PatFrag<(ops node:$val, node:$base, node:$offset), 1385 (pre_truncst node:$val, node:$base, node:$offset)> { 1386 let IsStore = true; 1387 let ScalarMemoryVT = i16; 1388} 1389 1390def post_store : PatFrag<(ops node:$val, node:$ptr, node:$offset), 1391 (istore node:$val, node:$ptr, node:$offset), [{ 1392 ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); 1393 return AM == ISD::POST_INC || AM == ISD::POST_DEC; 1394}]>; 1395 1396def post_truncst : PatFrag<(ops node:$val, node:$base, node:$offset), 1397 (itruncstore node:$val, node:$base, node:$offset), [{ 1398 ISD::MemIndexedMode AM = cast<StoreSDNode>(N)->getAddressingMode(); 1399 return AM == ISD::POST_INC || AM == ISD::POST_DEC; 1400}]>; 1401def post_truncsti1 : PatFrag<(ops node:$val, node:$base, node:$offset), 1402 (post_truncst node:$val, node:$base, node:$offset)> { 1403 let IsStore = true; 1404 let MemoryVT = i1; 1405} 1406def post_truncsti8 : PatFrag<(ops node:$val, node:$base, node:$offset), 1407 (post_truncst node:$val, node:$base, node:$offset)> { 1408 let IsStore = true; 1409 let MemoryVT = i8; 1410} 1411def post_truncsti16 : PatFrag<(ops node:$val, node:$base, node:$offset), 1412 (post_truncst node:$val, node:$base, node:$offset)> { 1413 let IsStore = true; 1414 let MemoryVT = i16; 1415} 1416def post_truncsti32 : PatFrag<(ops node:$val, node:$base, node:$offset), 1417 (post_truncst node:$val, node:$base, node:$offset)> { 1418 let IsStore = true; 1419 let MemoryVT = i32; 1420} 1421def post_truncstf32 : PatFrag<(ops node:$val, node:$base, node:$offset), 1422 (post_truncst node:$val, node:$base, node:$offset)> { 1423 let IsStore = true; 1424 let MemoryVT = f32; 1425} 1426def post_truncstvi8 : PatFrag<(ops node:$val, node:$base, node:$offset), 1427 (post_truncst node:$val, node:$base, node:$offset)> { 1428 let IsStore = true; 1429 let ScalarMemoryVT = i8; 1430} 1431def post_truncstvi16 : PatFrag<(ops node:$val, node:$base, node:$offset), 1432 (post_truncst node:$val, node:$base, node:$offset)> { 1433 let IsStore = true; 1434 let ScalarMemoryVT = i16; 1435} 1436 1437// A helper for matching undef or freeze undef 1438def undef_or_freeze_undef : PatFrags<(ops), [(undef), (freeze undef)]>; 1439 1440// TODO: Split these into volatile and unordered flavors to enable 1441// selectively legal optimizations for each. (See D66309) 1442def simple_load : PatFrag<(ops node:$ptr), 1443 (load node:$ptr), [{ 1444 return cast<LoadSDNode>(N)->isSimple(); 1445}]>; 1446def simple_store : PatFrag<(ops node:$val, node:$ptr), 1447 (store node:$val, node:$ptr), [{ 1448 return cast<StoreSDNode>(N)->isSimple(); 1449}]>; 1450 1451// nontemporal store fragments. 1452def nontemporalstore : PatFrag<(ops node:$val, node:$ptr), 1453 (store node:$val, node:$ptr), [{ 1454 return cast<StoreSDNode>(N)->isNonTemporal(); 1455}]>; 1456 1457def alignednontemporalstore : PatFrag<(ops node:$val, node:$ptr), 1458 (nontemporalstore node:$val, node:$ptr), [{ 1459 StoreSDNode *St = cast<StoreSDNode>(N); 1460 return St->getAlign() >= St->getMemoryVT().getStoreSize(); 1461}]>; 1462 1463def unalignednontemporalstore : PatFrag<(ops node:$val, node:$ptr), 1464 (nontemporalstore node:$val, node:$ptr), [{ 1465 StoreSDNode *St = cast<StoreSDNode>(N); 1466 return St->getAlignment() < St->getMemoryVT().getStoreSize(); 1467}]>; 1468 1469// nontemporal load fragments. 1470def nontemporalload : PatFrag<(ops node:$ptr), 1471 (load node:$ptr), [{ 1472 return cast<LoadSDNode>(N)->isNonTemporal(); 1473}]>; 1474 1475def alignednontemporalload : PatFrag<(ops node:$ptr), 1476 (nontemporalload node:$ptr), [{ 1477 LoadSDNode *Ld = cast<LoadSDNode>(N); 1478 return Ld->getAlign() >= Ld->getMemoryVT().getStoreSize(); 1479}]>; 1480 1481// setcc convenience fragments. 1482def setoeq : PatFrag<(ops node:$lhs, node:$rhs), 1483 (setcc node:$lhs, node:$rhs, SETOEQ)>; 1484def setogt : PatFrag<(ops node:$lhs, node:$rhs), 1485 (setcc node:$lhs, node:$rhs, SETOGT)>; 1486def setoge : PatFrag<(ops node:$lhs, node:$rhs), 1487 (setcc node:$lhs, node:$rhs, SETOGE)>; 1488def setolt : PatFrag<(ops node:$lhs, node:$rhs), 1489 (setcc node:$lhs, node:$rhs, SETOLT)>; 1490def setole : PatFrag<(ops node:$lhs, node:$rhs), 1491 (setcc node:$lhs, node:$rhs, SETOLE)>; 1492def setone : PatFrag<(ops node:$lhs, node:$rhs), 1493 (setcc node:$lhs, node:$rhs, SETONE)>; 1494def seto : PatFrag<(ops node:$lhs, node:$rhs), 1495 (setcc node:$lhs, node:$rhs, SETO)>; 1496def setuo : PatFrag<(ops node:$lhs, node:$rhs), 1497 (setcc node:$lhs, node:$rhs, SETUO)>; 1498def setueq : PatFrag<(ops node:$lhs, node:$rhs), 1499 (setcc node:$lhs, node:$rhs, SETUEQ)>; 1500def setugt : PatFrag<(ops node:$lhs, node:$rhs), 1501 (setcc node:$lhs, node:$rhs, SETUGT)>; 1502def setuge : PatFrag<(ops node:$lhs, node:$rhs), 1503 (setcc node:$lhs, node:$rhs, SETUGE)>; 1504def setult : PatFrag<(ops node:$lhs, node:$rhs), 1505 (setcc node:$lhs, node:$rhs, SETULT)>; 1506def setule : PatFrag<(ops node:$lhs, node:$rhs), 1507 (setcc node:$lhs, node:$rhs, SETULE)>; 1508def setune : PatFrag<(ops node:$lhs, node:$rhs), 1509 (setcc node:$lhs, node:$rhs, SETUNE)>; 1510def seteq : PatFrag<(ops node:$lhs, node:$rhs), 1511 (setcc node:$lhs, node:$rhs, SETEQ)>; 1512def setgt : PatFrag<(ops node:$lhs, node:$rhs), 1513 (setcc node:$lhs, node:$rhs, SETGT)>; 1514def setge : PatFrag<(ops node:$lhs, node:$rhs), 1515 (setcc node:$lhs, node:$rhs, SETGE)>; 1516def setlt : PatFrag<(ops node:$lhs, node:$rhs), 1517 (setcc node:$lhs, node:$rhs, SETLT)>; 1518def setle : PatFrag<(ops node:$lhs, node:$rhs), 1519 (setcc node:$lhs, node:$rhs, SETLE)>; 1520def setne : PatFrag<(ops node:$lhs, node:$rhs), 1521 (setcc node:$lhs, node:$rhs, SETNE)>; 1522 1523// We don't have strict FP extended loads as single DAG nodes, but we can 1524// still provide convenience fragments to match those operations. 1525def strict_extloadf32 : PatFrag<(ops node:$ptr), 1526 (strict_fpextend (f32 (load node:$ptr)))>; 1527def strict_extloadf64 : PatFrag<(ops node:$ptr), 1528 (strict_fpextend (f64 (load node:$ptr)))>; 1529 1530// Convenience fragments to match both strict and non-strict fp operations 1531def any_fadd : PatFrags<(ops node:$lhs, node:$rhs), 1532 [(strict_fadd node:$lhs, node:$rhs), 1533 (fadd node:$lhs, node:$rhs)]>; 1534def any_fsub : PatFrags<(ops node:$lhs, node:$rhs), 1535 [(strict_fsub node:$lhs, node:$rhs), 1536 (fsub node:$lhs, node:$rhs)]>; 1537def any_fmul : PatFrags<(ops node:$lhs, node:$rhs), 1538 [(strict_fmul node:$lhs, node:$rhs), 1539 (fmul node:$lhs, node:$rhs)]>; 1540def any_fdiv : PatFrags<(ops node:$lhs, node:$rhs), 1541 [(strict_fdiv node:$lhs, node:$rhs), 1542 (fdiv node:$lhs, node:$rhs)]>; 1543def any_frem : PatFrags<(ops node:$lhs, node:$rhs), 1544 [(strict_frem node:$lhs, node:$rhs), 1545 (frem node:$lhs, node:$rhs)]>; 1546def any_fma : PatFrags<(ops node:$src1, node:$src2, node:$src3), 1547 [(strict_fma node:$src1, node:$src2, node:$src3), 1548 (fma node:$src1, node:$src2, node:$src3)]>; 1549def any_fsqrt : PatFrags<(ops node:$src), 1550 [(strict_fsqrt node:$src), 1551 (fsqrt node:$src)]>; 1552def any_fsin : PatFrags<(ops node:$src), 1553 [(strict_fsin node:$src), 1554 (fsin node:$src)]>; 1555def any_fcos : PatFrags<(ops node:$src), 1556 [(strict_fcos node:$src), 1557 (fcos node:$src)]>; 1558def any_ftan : PatFrags<(ops node:$src), 1559 [(strict_ftan node:$src), 1560 (ftan node:$src)]>; 1561def any_fasin : PatFrags<(ops node:$src), 1562 [(strict_fasin node:$src), 1563 (fasin node:$src)]>; 1564def any_facos : PatFrags<(ops node:$src), 1565 [(strict_facos node:$src), 1566 (facos node:$src)]>; 1567def any_fatan : PatFrags<(ops node:$src), 1568 [(strict_fatan node:$src), 1569 (fatan node:$src)]>; 1570def any_fsinh : PatFrags<(ops node:$src), 1571 [(strict_fsinh node:$src), 1572 (fsinh node:$src)]>; 1573def any_fcosh : PatFrags<(ops node:$src), 1574 [(strict_fcosh node:$src), 1575 (fcosh node:$src)]>; 1576def any_ftanh : PatFrags<(ops node:$src), 1577 [(strict_ftanh node:$src), 1578 (ftanh node:$src)]>; 1579def any_fexp2 : PatFrags<(ops node:$src), 1580 [(strict_fexp2 node:$src), 1581 (fexp2 node:$src)]>; 1582def any_fpow : PatFrags<(ops node:$lhs, node:$rhs), 1583 [(strict_fpow node:$lhs, node:$rhs), 1584 (fpow node:$lhs, node:$rhs)]>; 1585def any_fldexp : PatFrags<(ops node:$lhs, node:$rhs), 1586 [(strict_fldexp node:$lhs, node:$rhs), 1587 (fldexp node:$lhs, node:$rhs)]>; 1588def any_flog2 : PatFrags<(ops node:$src), 1589 [(strict_flog2 node:$src), 1590 (flog2 node:$src)]>; 1591def any_frint : PatFrags<(ops node:$src), 1592 [(strict_frint node:$src), 1593 (frint node:$src)]>; 1594def any_lrint : PatFrags<(ops node:$src), 1595 [(strict_lrint node:$src), 1596 (lrint node:$src)]>; 1597def any_llrint : PatFrags<(ops node:$src), 1598 [(strict_llrint node:$src), 1599 (llrint node:$src)]>; 1600def any_fnearbyint : PatFrags<(ops node:$src), 1601 [(strict_fnearbyint node:$src), 1602 (fnearbyint node:$src)]>; 1603def any_fceil : PatFrags<(ops node:$src), 1604 [(strict_fceil node:$src), 1605 (fceil node:$src)]>; 1606def any_ffloor : PatFrags<(ops node:$src), 1607 [(strict_ffloor node:$src), 1608 (ffloor node:$src)]>; 1609def any_lround : PatFrags<(ops node:$src), 1610 [(strict_lround node:$src), 1611 (lround node:$src)]>; 1612def any_llround : PatFrags<(ops node:$src), 1613 [(strict_llround node:$src), 1614 (llround node:$src)]>; 1615def any_fround : PatFrags<(ops node:$src), 1616 [(strict_fround node:$src), 1617 (fround node:$src)]>; 1618def any_froundeven : PatFrags<(ops node:$src), 1619 [(strict_froundeven node:$src), 1620 (froundeven node:$src)]>; 1621def any_ftrunc : PatFrags<(ops node:$src), 1622 [(strict_ftrunc node:$src), 1623 (ftrunc node:$src)]>; 1624def any_fmaxnum : PatFrags<(ops node:$lhs, node:$rhs), 1625 [(strict_fmaxnum node:$lhs, node:$rhs), 1626 (fmaxnum node:$lhs, node:$rhs)]>; 1627def any_fminnum : PatFrags<(ops node:$lhs, node:$rhs), 1628 [(strict_fminnum node:$lhs, node:$rhs), 1629 (fminnum node:$lhs, node:$rhs)]>; 1630def any_fmaximum : PatFrags<(ops node:$lhs, node:$rhs), 1631 [(strict_fmaximum node:$lhs, node:$rhs), 1632 (fmaximum node:$lhs, node:$rhs)]>; 1633def any_fminimum : PatFrags<(ops node:$lhs, node:$rhs), 1634 [(strict_fminimum node:$lhs, node:$rhs), 1635 (fminimum node:$lhs, node:$rhs)]>; 1636def any_fpround : PatFrags<(ops node:$src), 1637 [(strict_fpround node:$src), 1638 (fpround node:$src)]>; 1639def any_fpextend : PatFrags<(ops node:$src), 1640 [(strict_fpextend node:$src), 1641 (fpextend node:$src)]>; 1642def any_extloadf32 : PatFrags<(ops node:$ptr), 1643 [(strict_extloadf32 node:$ptr), 1644 (extloadf32 node:$ptr)]>; 1645def any_extloadf64 : PatFrags<(ops node:$ptr), 1646 [(strict_extloadf64 node:$ptr), 1647 (extloadf64 node:$ptr)]>; 1648def any_fp_to_sint : PatFrags<(ops node:$src), 1649 [(strict_fp_to_sint node:$src), 1650 (fp_to_sint node:$src)]>; 1651def any_fp_to_uint : PatFrags<(ops node:$src), 1652 [(strict_fp_to_uint node:$src), 1653 (fp_to_uint node:$src)]>; 1654def any_sint_to_fp : PatFrags<(ops node:$src), 1655 [(strict_sint_to_fp node:$src), 1656 (sint_to_fp node:$src)]>; 1657def any_uint_to_fp : PatFrags<(ops node:$src), 1658 [(strict_uint_to_fp node:$src), 1659 (uint_to_fp node:$src)]>; 1660def any_fsetcc : PatFrags<(ops node:$lhs, node:$rhs, node:$pred), 1661 [(strict_fsetcc node:$lhs, node:$rhs, node:$pred), 1662 (setcc node:$lhs, node:$rhs, node:$pred)]>; 1663def any_fsetccs : PatFrags<(ops node:$lhs, node:$rhs, node:$pred), 1664 [(strict_fsetccs node:$lhs, node:$rhs, node:$pred), 1665 (setcc node:$lhs, node:$rhs, node:$pred)]>; 1666 1667def any_f16_to_fp : PatFrags<(ops node:$src), 1668 [(f16_to_fp node:$src), 1669 (strict_f16_to_fp node:$src)]>; 1670def any_fp_to_f16 : PatFrags<(ops node:$src), 1671 [(fp_to_f16 node:$src), 1672 (strict_fp_to_f16 node:$src)]>; 1673def any_bf16_to_fp : PatFrags<(ops node:$src), 1674 [(bf16_to_fp node:$src), 1675 (strict_bf16_to_fp node:$src)]>; 1676def any_fp_to_bf16 : PatFrags<(ops node:$src), 1677 [(fp_to_bf16 node:$src), 1678 (strict_fp_to_bf16 node:$src)]>; 1679 1680multiclass binary_atomic_op_ord { 1681 def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val), 1682 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1683 let IsAtomic = true; 1684 let IsAtomicOrderingMonotonic = true; 1685 } 1686 def NAME#_acquire : PatFrag<(ops node:$ptr, node:$val), 1687 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1688 let IsAtomic = true; 1689 let IsAtomicOrderingAcquire = true; 1690 } 1691 def NAME#_release : PatFrag<(ops node:$ptr, node:$val), 1692 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1693 let IsAtomic = true; 1694 let IsAtomicOrderingRelease = true; 1695 } 1696 def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val), 1697 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1698 let IsAtomic = true; 1699 let IsAtomicOrderingAcquireRelease = true; 1700 } 1701 def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val), 1702 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> { 1703 let IsAtomic = true; 1704 let IsAtomicOrderingSequentiallyConsistent = true; 1705 } 1706} 1707 1708multiclass ternary_atomic_op_ord { 1709 def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1710 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1711 let IsAtomic = true; 1712 let IsAtomicOrderingMonotonic = true; 1713 } 1714 def NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1715 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1716 let IsAtomic = true; 1717 let IsAtomicOrderingAcquire = true; 1718 } 1719 def NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1720 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1721 let IsAtomic = true; 1722 let IsAtomicOrderingRelease = true; 1723 } 1724 def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1725 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1726 let IsAtomic = true; 1727 let IsAtomicOrderingAcquireRelease = true; 1728 } 1729 def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1730 (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> { 1731 let IsAtomic = true; 1732 let IsAtomicOrderingSequentiallyConsistent = true; 1733 } 1734} 1735 1736multiclass binary_atomic_op<SDNode atomic_op> { 1737 foreach vt = [ i8, i16, i32, i64 ] in { 1738 def _#vt : PatFrag<(ops node:$ptr, node:$val), 1739 (atomic_op node:$ptr, node:$val)> { 1740 let IsAtomic = true; 1741 let MemoryVT = vt; 1742 } 1743 1744 defm NAME#_#vt : binary_atomic_op_ord; 1745 } 1746} 1747 1748multiclass binary_atomic_op_fp<SDNode atomic_op> { 1749 foreach vt = [ f16, bf16, v2f16, v2bf16, f32, f64 ] in { 1750 def _#vt : PatFrag<(ops node:$ptr, node:$val), 1751 (atomic_op node:$ptr, node:$val)> { 1752 let IsAtomic = true; 1753 let MemoryVT = vt; 1754 } 1755 } 1756} 1757 1758multiclass ternary_atomic_op<SDNode atomic_op> { 1759 foreach vt = [ i8, i16, i32, i64 ] in { 1760 def _#vt : PatFrag<(ops node:$ptr, node:$cmp, node:$val), 1761 (atomic_op node:$ptr, node:$cmp, node:$val)> { 1762 let IsAtomic = true; 1763 let MemoryVT = vt; 1764 } 1765 1766 defm NAME#_#vt : ternary_atomic_op_ord; 1767 } 1768} 1769 1770defm atomic_load_add : binary_atomic_op<atomic_load_add>; 1771defm atomic_swap : binary_atomic_op<atomic_swap>; 1772defm atomic_load_sub : binary_atomic_op<atomic_load_sub>; 1773defm atomic_load_and : binary_atomic_op<atomic_load_and>; 1774defm atomic_load_clr : binary_atomic_op<atomic_load_clr>; 1775defm atomic_load_or : binary_atomic_op<atomic_load_or>; 1776defm atomic_load_xor : binary_atomic_op<atomic_load_xor>; 1777defm atomic_load_nand : binary_atomic_op<atomic_load_nand>; 1778defm atomic_load_min : binary_atomic_op<atomic_load_min>; 1779defm atomic_load_max : binary_atomic_op<atomic_load_max>; 1780defm atomic_load_umin : binary_atomic_op<atomic_load_umin>; 1781defm atomic_load_umax : binary_atomic_op<atomic_load_umax>; 1782defm atomic_cmp_swap : ternary_atomic_op<atomic_cmp_swap>; 1783 1784/// Atomic load which zeroes the excess high bits. 1785def atomic_load_zext : 1786 PatFrag<(ops node:$ptr), (atomic_load node:$ptr)> { 1787 let IsAtomic = true; // FIXME: Should be IsLoad and/or IsAtomic? 1788 let IsZeroExtLoad = true; 1789} 1790 1791/// Atomic load which sign extends the excess high bits. 1792def atomic_load_sext : 1793 PatFrag<(ops node:$ptr), (atomic_load node:$ptr)> { 1794 let IsAtomic = true; // FIXME: Should be IsLoad and/or IsAtomic? 1795 let IsSignExtLoad = true; 1796} 1797 1798def atomic_load_8 : 1799 PatFrag<(ops node:$ptr), 1800 (atomic_load node:$ptr)> { 1801 let IsAtomic = true; 1802 let MemoryVT = i8; 1803} 1804 1805def atomic_load_16 : 1806 PatFrag<(ops node:$ptr), 1807 (atomic_load node:$ptr)> { 1808 let IsAtomic = true; 1809 let MemoryVT = i16; 1810} 1811 1812def atomic_load_32 : 1813 PatFrag<(ops node:$ptr), 1814 (atomic_load node:$ptr)> { 1815 let IsAtomic = true; 1816 let MemoryVT = i32; 1817} 1818def atomic_load_64 : 1819 PatFrag<(ops node:$ptr), 1820 (atomic_load node:$ptr)> { 1821 let IsAtomic = true; 1822 let MemoryVT = i64; 1823} 1824 1825def atomic_load_zext_8 : 1826 PatFrag<(ops node:$ptr), (atomic_load_zext node:$ptr)> { 1827 let IsAtomic = true; // FIXME: Should be IsLoad and/or IsAtomic? 1828 let MemoryVT = i8; 1829} 1830 1831def atomic_load_zext_16 : 1832 PatFrag<(ops node:$ptr), (atomic_load_zext node:$ptr)> { 1833 let IsAtomic = true; // FIXME: Should be IsLoad and/or IsAtomic? 1834 let MemoryVT = i16; 1835} 1836 1837def atomic_load_sext_8 : 1838 PatFrag<(ops node:$ptr), (atomic_load_sext node:$ptr)> { 1839 let IsAtomic = true; // FIXME: Should be IsLoad and/or IsAtomic? 1840 let MemoryVT = i8; 1841} 1842 1843def atomic_load_sext_16 : 1844 PatFrag<(ops node:$ptr), (atomic_load_sext node:$ptr)> { 1845 let IsAtomic = true; // FIXME: Should be IsLoad and/or IsAtomic? 1846 let MemoryVT = i16; 1847} 1848 1849// Atomic load which zeroes or anyextends the high bits. 1850def atomic_load_az_8 : PatFrags<(ops node:$op), 1851 [(atomic_load_8 node:$op), 1852 (atomic_load_zext_8 node:$op)]>; 1853 1854// Atomic load which zeroes or anyextends the high bits. 1855def atomic_load_az_16 : PatFrags<(ops node:$op), 1856 [(atomic_load_16 node:$op), 1857 (atomic_load_zext_16 node:$op)]>; 1858 1859def nonext_masked_gather : 1860 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1861 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1862 return cast<MaskedGatherSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD; 1863}]>; 1864 1865// Any extending masked gather fragments. 1866def ext_masked_gather_i8 : 1867 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1868 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1869 auto MGN = cast<MaskedGatherSDNode>(N); 1870 return MGN->getExtensionType() == ISD::EXTLOAD && 1871 MGN->getMemoryVT().getScalarType() == MVT::i8; 1872}]>; 1873def ext_masked_gather_i16 : 1874 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1875 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1876 auto MGN = cast<MaskedGatherSDNode>(N); 1877 return MGN->getExtensionType() == ISD::EXTLOAD && 1878 MGN->getMemoryVT().getScalarType() == MVT::i16; 1879}]>; 1880def ext_masked_gather_i32 : 1881 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1882 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1883 auto MGN = cast<MaskedGatherSDNode>(N); 1884 return MGN->getExtensionType() == ISD::EXTLOAD && 1885 MGN->getMemoryVT().getScalarType() == MVT::i32; 1886}]>; 1887 1888// Sign extending masked gather fragments. 1889def sext_masked_gather_i8 : 1890 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1891 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1892 auto MGN = cast<MaskedGatherSDNode>(N); 1893 return MGN->getExtensionType() == ISD::SEXTLOAD && 1894 MGN->getMemoryVT().getScalarType() == MVT::i8; 1895}]>; 1896def sext_masked_gather_i16 : 1897 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1898 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1899 auto MGN = cast<MaskedGatherSDNode>(N); 1900 return MGN->getExtensionType() == ISD::SEXTLOAD && 1901 MGN->getMemoryVT().getScalarType() == MVT::i16; 1902}]>; 1903def sext_masked_gather_i32 : 1904 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1905 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1906 auto MGN = cast<MaskedGatherSDNode>(N); 1907 return MGN->getExtensionType() == ISD::SEXTLOAD && 1908 MGN->getMemoryVT().getScalarType() == MVT::i32; 1909}]>; 1910 1911// Zero extending masked gather fragments. 1912def zext_masked_gather_i8 : 1913 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1914 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1915 auto MGN = cast<MaskedGatherSDNode>(N); 1916 return MGN->getExtensionType() == ISD::ZEXTLOAD && 1917 MGN->getMemoryVT().getScalarType() == MVT::i8; 1918}]>; 1919def zext_masked_gather_i16 : 1920 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1921 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1922 auto MGN = cast<MaskedGatherSDNode>(N); 1923 return MGN->getExtensionType() == ISD::ZEXTLOAD && 1924 MGN->getMemoryVT().getScalarType() == MVT::i16; 1925}]>; 1926def zext_masked_gather_i32 : 1927 PatFrag<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1928 (masked_gather node:$def, node:$pred, node:$ptr, node:$idx), [{ 1929 auto MGN = cast<MaskedGatherSDNode>(N); 1930 return MGN->getExtensionType() == ISD::ZEXTLOAD && 1931 MGN->getMemoryVT().getScalarType() == MVT::i32; 1932}]>; 1933 1934// Any/Zero extending masked gather fragments. 1935def azext_masked_gather_i8 : 1936 PatFrags<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1937 [(ext_masked_gather_i8 node:$def, node:$pred, node:$ptr, node:$idx), 1938 (zext_masked_gather_i8 node:$def, node:$pred, node:$ptr, node:$idx)]>; 1939def azext_masked_gather_i16 : 1940 PatFrags<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1941 [(ext_masked_gather_i16 node:$def, node:$pred, node:$ptr, node:$idx), 1942 (zext_masked_gather_i16 node:$def, node:$pred, node:$ptr, node:$idx)]>; 1943def azext_masked_gather_i32 : 1944 PatFrags<(ops node:$def, node:$pred, node:$ptr, node:$idx), 1945 [(ext_masked_gather_i32 node:$def, node:$pred, node:$ptr, node:$idx), 1946 (zext_masked_gather_i32 node:$def, node:$pred, node:$ptr, node:$idx)]>; 1947 1948def nontrunc_masked_scatter : 1949 PatFrag<(ops node:$val, node:$pred, node:$ptr, node:$idx), 1950 (masked_scatter node:$val, node:$pred, node:$ptr, node:$idx), [{ 1951 return !cast<MaskedScatterSDNode>(N)->isTruncatingStore(); 1952}]>; 1953 1954// Truncating masked scatter fragments. 1955def trunc_masked_scatter_i8 : 1956 PatFrag<(ops node:$val, node:$pred, node:$ptr, node:$idx), 1957 (masked_scatter node:$val, node:$pred, node:$ptr, node:$idx), [{ 1958 auto MSN = cast<MaskedScatterSDNode>(N); 1959 return MSN->isTruncatingStore() && 1960 MSN->getMemoryVT().getScalarType() == MVT::i8; 1961}]>; 1962def trunc_masked_scatter_i16 : 1963 PatFrag<(ops node:$val, node:$pred, node:$ptr, node:$idx), 1964 (masked_scatter node:$val, node:$pred, node:$ptr, node:$idx), [{ 1965 auto MSN = cast<MaskedScatterSDNode>(N); 1966 return MSN->isTruncatingStore() && 1967 MSN->getMemoryVT().getScalarType() == MVT::i16; 1968}]>; 1969def trunc_masked_scatter_i32 : 1970 PatFrag<(ops node:$val, node:$pred, node:$ptr, node:$idx), 1971 (masked_scatter node:$val, node:$pred, node:$ptr, node:$idx), [{ 1972 auto MSN = cast<MaskedScatterSDNode>(N); 1973 return MSN->isTruncatingStore() && 1974 MSN->getMemoryVT().getScalarType() == MVT::i32; 1975}]>; 1976 1977 1978def atomic_store_8 : 1979 PatFrag<(ops node:$val, node:$ptr), 1980 (atomic_store node:$val, node:$ptr)> { 1981 let IsAtomic = true; 1982 let MemoryVT = i8; 1983} 1984 1985def atomic_store_16 : 1986 PatFrag<(ops node:$val, node:$ptr), 1987 (atomic_store node:$val, node:$ptr)> { 1988 let IsAtomic = true; 1989 let MemoryVT = i16; 1990} 1991 1992def atomic_store_32 : 1993 PatFrag<(ops node:$val, node:$ptr), 1994 (atomic_store node:$val, node:$ptr)> { 1995 let IsAtomic = true; 1996 let MemoryVT = i32; 1997} 1998 1999def atomic_store_64 : 2000 PatFrag<(ops node:$val, node:$ptr), 2001 (atomic_store node:$val, node:$ptr)> { 2002 let IsAtomic = true; 2003 let MemoryVT = i64; 2004} 2005 2006//===----------------------------------------------------------------------===// 2007// Selection DAG Pattern Support. 2008// 2009// Patterns are what are actually matched against by the target-flavored 2010// instruction selection DAG. Instructions defined by the target implicitly 2011// define patterns in most cases, but patterns can also be explicitly added when 2012// an operation is defined by a sequence of instructions (e.g. loading a large 2013// immediate value on RISC targets that do not support immediates as large as 2014// their GPRs). 2015// 2016 2017class Pattern<dag patternToMatch, list<dag> resultInstrs> { 2018 dag PatternToMatch = patternToMatch; 2019 list<dag> ResultInstrs = resultInstrs; 2020 list<Predicate> Predicates = []; // See class Instruction in Target.td. 2021 int AddedComplexity = 0; // See class Instruction in Target.td. 2022 bit GISelShouldIgnore = 0; 2023} 2024 2025// Pat - A simple (but common) form of a pattern, which produces a simple result 2026// not needing a full list. 2027class Pat<dag pattern, dag result> : Pattern<pattern, [result]>; 2028 2029//===----------------------------------------------------------------------===// 2030// Complex pattern definitions. 2031// 2032 2033// Complex patterns, e.g. X86 addressing mode, requires pattern matching code 2034// in C++. Ty is the type of return value; NumOperands is the number of operands 2035// returned by the select function; SelectFunc is the name of the function used 2036// to pattern match the max. pattern; RootNodes are the list of possible root nodes 2037// of the sub-dags to match. 2038// e.g. X86 addressing mode - def addr : ComplexPattern<iPTR, 4, "SelectAddr", [add]>; 2039// 2040class ComplexPattern<ValueType ty, int numops, string fn, 2041 list<SDNode> roots = [], list<SDNodeProperty> props = [], 2042 int complexity = -1> { 2043 ValueType Ty = ty; 2044 int NumOperands = numops; 2045 string SelectFunc = fn; 2046 list<SDNode> RootNodes = roots; 2047 list<SDNodeProperty> Properties = props; 2048 int Complexity = complexity; 2049} 2050