1 // RUN: llvm-tblgen %s -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common -o - | FileCheck %s
3 // Verify that all MI predicates are enumerated.
5 // CHECK: // PatFrag predicates.
7 // CHECK-NEXT: GIPFP_MI_Predicate_and_or_pat = GIPFP_MI_Invalid + 1,
8 // CHECK-NEXT: GIPFP_MI_Predicate_or_oneuse,
9 // CHECK-NEXT: GIPFP_MI_Predicate_patfrags_test_pat,
10 // CHECK-NEXT: GIPFP_MI_Predicate_sub3_pat,
13 // Verify that we emit cases for all MI predicates.
15 // CHECK: bool MyTargetInstructionSelector::testMIPredicate_MI(
16 // CHECK: case GIPFP_MI_Predicate_and_or_pat: {
17 // CHECK: llvm_unreachable("GISelPredicateCode should have returned");
18 // CHECK: case GIPFP_MI_Predicate_or_oneuse: {
19 // CHECK: llvm_unreachable("GISelPredicateCode should have returned");
20 // CHECK: case GIPFP_MI_Predicate_patfrags_test_pat: {
21 // CHECK: llvm_unreachable("GISelPredicateCode should have returned");
22 // CHECK: case GIPFP_MI_Predicate_sub3_pat: {
23 // CHECK: llvm_unreachable("GISelPredicateCode should have returned");
25 include "llvm/Target/Target.td"
26 include "GlobalISelEmitterCommon.td"
28 // Boilerplate code for setting up some registers with subregs.
29 class MyReg<string n, list<Register> subregs = []>
31 let SubRegs = subregs;
34 class MyClass<int size, list<ValueType> types, dag registers>
35 : RegisterClass<"Test", types, size, registers> {
39 def sub0 : SubRegIndex<16>;
40 def sub1 : SubRegIndex<16, 16>;
43 def SRegs : MyClass<16, [i16], (sequence "S%u", 0, 1)>;
45 let SubRegIndices = [sub0, sub1] in {
46 def D0 : MyReg<"d0", [S0, S1]>;
49 def DRegs : MyClass<32, [i32], (sequence "D%u", 0, 0)>;
50 def DOP : RegisterOperand<DRegs>;
51 def AND_OR : I<(outs DRegs:$dst), (ins DOP:$src0, DOP:$src1, DOP:$src2), []>;
53 def or_oneuse : PatFrag<
54 (ops node:$x, node:$y),
55 (or node:$x, node:$y), [{ return foo(); }]> {
56 let GISelPredicateCode = [{
57 return MRI.hasOneNonDBGUse(MI.getOperand(0).getReg());
62 // FIXME: GISelPredicateCode ignored if DAG predicate not set.
63 def and_or_pat : PatFrag<
64 (ops node:$x, node:$y, node:$z),
65 (and (or node:$x, node:$y), node:$z), [{ return foo(); }]> {
66 let GISelPredicateCode = [{
67 return doesComplexCheck(MI);
69 let PredicateCodeUsesOperands = 1;
72 // CHECK: GIM_Try, /*On fail goto*//*Label 0*/ 99, // Rule ID 6 //
73 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
74 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND,
75 // CHECK-NEXT: // MIs[0] dst
76 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
77 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID,
78 // CHECK-NEXT: // MIs[0] src2
79 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
80 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/1, /*StoreIdx*/2, // Name : pred:3:z
81 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/Test::DRegsRegClassID,
82 // CHECK-NEXT: // MIs[0] Operand 2
83 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
84 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, // MIs[1]
85 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
86 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_OR,
87 // CHECK-NEXT: // MIs[1] Operand 0
88 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
89 // CHECK-NEXT: // MIs[1] src0
90 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
91 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/1, /*StoreIdx*/0, // Name : pred:3:x
92 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID,
93 // CHECK-NEXT: // MIs[1] src1
94 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
95 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:3:y
96 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID,
97 // CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat,
98 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
99 // CHECK-NEXT: // (and:{ *:[i32] } DOP:{ *:[i32] }:$src2:$pred:3:z, (or:{ *:[i32] } DOP:{ *:[i32] }:$src0:$pred:3:x, DOP:{ *:[i32] }:$src1:$pred:3:y))<<P:3:Predicate_and_or_pat>> => (AND_OR:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1, DOP:{ *:[i32] }:$src2)
100 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR,
102 // CHECK: GIM_Try, /*On fail goto*//*Label 1*/ 198, // Rule ID 3 //
103 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
104 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND,
105 // CHECK-NEXT: // MIs[0] dst
106 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
107 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID,
108 // CHECK-NEXT: // MIs[0] Operand 1
109 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
110 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
111 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
112 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_OR,
113 // CHECK-NEXT: // MIs[1] Operand 0
114 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
115 // CHECK-NEXT: // MIs[1] src0
116 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
117 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/1, /*StoreIdx*/0, // Name : pred:3:x
118 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID,
119 // CHECK-NEXT: // MIs[1] src1
120 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
121 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:3:y
122 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID,
123 // CHECK-NEXT: // MIs[0] src2
124 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
125 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/2, /*StoreIdx*/2, // Name : pred:3:z
126 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/Test::DRegsRegClassID,
127 // CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat,
128 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
129 // CHECK-NEXT: // (and:{ *:[i32] } (or:{ *:[i32] } DOP:{ *:[i32] }:$src0:$pred:3:x, DOP:{ *:[i32] }:$src1:$pred:3:y), DOP:{ *:[i32] }:$src2:$pred:3:z)<<P:3:Predicate_and_or_pat>> => (AND_OR:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1, DOP:{ *:[i32] }:$src2)
130 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR,
132 // Test commutative, standalone pattern.
134 (i32 (and_or_pat DOP:$src0, DOP:$src1, DOP:$src2)),
135 (AND_OR DOP:$src0, DOP:$src1, DOP:$src2)
139 def sub3_pat : PatFrag<
140 (ops node:$x, node:$y, node:$z),
141 (sub (sub node:$x, node:$y), node:$z), [{ return foo(); }]> {
142 let GISelPredicateCode = [{
143 return doesComplexCheck(MI);
146 let PredicateCodeUsesOperands = 1;
149 // CHECK: GIM_Try, /*On fail goto*//*Label 2*/ 285, // Rule ID 0 //
150 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
151 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB,
152 // CHECK-NEXT: // MIs[0] dst
153 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
154 // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID,
155 // CHECK-NEXT: // MIs[0] Operand 1
156 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
157 // CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1]
158 // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3,
159 // CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SUB,
160 // CHECK-NEXT: // MIs[1] Operand 0
161 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
162 // CHECK-NEXT: // MIs[1] src0
163 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
164 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/1, /*StoreIdx*/0, // Name : pred:1:x
165 // CHECK-NEXT: // MIs[1] src1
166 // CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
167 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:1:y
168 // CHECK-NEXT: // MIs[0] src2
169 // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
170 // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/2, /*StoreIdx*/2, // Name : pred:1:z
171 // CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_sub3_pat,
172 // CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
173 // CHECK-NEXT: // (sub:{ *:[i32] } (sub:{ *:[i32] } i32:{ *:[i32] }:$src0:$pred:1:x, i32:{ *:[i32] }:$src1:$pred:1:y), i32:{ *:[i32] }:$src2:$pred:1:z)<<P:1:Predicate_sub3_pat>> => (SUB3:{ *:[i32] } i32:{ *:[i32] }:$src0, i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
174 // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::SUB3,
176 // Test a non-commutative pattern.
177 def SUB3 : I<(outs DRegs:$dst),
178 (ins DOP:$src0, DOP:$src1, DOP:$src2),
179 [(set DRegs:$dst, (sub3_pat i32:$src0, i32:$src1, i32:$src2))]
183 def patfrags_test_pat : PatFrags<
184 (ops node:$x, node:$y, node:$z),
185 [ (xor (add node:$x, node:$y), node:$z),
186 (xor (sub node:$x, node:$y), node:$z)
187 ], [{ return foo(); }]> {
188 let GISelPredicateCode = [{
189 return doesComplexCheck(MI);
192 let PredicateCodeUsesOperands = 1;
195 // CHECK: GIM_Try, /*On fail goto*//*Label 3*/ 372, // Rule ID 1 //
196 // CHECK: // (xor:{ *:[i32] } (add:{ *:[i32] } i32:{ *:[i32] }:$src0:$pred:2:x, i32:{ *:[i32] }:$src1:$pred:2:y), i32:{ *:[i32] }:$src2:$pred:2:z)<<P:2:Predicate_patfrags_test_pat>> => (PATFRAGS:{ *:[i32] } i32:{ *:[i32] }:$src0, i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
198 // CHECK: GIM_Try, /*On fail goto*//*Label 4*/ 459, // Rule ID 2 //
199 // CHECK: // (xor:{ *:[i32] } (sub:{ *:[i32] } i32:{ *:[i32] }:$src0:$pred:2:x, i32:{ *:[i32] }:$src1:$pred:2:y), i32:{ *:[i32] }:$src2:$pred:2:z)<<P:2:Predicate_patfrags_test_pat>> => (PATFRAGS:{ *:[i32] } i32:{ *:[i32] }:$src0, i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
201 // CHECK: GIM_Try, /*On fail goto*//*Label 5*/ 546, // Rule ID 4 //
202 // CHECK: // (xor:{ *:[i32] } i32:{ *:[i32] }:$src2:$pred:2:z, (add:{ *:[i32] } i32:{ *:[i32] }:$src0:$pred:2:x, i32:{ *:[i32] }:$src1:$pred:2:y))<<P:2:Predicate_patfrags_test_pat>> => (PATFRAGS:{ *:[i32] } i32:{ *:[i32] }:$src0, i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
204 // CHECK: GIM_Try, /*On fail goto*//*Label 6*/ 633, // Rule ID 5 //
205 // CHECK: // (xor:{ *:[i32] } i32:{ *:[i32] }:$src2:$pred:2:z, (sub:{ *:[i32] } i32:{ *:[i32] }:$src0:$pred:2:x, i32:{ *:[i32] }:$src1:$pred:2:y))<<P:2:Predicate_patfrags_test_pat>> => (PATFRAGS:{ *:[i32] } i32:{ *:[i32] }:$src0, i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2)
208 // Test a commutative pattern using multiple patterns using PatFrags.
209 def PATFRAGS : I<(outs DRegs:$dst),
210 (ins DOP:$src0, DOP:$src1, DOP:$src2),
211 [(set DRegs:$dst, (patfrags_test_pat i32:$src0, i32:$src1, i32:$src2))]