1// RUN: llvm-tblgen %s -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common -o - | FileCheck %s
2
3// Verify that all MI predicates are enumerated.
4//
5// CHECK: // PatFrag predicates.
6// CHECK-NEXT: enum {
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,
11// CHECK-NEXT: };
12
13// Verify that we emit cases for all MI predicates.
14//
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");
24
25include "llvm/Target/Target.td"
26include "GlobalISelEmitterCommon.td"
27
28// Boilerplate code for setting up some registers with subregs.
29class MyReg<string n, list<Register> subregs = []>
30  : Register<n> {
31  let SubRegs = subregs;
32}
33
34class MyClass<int size, list<ValueType> types, dag registers>
35  : RegisterClass<"Test", types, size, registers> {
36  let Size = size;
37}
38
39def sub0 : SubRegIndex<16>;
40def sub1 : SubRegIndex<16, 16>;
41def S0 : MyReg<"s0">;
42def S1 : MyReg<"s1">;
43def SRegs : MyClass<16, [i16], (sequence "S%u", 0, 1)>;
44
45let SubRegIndices = [sub0, sub1] in {
46def D0 : MyReg<"d0", [S0, S1]>;
47}
48
49def DRegs : MyClass<32, [i32], (sequence "D%u", 0, 0)>;
50def DOP : RegisterOperand<DRegs>;
51def AND_OR : I<(outs DRegs:$dst), (ins DOP:$src0, DOP:$src1, DOP:$src2), []>;
52
53def 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());
58  }];
59}
60
61
62// FIXME: GISelPredicateCode ignored if DAG predicate not set.
63def 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);
68  }];
69  let PredicateCodeUsesOperands = 1;
70}
71
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,
101
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,
131
132// Test commutative, standalone pattern.
133def : Pat<
134  (i32 (and_or_pat DOP:$src0, DOP:$src1, DOP:$src2)),
135  (AND_OR DOP:$src0, DOP:$src1, DOP:$src2)
136>;
137
138
139def 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);
144  }];
145
146  let PredicateCodeUsesOperands = 1;
147}
148
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,
175
176// Test a non-commutative pattern.
177def 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))]
180>;
181
182
183def 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);
190  }];
191
192  let PredicateCodeUsesOperands = 1;
193}
194
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)
197
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)
200
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)
203
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)
206
207
208// Test a commutative pattern using multiple patterns using PatFrags.
209def 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))]
212>;
213