1// RUN: llvm-tblgen %s -gen-global-isel -optimize-match-table=false -I %p/../../include -I %p/Common -o - | FileCheck %s 2 3include "llvm/Target/Target.td" 4include "GlobalISelEmitterCommon.td" 5 6// Boilerplate code for setting up some registers with subregs. 7class MyReg<string n, list<Register> subregs = []> 8 : Register<n> { 9 let SubRegs = subregs; 10} 11 12class MyClass<int size, list<ValueType> types, dag registers> 13 : RegisterClass<"Test", types, size, registers> { 14 let Size = size; 15} 16 17def sub0 : SubRegIndex<16>; 18def sub1 : SubRegIndex<16, 16>; 19def S0 : MyReg<"s0">; 20def S1 : MyReg<"s1">; 21def SRegs : MyClass<16, [i16], (sequence "S%u", 0, 1)>; 22 23let SubRegIndices = [sub0, sub1] in { 24def D0 : MyReg<"d0", [S0, S1]>; 25} 26 27def DRegs : MyClass<32, [i32], (sequence "D%u", 0, 0)>; 28def DOP : RegisterOperand<DRegs>; 29def AND_OR : I<(outs DRegs:$dst), (ins DOP:$src0, DOP:$src1, DOP:$src2), []>; 30 31 32def or_oneuse : PatFrag< 33 (ops node:$x, node:$y), 34 (or node:$x, node:$y), [{ return foo(); }]> { 35 let GISelPredicateCode = [{ 36 return MRI.hasOneNonDBGUse(MI.getOperand(0).getReg()); 37 }]; 38} 39 40 41// FIXME: GISelPredicateCode ignored if DAG predicate not set. 42def and_or_pat : PatFrag< 43 (ops node:$x, node:$y, node:$z), 44 (and (or node:$x, node:$y), node:$z), [{ return foo(); }]> { 45 let GISelPredicateCode = [{ 46 return doesComplexCheck(MI); 47 }]; 48 let PredicateCodeUsesOperands = 1; 49} 50 51// CHECK: GIM_Try, /*On fail goto*//*Label 0*/ 99, // Rule ID 2 // 52// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 53// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND, 54// CHECK-NEXT: // MIs[0] dst 55// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 56// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID, 57// CHECK-NEXT: // MIs[0] src2 58// 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 60// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/Test::DRegsRegClassID, 61// CHECK-NEXT: // MIs[0] Operand 2 62// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 63// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, // MIs[1] 64// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 65// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_OR, 66// CHECK-NEXT: // MIs[1] Operand 0 67// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 68// CHECK-NEXT: // MIs[1] src0 69// 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 71// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID, 72// CHECK-NEXT: // MIs[1] src1 73// 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 75// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID, 76// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat, 77// 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) 79// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR, 80 81// CHECK: GIM_Try, /*On fail goto*//*Label 1*/ 198, // Rule ID 1 // 82// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 83// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND, 84// CHECK-NEXT: // MIs[0] dst 85// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 86// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID, 87// CHECK-NEXT: // MIs[0] Operand 1 88// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 89// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] 90// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 91// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_OR, 92// CHECK-NEXT: // MIs[1] Operand 0 93// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 94// CHECK-NEXT: // MIs[1] src0 95// 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 97// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID, 98// CHECK-NEXT: // MIs[1] src1 99// 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 101// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID, 102// CHECK-NEXT: // MIs[0] src2 103// 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 105// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/Test::DRegsRegClassID, 106// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat, 107// 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) 109// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR, 110 111// Test commutative, standalone pattern. 112def : Pat< 113 (i32 (and_or_pat DOP:$src0, DOP:$src1, DOP:$src2)), 114 (AND_OR DOP:$src0, DOP:$src1, DOP:$src2) 115>; 116 117 118def sub3_pat : PatFrag< 119 (ops node:$x, node:$y, node:$z), 120 (sub (sub node:$x, node:$y), node:$z), [{ return foo(); }]> { 121 let GISelPredicateCode = [{ 122 return doesComplexCheck(MI); 123 }]; 124 125 let PredicateCodeUsesOperands = 1; 126} 127 128// CHECK: GIM_Try, /*On fail goto*//*Label 2*/ 285, // Rule ID 0 // 129// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 130// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB, 131// CHECK-NEXT: // MIs[0] dst 132// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 133// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID, 134// CHECK-NEXT: // MIs[0] Operand 1 135// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 136// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] 137// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 138// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SUB, 139// CHECK-NEXT: // MIs[1] Operand 0 140// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 141// CHECK-NEXT: // MIs[1] src0 142// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, 143// CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/1, /*StoreIdx*/0, // Name : pred:1:x 144// CHECK-NEXT: // MIs[1] src1 145// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 146// CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/1, /*Op*/2, /*StoreIdx*/1, // Name : pred:1:y 147// CHECK-NEXT: // MIs[0] src2 148// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 149// CHECK-NEXT: GIM_RecordNamedOperand, /*MI*/0, /*Op*/2, /*StoreIdx*/2, // Name : pred:1:z 150// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_sub3_pat, 151// CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 152// 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) 153// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::SUB3, 154 155// Test a non-commutative pattern. 156def SUB3 : I<(outs DRegs:$dst), 157 (ins DOP:$src0, DOP:$src1, DOP:$src2), 158 [(set DRegs:$dst, (sub3_pat i32:$src0, i32:$src1, i32:$src2))] 159>; 160