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