@@ -1814,7 +1814,7 @@ def PseudoMaskedAtomicLoadMin32 : PseudoMaskedAMMinMax;
1814
1814
1815
1815
class PseudoCmpXchg
1816
1816
: 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 )> {
1818
1818
let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
1819
1819
let mayLoad = 1;
1820
1820
let mayStore = 1;
@@ -1828,7 +1828,7 @@ def PseudoCmpXchg64 : PseudoCmpXchg;
1828
1828
def PseudoMaskedCmpXchg32
1829
1829
: Pseudo<(outs GPR:$res, GPR:$scratch),
1830
1830
(ins GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask,
1831
- grlenimm:$ordering )> {
1831
+ grlenimm:$fail_order )> {
1832
1832
let Constraints = "@earlyclobber $res,@earlyclobber $scratch";
1833
1833
let mayLoad = 1;
1834
1834
let mayStore = 1;
@@ -1846,6 +1846,43 @@ class AtomicPat<Intrinsic intrin, Pseudo AMInst>
1846
1846
: Pat<(intrin GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering),
1847
1847
(AMInst GPR:$addr, GPR:$incr, GPR:$mask, timm:$ordering)>;
1848
1848
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
+
1849
1886
let Predicates = [IsLA64] in {
1850
1887
def : AtomicPat<int_loongarch_masked_atomicrmw_xchg_i64,
1851
1888
PseudoMaskedAtomicSwap32>;
@@ -1908,24 +1945,24 @@ def : AtomicPat<int_loongarch_masked_atomicrmw_umin_i64,
1908
1945
// AtomicOrdering.h.
1909
1946
multiclass PseudoCmpXchgPat<string Op, Pseudo CmpXchgInst,
1910
1947
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)),
1912
1949
(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)),
1914
1951
(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)),
1916
1953
(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)),
1918
1955
(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)),
1920
1957
(CmpXchgInst GPR:$addr, GPR:$cmp, GPR:$new, 7)>;
1921
1958
}
1922
1959
1923
1960
defm : PseudoCmpXchgPat<"atomic_cmp_swap_32", PseudoCmpXchg32>;
1924
1961
defm : PseudoCmpXchgPat<"atomic_cmp_swap_64", PseudoCmpXchg64, i64>;
1925
1962
def : 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 ),
1927
1964
(PseudoMaskedCmpXchg32
1928
- GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$ordering )>;
1965
+ GPR:$addr, GPR:$cmpval, GPR:$newval, GPR:$mask, timm:$fail_order )>;
1929
1966
1930
1967
def : PseudoMaskedAMMinMaxPat<int_loongarch_masked_atomicrmw_max_i64,
1931
1968
PseudoMaskedAtomicLoadMax32>;
0 commit comments