Skip to content

Commit a242880

Browse files
authored
[TableGen][GlobalISel] Reorder atomic predicate to preserve the order (#121806)
Since there are no opcodes for atomic loads and stores comparing to SelectionDAG, we add `CheckMMOIsNonAtomic` predicate immediately after the opcode predicate to make a logical combination of them. Otherwise when `IPM_AtomicOrderingMMO` is inserted after `IPM_GenericPredicate`, the patterns without predicates get a higher priority as `IPM_AtomicOrderingMMO` has higher priority than `IPM_GenericPredicate`. This is important to preserve an order of aligned/unaligned patterns on X86 because aligned memory operations have an additional alignment predicate and should be checked first according to their placement in td file. Closes #121446
1 parent 1819646 commit a242880

9 files changed

+111
-24
lines changed

llvm/test/TableGen/GlobalISelEmitter/GlobalISelEmitter.td

+3-3
Original file line numberDiff line numberDiff line change
@@ -950,8 +950,8 @@ def MOVcimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, cimm8:$
950950
// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
951951
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
952952
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
953-
// NOOPT-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
954953
// NOOPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
954+
// NOOPT-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
955955
// NOOPT-NEXT: // MIs[0] DstI[dst]
956956
// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
957957
// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
@@ -973,8 +973,8 @@ def LOAD : I<(outs GPR32:$dst), (ins GPR32:$src1),
973973
// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
974974
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
975975
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
976-
// NOOPT-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
977976
// NOOPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
977+
// NOOPT-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
978978
// NOOPT-NEXT: // MIs[0] DstI[dst]
979979
// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_p0s32,
980980
// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
@@ -996,8 +996,8 @@ def : Pat<(load GPR32:$src),
996996
// NOOPT-NEXT: GIM_Try, /*On fail goto*//*Label [[LABEL_NUM:[0-9]+]]*/ GIMT_Encode4([[LABEL:[0-9]+]]),
997997
// NOOPT-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
998998
// NOOPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_SEXTLOAD),
999-
// NOOPT-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/GIMT_Encode4(2),
1000999
// NOOPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
1000+
// NOOPT-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/GIMT_Encode4(2),
10011001
// NOOPT-NEXT: // MIs[0] DstI[dst]
10021002
// NOOPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
10031003
// NOOPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),

llvm/test/TableGen/GlobalISelEmitter/HwModes.td

+4-4
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ class I<dag OOps, dag IOps, list<dag> Pat>
131131
// CHECK-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HwMode0),
132132
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
133133
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
134-
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
135134
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
135+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
136136
// CHECK-NEXT: // MIs[0] DstI[dst]
137137
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s64,
138138
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
@@ -149,8 +149,8 @@ class I<dag OOps, dag IOps, list<dag> Pat>
149149
// CHECK-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HwMode1),
150150
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
151151
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
152-
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
153152
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
153+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
154154
// CHECK-NEXT: // MIs[0] DstI[dst]
155155
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
156156
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
@@ -173,8 +173,8 @@ def LOAD : I<(outs GPR:$dst), (ins GPR:$src1),
173173
// CHECK-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HwMode0),
174174
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
175175
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
176-
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
177176
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
177+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
178178
// CHECK-NEXT: // MIs[0] DstI[dst]
179179
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_p0s64,
180180
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),
@@ -191,8 +191,8 @@ def LOAD : I<(outs GPR:$dst), (ins GPR:$src1),
191191
// CHECK-NEXT: GIM_CheckFeatures, GIMT_Encode2(GIFBS_HwMode1),
192192
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
193193
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
194-
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
195194
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
195+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
196196
// CHECK-NEXT: // MIs[0] DstI[dst]
197197
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_p0s32,
198198
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPRRegClassID),

