Skip to content

Commit 435ba72

Browse files
authored
[SystemZ] Simplify handling of AtomicRMW instructions. (#74789)
Let the AtomicExpand pass do more of the job of expanding AtomicRMWInst:s in order to simplify the handling in the backend. The only cases that the backend needs to handle itself are those of subword size (8/16 bits) and those directly corresponding to a target instruction.
1 parent a87738f commit 435ba72

16 files changed

+646
-696
lines changed

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 119 additions & 289 deletions
Large diffs are not rendered by default.

llvm/lib/Target/SystemZ/SystemZISelLowering.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,13 +748,12 @@ class SystemZTargetLowering : public TargetLowering {
748748
bool ClearEven) const;
749749
MachineBasicBlock *emitAtomicLoadBinary(MachineInstr &MI,
750750
MachineBasicBlock *BB,
751-
unsigned BinOpcode, unsigned BitSize,
751+
unsigned BinOpcode,
752752
bool Invert = false) const;
753753
MachineBasicBlock *emitAtomicLoadMinMax(MachineInstr &MI,
754754
MachineBasicBlock *MBB,
755755
unsigned CompareOpcode,
756-
unsigned KeepOldMask,
757-
unsigned BitSize) const;
756+
unsigned KeepOldMask) const;
758757
MachineBasicBlock *emitAtomicCmpSwapW(MachineInstr &MI,
759758
MachineBasicBlock *BB) const;
760759
MachineBasicBlock *emitMemMemWrapper(MachineInstr &MI, MachineBasicBlock *BB,

llvm/lib/Target/SystemZ/SystemZInstrFormats.td

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5327,30 +5327,6 @@ multiclass CondStores<RegisterOperand cls, SDPatternOperator store,
53275327
}
53285328
}
53295329

5330-
// OPERATOR is ATOMIC_SWAP or an ATOMIC_LOAD_* operation. PAT and OPERAND
5331-
// describe the second (non-memory) operand.
5332-
class AtomicLoadBinary<SDPatternOperator operator, RegisterOperand cls,
5333-
dag pat, DAGOperand operand>
5334-
: Pseudo<(outs cls:$dst), (ins bdaddr20only:$ptr, operand:$src2),
5335-
[(set cls:$dst, (operator bdaddr20only:$ptr, pat))]> {
5336-
let Defs = [CC];
5337-
let Has20BitOffset = 1;
5338-
let mayLoad = 1;
5339-
let mayStore = 1;
5340-
let usesCustomInserter = 1;
5341-
let hasNoSchedulingInfo = 1;
5342-
}
5343-
5344-
// Specializations of AtomicLoadWBinary.
5345-
class AtomicLoadBinaryReg32<SDPatternOperator operator>
5346-
: AtomicLoadBinary<operator, GR32, (i32 GR32:$src2), GR32>;
5347-
class AtomicLoadBinaryImm32<SDPatternOperator operator, ImmOpWithPattern imm>
5348-
: AtomicLoadBinary<operator, GR32, (i32 imm:$src2), imm>;
5349-
class AtomicLoadBinaryReg64<SDPatternOperator operator>
5350-
: AtomicLoadBinary<operator, GR64, (i64 GR64:$src2), GR64>;
5351-
class AtomicLoadBinaryImm64<SDPatternOperator operator, ImmOpWithPattern imm>
5352-
: AtomicLoadBinary<operator, GR64, (i64 imm:$src2), imm>;
5353-
53545330
// OPERATOR is ATOMIC_SWAPW or an ATOMIC_LOADW_* operation. PAT and OPERAND
53555331
// describe the second (non-memory) operand.
53565332
class AtomicLoadWBinary<SDPatternOperator operator, dag pat,

llvm/lib/Target/SystemZ/SystemZInstrInfo.td

Lines changed: 0 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1746,112 +1746,29 @@ let Predicates = [FeatureInterlockedAccess1], Defs = [CC] in {
17461746
}
17471747

17481748
def ATOMIC_SWAPW : AtomicLoadWBinaryReg<z_atomic_swapw>;
1749-
def ATOMIC_SWAP_32 : AtomicLoadBinaryReg32<atomic_swap_32>;
1750-
def ATOMIC_SWAP_64 : AtomicLoadBinaryReg64<atomic_swap_64>;
17511749

