11// RUN: llvm-tblgen %s -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common -o - | FileCheck %s
22
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+
325include "llvm/Target/Target.td"
426include "GlobalISelEmitterCommon.td"
527
@@ -28,7 +50,6 @@ def DRegs : MyClass<32, [i32], (sequence "D%u", 0, 0)>;
2850def DOP : RegisterOperand<DRegs>;
2951def AND_OR : I<(outs DRegs:$dst), (ins DOP:$src0, DOP:$src1, DOP:$src2), []>;
3052
31-
3253def or_oneuse : PatFrag<
3354 (ops node:$x, node:$y),
3455 (or node:$x, node:$y), [{ return foo(); }]> {
@@ -48,15 +69,15 @@ def and_or_pat : PatFrag<
4869 let PredicateCodeUsesOperands = 1;
4970}
5071
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 //
5273// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
5374// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND,
5475// CHECK-NEXT: // MIs[0] dst
5576// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32,
5677// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID,
5778// CHECK-NEXT: // MIs[0] src2
5879// 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
6081// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/Test::DRegsRegClassID,
6182// CHECK-NEXT: // MIs[0] Operand 2
6283// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32,
@@ -67,18 +88,18 @@ def and_or_pat : PatFrag<
6788// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
6889// CHECK-NEXT: // MIs[1] src0
6990// 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
7192// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID,
7293// CHECK-NEXT: // MIs[1] src1
7394// 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
7596// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID,
7697// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat,
7798// 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)
79100// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR,
80101
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 //
82103// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3,
83104// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND,
84105// CHECK-NEXT: // MIs[0] dst
@@ -93,19 +114,19 @@ def and_or_pat : PatFrag<
93114// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32,
94115// CHECK-NEXT: // MIs[1] src0
95116// 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
97118// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID,
98119// CHECK-NEXT: // MIs[1] src1
99120// 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
101122// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID,
102123// CHECK-NEXT: // MIs[0] src2
103124// 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
105126// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/Test::DRegsRegClassID,
106127// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat,
107128// 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)
109130// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR,
110131
111132// Test commutative, standalone pattern.
@@ -157,3 +178,35 @@ def SUB3 : I<(outs DRegs:$dst),
157178 (ins DOP:$src0, DOP:$src1, DOP:$src2),
158179 [(set DRegs:$dst, (sub3_pat i32:$src0, i32:$src1, i32:$src2))]
159180>;
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