@@ -1753,7 +1753,7 @@ def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMMinMax;
1753
1753
1754
1754
class PseudoCmpXchg
1755
1755
: Pseudo<(outs GPR:$res, GPR:$scratch),
1756
- (ins GPR:$addr, GPR:$cmpval, GPR:$newval, grlenimm:$ordering )> {
1756
+ (ins GPR:$addr, GPR:$cmpval, GPR:$newval, grlenimm:$fail_order )> {
1757
1757
let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
1758
1758
let mayLoad = 1;
1759
1759
let mayStore = 1;
@@ -1767,7 +1767,7 @@ def PseudoCmpXchg64 : PseudoCmpXchg;
1767
1767
def PseudoMaskedCmpXchg32
1768
1768
: Pseudo<(outs GPR:$res, GPR:$scratch),
1769
1769
(ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,
1770
- grlenimm:$ordering )> {
1770
+ grlenimm:$fail_order )> {
1771
1771
let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
1772
1772
let mayLoad = 1;
1773
1773
let mayStore = 1;
@@ -1785,6 +1785,43 @@ class AtomicPat<Intrinsic intrin, Pseudo AMInst>
1785
1785
: Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering),
1786
1786
(AMInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>;
1787
1787
1788
+ // These atomic cmpxchg PatFrags only care about the failure ordering.
1789
+ // The PatFrags defined by multiclass `ternary_atomic_op_ord` in
1790
+ // TargetSelectionDAG.td care about the merged memory ordering that is the
1791
+ // stronger one between success and failure. But for LoongArch LL-SC we only
1792
+ // need to care about the failure ordering as explained in PR #67391. So we
1793
+ // define these PatFrags that will be used to define cmpxchg pats below.
1794
+ multiclass ternary_atomic_op_failure_ord {
1795
+ def NAME#_failure_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1796
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1797
+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1798
+ return Ordering == AtomicOrdering::Monotonic;
1799
+ }]>;
1800
+ def NAME#_failure_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1801
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1802
+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1803
+ return Ordering == AtomicOrdering::Acquire;
1804
+ }]>;
1805
+ def NAME#_failure_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1806
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1807
+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1808
+ return Ordering == AtomicOrdering::Release;
1809
+ }]>;
1810
+ def NAME#_failure_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1811
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1812
+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1813
+ return Ordering == AtomicOrdering::AcquireRelease;
1814
+ }]>;
1815
+ def NAME#_failure_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
1816
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val), [{
1817
+ AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getFailureOrdering();
1818
+ return Ordering == AtomicOrdering::SequentiallyConsistent;
1819
+ }]>;
1820
+ }
1821
+
1822
+ defm atomic_cmp_swap_32 : ternary_atomic_op_failure_ord;
1823
+ defm atomic_cmp_swap_64 : ternary_atomic_op_failure_ord;
1824
+
1788
1825
let Predicates = [IsLA64] in {
1789
1826
def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64,
1790
1827
PseudoMaskedAtomicSwap32>;
@@ -1847,24 +1884,24 @@ def : AtomicPat<int_loongarch_masked_atomicrmw_umin_i64,
1847
1884
// AtomicOrdering.h.
1848
1885
multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst,
1849
1886
ValueType vt = GRLenVT> {
1850
- def : Pat<(vt (!cast<PatFrag>(Op#"_monotonic ") GPR:$addr, GPR:$cmp, GPR:$new)),
1887
+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_monotonic ") GPR:$addr, GPR:$cmp, GPR:$new)),
1851
1888
(CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 2)>;
1852
- def : Pat<(vt (!cast<PatFrag>(Op#"_acquire ") GPR:$addr, GPR:$cmp, GPR:$new)),
1889
+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acquire ") GPR:$addr, GPR:$cmp, GPR:$new)),
1853
1890
(CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 4)>;
1854
- def : Pat<(vt (!cast<PatFrag>(Op#"_release ") GPR:$addr, GPR:$cmp, GPR:$new)),
1891
+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_release ") GPR:$addr, GPR:$cmp, GPR:$new)),
1855
1892
(CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 5)>;
1856
- def : Pat<(vt (!cast<PatFrag>(Op#"_acq_rel ") GPR:$addr, GPR:$cmp, GPR:$new)),
1893
+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_acq_rel ") GPR:$addr, GPR:$cmp, GPR:$new)),
1857
1894
(CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 6)>;
1858
- def : Pat<(vt (!cast<PatFrag>(Op#"_seq_cst ") GPR:$addr, GPR:$cmp, GPR:$new)),
1895
+ def : Pat<(vt (!cast<PatFrag>(Op#"_failure_seq_cst ") GPR:$addr, GPR:$cmp, GPR:$new)),
1859
1896
(CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;
1860
1897
}
1861
1898
1862
1899
defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>;
1863
1900
defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64, i64>;
1864
1901
def : Pat<(int_loongarch_masked_cmpxchg_i64
1865
- GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering ),
1902
+ GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order ),
1866
1903
(PseudoMaskedCmpXchg32
1867
- GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering )>;
1904
+ GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order )>;
1868
1905
1869
1906
def : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_max_i64,
1870
1907
PseudoMaskedAtomicLoadMax32>;
0 commit comments