17521750
def ATOMIC_LOADW_AR : AtomicLoadWBinaryReg<z_atomic_loadw_add>;
17531751
def ATOMIC_LOADW_AFI : AtomicLoadWBinaryImm<z_atomic_loadw_add, simm32>;
1754-
let Predicates = [FeatureNoInterlockedAccess1] in {
1755-
def ATOMIC_LOAD_AR : AtomicLoadBinaryReg32<atomic_load_add_32>;
1756-
def ATOMIC_LOAD_AHI : AtomicLoadBinaryImm32<atomic_load_add_32, imm32sx16>;
1757-
def ATOMIC_LOAD_AFI : AtomicLoadBinaryImm32<atomic_load_add_32, simm32>;
1758-
def ATOMIC_LOAD_AGR : AtomicLoadBinaryReg64<atomic_load_add_64>;
1759-
def ATOMIC_LOAD_AGHI : AtomicLoadBinaryImm64<atomic_load_add_64, imm64sx16>;
1760-
def ATOMIC_LOAD_AGFI : AtomicLoadBinaryImm64<atomic_load_add_64, imm64sx32>;
1761-
}
17621752

17631753
def ATOMIC_LOADW_SR : AtomicLoadWBinaryReg<z_atomic_loadw_sub>;
1764-
def ATOMIC_LOAD_SR : AtomicLoadBinaryReg32<atomic_load_sub_32>;
1765-
def ATOMIC_LOAD_SGR : AtomicLoadBinaryReg64<atomic_load_sub_64>;
17661754

17671755
def ATOMIC_LOADW_NR : AtomicLoadWBinaryReg<z_atomic_loadw_and>;
17681756
def ATOMIC_LOADW_NILH : AtomicLoadWBinaryImm<z_atomic_loadw_and, imm32lh16c>;
1769-
let Predicates = [FeatureNoInterlockedAccess1] in {
1770-
def ATOMIC_LOAD_NR : AtomicLoadBinaryReg32<atomic_load_and_32>;
1771-
def ATOMIC_LOAD_NILL : AtomicLoadBinaryImm32<atomic_load_and_32,
1772-
imm32ll16c>;
1773-
def ATOMIC_LOAD_NILH : AtomicLoadBinaryImm32<atomic_load_and_32,
1774-
imm32lh16c>;
1775-
def ATOMIC_LOAD_NILF : AtomicLoadBinaryImm32<atomic_load_and_32, uimm32>;
1776-
def ATOMIC_LOAD_NGR : AtomicLoadBinaryReg64<atomic_load_and_64>;
1777-
def ATOMIC_LOAD_NILL64 : AtomicLoadBinaryImm64<atomic_load_and_64,
1778-
imm64ll16c>;
1779-
def ATOMIC_LOAD_NILH64 : AtomicLoadBinaryImm64<atomic_load_and_64,
1780-
imm64lh16c>;
1781-
def ATOMIC_LOAD_NIHL64 : AtomicLoadBinaryImm64<atomic_load_and_64,
1782-
imm64hl16c>;
1783-
def ATOMIC_LOAD_NIHH64 : AtomicLoadBinaryImm64<atomic_load_and_64,
1784-
imm64hh16c>;
1785-
def ATOMIC_LOAD_NILF64 : AtomicLoadBinaryImm64<atomic_load_and_64,
1786-
imm64lf32c>;
1787-
def ATOMIC_LOAD_NIHF64 : AtomicLoadBinaryImm64<atomic_load_and_64,
1788-
imm64hf32c>;
1789-
}
17901757

