@@ -118,22 +118,65 @@ defm AMOMAXU_D : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">,
118118// Pseudo-instructions and codegen patterns
119119//===----------------------------------------------------------------------===//
120120
121+ let IsAtomic = 1 in {
122+ // An atomic load operation that does not need either acquire or release
123+ // semantics.
124+ class relaxed_load<PatFrags base>
125+ : PatFrag<(ops node:$ptr), (base node:$ptr)> {
126+ let IsAtomicOrderingAcquireOrStronger = 0;
127+ }
128+
129+ // A atomic load operation that actually needs acquire semantics.
130+ class acquiring_load<PatFrags base>
131+ : PatFrag<(ops node:$ptr), (base node:$ptr)> {
132+ let IsAtomicOrderingAcquire = 1;
133+ }
134+
135+ // An atomic load operation that needs sequential consistency.
136+ class seq_cst_load<PatFrags base>
137+ : PatFrag<(ops node:$ptr), (base node:$ptr)> {
138+ let IsAtomicOrderingSequentiallyConsistent = 1;
139+ }
140+
141+ // An atomic store operation that does not need either acquire or release
142+ // semantics.
143+ class relaxed_store<PatFrag base>
144+ : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr)> {
145+ let IsAtomicOrderingReleaseOrStronger = 0;
146+ }
147+
148+ // A store operation that actually needs release semantics.
149+ class releasing_store<PatFrag base>
150+ : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr)> {
151+ let IsAtomicOrderingRelease = 1;
152+ }
153+
154+ // A store operation that actually needs sequential consistency.
155+ class seq_cst_store<PatFrag base>
156+ : PatFrag<(ops node:$val, node:$ptr), (base node:$val, node:$ptr)> {
157+ let IsAtomicOrderingSequentiallyConsistent = 1;
158+ }
159+ } // IsAtomic = 1
160+
121161// Atomic load/store are available under both +a and +force-atomics.
122162// Fences will be inserted for atomic load/stores according to the logic in
123163// RISCVTargetLowering::{emitLeadingFence,emitTrailingFence}.
164+ // The normal loads/stores are relaxed (unordered) loads/stores that don't have
165+ // any ordering. This is necessary because AtomicExpandPass has added fences to
166+ // atomic load/stores and changed them to unordered ones.
124167let Predicates = [HasAtomicLdSt] in {
125- def : LdPat<atomic_load_8, LB>;
126- def : LdPat<atomic_load_16, LH>;
127- def : LdPat<atomic_load_32, LW>;
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>;
128171
129- def : StPat<atomic_store_8, SB, GPR, XLenVT>;
130- def : StPat<atomic_store_16, SH, GPR, XLenVT>;
131- def : StPat<atomic_store_32, SW, GPR, XLenVT>;
172+ def : StPat<relaxed_store< atomic_store_8> , SB, GPR, XLenVT>;
173+ def : StPat<relaxed_store< atomic_store_16> , SH, GPR, XLenVT>;
174+ def : StPat<relaxed_store< atomic_store_32> , SW, GPR, XLenVT>;
132175}
133176
134177let Predicates = [HasAtomicLdSt, IsRV64] in {
135- def : LdPat<atomic_load_64, LD, i64>;
136- def : StPat<atomic_store_64, SD, GPR, i64>;
178+ def : LdPat<relaxed_load< atomic_load_64> , LD, i64>;
179+ def : StPat<relaxed_store< atomic_store_64> , SD, GPR, i64>;
137180}
138181
139182/// AMOs
@@ -386,3 +429,14 @@ def : Pat<(int_riscv_masked_cmpxchg_i64
386429 (PseudoMaskedCmpXchg32
387430 GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering)>;
388431} // Predicates = [HasStdExtA, IsRV64]
432+
433+ let Predicates = [HasAtomicLdSt] in {
434+ def : LdPat<relaxed_load<atomic_load_8>, LB, i32>;
435+ def : LdPat<relaxed_load<atomic_load_16>, LH, i32>;
436+ def : LdPat<relaxed_load<atomic_load_32>, LW, i32>;
437+
438+ def : StPat<relaxed_store<atomic_store_8>, SB, GPR, i32>;
439+ def : StPat<relaxed_store<atomic_store_16>, SH, GPR, i32>;
440+ def : StPat<relaxed_store<atomic_store_32>, SW, GPR, i32>;
441+ }
442+
0 commit comments