Skip to content

Commit e13f1d1

Browse files
authored
[M68k] ARII atomic load/store (#108982)
Only ARI was supported, this PR adds ARII support for atomic loads/stores (also with zero displacement). Closes #107939
1 parent 721b796 commit e13f1d1

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,6 +772,20 @@ static bool isAddressBase(const SDValue &N) {
772772
}
773773
}
774774

775+
static bool AllowARIIWithZeroDisp(SDNode *Parent) {
776+
if (!Parent)
777+
return false;
778+
switch (Parent->getOpcode()) {
779+
case ISD::LOAD:
780+
case ISD::STORE:
781+
case ISD::ATOMIC_LOAD:
782+
case ISD::ATOMIC_STORE:
783+
return true;
784+
default:
785+
return false;
786+
}
787+
}
788+
775789
bool M68kDAGToDAGISel::SelectARII(SDNode *Parent, SDValue N, SDValue &Disp,
776790
SDValue &Base, SDValue &Index) {
777791
M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARII);
@@ -811,8 +825,7 @@ bool M68kDAGToDAGISel::SelectARII(SDNode *Parent, SDValue N, SDValue &Disp,
811825
// The idea here is that we want to use AddrType::ARII without displacement
812826
// only if necessary like memory operations, otherwise this must be lowered
813827
// into addition
814-
if (AM.Disp == 0 && (!Parent || (Parent->getOpcode() != ISD::LOAD &&
815-
Parent->getOpcode() != ISD::STORE))) {
828+
if (AM.Disp == 0 && !AllowARIIWithZeroDisp(Parent)) {
816829
LLVM_DEBUG(dbgs() << "REJECT: Displacement is Zero\n");
817830
return false;
818831
}

llvm/lib/Target/M68k/M68kInstrAtomics.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,16 @@ foreach size = [8, 16, 32] in {
1010
def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_ARI:$ptr),
1111
(!cast<MxInst>("MOV"#size#"dj") !cast<MxMemOp>("MxARI"#size):$ptr)>;
1212

13+
def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_ARII:$ptr),
14+
(!cast<MxInst>("MOV"#size#"df") !cast<MxMemOp>("MxARII"#size):$ptr)>;
15+
1316
def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_ARI:$ptr),
1417
(!cast<MxInst>("MOV"#size#"jd") !cast<MxMemOp>("MxARI"#size):$ptr,
1518
!cast<MxRegOp>("MxDRD"#size):$val)>;
19+
20+
def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_ARII:$ptr),
21+
(!cast<MxInst>("MOV"#size#"fd") !cast<MxMemOp>("MxARII"#size):$ptr,
22+
!cast<MxRegOp>("MxDRD"#size):$val)>;
1623
}
1724

1825
let Predicates = [AtLeastM68020] in {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68000 | FileCheck %s --check-prefix=NO-ATOMIC
3+
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68010 | FileCheck %s --check-prefix=NO-ATOMIC
4+
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68020 | FileCheck %s --check-prefix=ATOMIC
5+
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68030 | FileCheck %s --check-prefix=ATOMIC
6+
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68040 | FileCheck %s --check-prefix=ATOMIC
7+
8+
define void @atomic_store_i8_element_monotonic(i8 %val, ptr %base, i32 %offset) nounwind {
9+
; NO-ATOMIC-LABEL: atomic_store_i8_element_monotonic:
10+
; NO-ATOMIC: ; %bb.0:
11+
; NO-ATOMIC-NEXT: move.b (7,%sp), %d0
12+
; NO-ATOMIC-NEXT: move.l (12,%sp), %d1
13+
; NO-ATOMIC-NEXT: move.l (8,%sp), %a0
14+
; NO-ATOMIC-NEXT: move.b %d0, (0,%a0,%d1)
15+
; NO-ATOMIC-NEXT: rts
16+
;
17+
; ATOMIC-LABEL: atomic_store_i8_element_monotonic:
18+
; ATOMIC: ; %bb.0:
19+
; ATOMIC-NEXT: move.b (7,%sp), %d0
20+
; ATOMIC-NEXT: move.l (12,%sp), %d1
21+
; ATOMIC-NEXT: move.l (8,%sp), %a0
22+
; ATOMIC-NEXT: move.b %d0, (0,%a0,%d1)
23+
; ATOMIC-NEXT: rts
24+
%store_pointer = getelementptr i8, ptr %base, i32 %offset
25+
store atomic i8 %val, ptr %store_pointer monotonic, align 1
26+
ret void
27+
}
28+
29+
define i8 @atomic_load_i8_element_monotonic(ptr %base, i32 %offset) nounwind {
30+
; NO-ATOMIC-LABEL: atomic_load_i8_element_monotonic:
31+
; NO-ATOMIC: ; %bb.0:
32+
; NO-ATOMIC-NEXT: move.l (8,%sp), %d0
33+
; NO-ATOMIC-NEXT: move.l (4,%sp), %a0
34+
; NO-ATOMIC-NEXT: move.b (0,%a0,%d0), %d0
35+
; NO-ATOMIC-NEXT: rts
36+
;
37+
; ATOMIC-LABEL: atomic_load_i8_element_monotonic:
38+
; ATOMIC: ; %bb.0:
39+
; ATOMIC-NEXT: move.l (8,%sp), %d0
40+
; ATOMIC-NEXT: move.l (4,%sp), %a0
41+
; ATOMIC-NEXT: move.b (0,%a0,%d0), %d0
42+
; ATOMIC-NEXT: rts
43+
%load_pointer = getelementptr i8, ptr %base, i32 %offset
44+
%return_val = load atomic i8, ptr %load_pointer monotonic, align 1
45+
ret i8 %return_val
46+
}

0 commit comments

Comments
 (0)