Skip to content

Commit 6388a7a

Browse files
authored
[RISCV] Check the extension type for atomic loads in isel patterns. (#137019)
Previously we ignored the extension type and only used the memory type. The extension type on RISC-V today can only be nonextload, extload, or sextload. It is ok to treat extload as the same as sextload so ignoring the extension type is fine. For #136502, we want to support zextload as well so we will need to disambiguate based on the extension type. I wanted to use IsAtomic/IsZeroExtLoad/IsSignExtLoad/IsAnyExtLoad flags from PatFrags to autogenerate the predicates, but those aren't hooked up properly in tablegen for ISD::ATOMIC_LOAD. Fixing that will impact other targets as almost all of them also ignore the extension type.
1 parent 0d00b6b commit 6388a7a

File tree

2 files changed

+46
-13
lines changed

2 files changed

+46
-13
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoA.td

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,29 @@ defm AMOMAXU_D : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">,
118118
// Pseudo-instructions and codegen patterns
119119
//===----------------------------------------------------------------------===//
120120

121+
def riscv_atomic_asextload : PatFrag<(ops node:$ptr), (atomic_load node:$ptr), [{
122+
ISD::LoadExtType ETy = cast<AtomicSDNode>(N)->getExtensionType();
123+
return ETy == ISD::EXTLOAD || ETy == ISD::SEXTLOAD;
124+
}]>;
125+
126+
def riscv_atomic_asextload_8 : PatFrag<(ops node:$ptr),
127+
(riscv_atomic_asextload node:$ptr)> {
128+
let IsAtomic = true;
129+
let MemoryVT = i8;
130+
}
131+
132+
def riscv_atomic_asextload_16 : PatFrag<(ops node:$ptr),
133+
(riscv_atomic_asextload node:$ptr)> {
134+
let IsAtomic = true;
135+
let MemoryVT = i16;
136+
}
137+
138+
def riscv_atomic_asextload_32 : PatFrag<(ops node:$ptr),
139+
(riscv_atomic_asextload node:$ptr)> {
140+
let IsAtomic = true;
141+
let MemoryVT = i32;
142+
}
143+
121144
let IsAtomic = 1 in {
122145
// An atomic load operation that does not need either acquire or release
123146
// semantics.
@@ -165,16 +188,20 @@ class seq_cst_store<PatFrag base>
165188
// any ordering. This is necessary because AtomicExpandPass has added fences to
166189
// atomic load/stores and changed them to unordered ones.
167190
let Predicates = [HasAtomicLdSt] in {
168-
def : LdPat<relaxed_load<atomic_load_8>, LB>;
169-
def : LdPat<relaxed_load<atomic_load_16>, LH>;
170-
def : LdPat<relaxed_load<atomic_load_32>, LW>;
191+
def : LdPat<relaxed_load<riscv_atomic_asextload_8>, LB>;
192+
def : LdPat<relaxed_load<riscv_atomic_asextload_16>, LH>;
171193

172194
def : StPat<relaxed_store<atomic_store_8>, SB, GPR, XLenVT>;
173195
def : StPat<relaxed_store<atomic_store_16>, SH, GPR, XLenVT>;
174196
def : StPat<relaxed_store<atomic_store_32>, SW, GPR, XLenVT>;
175197
}
176198

199+
let Predicates = [HasAtomicLdSt, IsRV32] in {
200+
def : LdPat<relaxed_load<atomic_load_32>, LW>;
201+
}
202+
177203
let Predicates = [HasAtomicLdSt, IsRV64] in {
204+
def : LdPat<relaxed_load<riscv_atomic_asextload_32>, LW>;
178205
def : LdPat<relaxed_load<atomic_load_64>, LD, i64>;
179206
def : StPat<relaxed_store<atomic_store_64>, SD, GPR, i64>;
180207
}

llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,25 +70,22 @@ class PatLAQ<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
7070
// while atomic_store has data, addr
7171
class PatSRL<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT>
7272
: Pat<(OpNode (vt GPR:$rs2), (vt GPRMemZeroOffset:$rs1)),
73-
(Inst GPRMemZeroOffset:$rs1, GPR:$rs2)>;
74-
73+
(Inst GPRMemZeroOffset:$rs1, GPR:$rs2)>;
74+
7575

7676
let Predicates = [HasStdExtZalasr] in {
7777
// the sequentially consistent loads use
7878
// .aq instead of .aqrl to match the psABI/A.7
79-
def : PatLAQ<acquiring_load<atomic_load_8>, LB_AQ>;
80-
def : PatLAQ<seq_cst_load<atomic_load_8>, LB_AQ>;
79+
def : PatLAQ<acquiring_load<riscv_atomic_asextload_8>, LB_AQ>;
80+
def : PatLAQ<seq_cst_load<riscv_atomic_asextload_8>, LB_AQ>;
8181

82-
def : PatLAQ<acquiring_load<atomic_load_16>, LH_AQ>;
83-
def : PatLAQ<seq_cst_load<atomic_load_16>, LH_AQ>;
84-
85-
def : PatLAQ<acquiring_load<atomic_load_32>, LW_AQ>;
86-
def : PatLAQ<seq_cst_load<atomic_load_32>, LW_AQ>;
82+
def : PatLAQ<acquiring_load<riscv_atomic_asextload_16>, LH_AQ>;
83+
def : PatLAQ<seq_cst_load<riscv_atomic_asextload_16>, LH_AQ>;
8784

8885
// the sequentially consistent stores use
8986
// .rl instead of .aqrl to match the psABI/A.7
9087
def : PatSRL<releasing_store<atomic_store_8>, SB_RL>;
91-
def : PatSRL<seq_cst_store<atomic_store_8>, SB_RL>;
88+
def : PatSRL<seq_cst_store<atomic_store_8>, SB_RL>;
9289

9390
def : PatSRL<releasing_store<atomic_store_16>, SH_RL>;
9491
def : PatSRL<seq_cst_store<atomic_store_16>, SH_RL>;
@@ -97,7 +94,16 @@ let Predicates = [HasStdExtZalasr] in {
9794
def : PatSRL<seq_cst_store<atomic_store_32>, SW_RL>;
9895
} // Predicates = [HasStdExtZalasr]
9996

97+
let Predicates = [HasStdExtZalasr, IsRV32] in {
98+
def : PatLAQ<acquiring_load<atomic_load_32>, LW_AQ>;
99+
def : PatLAQ<seq_cst_load<atomic_load_32>, LW_AQ>;
100+
101+
} // Predicates = [HasStdExtZalasr, IsRV64]
102+
100103
let Predicates = [HasStdExtZalasr, IsRV64] in {
104+
def : PatLAQ<acquiring_load<riscv_atomic_asextload_32>, LW_AQ>;
105+
def : PatLAQ<seq_cst_load<riscv_atomic_asextload_32>, LW_AQ>;
106+
101107
def : PatLAQ<acquiring_load<atomic_load_64>, LD_AQ>;
102108
def : PatLAQ<seq_cst_load<atomic_load_64>, LD_AQ>;
103109

0 commit comments

Comments
 (0)