llvm/test/TableGen/GlobalISelEmitter/MatchTableOptimizer.td

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ def LOAD8 : I<(outs GPR8:$dst), (ins GPR8:$src), []>;
99
def LOAD32 : I<(outs GPR8:$dst), (ins GPR32:$src), []>;
1010
// CHECK: Label 1: @{{[0-9]+}}
1111
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L1_ID:[0-9]+]]*/ GIMT_Encode4([[L1_AT:[0-9]+]]),
12+
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
1213
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
13-
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
1414
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR8RegClassID),
1515
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L2_ID:[0-9]+]]*/ GIMT_Encode4([[L2_AT:[0-9]+]]),
1616
// CHECK-NEXT: // MIs[0] src
@@ -47,8 +47,8 @@ def LOAD16 : I<(outs GPR16:$dst), (ins GPR16:$src), []>;
4747
def LOAD16Imm : I<(outs GPR16:$dst), (ins GPR16:$src), []>;
4848
// CHECK: // Label 2: @{{[0-9]+}}
4949
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L1_ID:[0-9]+]]*/ GIMT_Encode4([[L1_AT:[0-9]+]]),
50-
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
5150
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
51+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
5252
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR16RegClassID),
5353
// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/16,
5454
// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label [[L2_ID:[0-9]+]]*/ GIMT_Encode4([[L2_AT:[0-9]+]]),

