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