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