1
1
// RUN: llvm-tblgen %s -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common -o - | FileCheck %s
2
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
+
3
25
include "llvm/Target/Target.td"
4
26
include "GlobalISelEmitterCommon.td"
5
27
@@ -28,7 +50,6 @@ def DRegs : MyClass<32, [i32], (sequence "D%u", 0, 0)>;
28
50
def DOP : RegisterOperand<DRegs>;
29
51
def AND_OR : I<(outs DRegs:$dst), (ins DOP:$src0, DOP:$src1, DOP:$src2), []>;
30
52
31
-
32
53
def or_oneuse : PatFrag<
33
54
(ops node:$x, node:$y),
34
55
(or node:$x, node:$y), [{ return foo(); }]> {
@@ -48,15 +69,15 @@ def and_or_pat : PatFrag<
48
69
let PredicateCodeUsesOperands = 1;
49
70
}
50
71
51
- // CHECK: GIM_Try, /*On fail goto*//*Label 0*/ 99, // Rule ID 2 //
72
+ // CHECK: GIM_Try, /*On fail goto*//*Label 0*/ 99, // Rule ID 6 //
52
73
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
53
74
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND,
54
75
// CHECK-NEXT: // MIs[0] dst
55
76
// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
56
77
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID,
57
78
// CHECK-NEXT: // MIs[0] src2
58
79
// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32,
59
- // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/1, /*StoreIdx*/2, // Name : pred:2 :z
80
+ // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/1, /*StoreIdx*/2, // Name : pred:3 :z
60
81
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/Test::DRegsRegClassID,
61
82
// CHECK-NEXT: // MIs[0] Operand 2
62
83
// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
@@ -67,18 +88,18 @@ def and_or_pat : PatFrag<
67
88
// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
68
89
// CHECK-NEXT: // MIs[1] src0
69
90
// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
70
- // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/1, /*StoreIdx*/0, // Name : pred:2 :x
91
+ // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/1, /*StoreIdx*/0, // Name : pred:3 :x
71
92
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID,
72
93
// CHECK-NEXT: // MIs[1] src1
73
94
// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
74
- // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:2 :y
95
+ // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:3 :y
75
96
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID,
76
97
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat,
77
98
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
78
- // CHECK-NEXT: // (and:{ *:[i32] } DOP:{ *:[i32] }:$src2:$pred:2 :z, (or:{ *:[i32] } DOP:{ *:[i32] }:$src0:$pred:2 :x, DOP:{ *:[i32] }:$src1:$pred:2 :y))<<P:2 :Predicate_and_or_pat>> => (AND_OR:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1, DOP:{ *:[i32] }:$src2)
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)
79
100
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR,
80
101
81
- // CHECK: GIM_Try, /*On fail goto*//*Label 1*/ 198, // Rule ID 1 //
102
+ // CHECK: GIM_Try, /*On fail goto*//*Label 1*/ 198, // Rule ID 3 //
82
103
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
83
104
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND,
84
105
// CHECK-NEXT: // MIs[0] dst
@@ -93,19 +114,19 @@ def and_or_pat : PatFrag<
93
114
// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
94
115
// CHECK-NEXT: // MIs[1] src0
95
116
// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32,
96
- // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/1, /*StoreIdx*/0, // Name : pred:2 :x
117
+ // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/1, /*StoreIdx*/0, // Name : pred:3 :x
97
118
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID,
98
119
// CHECK-NEXT: // MIs[1] src1
99
120
// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32,
100
- // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:2 :y
121
+ // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:3 :y
101
122
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID,
102
123
// CHECK-NEXT: // MIs[0] src2
103
124
// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
104
- // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/2, /*StoreIdx*/2, // Name : pred:2 :z
125
+ // CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/2, /*StoreIdx*/2, // Name : pred:3 :z
105
126
// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/Test::DRegsRegClassID,
106
127
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat,
107
128
// CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1,
108
- // CHECK-NEXT: // (and:{ *:[i32] } (or:{ *:[i32] } DOP:{ *:[i32] }:$src0:$pred:2 :x, DOP:{ *:[i32] }:$src1:$pred:2 :y), DOP:{ *:[i32] }:$src2:$pred:2 :z)<<P:2 :Predicate_and_or_pat>> => (AND_OR:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1, DOP:{ *:[i32] }:$src2)
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)
109
130
// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR,
110
131
111
132
// Test commutative, standalone pattern.
@@ -157,3 +178,35 @@ def SUB3 : I<(outs DRegs:$dst),
157
178
(ins DOP:$src0, DOP:$src1, DOP:$src2),
158
179
[(set DRegs:$dst, (sub3_pat i32:$src0, i32:$src1, i32:$src2))]
159
180
>;
181
+
182
+
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);
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.
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))]
212
+ >;
0 commit comments