xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td (revision 6966ac055c3b7a39266fb982493330df7a097997)
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 = 0;
30
31  // SelectionDAG has one node for all loads and uses predicates to
32  // differentiate them. GlobalISel on the other hand uses separate opcodes.
33  // When this is true, the resulting opcode is G_LOAD/G_SEXTLOAD/G_ZEXTLOAD
34  // depending on the predicates on the node.
35  Instruction IfSignExtend = ?;
36  Instruction IfZeroExtend = ?;
37}
38
39// These are defined in the same order as the G_* instructions.
40def : GINodeEquiv<G_ANYEXT, anyext>;
41def : GINodeEquiv<G_SEXT, sext>;
42def : GINodeEquiv<G_ZEXT, zext>;
43def : GINodeEquiv<G_TRUNC, trunc>;
44def : GINodeEquiv<G_BITCAST, bitconvert>;
45// G_INTTOPTR - SelectionDAG has no equivalent.
46// G_PTRTOINT - SelectionDAG has no equivalent.
47def : GINodeEquiv<G_CONSTANT, imm>;
48def : GINodeEquiv<G_FCONSTANT, fpimm>;
49def : GINodeEquiv<G_ADD, add>;
50def : GINodeEquiv<G_SUB, sub>;
51def : GINodeEquiv<G_MUL, mul>;
52def : GINodeEquiv<G_UMULH, mulhu>;
53def : GINodeEquiv<G_SMULH, mulhs>;
54def : GINodeEquiv<G_SDIV, sdiv>;
55def : GINodeEquiv<G_UDIV, udiv>;
56def : GINodeEquiv<G_SREM, srem>;
57def : GINodeEquiv<G_UREM, urem>;
58def : GINodeEquiv<G_AND, and>;
59def : GINodeEquiv<G_OR, or>;
60def : GINodeEquiv<G_XOR, xor>;
61def : GINodeEquiv<G_SHL, shl>;
62def : GINodeEquiv<G_LSHR, srl>;
63def : GINodeEquiv<G_ASHR, sra>;
64def : GINodeEquiv<G_SELECT, select>;
65def : GINodeEquiv<G_FNEG, fneg>;
66def : GINodeEquiv<G_FPEXT, fpextend>;
67def : GINodeEquiv<G_FPTRUNC, fpround>;
68def : GINodeEquiv<G_FPTOSI, fp_to_sint>;
69def : GINodeEquiv<G_FPTOUI, fp_to_uint>;
70def : GINodeEquiv<G_SITOFP, sint_to_fp>;
71def : GINodeEquiv<G_UITOFP, uint_to_fp>;
72def : GINodeEquiv<G_FADD, fadd>;
73def : GINodeEquiv<G_FSUB, fsub>;
74def : GINodeEquiv<G_FMA, fma>;
75def : GINodeEquiv<G_FMUL, fmul>;
76def : GINodeEquiv<G_FDIV, fdiv>;
77def : GINodeEquiv<G_FREM, frem>;
78def : GINodeEquiv<G_FPOW, fpow>;
79def : GINodeEquiv<G_FEXP2, fexp2>;
80def : GINodeEquiv<G_FLOG2, flog2>;
81def : GINodeEquiv<G_FCANONICALIZE, fcanonicalize>;
82def : GINodeEquiv<G_INTRINSIC, intrinsic_wo_chain>;
83// ISD::INTRINSIC_VOID can also be handled with G_INTRINSIC_W_SIDE_EFFECTS.
84def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_void>;
85def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>;
86def : GINodeEquiv<G_BR, br>;
87def : GINodeEquiv<G_BSWAP, bswap>;
88def : GINodeEquiv<G_CTLZ, ctlz>;
89def : GINodeEquiv<G_CTTZ, cttz>;
90def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>;
91def : GINodeEquiv<G_CTTZ_ZERO_UNDEF, cttz_zero_undef>;
92def : GINodeEquiv<G_CTPOP, ctpop>;
93def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>;
94def : GINodeEquiv<G_CONCAT_VECTORS, concat_vectors>;
95def : GINodeEquiv<G_FCEIL, fceil>;
96def : GINodeEquiv<G_FCOS, fcos>;
97def : GINodeEquiv<G_FSIN, fsin>;
98def : GINodeEquiv<G_FABS, fabs>;
99def : GINodeEquiv<G_FSQRT, fsqrt>;
100def : GINodeEquiv<G_FFLOOR, ffloor>;
101def : GINodeEquiv<G_FRINT, frint>;
102def : GINodeEquiv<G_FNEARBYINT, fnearbyint>;
103def : GINodeEquiv<G_SMIN, smin>;
104def : GINodeEquiv<G_SMAX, smax>;
105def : GINodeEquiv<G_UMIN, umin>;
106def : GINodeEquiv<G_UMAX, umax>;
107
108// Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some
109// complications that tablegen must take care of. For example, Predicates such
110// as isSignExtLoad require that this is not a perfect 1:1 mapping since a
111// sign-extending load is (G_SEXTLOAD x) in GlobalISel. Additionally,
112// G_LOAD handles both atomic and non-atomic loads where as SelectionDAG had
113// separate nodes for them. This GINodeEquiv maps the non-atomic loads to
114// G_LOAD with a non-atomic MachineMemOperand.
115def : GINodeEquiv<G_LOAD, ld> {
116  let CheckMMOIsNonAtomic = 1;
117  let IfSignExtend = G_SEXTLOAD;
118  let IfZeroExtend = G_ZEXTLOAD;
119}
120// Broadly speaking G_STORE is equivalent to ISD::STORE but there are some
121// complications that tablegen must take care of. For example, predicates such
122// as isTruncStore require that this is not a perfect 1:1 mapping since a
123// truncating store is (G_STORE (G_TRUNCATE x)) in GlobalISel. Additionally,
124// G_STORE handles both atomic and non-atomic stores where as SelectionDAG had
125// separate nodes for them. This GINodeEquiv maps the non-atomic stores to
126// G_STORE with a non-atomic MachineMemOperand.
127def : GINodeEquiv<G_STORE, st> { let CheckMMOIsNonAtomic = 1; }
128
129def : GINodeEquiv<G_ATOMIC_CMPXCHG, atomic_cmp_swap>;
130def : GINodeEquiv<G_ATOMICRMW_XCHG, atomic_swap>;
131def : GINodeEquiv<G_ATOMICRMW_ADD, atomic_load_add>;
132def : GINodeEquiv<G_ATOMICRMW_SUB, atomic_load_sub>;
133def : GINodeEquiv<G_ATOMICRMW_AND, atomic_load_and>;
134def : GINodeEquiv<G_ATOMICRMW_NAND, atomic_load_nand>;
135def : GINodeEquiv<G_ATOMICRMW_OR, atomic_load_or>;
136def : GINodeEquiv<G_ATOMICRMW_XOR, atomic_load_xor>;
137def : GINodeEquiv<G_ATOMICRMW_MIN, atomic_load_min>;
138def : GINodeEquiv<G_ATOMICRMW_MAX, atomic_load_max>;
139def : GINodeEquiv<G_ATOMICRMW_UMIN, atomic_load_umin>;
140def : GINodeEquiv<G_ATOMICRMW_UMAX, atomic_load_umax>;
141def : GINodeEquiv<G_FENCE, atomic_fence>;
142
143// Specifies the GlobalISel equivalents for SelectionDAG's ComplexPattern.
144// Should be used on defs that subclass GIComplexOperandMatcher<>.
145class GIComplexPatternEquiv<ComplexPattern seldag> {
146  ComplexPattern SelDAGEquivalent = seldag;
147}
148
149// Specifies the GlobalISel equivalents for SelectionDAG's SDNodeXForm.
150// Should be used on defs that subclass GICustomOperandRenderer<>.
151class GISDNodeXFormEquiv<SDNodeXForm seldag> {
152  SDNodeXForm SelDAGEquivalent = seldag;
153}
154