xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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