1//===- TargetGlobalISel.td - Common code for GlobalISel ----*- 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 to support 10// SelectionDAG instruction selection patterns (specified in 11// TargetSelectionDAG.td) when generating GlobalISel instruction selectors. 12// 13// This is intended as a compatibility layer, to enable reuse of target 14// descriptions written for SelectionDAG without requiring explicit GlobalISel 15// support. It will eventually supersede SelectionDAG patterns. 16// 17//===----------------------------------------------------------------------===// 18 19// Declare that a generic Instruction is 'equivalent' to an SDNode, that is, 20// SelectionDAG patterns involving the SDNode can be transformed to match the 21// Instruction instead. 22class GINodeEquiv<Instruction i, SDNode node> { 23 Instruction I = i; 24 SDNode Node = node; 25 26 // SelectionDAG has separate nodes for atomic and non-atomic memory operations 27 // (ISD::LOAD, ISD::ATOMIC_LOAD, ISD::STORE, ISD::ATOMIC_STORE) but GlobalISel 28 // stores this information in the MachineMemoryOperand. 29 bit CheckMMOIsNonAtomic = false; 30 bit CheckMMOIsAtomic = false; 31 32 // SelectionDAG has one node for all loads and uses predicates to 33 // differentiate them. GlobalISel on the other hand uses separate opcodes. 34 // When this is true, the resulting opcode is G_LOAD/G_SEXTLOAD/G_ZEXTLOAD 35 // depending on the predicates on the node. 36 Instruction IfSignExtend = ?; 37 Instruction IfZeroExtend = ?; 38 39 // SelectionDAG has one setcc for all compares. This differentiates 40 // for G_ICMP and G_FCMP. 41 Instruction IfFloatingPoint = ?; 42 43 // SelectionDAG does not differentiate between convergent and non-convergent 44 // intrinsics. This specifies an alternate opcode for a convergent intrinsic. 45 Instruction IfConvergent = ?; 46} 47 48// These are defined in the same order as the G_* instructions. 49def : GINodeEquiv<G_ANYEXT, anyext>; 50def : GINodeEquiv<G_SEXT, sext>; 51def : GINodeEquiv<G_ZEXT, zext>; 52def : GINodeEquiv<G_TRUNC, trunc>; 53def : GINodeEquiv<G_BITCAST, bitconvert>; 54// G_INTTOPTR - SelectionDAG has no equivalent. 55// G_PTRTOINT - SelectionDAG has no equivalent. 56def : GINodeEquiv<G_CONSTANT, imm>; 57// timm must not be materialized and therefore has no GlobalISel equivalent 58def : GINodeEquiv<G_FCONSTANT, fpimm>; 59def : GINodeEquiv<G_IMPLICIT_DEF, undef>; 60def : GINodeEquiv<G_FRAME_INDEX, frameindex>; 61def : GINodeEquiv<G_BLOCK_ADDR, blockaddress>; 62def : GINodeEquiv<G_PTR_ADD, ptradd>; 63def : GINodeEquiv<G_ADD, add>; 64def : GINodeEquiv<G_SUB, sub>; 65def : GINodeEquiv<G_MUL, mul>; 66def : GINodeEquiv<G_UMULH, mulhu>; 67def : GINodeEquiv<G_SMULH, mulhs>; 68def : GINodeEquiv<G_SDIV, sdiv>; 69def : GINodeEquiv<G_UDIV, udiv>; 70def : GINodeEquiv<G_SREM, srem>; 71def : GINodeEquiv<G_UREM, urem>; 72def : GINodeEquiv<G_AND, and>; 73def : GINodeEquiv<G_OR, or>; 74def : GINodeEquiv<G_XOR, xor>; 75def : GINodeEquiv<G_SHL, shl>; 76def : GINodeEquiv<G_LSHR, srl>; 77def : GINodeEquiv<G_ASHR, sra>; 78def : GINodeEquiv<G_SADDSAT, saddsat>; 79def : GINodeEquiv<G_UADDSAT, uaddsat>; 80def : GINodeEquiv<G_SSUBSAT, ssubsat>; 81def : GINodeEquiv<G_USUBSAT, usubsat>; 82def : GINodeEquiv<G_SSHLSAT, sshlsat>; 83def : GINodeEquiv<G_USHLSAT, ushlsat>; 84def : GINodeEquiv<G_SMULFIX, smulfix>; 85def : GINodeEquiv<G_UMULFIX, umulfix>; 86def : GINodeEquiv<G_SMULFIXSAT, smulfixsat>; 87def : GINodeEquiv<G_UMULFIXSAT, umulfixsat>; 88def : GINodeEquiv<G_SDIVFIX, sdivfix>; 89def : GINodeEquiv<G_UDIVFIX, udivfix>; 90def : GINodeEquiv<G_SDIVFIXSAT, sdivfixsat>; 91def : GINodeEquiv<G_UDIVFIXSAT, udivfixsat>; 92def : GINodeEquiv<G_SELECT, select>; 93def : GINodeEquiv<G_SELECT, vselect>; 94def : GINodeEquiv<G_FNEG, fneg>; 95def : GINodeEquiv<G_FPEXT, fpextend>; 96def : GINodeEquiv<G_FPTRUNC, fpround>; 97def : GINodeEquiv<G_FPTOSI, fp_to_sint>; 98def : GINodeEquiv<G_FPTOUI, fp_to_uint>; 99def : GINodeEquiv<G_SITOFP, sint_to_fp>; 100def : GINodeEquiv<G_UITOFP, uint_to_fp>; 101def : GINodeEquiv<G_FADD, fadd>; 102def : GINodeEquiv<G_FSUB, fsub>; 103def : GINodeEquiv<G_FMA, fma>; 104def : GINodeEquiv<G_FMAD, fmad>; 105def : GINodeEquiv<G_FMUL, fmul>; 106def : GINodeEquiv<G_FDIV, fdiv>; 107def : GINodeEquiv<G_FREM, frem>; 108def : GINodeEquiv<G_FPOW, fpow>; 109def : GINodeEquiv<G_FEXP2, fexp2>; 110def : GINodeEquiv<G_FEXP10, fexp10>; 111def : GINodeEquiv<G_FLOG2, flog2>; 112def : GINodeEquiv<G_FLDEXP, fldexp>; 113def : GINodeEquiv<G_FCANONICALIZE, fcanonicalize>; 114def : GINodeEquiv<G_IS_FPCLASS, is_fpclass>; 115 116def : GINodeEquiv<G_INTRINSIC, intrinsic_wo_chain> { 117 let IfConvergent = G_INTRINSIC_CONVERGENT; 118} 119 120def : GINodeEquiv<G_GET_FPENV, get_fpenv>; 121def : GINodeEquiv<G_SET_FPENV, set_fpenv>; 122def : GINodeEquiv<G_RESET_FPENV, reset_fpenv>; 123def : GINodeEquiv<G_GET_FPMODE, get_fpmode>; 124def : GINodeEquiv<G_SET_FPMODE, set_fpmode>; 125def : GINodeEquiv<G_RESET_FPMODE, reset_fpmode>; 126 127// ISD::INTRINSIC_VOID can also be handled with G_INTRINSIC_W_SIDE_EFFECTS. 128let IfConvergent = G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS in { 129 def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_void>; 130 def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>; 131} 132 133def : GINodeEquiv<G_BR, br>; 134def : GINodeEquiv<G_BRCOND, brcond>; 135def : GINodeEquiv<G_BSWAP, bswap>; 136def : GINodeEquiv<G_BITREVERSE, bitreverse>; 137def : GINodeEquiv<G_FSHL, fshl>; 138def : GINodeEquiv<G_FSHR, fshr>; 139def : GINodeEquiv<G_CTLZ, ctlz>; 140def : GINodeEquiv<G_CTTZ, cttz>; 141def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>; 142def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>; 143def : GINodeEquiv<G_CTPOP, ctpop>; 144def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, extractelt>; 145def : GINodeEquiv<G_INSERT_VECTOR_ELT, vector_insert>; 146def : GINodeEquiv<G_CONCAT_VECTORS, concat_vectors>; 147def : GINodeEquiv<G_BUILD_VECTOR, build_vector>; 148def : GINodeEquiv<G_FCEIL, fceil>; 149def : GINodeEquiv<G_FCOS, fcos>; 150def : GINodeEquiv<G_FSIN, fsin>; 151def : GINodeEquiv<G_FTAN, ftan>; 152def : GINodeEquiv<G_FACOS, facos>; 153def : GINodeEquiv<G_FASIN, fasin>; 154def : GINodeEquiv<G_FATAN, fatan>; 155def : GINodeEquiv<G_FCOSH, fcosh>; 156def : GINodeEquiv<G_FSINH, fsinh>; 157def : GINodeEquiv<G_FTANH, ftanh>; 158def : GINodeEquiv<G_FABS, fabs>; 159def : GINodeEquiv<G_FSQRT, fsqrt>; 160def : GINodeEquiv<G_FFLOOR, ffloor>; 161def : GINodeEquiv<G_FRINT, frint>; 162def : GINodeEquiv<G_FNEARBYINT, fnearbyint>; 163def : GINodeEquiv<G_INTRINSIC_TRUNC, ftrunc>; 164def : GINodeEquiv<G_INTRINSIC_ROUND, fround>; 165def : GINodeEquiv<G_INTRINSIC_ROUNDEVEN, froundeven>; 166def : GINodeEquiv<G_INTRINSIC_LRINT, lrint>; 167def : GINodeEquiv<G_INTRINSIC_LLRINT, llrint>; 168def : GINodeEquiv<G_FCOPYSIGN, fcopysign>; 169def : GINodeEquiv<G_SMIN, smin>; 170def : GINodeEquiv<G_SMAX, smax>; 171def : GINodeEquiv<G_UMIN, umin>; 172def : GINodeEquiv<G_UMAX, umax>; 173def : GINodeEquiv<G_ABS, abs>; 174def : GINodeEquiv<G_FMINNUM, fminnum>; 175def : GINodeEquiv<G_FMAXNUM, fmaxnum>; 176def : GINodeEquiv<G_FMINNUM_IEEE, fminnum_ieee>; 177def : GINodeEquiv<G_FMAXNUM_IEEE, fmaxnum_ieee>; 178def : GINodeEquiv<G_FMAXIMUM, fmaximum>; 179def : GINodeEquiv<G_FMINIMUM, fminimum>; 180def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>; 181def : GINodeEquiv<G_READSTEADYCOUNTER, readsteadycounter>; 182def : GINodeEquiv<G_ROTR, rotr>; 183def : GINodeEquiv<G_ROTL, rotl>; 184def : GINodeEquiv<G_LROUND, lround>; 185def : GINodeEquiv<G_LLROUND, llround>; 186def : GINodeEquiv<G_VECREDUCE_FADD, vecreduce_fadd>; 187def : GINodeEquiv<G_VECREDUCE_FMAX, vecreduce_fmax>; 188def : GINodeEquiv<G_VECREDUCE_FMIN, vecreduce_fmin>; 189def : GINodeEquiv<G_VECREDUCE_FMAXIMUM, vecreduce_fmaximum>; 190def : GINodeEquiv<G_VECREDUCE_FMINIMUM, vecreduce_fminimum>; 191def : GINodeEquiv<G_VECREDUCE_UMIN, vecreduce_umin>; 192def : GINodeEquiv<G_VECREDUCE_UMAX, vecreduce_umax>; 193def : GINodeEquiv<G_VECREDUCE_SMIN, vecreduce_smin>; 194def : GINodeEquiv<G_VECREDUCE_SMAX, vecreduce_smax>; 195def : GINodeEquiv<G_VECREDUCE_ADD, vecreduce_add>; 196def : GINodeEquiv<G_VECTOR_COMPRESS, vector_compress>; 197 198def : GINodeEquiv<G_STRICT_FADD, strict_fadd>; 199def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>; 200def : GINodeEquiv<G_STRICT_FMUL, strict_fmul>; 201def : GINodeEquiv<G_STRICT_FDIV, strict_fdiv>; 202def : GINodeEquiv<G_STRICT_FREM, strict_frem>; 203def : GINodeEquiv<G_STRICT_FMA, strict_fma>; 204def : GINodeEquiv<G_STRICT_FSQRT, strict_fsqrt>; 205def : GINodeEquiv<G_STRICT_FLDEXP, strict_fldexp>; 206 207// Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some 208// complications that tablegen must take care of. For example, Predicates such 209// as isSignExtLoad require that this is not a perfect 1:1 mapping since a 210// sign-extending load is (G_SEXTLOAD x) in GlobalISel. Additionally, 211// G_LOAD handles both atomic and non-atomic loads where as SelectionDAG had 212// separate nodes for them. This GINodeEquiv maps the non-atomic loads to 213// G_LOAD with a non-atomic MachineMemOperand. 214def : GINodeEquiv<G_LOAD, ld> { 215 let CheckMMOIsNonAtomic = true; 216 let IfSignExtend = G_SEXTLOAD; 217 let IfZeroExtend = G_ZEXTLOAD; 218} 219 220def : GINodeEquiv<G_ICMP, setcc> { 221 let IfFloatingPoint = G_FCMP; 222} 223 224// Broadly speaking G_STORE is equivalent to ISD::STORE but there are some 225// complications that tablegen must take care of. For example, predicates such 226// as isTruncStore require that this is not a perfect 1:1 mapping since a 227// truncating store is (G_STORE (G_TRUNCATE x)) in GlobalISel. Additionally, 228// G_STORE handles both atomic and non-atomic stores where as SelectionDAG had 229// separate nodes for them. This GINodeEquiv maps the non-atomic stores to 230// G_STORE with a non-atomic MachineMemOperand. 231def : GINodeEquiv<G_STORE, st> { let CheckMMOIsNonAtomic = true; } 232def : GINodeEquiv<G_STORE, atomic_store> { 233 let CheckMMOIsNonAtomic = false; 234 let CheckMMOIsAtomic = true; 235} 236 237def : GINodeEquiv<G_LOAD, atomic_load> { 238 let CheckMMOIsNonAtomic = false; 239 let CheckMMOIsAtomic = true; 240 let IfSignExtend = G_SEXTLOAD; 241 let IfZeroExtend = G_ZEXTLOAD; 242} 243 244def : GINodeEquiv<G_ATOMIC_CMPXCHG, atomic_cmp_swap>; 245def : GINodeEquiv<G_ATOMICRMW_XCHG, atomic_swap>; 246def : GINodeEquiv<G_ATOMICRMW_ADD, atomic_load_add>; 247def : GINodeEquiv<G_ATOMICRMW_SUB, atomic_load_sub>; 248def : GINodeEquiv<G_ATOMICRMW_AND, atomic_load_and>; 249def : GINodeEquiv<G_ATOMICRMW_NAND, atomic_load_nand>; 250def : GINodeEquiv<G_ATOMICRMW_OR, atomic_load_or>; 251def : GINodeEquiv<G_ATOMICRMW_XOR, atomic_load_xor>; 252def : GINodeEquiv<G_ATOMICRMW_MIN, atomic_load_min>; 253def : GINodeEquiv<G_ATOMICRMW_MAX, atomic_load_max>; 254def : GINodeEquiv<G_ATOMICRMW_UMIN, atomic_load_umin>; 255def : GINodeEquiv<G_ATOMICRMW_UMAX, atomic_load_umax>; 256def : GINodeEquiv<G_ATOMICRMW_FADD, atomic_load_fadd>; 257def : GINodeEquiv<G_ATOMICRMW_FSUB, atomic_load_fsub>; 258def : GINodeEquiv<G_ATOMICRMW_FMAX, atomic_load_fmax>; 259def : GINodeEquiv<G_ATOMICRMW_FMIN, atomic_load_fmin>; 260def : GINodeEquiv<G_ATOMICRMW_UINC_WRAP, atomic_load_uinc_wrap>; 261def : GINodeEquiv<G_ATOMICRMW_UDEC_WRAP, atomic_load_udec_wrap>; 262def : GINodeEquiv<G_FENCE, atomic_fence>; 263def : GINodeEquiv<G_PREFETCH, prefetch>; 264def : GINodeEquiv<G_TRAP, trap>; 265def : GINodeEquiv<G_DEBUGTRAP, debugtrap>; 266def : GINodeEquiv<G_UBSANTRAP, ubsantrap>; 267 268// Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern. 269// Should be used on defs that subclass GIComplexOperandMatcher<>. 270class GIComplexPatternEquiv<ComplexPattern seldag> { 271 ComplexPattern SelDAGEquivalent = seldag; 272} 273 274// Specifies the GlobalISel equivalents for SelectionDAG's SDNodeXForm. 275// Should be used on defs that subclass GICustomOperandRenderer<>. 276class GISDNodeXFormEquiv<SDNodeXForm seldag> { 277 SDNodeXForm SelDAGEquivalent = seldag; 278} 279