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