Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/llvm/Target/GlobalISel/SelectionDAGCompat.td is written in an unsupported language. File is not indexed.

0001 //===- TargetGlobalISel.td - Common code for GlobalISel ----*- tablegen -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the target-independent interfaces used to support
0010 // SelectionDAG instruction selection patterns (specified in
0011 // TargetSelectionDAG.td) when generating GlobalISel instruction selectors.
0012 //
0013 // This is intended as a compatibility layer, to enable reuse of target
0014 // descriptions written for SelectionDAG without requiring explicit GlobalISel
0015 // support.  It will eventually supersede SelectionDAG patterns.
0016 //
0017 //===----------------------------------------------------------------------===//
0018 
0019 // Declare that a generic Instruction is 'equivalent' to an SDNode, that is,
0020 // SelectionDAG patterns involving the SDNode can be transformed to match the
0021 // Instruction instead.
0022 class GINodeEquiv<Instruction i, SDNode node> {
0023   Instruction I = i;
0024   SDNode Node = node;
0025 
0026   // SelectionDAG has separate nodes for atomic and non-atomic memory operations
0027   // (ISD::LOAD, ISD::ATOMIC_LOAD, ISD::STORE, ISD::ATOMIC_STORE) but GlobalISel
0028   // stores this information in the MachineMemoryOperand.
0029   bit CheckMMOIsNonAtomic = false;
0030   bit CheckMMOIsAtomic = false;
0031 
0032   // SelectionDAG has one node for all loads and uses predicates to
0033   // differentiate them. GlobalISel on the other hand uses separate opcodes.
0034   // When this is true, the resulting opcode is G_LOAD/G_SEXTLOAD/G_ZEXTLOAD
0035   // depending on the predicates on the node.
0036   Instruction IfSignExtend = ?;
0037   Instruction IfZeroExtend = ?;
0038 
0039   // SelectionDAG has one setcc for all compares. This differentiates
0040   // for G_ICMP and G_FCMP.
0041   Instruction IfFloatingPoint = ?;
0042 
0043   // SelectionDAG does not differentiate between convergent and non-convergent
0044   // intrinsics. This specifies an alternate opcode for a convergent intrinsic.
0045   Instruction IfConvergent = ?;
0046 }
0047 
0048 // These are defined in the same order as the G_* instructions.
0049 def : GINodeEquiv<G_ANYEXT, anyext>;
0050 def : GINodeEquiv<G_SEXT, sext>;
0051 def : GINodeEquiv<G_SEXT_INREG, sext_inreg>;
0052 def : GINodeEquiv<G_ZEXT, zext>;
0053 def : GINodeEquiv<G_TRUNC, trunc>;
0054 def : GINodeEquiv<G_BITCAST, bitconvert>;
0055 // G_INTTOPTR - SelectionDAG has no equivalent.
0056 // G_PTRTOINT - SelectionDAG has no equivalent.
0057 def : GINodeEquiv<G_CONSTANT, imm>;
0058 // timm must not be materialized and therefore has no GlobalISel equivalent
0059 def : GINodeEquiv<G_FCONSTANT, fpimm>;
0060 def : GINodeEquiv<G_IMPLICIT_DEF, undef>;
0061 def : GINodeEquiv<G_FRAME_INDEX, frameindex>;
0062 def : GINodeEquiv<G_BLOCK_ADDR, blockaddress>;
0063 def : GINodeEquiv<G_PTR_ADD, ptradd>;
0064 def : GINodeEquiv<G_ADD, add>;
0065 def : GINodeEquiv<G_SUB, sub>;
0066 def : GINodeEquiv<G_MUL, mul>;
0067 def : GINodeEquiv<G_UMULH, mulhu>;
0068 def : GINodeEquiv<G_SMULH, mulhs>;
0069 def : GINodeEquiv<G_SDIV, sdiv>;
0070 def : GINodeEquiv<G_UDIV, udiv>;
0071 def : GINodeEquiv<G_SREM, srem>;
0072 def : GINodeEquiv<G_UREM, urem>;
0073 def : GINodeEquiv<G_SDIVREM, sdivrem>;
0074 def : GINodeEquiv<G_UDIVREM, udivrem>;
0075 def : GINodeEquiv<G_AND, and>;
0076 def : GINodeEquiv<G_OR, or>;
0077 def : GINodeEquiv<G_XOR, xor>;
0078 def : GINodeEquiv<G_SHL, shl>;
0079 def : GINodeEquiv<G_LSHR, srl>;
0080 def : GINodeEquiv<G_ASHR, sra>;
0081 def : GINodeEquiv<G_SADDSAT, saddsat>;
0082 def : GINodeEquiv<G_UADDSAT, uaddsat>;
0083 def : GINodeEquiv<G_SSUBSAT, ssubsat>;
0084 def : GINodeEquiv<G_USUBSAT, usubsat>;
0085 def : GINodeEquiv<G_SSHLSAT, sshlsat>;
0086 def : GINodeEquiv<G_USHLSAT, ushlsat>;
0087 def : GINodeEquiv<G_SMULFIX, smulfix>;
0088 def : GINodeEquiv<G_UMULFIX, umulfix>;
0089 def : GINodeEquiv<G_SMULFIXSAT, smulfixsat>;
0090 def : GINodeEquiv<G_UMULFIXSAT, umulfixsat>;
0091 def : GINodeEquiv<G_SDIVFIX, sdivfix>;
0092 def : GINodeEquiv<G_UDIVFIX, udivfix>;
0093 def : GINodeEquiv<G_SDIVFIXSAT, sdivfixsat>;
0094 def : GINodeEquiv<G_UDIVFIXSAT, udivfixsat>;
0095 def : GINodeEquiv<G_SELECT, select>;
0096 def : GINodeEquiv<G_SELECT, vselect>;
0097 def : GINodeEquiv<G_FNEG, fneg>;
0098 def : GINodeEquiv<G_FPEXT, fpextend>;
0099 def : GINodeEquiv<G_FPTRUNC, fpround>;
0100 def : GINodeEquiv<G_FPTOSI, fp_to_sint>;
0101 def : GINodeEquiv<G_FPTOUI, fp_to_uint>;
0102 def : GINodeEquiv<G_SITOFP, sint_to_fp>;
0103 def : GINodeEquiv<G_UITOFP, uint_to_fp>;
0104 def : GINodeEquiv<G_FPTOSI_SAT, fp_to_sint_sat_gi>;
0105 def : GINodeEquiv<G_FPTOUI_SAT, fp_to_uint_sat_gi>;
0106 def : GINodeEquiv<G_FADD, fadd>;
0107 def : GINodeEquiv<G_FSUB, fsub>;
0108 def : GINodeEquiv<G_FMA, fma>;
0109 def : GINodeEquiv<G_FMAD, fmad>;
0110 def : GINodeEquiv<G_FMUL, fmul>;
0111 def : GINodeEquiv<G_FDIV, fdiv>;
0112 def : GINodeEquiv<G_FREM, frem>;
0113 def : GINodeEquiv<G_FPOW, fpow>;
0114 def : GINodeEquiv<G_FEXP2, fexp2>;
0115 def : GINodeEquiv<G_FEXP10, fexp10>;
0116 def : GINodeEquiv<G_FLOG2, flog2>;
0117 def : GINodeEquiv<G_FLDEXP, fldexp>;
0118 def : GINodeEquiv<G_FCANONICALIZE, fcanonicalize>;
0119 def : GINodeEquiv<G_IS_FPCLASS, is_fpclass>;
0120 
0121 def : GINodeEquiv<G_INTRINSIC, intrinsic_wo_chain> {
0122   let IfConvergent = G_INTRINSIC_CONVERGENT;
0123 }
0124 
0125 def : GINodeEquiv<G_GET_FPENV, get_fpenv>;
0126 def : GINodeEquiv<G_SET_FPENV, set_fpenv>;
0127 def : GINodeEquiv<G_RESET_FPENV, reset_fpenv>;
0128 def : GINodeEquiv<G_GET_FPMODE, get_fpmode>;
0129 def : GINodeEquiv<G_SET_FPMODE, set_fpmode>;
0130 def : GINodeEquiv<G_RESET_FPMODE, reset_fpmode>;
0131 
0132 // ISD::INTRINSIC_VOID can also be handled with G_INTRINSIC_W_SIDE_EFFECTS.
0133 let IfConvergent = G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS in {
0134   def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_void>;
0135   def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>;
0136 }
0137 
0138 def : GINodeEquiv<G_BR, br>;
0139 def : GINodeEquiv<G_BRCOND, brcond>;
0140 def : GINodeEquiv<G_BSWAP, bswap>;
0141 def : GINodeEquiv<G_BITREVERSE, bitreverse>;
0142 def : GINodeEquiv<G_FSHL, fshl>;
0143 def : GINodeEquiv<G_FSHR, fshr>;
0144 def : GINodeEquiv<G_CTLZ, ctlz>;
0145 def : GINodeEquiv<G_CTTZ, cttz>;
0146 def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>;
0147 def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>;
0148 def : GINodeEquiv<G_CTPOP, ctpop>;
0149 def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, extractelt>;
0150 def : GINodeEquiv<G_INSERT_VECTOR_ELT, vector_insert>;
0151 def : GINodeEquiv<G_CONCAT_VECTORS, concat_vectors>;
0152 def : GINodeEquiv<G_BUILD_VECTOR, build_vector>;
0153 def : GINodeEquiv<G_EXTRACT_SUBVECTOR, extract_subvector>;
0154 def : GINodeEquiv<G_SPLAT_VECTOR, splat_vector>;
0155 def : GINodeEquiv<G_FCEIL, fceil>;
0156 def : GINodeEquiv<G_FCOS, fcos>;
0157 def : GINodeEquiv<G_FSIN, fsin>;
0158 def : GINodeEquiv<G_FTAN, ftan>;
0159 def : GINodeEquiv<G_FACOS, facos>;
0160 def : GINodeEquiv<G_FASIN, fasin>;
0161 def : GINodeEquiv<G_FATAN, fatan>;
0162 def : GINodeEquiv<G_FATAN2, fatan2>;
0163 def : GINodeEquiv<G_FCOSH, fcosh>;
0164 def : GINodeEquiv<G_FSINH, fsinh>;
0165 def : GINodeEquiv<G_FTANH, ftanh>;
0166 def : GINodeEquiv<G_FABS, fabs>;
0167 def : GINodeEquiv<G_FSQRT, fsqrt>;
0168 def : GINodeEquiv<G_FFLOOR, ffloor>;
0169 def : GINodeEquiv<G_FRINT, frint>;
0170 def : GINodeEquiv<G_FNEARBYINT, fnearbyint>;
0171 def : GINodeEquiv<G_INTRINSIC_TRUNC, ftrunc>;
0172 def : GINodeEquiv<G_INTRINSIC_FPTRUNC_ROUND, fptrunc_round>;
0173 def : GINodeEquiv<G_INTRINSIC_ROUND, fround>;
0174 def : GINodeEquiv<G_INTRINSIC_ROUNDEVEN, froundeven>;
0175 def : GINodeEquiv<G_INTRINSIC_LRINT, lrint>;
0176 def : GINodeEquiv<G_INTRINSIC_LLRINT, llrint>;
0177 def : GINodeEquiv<G_FCOPYSIGN, fcopysign>;
0178 def : GINodeEquiv<G_SMIN, smin>;
0179 def : GINodeEquiv<G_SMAX, smax>;
0180 def : GINodeEquiv<G_UMIN, umin>;
0181 def : GINodeEquiv<G_UMAX, umax>;
0182 def : GINodeEquiv<G_ABS, abs>;
0183 def : GINodeEquiv<G_FMINNUM, fminnum>;
0184 def : GINodeEquiv<G_FMAXNUM, fmaxnum>;
0185 def : GINodeEquiv<G_FMINNUM_IEEE, fminnum_ieee>;
0186 def : GINodeEquiv<G_FMAXNUM_IEEE, fmaxnum_ieee>;
0187 def : GINodeEquiv<G_FMAXIMUM, fmaximum>;
0188 def : GINodeEquiv<G_FMINIMUM, fminimum>;
0189 def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>;
0190 def : GINodeEquiv<G_READSTEADYCOUNTER, readsteadycounter>;
0191 def : GINodeEquiv<G_ROTR, rotr>;
0192 def : GINodeEquiv<G_ROTL, rotl>;
0193 def : GINodeEquiv<G_LROUND, lround>;
0194 def : GINodeEquiv<G_LLROUND, llround>;
0195 def : GINodeEquiv<G_VECREDUCE_FADD, vecreduce_fadd>;
0196 def : GINodeEquiv<G_VECREDUCE_FMAX, vecreduce_fmax>;
0197 def : GINodeEquiv<G_VECREDUCE_FMIN, vecreduce_fmin>;
0198 def : GINodeEquiv<G_VECREDUCE_FMAXIMUM, vecreduce_fmaximum>;
0199 def : GINodeEquiv<G_VECREDUCE_FMINIMUM, vecreduce_fminimum>;
0200 def : GINodeEquiv<G_VECREDUCE_UMIN, vecreduce_umin>;
0201 def : GINodeEquiv<G_VECREDUCE_UMAX, vecreduce_umax>;
0202 def : GINodeEquiv<G_VECREDUCE_SMIN, vecreduce_smin>;
0203 def : GINodeEquiv<G_VECREDUCE_SMAX, vecreduce_smax>;
0204 def : GINodeEquiv<G_VECREDUCE_ADD, vecreduce_add>;
0205 def : GINodeEquiv<G_VECTOR_COMPRESS, vector_compress>;
0206 
0207 def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
0208 def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;
0209 def : GINodeEquiv<G_STRICT_FMUL, strict_fmul>;
0210 def : GINodeEquiv<G_STRICT_FDIV, strict_fdiv>;
0211 def : GINodeEquiv<G_STRICT_FREM, strict_frem>;
0212 def : GINodeEquiv<G_STRICT_FMA, strict_fma>;
0213 def : GINodeEquiv<G_STRICT_FSQRT, strict_fsqrt>;
0214 def : GINodeEquiv<G_STRICT_FLDEXP, strict_fldexp>;
0215 
0216 // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some
0217 // complications that tablegen must take care of. For example, Predicates such
0218 // as isSignExtLoad require that this is not a perfect 1:1 mapping since a
0219 // sign-extending load is (G_SEXTLOAD x) in GlobalISel. Additionally,
0220 // G_LOAD handles both atomic and non-atomic loads where as SelectionDAG had
0221 // separate nodes for them. This GINodeEquiv maps the non-atomic loads to
0222 // G_LOAD with a non-atomic MachineMemOperand.
0223 def : GINodeEquiv<G_LOAD, ld> {
0224   let CheckMMOIsNonAtomic = true;
0225   let IfSignExtend = G_SEXTLOAD;
0226   let IfZeroExtend = G_ZEXTLOAD;
0227 }
0228 
0229 def : GINodeEquiv<G_ICMP, setcc> {
0230   let IfFloatingPoint = G_FCMP;
0231 }
0232 
0233 // Broadly speaking G_STORE is equivalent to ISD::STORE but there are some
0234 // complications that tablegen must take care of. For example, predicates such
0235 // as isTruncStore require that this is not a perfect 1:1 mapping since a
0236 // truncating store is (G_STORE (G_TRUNCATE x)) in GlobalISel. Additionally,
0237 // G_STORE handles both atomic and non-atomic stores where as SelectionDAG had
0238 // separate nodes for them. This GINodeEquiv maps the non-atomic stores to
0239 // G_STORE with a non-atomic MachineMemOperand.
0240 def : GINodeEquiv<G_STORE, st> { let CheckMMOIsNonAtomic = true; }
0241 def : GINodeEquiv<G_STORE, atomic_store> {
0242   let CheckMMOIsNonAtomic = false;
0243   let CheckMMOIsAtomic = true;
0244 }
0245 
0246 def : GINodeEquiv<G_LOAD, atomic_load> {
0247   let CheckMMOIsNonAtomic = false;
0248   let CheckMMOIsAtomic = true;
0249   let IfSignExtend = G_SEXTLOAD;
0250   let IfZeroExtend = G_ZEXTLOAD;
0251 }
0252 
0253 def : GINodeEquiv<G_ATOMIC_CMPXCHG, atomic_cmp_swap>;
0254 def : GINodeEquiv<G_ATOMICRMW_XCHG, atomic_swap>;
0255 def : GINodeEquiv<G_ATOMICRMW_ADD, atomic_load_add>;
0256 def : GINodeEquiv<G_ATOMICRMW_SUB, atomic_load_sub>;
0257 def : GINodeEquiv<G_ATOMICRMW_AND, atomic_load_and>;
0258 def : GINodeEquiv<G_ATOMICRMW_NAND, atomic_load_nand>;
0259 def : GINodeEquiv<G_ATOMICRMW_OR, atomic_load_or>;
0260 def : GINodeEquiv<G_ATOMICRMW_XOR, atomic_load_xor>;
0261 def : GINodeEquiv<G_ATOMICRMW_MIN, atomic_load_min>;
0262 def : GINodeEquiv<G_ATOMICRMW_MAX, atomic_load_max>;
0263 def : GINodeEquiv<G_ATOMICRMW_UMIN, atomic_load_umin>;
0264 def : GINodeEquiv<G_ATOMICRMW_UMAX, atomic_load_umax>;
0265 def : GINodeEquiv<G_ATOMICRMW_FADD, atomic_load_fadd>;
0266 def : GINodeEquiv<G_ATOMICRMW_FSUB, atomic_load_fsub>;
0267 def : GINodeEquiv<G_ATOMICRMW_FMAX, atomic_load_fmax>;
0268 def : GINodeEquiv<G_ATOMICRMW_FMIN, atomic_load_fmin>;
0269 def : GINodeEquiv<G_ATOMICRMW_UINC_WRAP, atomic_load_uinc_wrap>;
0270 def : GINodeEquiv<G_ATOMICRMW_UDEC_WRAP, atomic_load_udec_wrap>;
0271 def : GINodeEquiv<G_ATOMICRMW_USUB_COND, atomic_load_usub_cond>;
0272 def : GINodeEquiv<G_ATOMICRMW_USUB_SAT, atomic_load_usub_sat>;
0273 def : GINodeEquiv<G_FENCE, atomic_fence>;
0274 def : GINodeEquiv<G_PREFETCH, prefetch>;
0275 def : GINodeEquiv<G_TRAP, trap>;
0276 def : GINodeEquiv<G_DEBUGTRAP, debugtrap>;
0277 def : GINodeEquiv<G_UBSANTRAP, ubsantrap>;
0278 
0279 // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern.
0280 // Should be used on defs that subclass GIComplexOperandMatcher<>.
0281 class GIComplexPatternEquiv<ComplexPattern seldag> {
0282   ComplexPattern SelDAGEquivalent = seldag;
0283 }
0284 
0285 // Specifies the GlobalISel equivalents for SelectionDAG's SDNodeXForm.
0286 // Should be used on defs that subclass GICustomOperandRenderer<>.
0287 class GISDNodeXFormEquiv<SDNodeXForm seldag> {
0288   SDNodeXForm SelDAGEquivalent = seldag;
0289 }