17911758
def ATOMIC_LOADW_OR : AtomicLoadWBinaryReg<z_atomic_loadw_or>;
17921759
def ATOMIC_LOADW_OILH : AtomicLoadWBinaryImm<z_atomic_loadw_or, imm32lh16>;
1793-
let Predicates = [FeatureNoInterlockedAccess1] in {
1794-
def ATOMIC_LOAD_OR : AtomicLoadBinaryReg32<atomic_load_or_32>;
1795-
def ATOMIC_LOAD_OILL : AtomicLoadBinaryImm32<atomic_load_or_32, imm32ll16>;
1796-
def ATOMIC_LOAD_OILH : AtomicLoadBinaryImm32<atomic_load_or_32, imm32lh16>;
1797-
def ATOMIC_LOAD_OILF : AtomicLoadBinaryImm32<atomic_load_or_32, uimm32>;
1798-
def ATOMIC_LOAD_OGR : AtomicLoadBinaryReg64<atomic_load_or_64>;
1799-
def ATOMIC_LOAD_OILL64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64ll16>;
1800-
def ATOMIC_LOAD_OILH64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64lh16>;
1801-
def ATOMIC_LOAD_OIHL64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hl16>;
1802-
def ATOMIC_LOAD_OIHH64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hh16>;
1803-
def ATOMIC_LOAD_OILF64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64lf32>;
1804-
def ATOMIC_LOAD_OIHF64 : AtomicLoadBinaryImm64<atomic_load_or_64, imm64hf32>;
1805-
}
18061760

18071761
def ATOMIC_LOADW_XR : AtomicLoadWBinaryReg<z_atomic_loadw_xor>;
18081762
def ATOMIC_LOADW_XILF : AtomicLoadWBinaryImm<z_atomic_loadw_xor, uimm32>;
1809-
let Predicates = [FeatureNoInterlockedAccess1] in {
1810-
def ATOMIC_LOAD_XR : AtomicLoadBinaryReg32<atomic_load_xor_32>;
1811-
def ATOMIC_LOAD_XILF : AtomicLoadBinaryImm32<atomic_load_xor_32, uimm32>;
1812-
def ATOMIC_LOAD_XGR : AtomicLoadBinaryReg64<atomic_load_xor_64>;
1813-
def ATOMIC_LOAD_XILF64 : AtomicLoadBinaryImm64<atomic_load_xor_64, imm64lf32>;
1814-
def ATOMIC_LOAD_XIHF64 : AtomicLoadBinaryImm64<atomic_load_xor_64, imm64hf32>;
1815-
}
18161763

18171764
def ATOMIC_LOADW_NRi : AtomicLoadWBinaryReg<z_atomic_loadw_nand>;
18181765
def ATOMIC_LOADW_NILHi : AtomicLoadWBinaryImm<z_atomic_loadw_nand,
18191766
imm32lh16c>;
1820-
def ATOMIC_LOAD_NRi : AtomicLoadBinaryReg32<atomic_load_nand_32>;
1821-
def ATOMIC_LOAD_NILLi : AtomicLoadBinaryImm32<atomic_load_nand_32,
1822-
imm32ll16c>;
1823-
def ATOMIC_LOAD_NILHi : AtomicLoadBinaryImm32<atomic_load_nand_32,
1824-
imm32lh16c>;
1825-
def ATOMIC_LOAD_NILFi : AtomicLoadBinaryImm32<atomic_load_nand_32, uimm32>;
1826-
def ATOMIC_LOAD_NGRi : AtomicLoadBinaryReg64<atomic_load_nand_64>;
1827-
def ATOMIC_LOAD_NILL64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
1828-
imm64ll16c>;
1829-
def ATOMIC_LOAD_NILH64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
1830-
imm64lh16c>;
1831-
def ATOMIC_LOAD_NIHL64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
1832-
imm64hl16c>;
1833-
def ATOMIC_LOAD_NIHH64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
1834-
imm64hh16c>;
1835-
def ATOMIC_LOAD_NILF64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
1836-
imm64lf32c>;
1837-
def ATOMIC_LOAD_NIHF64i : AtomicLoadBinaryImm64<atomic_load_nand_64,
1838-
imm64hf32c>;
18391767

18401768
def ATOMIC_LOADW_MIN : AtomicLoadWBinaryReg<z_atomic_loadw_min>;
1841-
def ATOMIC_LOAD_MIN_32 : AtomicLoadBinaryReg32<atomic_load_min_32>;
1842-
def ATOMIC_LOAD_MIN_64 : AtomicLoadBinaryReg64<atomic_load_min_64>;
1843-
18441769
def ATOMIC_LOADW_MAX : AtomicLoadWBinaryReg<z_atomic_loadw_max>;
1845-
def ATOMIC_LOAD_MAX_32 : AtomicLoadBinaryReg32<atomic_load_max_32>;
1846-
def ATOMIC_LOAD_MAX_64 : AtomicLoadBinaryReg64<atomic_load_max_64>;
1847-
18481770
def ATOMIC_LOADW_UMIN : AtomicLoadWBinaryReg<z_atomic_loadw_umin>;
1849-
def ATOMIC_LOAD_UMIN_32 : AtomicLoadBinaryReg32<atomic_load_umin_32>;
1850-
def ATOMIC_LOAD_UMIN_64 : AtomicLoadBinaryReg64<atomic_load_umin_64>;
1851-
18521771
def ATOMIC_LOADW_UMAX : AtomicLoadWBinaryReg<z_atomic_loadw_umax>;
1853-
def ATOMIC_LOAD_UMAX_32 : AtomicLoadBinaryReg32<atomic_load_umax_32>;
1854-
def ATOMIC_LOAD_UMAX_64 : AtomicLoadBinaryReg64<atomic_load_umax_64>;
18551772

