[llvm] Handle moves of non-16 size to/from CCR (PR #108581)

via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 16 05:39:43 PDT 2024


https://github.com/knickish updated https://github.com/llvm/llvm-project/pull/108581

>From 8f0178d6f2147b5b9849642415ffcc3087c0a05b Mon Sep 17 00:00:00 2001
From: kirk <knickish at gmail.com>
Date: Fri, 13 Sep 2024 14:34:06 +0000
Subject: [PATCH 1/3] add pseudo instrs for 8 and 32 bit src/dst ccr moves and
 expand them to 16 bit instrs

---
 llvm/lib/Target/M68k/M68kExpandPseudo.cpp |  3 +++
 llvm/lib/Target/M68k/M68kInstrData.td     |  6 +++++
 llvm/lib/Target/M68k/M68kInstrInfo.cpp    | 27 ++++++++++++++++++-----
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
index c7fdd7d7c35023..e2e32a474cfd67 100644
--- a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
+++ b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
@@ -189,8 +189,11 @@ bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
                                 MVT::i16);
 
   case M68k::MOV8cd:
+  case M68k::MOV32cd:
     return TII->ExpandCCR(MIB, /*IsToCCR=*/true);
+
   case M68k::MOV8dc:
+  case M68k::MOV32dc:
     return TII->ExpandCCR(MIB, /*IsToCCR=*/false);
 
   case M68k::MOVM8jm_P:
diff --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td
index dc777a933e2786..be2d43ce1de3ae 100644
--- a/llvm/lib/Target/M68k/M68kInstrData.td
+++ b/llvm/lib/Target/M68k/M68kInstrData.td
@@ -385,12 +385,14 @@ class MxMoveToCCRPseudo<MxOperand MEMOp>
 
 let mayLoad = 1 in
 foreach AM = MxMoveSupportedAMs in {
+  def MOV32c # AM : MxMoveToCCRPseudo<!cast<MxOpBundle>("MxOp32AddrMode_"#AM).Op>;
   def MOV16c # AM : MxMoveToCCR<!cast<MxOpBundle>("MxOp16AddrMode_"#AM).Op,
                                 !cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM)>;
   def MOV8c # AM  : MxMoveToCCRPseudo<!cast<MxOpBundle>("MxOp8AddrMode_"#AM).Op>;
 } // foreach AM
 
 // Only data register is allowed.
+def MOV32cd : MxMoveToCCRPseudo<MxOp32AddrMode_d.Op>;
 def MOV16cd : MxMoveToCCR<MxOp16AddrMode_d.Op, MxMoveSrcOpEnc_d>;
 def MOV8cd  : MxMoveToCCRPseudo<MxOp8AddrMode_d.Op>;
 