llvm/test/TableGen/GlobalISelEmitter/OverloadedPtr.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ let TargetPrefix = "mytarget" in {
1313
// Check that iPTR in the destination DAG doesn't prevent the pattern from being imported.
1414

1515
// CHECK: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
16-
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
1716
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
17+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
1818
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
1919
// CHECK-NEXT: // MIs[0] src1
2020
// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/0,

llvm/test/TableGen/GlobalISelEmitter/atomic-store.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ include "GlobalISelEmitterCommon.td"
66
def ST_ATOM_B32 : I<(outs), (ins GPR32Op:$val, GPR32Op:$ptr), []>;
77

88
// GISEL: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
9-
// GISEL-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/GIMT_Encode4(1),
109
// GISEL-NEXT: GIM_CheckAtomicOrderingOrStrongerThan, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::Unordered,
10+
// GISEL-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/GIMT_Encode4(1),
1111
// GISEL-NEXT: // MIs[0] val
1212
// GISEL-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
1313
// GISEL-NEXT: // MIs[0] ptr
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=false -I %p/../../../include -I %p/../Common %s | FileCheck %s
2+
// RUN: llvm-tblgen -gen-global-isel -optimize-match-table=true -I %p/../../../include -I %p/../Common %s | FileCheck -check-prefix=OPT %s
3+
4+
include "llvm/Target/Target.td"
5+
include "GlobalISelEmitterCommon.td"
6+
7+
// Check that IPM_GenericPredicate doesn't influence the final order of patterns.
8+
// https://github.com/llvm/llvm-project/issues/121446
9+
10+
def aligned_store: PatFrag<(ops node:$v, node:$a), (store $v, $a), [{
11+
return true;
12+
}]>{
13+
let GISelPredicateCode = [{ return true; }];
14+
}
15+
16+
// CHECK: GIM_Try
17+
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
18+
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
19+
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
20+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
21+
// CHECK-NEXT: // MIs[0] src0
22+
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
23+
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
24+
// CHECK-NEXT: // MIs[0] src1
25+
// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
26+
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
27+
// CHECK-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_aligned_store),
28+
// CHECK-NEXT: // (st GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedstore>><<P:Predicate_store>><<P:Predicate_aligned_store>> => (MOVALIGNED GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)
29+
// CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::MOVALIGNED),
30+
// CHECK-NEXT: GIR_RootConstrainSelectedInstOperands,
31+
// CHECK-NEXT: // GIR_Coverage
32+
33+
// CHECK: GIM_Try
34+
// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
35+
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
36+
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
37+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
38+
// CHECK-NEXT: // MIs[0] src0
39+
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
40+
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
41+
// CHECK-NEXT: // MIs[0] src1
42+
// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
43+
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
44+
// CHECK-NEXT: // (st GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedstore>><<P:Predicate_store>> => (MOVUNALIGNED GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)
45+
// CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::MOVUNALIGNED),
46+
// CHECK-NEXT: GIR_RootConstrainSelectedInstOperands,
47+
// CHECK-NEXT: // GIR_Coverage
48+
49+
// OPT: GIM_Try
50+
// OPT-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
51+
// OPT-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
52+
// OPT-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
53+
// OPT-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
54+
55+
// OPT-NEXT: GIM_Try
56+
// OPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
57+
// OPT-NEXT: // MIs[0] src1
58+
// OPT-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
59+
// OPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
60+
// OPT-NEXT: GIM_CheckCxxInsnPredicate, /*MI*/0, /*FnId*/GIMT_Encode2(GICXXPred_MI_Predicate_aligned_store),
61+
// OPT-NEXT: // (st GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedstore>><<P:Predicate_store>><<P:Predicate_aligned_store>> => (MOVALIGNED GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)
62+
// OPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::MOVALIGNED),
63+
// OPT-NEXT: GIR_RootConstrainSelectedInstOperands,
64+
// OPT-NEXT: // GIR_Coverage
65+
66+
// OPT: GIM_Try
67+
// OPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
68+
// OPT-NEXT: // MIs[0] src1
69+
// OPT-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/1, /*SizeInBits*/32,
70+
// OPT-NEXT: GIM_RootCheckRegBankForClass, /*Op*/1, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
71+
// OPT-NEXT: // (st GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)<<P:Predicate_unindexedstore>><<P:Predicate_store>> => (MOVUNALIGNED GPR32:{ *:[i32] }:$src0, GPR32:{ *:[i32] }:$src1)
72+
// OPT-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::MOVUNALIGNED),
73+
// OPT-NEXT: GIR_RootConstrainSelectedInstOperands,
74+
// OPT-NEXT: // GIR_Coverage
75+
76+
def MOVALIGNED : I<(outs), (ins GPR32:$src0, GPR32:$src1),
77+
[(aligned_store GPR32:$src0, GPR32:$src1)]>;
78+
79+
80+
def MOVUNALIGNED : I<(outs), (ins GPR32:$src0, GPR32:$src1),
81+
[(store GPR32:$src0, GPR32:$src1)]>;
82+

llvm/test/TableGen/GlobalISelEmitter/zero-reg.td

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ def INST : PredI<(outs GPR32:$dst), (ins GPR32:$src), []>;
2222

2323
// CHECK: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
2424
// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
25-
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
2625
// CHECK-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
26+
// CHECK-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
2727
// CHECK-NEXT: // MIs[0] DstI[dst]
2828
// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
2929
// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),

llvm/test/TableGen/address-space-patfrags.td

+5-3
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ def inst_d : Instruction {
6060
// GISEL: GIM_Try, /*On fail goto*//*Label 0*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 0 //
6161
// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
6262
// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
63+
// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
6364
// GISEL-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
6465
// GISEL-NEXT: GIM_CheckMemoryAddressSpace, /*MI*/0, /*MMO*/0, /*NumAddrSpace*/2, /*AddrSpace*/123, /*AddrSpace*//* 455(*/0xC7, 0x03/*)*/,
65-
// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
6666
def : Pat <
6767
(pat_frag_b GPR32:$src),
6868
(inst_b GPR32:$src)
@@ -80,9 +80,9 @@ def : Pat <
8080
// GISEL: GIM_Try, /*On fail goto*//*Label 1*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 1 //
8181
// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
8282
// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_LOAD),
83+
// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
8384
// GISEL-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
8485
// GISEL-NEXT: GIM_CheckMemoryAlignment, /*MI*/0, /*MMO*/0, /*MinAlign*/2,
85-
// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
8686
def : Pat <
8787
(pat_frag_a GPR32:$src),
8888
(inst_a GPR32:$src)
@@ -99,8 +99,8 @@ def truncstorei16_addrspace : PatFrag<(ops node:$val, node:$ptr),
9999
// GISEL: GIM_Try, /*On fail goto*//*Label 2*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 2 //
100100
// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
101101
// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
102-
// GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
103102
// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
103+
// GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
104104
// GISEL-NEXT: // MIs[0] src0
105105
// GISEL-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
106106
def : Pat <
@@ -112,6 +112,7 @@ def : Pat <
112112
// GISEL: GIM_Try, /*On fail goto*//*Label 3*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 3 //
113113
// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
114114
// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
115+
// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
115116
// GISEL-NEXT: GIM_CheckMemorySizeEqualToLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
116117
def : Pat <
117118
(store GPR32:$src0, GPR32:$src1),
@@ -122,6 +123,7 @@ def : Pat <
122123
// GISEL: GIM_Try, /*On fail goto*//*Label 4*/ GIMT_Encode4({{[0-9]+}}), // Rule ID 4 //
123124
// GISEL-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2,
124125
// GISEL-NEXT: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_STORE),
126+
// GISEL-NEXT: GIM_CheckAtomicOrdering, /*MI*/0, /*Order*/(uint8_t)AtomicOrdering::NotAtomic,
125127
// GISEL-NEXT: GIM_CheckMemorySizeLessThanLLT, /*MI*/0, /*MMO*/0, /*OpIdx*/0,
126128
// GISEL-NEXT: GIM_CheckMemorySizeEqualTo, /*MI*/0, /*MMO*/0, /*Size*/GIMT_Encode4(2),
127129
// GISEL-NEXT: GIM_CheckMemoryAddressSpace, /*MI*/0, /*MMO*/0, /*NumAddrSpace*/2, /*AddrSpace*/123, /*AddrSpace*//* 455(*/0xC7, 0x03/*)*/,

llvm/utils/TableGen/GlobalISelEmitter.cpp

+12-9
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,18 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
765765
InsnMatcher.addPredicate<InstructionOpcodeMatcher>(SrcGIOrNull);
766766
}
767767

768+
// Since there are no opcodes for atomic loads and stores comparing to
769+
// SelectionDAG, we add CheckMMOIsNonAtomic predicate immediately after the
770+
// opcode predicate to make a logical combination of them.
771+
if (SrcGIEquivOrNull &&
772+
SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
773+
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
774+
else if (SrcGIEquivOrNull &&
775+
SrcGIEquivOrNull->getValueAsBit("CheckMMOIsAtomic")) {
776+
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
777+
"Unordered", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
778+
}
779+
768780
unsigned OpIdx = 0;
769781
for (const TypeSetByHwMode &VTy : Src.getExtTypes()) {
770782
// Results don't have a name unless they are the root node. The caller will
@@ -827,15 +839,6 @@ Expected<InstructionMatcher &> GlobalISelEmitter::createAndImportSelDAGMatcher(
827839
}
828840
}
829841

830-
if (SrcGIEquivOrNull &&
831-
SrcGIEquivOrNull->getValueAsBit("CheckMMOIsNonAtomic"))
832-
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>("NotAtomic");
833-
else if (SrcGIEquivOrNull &&
834-
SrcGIEquivOrNull->getValueAsBit("CheckMMOIsAtomic")) {
835-
InsnMatcher.addPredicate<AtomicOrderingMMOPredicateMatcher>(
836-
"Unordered", AtomicOrderingMMOPredicateMatcher::AO_OrStronger);
837-
}
838-
839842
if (Src.isLeaf()) {
840843
const Init *SrcInit = Src.getLeafValue();
841844
if (const IntInit *SrcIntInit = dyn_cast<IntInit>(SrcInit)) {

0 commit comments

Comments
 (0)