SelectionDAGCompat.td 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. // Declare that a generic Instruction is 'equivalent' to an SDNode, that is,
  19. // SelectionDAG patterns involving the SDNode can be transformed to match the
  20. // Instruction instead.
  21. class GINodeEquiv<Instruction i, SDNode node> {
  22. Instruction I = i;
  23. SDNode Node = node;
  24. // SelectionDAG has separate nodes for atomic and non-atomic memory operations
  25. // (ISD::LOAD, ISD::ATOMIC_LOAD, ISD::STORE, ISD::ATOMIC_STORE) but GlobalISel
  26. // stores this information in the MachineMemoryOperand.
  27. bit CheckMMOIsNonAtomic = false;
  28. bit CheckMMOIsAtomic = false;
  29. // SelectionDAG has one node for all loads and uses predicates to
  30. // differentiate them. GlobalISel on the other hand uses separate opcodes.
  31. // When this is true, the resulting opcode is G_LOAD/G_SEXTLOAD/G_ZEXTLOAD
  32. // depending on the predicates on the node.
  33. Instruction IfSignExtend = ?;
  34. Instruction IfZeroExtend = ?;
  35. // SelectionDAG has one setcc for all compares. This differentiates
  36. // for G_ICMP and G_FCMP.
  37. Instruction IfFloatingPoint = ?;
  38. }
  39. // These are defined in the same order as the G_* instructions.
  40. def : GINodeEquiv<G_ANYEXT, anyext>;
  41. def : GINodeEquiv<G_SEXT, sext>;
  42. def : GINodeEquiv<G_ZEXT, zext>;
  43. def : GINodeEquiv<G_TRUNC, trunc>;
  44. def : GINodeEquiv<G_BITCAST, bitconvert>;
  45. // G_INTTOPTR - SelectionDAG has no equivalent.
  46. // G_PTRTOINT - SelectionDAG has no equivalent.
  47. def : GINodeEquiv<G_CONSTANT, imm>;
  48. // timm must not be materialized and therefore has no GlobalISel equivalent
  49. def : GINodeEquiv<G_FCONSTANT, fpimm>;
  50. def : GINodeEquiv<G_IMPLICIT_DEF, undef>;
  51. def : GINodeEquiv<G_FRAME_INDEX, frameindex>;
  52. def : GINodeEquiv<G_BLOCK_ADDR, blockaddress>;
  53. def : GINodeEquiv<G_PTR_ADD, ptradd>;
  54. def : GINodeEquiv<G_ADD, add>;
  55. def : GINodeEquiv<G_SUB, sub>;
  56. def : GINodeEquiv<G_MUL, mul>;
  57. def : GINodeEquiv<G_UMULH, mulhu>;
  58. def : GINodeEquiv<G_SMULH, mulhs>;
  59. def : GINodeEquiv<G_SDIV, sdiv>;
  60. def : GINodeEquiv<G_UDIV, udiv>;
  61. def : GINodeEquiv<G_SREM, srem>;
  62. def : GINodeEquiv<G_UREM, urem>;
  63. def : GINodeEquiv<G_AND, and>;
  64. def : GINodeEquiv<G_OR, or>;
  65. def : GINodeEquiv<G_XOR, xor>;
  66. def : GINodeEquiv<G_SHL, shl>;
  67. def : GINodeEquiv<G_LSHR, srl>;
  68. def : GINodeEquiv<G_ASHR, sra>;
  69. def : GINodeEquiv<G_SADDSAT, saddsat>;
  70. def : GINodeEquiv<G_UADDSAT, uaddsat>;
  71. def : GINodeEquiv<G_SSUBSAT, ssubsat>;
  72. def : GINodeEquiv<G_USUBSAT, usubsat>;
  73. def : GINodeEquiv<G_SSHLSAT, sshlsat>;
  74. def : GINodeEquiv<G_USHLSAT, ushlsat>;
  75. def : GINodeEquiv<G_SMULFIX, smulfix>;
  76. def : GINodeEquiv<G_UMULFIX, umulfix>;
  77. def : GINodeEquiv<G_SMULFIXSAT, smulfixsat>;
  78. def : GINodeEquiv<G_UMULFIXSAT, umulfixsat>;
  79. def : GINodeEquiv<G_SDIVFIX, sdivfix>;
  80. def : GINodeEquiv<G_UDIVFIX, udivfix>;
  81. def : GINodeEquiv<G_SDIVFIXSAT, sdivfixsat>;
  82. def : GINodeEquiv<G_UDIVFIXSAT, udivfixsat>;
  83. def : GINodeEquiv<G_SELECT, select>;
  84. def : GINodeEquiv<G_FNEG, fneg>;
  85. def : GINodeEquiv<G_FPEXT, fpextend>;
  86. def : GINodeEquiv<G_FPTRUNC, fpround>;
  87. def : GINodeEquiv<G_FPTOSI, fp_to_sint>;
  88. def : GINodeEquiv<G_FPTOUI, fp_to_uint>;
  89. def : GINodeEquiv<G_SITOFP, sint_to_fp>;
  90. def : GINodeEquiv<G_UITOFP, uint_to_fp>;
  91. def : GINodeEquiv<G_FADD, fadd>;
  92. def : GINodeEquiv<G_FSUB, fsub>;
  93. def : GINodeEquiv<G_FMA, fma>;
  94. def : GINodeEquiv<G_FMAD, fmad>;
  95. def : GINodeEquiv<G_FMUL, fmul>;
  96. def : GINodeEquiv<G_FDIV, fdiv>;
  97. def : GINodeEquiv<G_FREM, frem>;
  98. def : GINodeEquiv<G_FPOW, fpow>;
  99. def : GINodeEquiv<G_FEXP2, fexp2>;
  100. def : GINodeEquiv<G_FLOG2, flog2>;
  101. def : GINodeEquiv<G_FCANONICALIZE, fcanonicalize>;
  102. def : GINodeEquiv<G_IS_FPCLASS, is_fpclass>;
  103. def : GINodeEquiv<G_INTRINSIC, intrinsic_wo_chain>;
  104. // ISD::INTRINSIC_VOID can also be handled with G_INTRINSIC_W_SIDE_EFFECTS.
  105. def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_void>;
  106. def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>;
  107. def : GINodeEquiv<G_BR, br>;
  108. def : GINodeEquiv<G_BSWAP, bswap>;
  109. def : GINodeEquiv<G_BITREVERSE, bitreverse>;
  110. def : GINodeEquiv<G_FSHL, fshl>;
  111. def : GINodeEquiv<G_FSHR, fshr>;
  112. def : GINodeEquiv<G_CTLZ, ctlz>;
  113. def : GINodeEquiv<G_CTTZ, cttz>;
  114. def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>;
  115. def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>;
  116. def : GINodeEquiv<G_CTPOP, ctpop>;
  117. def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, extractelt>;
  118. def : GINodeEquiv<G_CONCAT_VECTORS, concat_vectors>;
  119. def : GINodeEquiv<G_BUILD_VECTOR, build_vector>;
  120. def : GINodeEquiv<G_FCEIL, fceil>;
  121. def : GINodeEquiv<G_FCOS, fcos>;
  122. def : GINodeEquiv<G_FSIN, fsin>;
  123. def : GINodeEquiv<G_FABS, fabs>;
  124. def : GINodeEquiv<G_FSQRT, fsqrt>;
  125. def : GINodeEquiv<G_FFLOOR, ffloor>;
  126. def : GINodeEquiv<G_FRINT, frint>;
  127. def : GINodeEquiv<G_FNEARBYINT, fnearbyint>;
  128. def : GINodeEquiv<G_INTRINSIC_TRUNC, ftrunc>;
  129. def : GINodeEquiv<G_INTRINSIC_ROUND, fround>;
  130. def : GINodeEquiv<G_INTRINSIC_LRINT, lrint>;
  131. def : GINodeEquiv<G_FCOPYSIGN, fcopysign>;
  132. def : GINodeEquiv<G_SMIN, smin>;
  133. def : GINodeEquiv<G_SMAX, smax>;
  134. def : GINodeEquiv<G_UMIN, umin>;
  135. def : GINodeEquiv<G_UMAX, umax>;
  136. def : GINodeEquiv<G_ABS, abs>;
  137. def : GINodeEquiv<G_FMINNUM, fminnum>;
  138. def : GINodeEquiv<G_FMAXNUM, fmaxnum>;
  139. def : GINodeEquiv<G_FMINNUM_IEEE, fminnum_ieee>;
  140. def : GINodeEquiv<G_FMAXNUM_IEEE, fmaxnum_ieee>;
  141. def : GINodeEquiv<G_FMAXIMUM, fmaximum>;
  142. def : GINodeEquiv<G_FMINIMUM, fminimum>;
  143. def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>;
  144. def : GINodeEquiv<G_ROTR, rotr>;
  145. def : GINodeEquiv<G_ROTL, rotl>;
  146. def : GINodeEquiv<G_LROUND, lround>;
  147. def : GINodeEquiv<G_LLROUND, llround>;
  148. def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
  149. def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;
  150. def : GINodeEquiv<G_STRICT_FMUL, strict_fmul>;
  151. def : GINodeEquiv<G_STRICT_FDIV, strict_fdiv>;
  152. def : GINodeEquiv<G_STRICT_FREM, strict_frem>;
  153. def : GINodeEquiv<G_STRICT_FMA, strict_fma>;
  154. def : GINodeEquiv<G_STRICT_FSQRT, strict_fsqrt>;
  155. // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some
  156. // complications that tablegen must take care of. For example, Predicates such
  157. // as isSignExtLoad require that this is not a perfect 1:1 mapping since a
  158. // sign-extending load is (G_SEXTLOAD x) in GlobalISel. Additionally,
  159. // G_LOAD handles both atomic and non-atomic loads where as SelectionDAG had
  160. // separate nodes for them. This GINodeEquiv maps the non-atomic loads to
  161. // G_LOAD with a non-atomic MachineMemOperand.
  162. def : GINodeEquiv<G_LOAD, ld> {
  163. let CheckMMOIsNonAtomic = true;
  164. let IfSignExtend = G_SEXTLOAD;
  165. let IfZeroExtend = G_ZEXTLOAD;
  166. }
  167. def : GINodeEquiv<G_ICMP, setcc> {
  168. let IfFloatingPoint = G_FCMP;
  169. }
  170. // Broadly speaking G_STORE is equivalent to ISD::STORE but there are some
  171. // complications that tablegen must take care of. For example, predicates such
  172. // as isTruncStore require that this is not a perfect 1:1 mapping since a
  173. // truncating store is (G_STORE (G_TRUNCATE x)) in GlobalISel. Additionally,
  174. // G_STORE handles both atomic and non-atomic stores where as SelectionDAG had
  175. // separate nodes for them. This GINodeEquiv maps the non-atomic stores to
  176. // G_STORE with a non-atomic MachineMemOperand.
  177. def : GINodeEquiv<G_STORE, st> { let CheckMMOIsNonAtomic = true; }
  178. def : GINodeEquiv<G_LOAD, atomic_load> {
  179. let CheckMMOIsNonAtomic = false;
  180. let CheckMMOIsAtomic = true;
  181. let IfSignExtend = G_SEXTLOAD;
  182. let IfZeroExtend = G_ZEXTLOAD;
  183. }
  184. // Operands are swapped for atomic_store vs. regular store
  185. def : GINodeEquiv<G_STORE, atomic_store> {
  186. let CheckMMOIsNonAtomic = false;
  187. let CheckMMOIsAtomic = true;
  188. }
  189. def : GINodeEquiv<G_ATOMIC_CMPXCHG, atomic_cmp_swap>;
  190. def : GINodeEquiv<G_ATOMICRMW_XCHG, atomic_swap>;
  191. def : GINodeEquiv<G_ATOMICRMW_ADD, atomic_load_add>;
  192. def : GINodeEquiv<G_ATOMICRMW_SUB, atomic_load_sub>;
  193. def : GINodeEquiv<G_ATOMICRMW_AND, atomic_load_and>;
  194. def : GINodeEquiv<G_ATOMICRMW_NAND, atomic_load_nand>;
  195. def : GINodeEquiv<G_ATOMICRMW_OR, atomic_load_or>;
  196. def : GINodeEquiv<G_ATOMICRMW_XOR, atomic_load_xor>;
  197. def : GINodeEquiv<G_ATOMICRMW_MIN, atomic_load_min>;
  198. def : GINodeEquiv<G_ATOMICRMW_MAX, atomic_load_max>;
  199. def : GINodeEquiv<G_ATOMICRMW_UMIN, atomic_load_umin>;
  200. def : GINodeEquiv<G_ATOMICRMW_UMAX, atomic_load_umax>;
  201. def : GINodeEquiv<G_ATOMICRMW_FADD, atomic_load_fadd>;
  202. def : GINodeEquiv<G_ATOMICRMW_FSUB, atomic_load_fsub>;
  203. def : GINodeEquiv<G_ATOMICRMW_FMAX, atomic_load_fmax>;
  204. def : GINodeEquiv<G_ATOMICRMW_FMIN, atomic_load_fmin>;
  205. def : GINodeEquiv<G_ATOMICRMW_UINC_WRAP, atomic_load_uinc_wrap>;
  206. def : GINodeEquiv<G_ATOMICRMW_UDEC_WRAP, atomic_load_udec_wrap>;
  207. def : GINodeEquiv<G_FENCE, atomic_fence>;
  208. // Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern.
  209. // Should be used on defs that subclass GIComplexOperandMatcher<>.
  210. class GIComplexPatternEquiv<ComplexPattern seldag> {
  211. ComplexPattern SelDAGEquivalent = seldag;
  212. }
  213. // Specifies the GlobalISel equivalents for SelectionDAG's SDNodeXForm.
  214. // Should be used on defs that subclass GICustomOperandRenderer<>.
  215. class GISDNodeXFormEquiv<SDNodeXForm seldag> {
  216. SDNodeXForm SelDAGEquivalent = seldag;
  217. }