@@ -423,6 +425,9 @@ class MxMoveFromCCRPseudo<MxOperand MEMOp>
 
 let mayStore = 1 in
 foreach AM = MxMoveSupportedAMs in {
+  def MOV32 # AM # c
+    : MxMoveFromCCR_M<!cast<MxOpBundle>("MxOp32AddrMode_"#AM).Op,
+                      !cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM)>;
   def MOV16 # AM # c
     : MxMoveFromCCR_M<!cast<MxOpBundle>("MxOp16AddrMode_"#AM).Op,
                       !cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM)>;
@@ -431,6 +436,7 @@ foreach AM = MxMoveSupportedAMs in {
 } // foreach AM
 
 // Only data register is allowed.
+def MOV32dc : MxMoveFromCCRPseudo<MxOp32AddrMode_d.Op>;
 def MOV16dc : MxMoveFromCCR_R;
 def MOV8dc  : MxMoveFromCCRPseudo<MxOp8AddrMode_d.Op>;
 
diff --git a/llvm/lib/Target/M68k/M68kInstrInfo.cpp b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
index 2d9285f89b74ae..80febbde4dadc1 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.cpp
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
@@ -757,13 +757,28 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
   bool ToSR = DstReg == M68k::SR;
 
   if (FromCCR) {
-    assert(M68k::DR8RegClass.contains(DstReg) &&
-           "Need DR8 register to copy CCR");
-    Opc = M68k::MOV8dc;
+    if (M68k::DR8RegClass.contains(DstReg))
+      Opc = M68k::MOV8dc;
+    else if (M68k::DR16RegClass.contains(DstReg))
+      Opc = M68k::MOV16dc;
+    else if (M68k::DR32RegClass.contains(DstReg))
+      Opc = M68k::MOV32dc;
+    else {
+    LLVM_DEBUG(dbgs() << "Cannot copy CCR to " << RI.getName(DstReg) 
+                << "(" << RI.getRegClass(DstReg) << ')\n');
+    llvm_unreachable("Invalid register for MOVE from CCR");
+    }
   } else if (ToCCR) {
-    assert(M68k::DR8RegClass.contains(SrcReg) &&
-           "Need DR8 register to copy CCR");
-    Opc = M68k::MOV8cd;
+    if (M68k::DR8RegClass.contains(SrcReg))
+      Opc = M68k::MOV8cd;
+    else if (M68k::DR16RegClass.contains(SrcReg))
+      Opc = M68k::MOV16cd;
+    else if (M68k::DR32RegClass.contains(SrcReg))
+      Opc = M68k::MOV32cd;
+    else {
+      LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to CCR" << '\n');
+      llvm_unreachable("Invalid register for MOVE to CCR");
+    }
   } else if (FromSR || ToSR)
     llvm_unreachable("Cannot emit SR copy instruction");
 

>From 45ec934fe27b4b81c82b5cd0c9f15a34c08cb586 Mon Sep 17 00:00:00 2001
From: kirk <knickish at gmail.com>
Date: Mon, 16 Sep 2024 12:22:26 +0000
Subject: [PATCH 2/3] add m68k filecheck test showing iselect failure for
 non-ARI atomic store

---
 llvm/test/CodeGen/M68k/Atomics/load-store.ll | 18 ++++++++
 llvm/test/CodeGen/M68k/Atomics/non-ari.ll    | 46 ++++++++++++++++++++
 2 files changed, 64 insertions(+)
 create mode 100644 llvm/test/CodeGen/M68k/Atomics/non-ari.ll

diff --git a/llvm/test/CodeGen/M68k/Atomics/load-store.ll b/llvm/test/CodeGen/M68k/Atomics/load-store.ll
index 23fdfad05cab5d..f7d12d5abb6249 100644
--- a/llvm/test/CodeGen/M68k/Atomics/load-store.ll
+++ b/llvm/test/CodeGen/M68k/Atomics/load-store.ll
@@ -604,3 +604,21 @@ define void @atomic_store_i64_seq_cst(ptr %a, i64 %val) nounwind {
   store atomic i64 %val, ptr %a seq_cst, align 8
   ret void
 }
+
+define void @atomic_store_i8_unordered(ptr %a, i8 %val) nounwind {
+; NO-ATOMIC-LABEL: atomic_store_i8_unordered:
+; NO-ATOMIC:       ; %bb.0:
+; NO-ATOMIC-NEXT:    move.b (11,%sp), %d0
+; NO-ATOMIC-NEXT:    move.l (4,%sp), %a0
+; NO-ATOMIC-NEXT:    move.b %d0, (%a0)
+; NO-ATOMIC-NEXT:    rts
+;
+; ATOMIC-LABEL: atomic_store_i8_unordered:
+; ATOMIC:       ; %bb.0:
+; ATOMIC-NEXT:    move.b (11,%sp), %d0
+; ATOMIC-NEXT:    move.l (4,%sp), %a0
+; ATOMIC-NEXT:    move.b %d0, (%a0)
+; ATOMIC-NEXT:    rts
+  store atomic i8 %val, ptr %a unordered, align 1
+  ret void
+}
diff --git a/llvm/test/CodeGen/M68k/Atomics/non-ari.ll b/llvm/test/CodeGen/M68k/Atomics/non-ari.ll
new file mode 100644
index 00000000000000..1ae545ed87227e
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Atomics/non-ari.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc %s -o - -mtriple=m68k -mcpu=M68000 | FileCheck %s --check-prefix=NO-ATOMIC
+; RUN: llc %s -o - -mtriple=m68k -mcpu=M68010 | FileCheck %s --check-prefix=NO-ATOMIC
+; RUN: llc %s -o - -mtriple=m68k -mcpu=M68020 | FileCheck %s --check-prefix=ATOMIC
+; RUN: llc %s -o - -mtriple=m68k -mcpu=M68030 | FileCheck %s --check-prefix=ATOMIC
+; RUN: llc %s -o - -mtriple=m68k -mcpu=M68040 | FileCheck %s --check-prefix=ATOMIC
+
+define void @atomic_store_i8_element_monotonic(i8 %val, ptr %base, i32 %offset) nounwind {
+; NO-ATOMIC-LABEL: atomic_store_i8_element_monotonic:
+; NO-ATOMIC:       ; %bb.0:
+; NO-ATOMIC-NEXT:    move.b (7,%sp), %d0
+; NO-ATOMIC-NEXT:    move.l (12,%sp), %d1
+; NO-ATOMIC-NEXT:    move.l (8,%sp), %a0
+; NO-ATOMIC-NEXT:    move.b %d0, (0,%a0,%d1)
+; NO-ATOMIC-NEXT:    rts
+;
+; ATOMIC-LABEL: atomic_store_i8_element_monotonic:
+; ATOMIC:       ; %bb.0:
+; ATOMIC-NEXT:    move.b (7,%sp), %d0
+; ATOMIC-NEXT:    move.l (12,%sp), %d1
+; ATOMIC-NEXT:    move.l (8,%sp), %a0
+; ATOMIC-NEXT:    move.b %d0, (0,%a0,%d1)
+; ATOMIC-NEXT:    rts
+  %store_pointer = getelementptr i8, ptr %base, i32 %offset
+  store atomic i8 %val, ptr %store_pointer monotonic, align 1
+  ret void
+}
+
+define i8 @atomic_load_i8_element_monotonic(ptr %base, i32 %offset) nounwind {
+; NO-ATOMIC-LABEL: atomic_load_i8_element_monotonic:
+; NO-ATOMIC:       ; %bb.0:
+; NO-ATOMIC-NEXT:    move.l (8,%sp), %d0
+; NO-ATOMIC-NEXT:    move.l (4,%sp), %a0
+; NO-ATOMIC-NEXT:    move.b (0,%a0,%d0), %d0
+; NO-ATOMIC-NEXT:    rts
+;
+; ATOMIC-LABEL: atomic_load_i8_element_monotonic:
+; ATOMIC:       ; %bb.0:
+; ATOMIC-NEXT:    move.l (8,%sp), %d0
+; ATOMIC-NEXT:    move.l (4,%sp), %a0
+; ATOMIC-NEXT:    move.b (0,%a0,%d0), %d0
+; ATOMIC-NEXT:    rts
+  %load_pointer = getelementptr i8, ptr %base, i32 %offset
+  %return_val = load atomic i8, ptr %load_pointer monotonic, align 1
+  ret i8 %return_val
+}

>From bccd237b04e69fcfefc6feee8e2909a053268cc5 Mon Sep 17 00:00:00 2001
From: kirk <knickish at gmail.com>
Date: Mon, 16 Sep 2024 12:36:04 +0000
Subject: [PATCH 3/3] add m68k isel support for non-ARI atomic loads/stores

---
 llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp | 16 ++++++++++++++--
 llvm/lib/Target/M68k/M68kInstrAtomics.td  |  7 +++++++
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
index dc89fec8108c2d..a6f393bcd8624b 100644
--- a/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
+++ b/llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp
@@ -772,6 +772,19 @@ static bool isAddressBase(const SDValue &N) {
   }
 }
 