18561773
def ATOMIC_CMP_SWAPW
18571774
: Pseudo<(outs GR32:$dst), (ins bdaddr20only:$addr, GR32:$cmp, GR32:$swap,

llvm/test/CodeGen/SystemZ/atomicrmw-add-04.ll

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -16,96 +16,77 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
1616
ret i64 %res
1717
}
1818

19-
; Check addition of 1, which can use AGHI.
19+
; Check addition of 1.
2020
define i64 @f2(i64 %dummy, ptr %src) {
2121
; CHECK-LABEL: f2:
2222
; CHECK: lg %r2, 0(%r3)
2323
; CHECK: [[LABEL:\.[^:]*]]:
24-
; CHECK: lgr %r0, %r2
25-
; CHECK: aghi %r0, 1
24+
; CHECK: la %r0, 1(%r2)
2625
; CHECK: csg %r2, %r0, 0(%r3)
2726
; CHECK: jl [[LABEL]]
2827
; CHECK: br %r14
2928
%res = atomicrmw add ptr %src, i64 1 seq_cst
3029
ret i64 %res
3130
}
3231

33-
; Check the high end of the AGHI range.
32+
; Check use of LAY.
3433
define i64 @f3(i64 %dummy, ptr %src) {
3534
; CHECK-LABEL: f3:
36-
; CHECK: aghi %r0, 32767
35+
; CHECK: lay %r0, 32767(%r2)
3736
; CHECK: br %r14
3837
%res = atomicrmw add ptr %src, i64 32767 seq_cst
3938
ret i64 %res
4039
}
4140

42-
; Check the next value up, which must use AGFI.
41+
; Check the high end of the AGFI range.
4342
define i64 @f4(i64 %dummy, ptr %src) {
4443
; CHECK-LABEL: f4:
45-
; CHECK: agfi %r0, 32768
44+
; CHECK: agfi %r0, 2147483647
4645
; CHECK: br %r14
47-
%res = atomicrmw add ptr %src, i64 32768 seq_cst
46+
%res = atomicrmw add ptr %src, i64 2147483647 seq_cst
4847
ret i64 %res
4948
}
5049

51-
; Check the high end of the AGFI range.
50+
; Check the next value up, which uses an ALGFI.
5251
define i64 @f5(i64 %dummy, ptr %src) {
5352
; CHECK-LABEL: f5:
54-
; CHECK: agfi %r0, 2147483647
53+
; CHECK: algfi %r0, 2147483648
5554
; CHECK: br %r14
56-
%res = atomicrmw add ptr %src, i64 2147483647 seq_cst
55+
%res = atomicrmw add ptr %src, i64 2147483648 seq_cst
5756
ret i64 %res
5857
}
5958

60-
; Check the next value up, which must use a register addition.
59+
; Check addition of -1, which can use LAY.
6160
define i64 @f6(i64 %dummy, ptr %src) {
6261
; CHECK-LABEL: f6:
63-
; CHECK: agr
62+
; CHECK: lay %r0, -1(%r2)
6463
; CHECK: br %r14
65-
%res = atomicrmw add ptr %src, i64 2147483648 seq_cst
64+
%res = atomicrmw add ptr %src, i64 -1 seq_cst
6665
ret i64 %res
6766
}
6867

