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} 49 50// CHECK: GIM_Try, /*On fail goto*//*Label 0*/ {{[0-9]+}}, // Rule ID 1 // 51// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 52// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND, 53// CHECK-NEXT: // MIs[0] dst 54// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 55// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID, 56// CHECK-NEXT: // MIs[0] Operand 1 57// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 58// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] 59// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 60// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_OR, 61// CHECK-NEXT: // MIs[1] Operand 0 62// CHECK-NEXT:GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 63// CHECK-NEXT: // MIs[1] src0 64// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, 65// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID, 66// CHECK-NEXT: // MIs[1] src1 67// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 68// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID, 69// CHECK-NEXT: // MIs[0] src2 70// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 71// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/2, /*RC*/Test::DRegsRegClassID, 72// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat, 73// CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 74// CHECK-NEXT: // (and:{ *:[i32] } (or:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1), DOP:{ *:[i32] }:$src2)<<P:Predicate_and_or_pat>> => (AND_OR:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1, DOP:{ *:[i32] }:$src2) 75// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR, 76 77 78// CHECK: GIM_Try, /*On fail goto*//*Label 1*/ {{[0-9]+}}, // Rule ID 2 // 79// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 80// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_AND, 81// CHECK-NEXT: // MIs[0] dst 82// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 83// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID, 84// CHECK-NEXT: // MIs[0] src2 85// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 86// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/1, /*RC*/Test::DRegsRegClassID, 87// CHECK-NEXT: // MIs[0] Operand 2 88// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 89// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/2, // 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_CheckRegBankForClass, /*MI*/1, /*Op*/1, /*RC*/Test::DRegsRegClassID, 97// CHECK-NEXT: // MIs[1] src1 98// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 99// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/1, /*Op*/2, /*RC*/Test::DRegsRegClassID, 100// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_and_or_pat, 101// CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 102// CHECK-NEXT: // (and:{ *:[i32] } DOP:{ *:[i32] }:$src2, (or:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1))<<P:Predicate_and_or_pat>> => (AND_OR:{ *:[i32] } DOP:{ *:[i32] }:$src0, DOP:{ *:[i32] }:$src1, DOP:{ *:[i32] }:$src2) 103// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::AND_OR, 104 105// Test commutative, standalone pattern. 106def : Pat< 107 (i32 (and_or_pat DOP:$src0, DOP:$src1, DOP:$src2)), 108 (AND_OR DOP:$src0, DOP:$src1, DOP:$src2) 109>; 110 111 112def sub3_pat : PatFrag< 113 (ops node:$x, node:$y, node:$z), 114 (sub (sub node:$x, node:$y), node:$z), [{ return foo(); }]> { 115 let GISelPredicateCode = [{ 116 return doesComplexCheck(MI); 117 }]; 118} 119 120// CHECK: GIM_Try, /*On fail goto*//*Label 2*/ {{[0-9]+}}, // Rule ID 0 // 121// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/3, 122// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_SUB, 123// CHECK-NEXT: // MIs[0] dst 124// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, 125// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/Test::DRegsRegClassID, 126// CHECK-NEXT: // MIs[0] Operand 1 127// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/1, /*Type*/GILLT_s32, 128// CHECK-NEXT: GIM_RecordInsn, /*DefineMI*/1, /*MI*/0, /*OpIdx*/1, // MIs[1] 129// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/1, /*Expected*/3, 130// CHECK-NEXT: GIM_CheckOpcode, /*MI*/1, TargetOpcode::G_SUB, 131// CHECK-NEXT: // MIs[1] Operand 0 132// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/0, /*Type*/GILLT_s32, 133// CHECK-NEXT: // MIs[1] src0 134// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/1, /*Type*/GILLT_s32, 135// CHECK-NEXT: // MIs[1] src1 136// CHECK-NEXT: GIM_CheckType, /*MI*/1, /*Op*/2, /*Type*/GILLT_s32, 137// CHECK-NEXT: // MIs[0] src2 138// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/2, /*Type*/GILLT_s32, 139// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIPFP_MI_Predicate_sub3_pat, 140// CHECK-NEXT: GIM_CheckIsSafeToFold, /*InsnID*/1, 141// CHECK-NEXT: // (sub:{ *:[i32] } (sub:{ *:[i32] } i32:{ *:[i32] }:$src0, i32:{ *:[i32] }:$src1), i32:{ *:[i32] }:$src2)<<P:Predicate_sub3_pat>> => (SUB3:{ *:[i32] } i32:{ *:[i32] }:$src0, i32:{ *:[i32] }:$src1, i32:{ *:[i32] }:$src2) 142// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::SUB3, 143 144// Test a non-commutative pattern. 145def SUB3 : I<(outs DRegs:$dst), 146 (ins DOP:$src0, DOP:$src1, DOP:$src2), 147 [(set DRegs:$dst, (sub3_pat i32:$src0, i32:$src1, i32:$src2))] 148>; 149