xref: /llvm-project/llvm/test/TableGen/address-space-patfrags.td (revision a242880371936a8a424b9d80d47eff1be051429c)
1// RUN: llvm-tblgen -gen-dag-isel -I %p/../../include %s 2>&1 | FileCheck -check-prefix=SDAG %s
2// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -I %p/../../include %s -o - < %s | FileCheck -check-prefix=GISEL %s
3
4include "llvm/Target/Target.td"
5
6def TestTargetInstrInfo : InstrInfo;
7
8
9def TestTarget : Target {
10  let InstructionSet = TestTargetInstrInfo;
11}
12
13def R0 : Register<"r0"> { let Namespace = "MyTarget"; }
14def GPR32 : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
15
16
17// With one address space
18def pat_frag_a : PatFrag <(ops node:$ptr), (load node:$ptr), [{}]> {
19  let IsLoad = 1; // FIXME: Can this be inferred?
20  let MinAlignment = 2;
21}
22
23// With multiple address spaces
24def pat_frag_b : PatFrag <(ops node:$ptr), (load node:$ptr), [{}]> {
25  let AddressSpaces = [ 123, 455 ];
26  let IsLoad = 1; // FIXME: Can this be inferred?
27}
28
29def inst_a : Instruction {
30  let OutOperandList = (outs GPR32:$dst);
31  let InOperandList = (ins GPR32:$src);
32}
33
34def inst_b : Instruction {
35  let OutOperandList = (outs GPR32:$dst);
36  let InOperandList = (ins GPR32:$src);
37}
38
39def inst_c : Instruction {
40  let OutOperandList = (outs);
41  let InOperandList = (ins GPR32:$src0, GPR32:$src1);
42}
43
44def inst_d : Instruction {
45  let OutOperandList = (outs);
46  let InOperandList = (ins GPR32:$src0, GPR32:$src1);
47}
48
49// SDAG: case 0: {
50// SDAG-NEXT: // Predicate_pat_frag_b
51// SDAG-NEXT: // Predicate_truncstorei16_addrspace
52// SDAG-NEXT: SDNode *N = Node;
53// SDAG-NEXT: (void)N;
54// SDAG-NEXT: unsigned AddrSpace = cast<MemSDNode>(N)->getAddressSpace();
55// SDAG-NEXT: if (AddrSpace != 123 && AddrSpace != 455)
56// SDAG-NEXT: return false;
57// SDAG-NEXT: return true;
58
59
60// GISEL: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 0 //
61// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
62// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
63// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
64// GISEL-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
65// GISEL-NEXT: GIM_CheckMemoryAddressSpace, /*MI*/0, /*MMO*/0, /*NumAddrSpace*/2, /*AddrSpace*/123, /*AddrSpace*//* 455(*/0xC7, 0x03/*)*/,
66def : Pat <
67  (pat_frag_b GPR32:$src),
68  (inst_b GPR32:$src)
69>;
70
71
72// SDAG: case 4: {
73// SDAG: // Predicate_pat_frag_a
74// SDAG-NEXT: SDNode *N = Node;
75// SDAG-NEXT: (void)N;
76// SDAG-NEXT: if (cast<MemSDNode>(N)->getAlign() < Align(2))
77// SDAG-NEXT: return false;
78// SDAG-NEXT: return true;
79
80// GISEL: GIM_Try, /*On fail goto*//*Label 1*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 1 //
81// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
82// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
83// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
84// GISEL-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
85// GISEL-NEXT: GIM_CheckMemoryAlignment, /*MI*/0, /*MMO*/0, /*MinAlign*/2,
86def : Pat <
87  (pat_frag_a GPR32:$src),
88  (inst_a GPR32:$src)
89>;
90
91
92def truncstorei16_addrspace : PatFrag<(ops node:$val, node:$ptr),
93                                (truncstorei16 node:$val, node:$ptr)> {
94  let IsStore = 1;
95  let AddressSpaces = [ 123, 455 ];
96}
97
98// Test truncstore without a specific MemoryVT
99// GISEL: GIM_Try, /*On fail goto*//*Label 2*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 2 //
100// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
101// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
102// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
103// GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
104// GISEL-NEXT: // MIs[0] src0
105// GISEL-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
106def : Pat <
107  (truncstore GPR32:$src0, GPR32:$src1),
108  (inst_c GPR32:$src0, GPR32:$src1)
109>;
110
111// Test non-truncstore has a size equal to LLT check.
112// GISEL: GIM_Try, /*On fail goto*//*Label 3*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 3 //
113// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
114// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
115// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
116// GISEL-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
117def : Pat <
118  (store GPR32:$src0, GPR32:$src1),
119  (inst_d GPR32:$src0, GPR32:$src1)
120>;
121
122// Test truncstore with specific MemoryVT
123// GISEL: GIM_Try, /*On fail goto*//*Label 4*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 4 //
124// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
125// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
126// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
127// GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
128// GISEL-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/GIMT_Encode4(2),
129// GISEL-NEXT: GIM_CheckMemoryAddressSpace, /*MI*/0, /*MMO*/0, /*NumAddrSpace*/2, /*AddrSpace*/123, /*AddrSpace*//* 455(*/0xC7, 0x03/*)*/,
130def : Pat <
131  (truncstorei16_addrspace GPR32:$src0, GPR32:$src1),
132  (inst_c GPR32:$src0, GPR32:$src1)
133>;
134