69-
; Check addition of -1, which can use AGHI.
68+
; LAY still OK.
7069
define i64 @f7(i64 %dummy, ptr %src) {
7170
; CHECK-LABEL: f7:
72-
; CHECK: aghi %r0, -1
73-
; CHECK: br %r14
74-
%res = atomicrmw add ptr %src, i64 -1 seq_cst
75-
ret i64 %res
76-
}
77-
78-
; Check the low end of the AGHI range.
79-
define i64 @f8(i64 %dummy, ptr %src) {
80-
; CHECK-LABEL: f8:
81-
; CHECK: aghi %r0, -32768
82-
; CHECK: br %r14
83-
%res = atomicrmw add ptr %src, i64 -32768 seq_cst
84-
ret i64 %res
85-
}
86-
87-
; Check the next value down, which must use AGFI instead.
88-
define i64 @f9(i64 %dummy, ptr %src) {
89-
; CHECK-LABEL: f9:
90-
; CHECK: agfi %r0, -32769
71+
; CHECK: lay %r0, -32769(%r2)
9172
; CHECK: br %r14
9273
%res = atomicrmw add ptr %src, i64 -32769 seq_cst
9374
ret i64 %res
9475
}
9576

9677
; Check the low end of the AGFI range.
97-
define i64 @f10(i64 %dummy, ptr %src) {
98-
; CHECK-LABEL: f10:
78+
define i64 @f8(i64 %dummy, ptr %src) {
79+
; CHECK-LABEL: f8:
9980
; CHECK: agfi %r0, -2147483648
10081
; CHECK: br %r14
10182
%res = atomicrmw add ptr %src, i64 -2147483648 seq_cst
10283
ret i64 %res
10384
}
10485

105-
; Check the next value down, which must use a register addition.
106-
define i64 @f11(i64 %dummy, ptr %src) {
107-
; CHECK-LABEL: f11:
108-
; CHECK: agr
86+
; Check the next value down, which uses an SLGFI.
87+
define i64 @f9(i64 %dummy, ptr %src) {
88+
; CHECK-LABEL: f9:
89+
; CHECK: slgfi %r0, 2147483649
10990
; CHECK: br %r14
11091
%res = atomicrmw add ptr %src, i64 -2147483649 seq_cst
11192
ret i64 %res

llvm/test/CodeGen/SystemZ/atomicrmw-and-03.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ define i32 @f2(i32 %dummy, ptr %src) {
3333
; Check ANDs of the low end of the NILH range.
3434
define i32 @f3(i32 %dummy, ptr %src) {
3535
; CHECK-LABEL: f3:
36-
; CHECK: nilh %r0, 0
36+
; CHECK: llhr %r0, %r2
3737
; CHECK: br %r14
3838
%res = atomicrmw and ptr %src, i32 65535 seq_cst
3939
ret i32 %res

llvm/test/CodeGen/SystemZ/atomicrmw-and-04.ll

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@ define i64 @f1(i64 %dummy, ptr %src, i64 %b) {
1616
ret i64 %res
1717
}
1818

19-
; Check ANDs of 1, which are done using a register. (We could use RISBG
20-
; instead, but that isn't implemented yet.)
19+
; Check ANDs of 1, which are done using a register.
2120
define i64 @f2(i64 %dummy, ptr %src) {
2221
; CHECK-LABEL: f2:
23-
; CHECK: ngr
22+
; CHECK: risbg
2423
; CHECK: br %r14
2524
%res = atomicrmw and ptr %src, i64 1 seq_cst
2625
ret i64 %res
@@ -56,7 +55,7 @@ define i64 @f4(i64 %dummy, ptr %src) {
5655
; Check the next value up, which must use a register.
5756
define i64 @f5(i64 %dummy, ptr %src) {
5857
; CHECK-LABEL: f5:
59-
; CHECK: ngr
58+
; CHECK: risbg
6059
; CHECK: br %r14
6160
%res = atomicrmw and ptr %src, i64 12884901888 seq_cst
6261
ret i64 %res
@@ -74,7 +73,7 @@ define i64 @f6(i64 %dummy, ptr %src) {
7473
; Check the next value up, which must use a register.
7574
define i64 @f7(i64 %dummy, ptr %src) {
7675
; CHECK-LABEL: f7:
77-
; CHECK: ngr
76+
; CHECK: risbg
7877
; CHECK: br %r14
7978
%res = atomicrmw and ptr %src, i64 281474976710656 seq_cst
8079
ret i64 %res

0 commit comments

Comments
 (0)