@@ -1814,7 +1814,7 @@ def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMMinMax;
18141814
18151815class PseudoCmpXchg
18161816 : Pseudo<(outs GPR:$res, GPR:$scratch),
1817- (ins GPR:$addr, GPR:$cmpval, GPR:$newval, grlenimm:$ordering )> {
1817+ (ins GPR:$addr, GPR:$cmpval, GPR:$newval, grlenimm:$fail_order )> {
18181818 let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
18191819 let mayLoad = 1;
18201820 let mayStore = 1;
@@ -1828,7 +1828,7 @@ def PseudoCmpXchg64 : PseudoCmpXchg;
18281828def PseudoMaskedCmpXchg32
18291829 : Pseudo<(outs GPR:$res, GPR:$scratch),
18301830 (ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,
1831- grlenimm:$ordering )> {
1831+ grlenimm:$fail_order )> {
18321832 let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
18331833 let mayLoad = 1;
18341834 let mayStore = 1;
@@ -1846,6 +1846,43 @@ class AtomicPat<Intrinsic intrin, Pseudo AMInst>
18461846 : Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering),
18471847 (AMInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>;
18481848
1849+ // These atomic cmpxchg PatFrags only care about the failure ordering.
1850+ // The PatFrags defined by multiclass `ternary_atomic_op_ord` in
1851+ // TargetSelectionDAG.td care about the merged memory ordering that is the
1852+ // stronger one between success and failure. But for LoongArch LL-SC we only
1853+ // need to care about the failure ordering as explained in PR #67391. So we
1854+ // define these PatFrags that will be used to define cmpxchg pats below.
1855+ multiclass ternary_atomic_op_failure_ord {
1856+ def NAME#_failure_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1857+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1858+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1859+ return Ordering == AtomicOrdering::Monotonic;
1860+ }]>;
1861+ def NAME#_failure_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1862+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1863+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1864+ return Ordering == AtomicOrdering::Acquire;
1865+ }]>;
1866+ def NAME#_failure_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1867+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1868+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1869+ return Ordering == AtomicOrdering::Release;
1870+ }]>;
1871+ def NAME#_failure_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1872+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1873+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1874+ return Ordering == AtomicOrdering::AcquireRelease;
1875+ }]>;
1876+ def NAME#_failure_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1877+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1878+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1879+ return Ordering == AtomicOrdering::SequentiallyConsistent;
1880+ }]>;
1881+ }
1882+
1883+ defm atomic_cmp_swap_32 : ternary_atomic_op_failure_ord;
1884+ defm atomic_cmp_swap_64 : ternary_atomic_op_failure_ord;
1885+
18491886let Predicates = [IsLA64] in {
18501887def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64,
18511888 PseudoMaskedAtomicSwap32>;
@@ -1908,24 +1945,24 @@ def : AtomicPat<int_loongarch_masked_atomicrmw_umin_i64,
19081945// AtomicOrdering.h.
19091946multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst,
19101947 ValueType vt = GRLenVT> {
1911- def : Pat<(vt (!cast<PatFrag>(Op#"_monotonic ") GPR:$addr, GPR:$cmp, GPR:$new)),
1948+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_monotonic ") GPR:$addr, GPR:$cmp, GPR:$new)),
19121949 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>;
1913- def : Pat<(vt (!cast<PatFrag>(Op#"_acquire ") GPR:$addr, GPR:$cmp, GPR:$new)),
1950+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acquire ") GPR:$addr, GPR:$cmp, GPR:$new)),
19141951 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>;
1915- def : Pat<(vt (!cast<PatFrag>(Op#"_release ") GPR:$addr, GPR:$cmp, GPR:$new)),
1952+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_release ") GPR:$addr, GPR:$cmp, GPR:$new)),
19161953 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>;
1917- def : Pat<(vt (!cast<PatFrag>(Op#"_acq_rel ") GPR:$addr, GPR:$cmp, GPR:$new)),
1954+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acq_rel ") GPR:$addr, GPR:$cmp, GPR:$new)),
19181955 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>;
1919- def : Pat<(vt (!cast<PatFrag>(Op#"_seq_cst ") GPR:$addr, GPR:$cmp, GPR:$new)),
1956+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_seq_cst ") GPR:$addr, GPR:$cmp, GPR:$new)),
19201957 (CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;
19211958}
19221959
19231960defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>;
19241961defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64, i64>;
19251962def : Pat<(int_loongarch_masked_cmpxchg_i64
1926- GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering ),
1963+ GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order ),
19271964 (PseudoMaskedCmpXchg32
1928- GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering )>;
1965+ GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order )>;
19291966
19301967def : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_max_i64,
19311968 PseudoMaskedAtomicLoadMax32>;
0 commit comments