+static bool AllowARIIWithZeroDisp(SDNode *Parent) {
+  if (!Parent) return false;
+  switch (Parent->getOpcode()) {
+    case ISD::LOAD:
+    case ISD::STORE:
+    case ISD::ATOMIC_LOAD:
+    case ISD::ATOMIC_STORE:
+      return true;
+    default:
+      return false;
+  }
+}
+
 bool M68kDAGToDAGISel::SelectARII(SDNode *Parent, SDValue N, SDValue &Disp,
                                   SDValue &Base, SDValue &Index) {
   M68kISelAddressMode AM(M68kISelAddressMode::AddrType::ARII);
@@ -811,8 +824,7 @@ bool M68kDAGToDAGISel::SelectARII(SDNode *Parent, SDValue N, SDValue &Disp,
   // The idea here is that we want to use AddrType::ARII without displacement
   // only if necessary like memory operations, otherwise this must be lowered
   // into addition
-  if (AM.Disp == 0 && (!Parent || (Parent->getOpcode() != ISD::LOAD &&
-                                   Parent->getOpcode() != ISD::STORE))) {
+  if (AM.Disp == 0 && !AllowARIIWithZeroDisp(Parent)) {
     LLVM_DEBUG(dbgs() << "REJECT: Displacement is Zero\n");
     return false;
   }
diff --git a/llvm/lib/Target/M68k/M68kInstrAtomics.td b/llvm/lib/Target/M68k/M68kInstrAtomics.td
index 84a66253354229..9203a3ef4ed093 100644
--- a/llvm/lib/Target/M68k/M68kInstrAtomics.td
+++ b/llvm/lib/Target/M68k/M68kInstrAtomics.td
@@ -10,9 +10,16 @@ foreach size = [8, 16, 32] in {
   def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_ARI:$ptr),
             (!cast<MxInst>("MOV"#size#"dj") !cast<MxMemOp>("MxARI"#size):$ptr)>;
 
+  def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_ARII:$ptr),
+            (!cast<MxInst>("MOV"#size#"df") !cast<MxMemOp>("MxARII"#size):$ptr)>;
+
   def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_ARI:$ptr),
             (!cast<MxInst>("MOV"#size#"jd") !cast<MxMemOp>("MxARI"#size):$ptr,
                                             !cast<MxRegOp>("MxDRD"#size):$val)>;
+
+  def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_ARII:$ptr),
+            (!cast<MxInst>("MOV"#size#"fd") !cast<MxMemOp>("MxARII"#size):$ptr,
+                                            !cast<MxRegOp>("MxDRD"#size):$val)>;
 }
 
 let Predicates = [AtLeastM68020] in {



More information about the llvm-commits mailing list