1 //===-- AMDGPUGIsel.td - AMDGPU GlobalISel Patterns---------*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
8 // This files contains patterns that should only be used by GlobalISel. For
9 // example patterns for V_* instructions that have S_* equivalents.
10 // SelectionDAG does not support selecting V_* instructions.
11 //===----------------------------------------------------------------------===//
15 def p0 : PtrValueType<i64, 0>;
16 def p1 : PtrValueType<i64, 1>;
17 def p4 : PtrValueType<i64, 4>;
19 def sd_vsrc0 : ComplexPattern<i32, 1, "">;
21 GIComplexOperandMatcher<s32, "selectVSRC0">,
22 GIComplexPatternEquiv<sd_vsrc0>;
24 def sd_vcsrc : ComplexPattern<i32, 1, "">;
26 GIComplexOperandMatcher<s32, "selectVCSRC">,
27 GIComplexPatternEquiv<sd_vcsrc>;
30 GIComplexOperandMatcher<s32, "selectVOP3Mods0">,
31 GIComplexPatternEquiv<VOP3Mods0>;
34 GIComplexOperandMatcher<s32, "selectVOP3Mods">,
35 GIComplexPatternEquiv<VOP3Mods>;
38 GIComplexOperandMatcher<s32, "selectVOP3OMods">,
39 GIComplexPatternEquiv<VOP3OMods>;
42 GIComplexOperandMatcher<s64, "selectSmrdImm">,
43 GIComplexPatternEquiv<SMRDImm>;
46 GIComplexOperandMatcher<s64, "selectSmrdImm32">,
47 GIComplexPatternEquiv<SMRDImm32>;
50 GIComplexOperandMatcher<s64, "selectSmrdSgpr">,
51 GIComplexPatternEquiv<SMRDSgpr>;
54 GIComplexOperandMatcher<s64, "selectFlatOffset">,
55 GIComplexPatternEquiv<FLATOffset>;
56 def gi_flat_offset_signed :
57 GIComplexOperandMatcher<s64, "selectFlatOffsetSigned">,
58 GIComplexPatternEquiv<FLATOffsetSigned>;
60 def gi_mubuf_scratch_offset :
61 GIComplexOperandMatcher<s32, "selectMUBUFScratchOffset">,
62 GIComplexPatternEquiv<MUBUFScratchOffset>;
63 def gi_mubuf_scratch_offen :
64 GIComplexOperandMatcher<s32, "selectMUBUFScratchOffen">,
65 GIComplexPatternEquiv<MUBUFScratchOffen>;
69 SDPatternOperator node,
72 ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat <
74 (dst_vt (node (src0_vt SReg_32:$src0), (src1_vt SReg_32:$src1))),
75 (inst src0_vt:$src0, src1_vt:$src1)
79 SDPatternOperator node,
82 ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat <
84 (dst_vt (node (src0_vt (sd_vsrc0 src0_vt:$src0)), (src1_vt VGPR_32:$src1))),
85 (inst src0_vt:$src0, src1_vt:$src1)
88 class GISelVop2CommutePat <
89 SDPatternOperator node,
92 ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat <
94 (dst_vt (node (src1_vt VGPR_32:$src1), (src0_vt (sd_vsrc0 src0_vt:$src0)))),
95 (inst src0_vt:$src0, src1_vt:$src1)
99 SDPatternOperator node,
102 ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat <
104 (dst_vt (node (src0_vt (sd_vcsrc src0_vt:$src0)), (src1_vt (sd_vcsrc src1_vt:$src1)))),
105 (inst src0_vt:$src0, src1_vt:$src1)
108 class GISelVop3Pat2CommutePat <
109 SDPatternOperator node,
112 ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat <
114 (dst_vt (node (src0_vt (sd_vcsrc src0_vt:$src0)), (src1_vt (sd_vcsrc src1_vt:$src1)))),
115 (inst src0_vt:$src1, src1_vt:$src0)
118 class GISelVop3Pat2ModsPat <
119 SDPatternOperator node,
122 ValueType src0_vt = dst_vt, ValueType src1_vt = src0_vt> : GCNPat <
124 (dst_vt (node (src0_vt (VOP3Mods0 src0_vt:$src0, i32:$src0_modifiers, i1:$clamp, i32:$omods)),
125 (src1_vt (VOP3Mods src1_vt:$src1, i32:$src1_modifiers)))),
126 (inst i32:$src0_modifiers, src0_vt:$src0,
127 i32:$src1_modifiers, src1_vt:$src1, $clamp, $omods)
130 multiclass GISelVop2IntrPat <
131 SDPatternOperator node, Instruction inst,
132 ValueType dst_vt, ValueType src_vt = dst_vt> {
134 def : GISelVop2Pat <node, inst, dst_vt, src_vt>;
136 // FIXME: Intrinsics aren't marked as commutable, so we need to add an explcit
137 // pattern to handle commuting. This is another reason why legalizing to a
138 // generic machine instruction may be better that matching the intrinsic
140 def : GISelVop2CommutePat <node, inst, dst_vt, src_vt>;
143 def : GISelSop2Pat <or, S_OR_B32, i32>;
144 def : GISelVop2Pat <or, V_OR_B32_e32, i32>;
146 // FIXME: We can't re-use SelectionDAG patterns here because they match
147 // against a custom SDNode and we would need to create a generic machine
148 // instruction that is equivalent to the custom SDNode. This would also require
149 // us to custom legalize the intrinsic to the new generic machine instruction,
150 // but I can't get custom legalizing of intrinsic to work and I'm not sure if
151 // this is even supported yet.
152 def : GISelVop3Pat2ModsPat <
153 int_amdgcn_cvt_pkrtz, V_CVT_PKRTZ_F16_F32_e64, v2f16, f32>;
155 defm : GISelVop2IntrPat <int_maxnum, V_MAX_F32_e32, f32>;
156 def : GISelVop3Pat2ModsPat <int_maxnum, V_MAX_F64, f64>;
157 defm : GISelVop2IntrPat <int_minnum, V_MIN_F32_e32, f32>;
158 def : GISelVop3Pat2ModsPat <int_minnum, V_MIN_F64, f64>;
160 // Since GlobalISel is more flexible then SelectionDAG, I think we can get
161 // away with adding patterns for integer types and not legalizing all
162 // loads and stores to vector types. This should help simplify the load/store
164 foreach Ty = [i64, p0, p1, p4] in {
165 defm : SMRD_Pattern <"S_LOAD_DWORDX2", Ty>;