[llvm] Handle moves of non-16 size to/from CCR (PR #108581)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 29 14:56:43 PDT 2024
https://github.com/knickish updated https://github.com/llvm/llvm-project/pull/108581
>From dce4c5757edfbcc990f4976ad71f3b038814f621 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/2] 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..53bc981fb4a322 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 72871273886173ce756c583a4f598c95edcc88f3 Mon Sep 17 00:00:00 2001
From: kirk <knickish at gmail.com>
Date: Tue, 29 Oct 2024 21:56:31 +0000
Subject: [PATCH 2/2] working CCR->DR32 copy
---
llvm/lib/Target/M68k/M68kInstrData.td | 6 +-
llvm/lib/Target/M68k/M68kInstrInfo.cpp | 65 ++++++++++++++++----
llvm/test/CodeGen/M68k/null-regsel-switch.ll | 23 +++++++
3 files changed, 81 insertions(+), 13 deletions(-)
create mode 100644 llvm/test/CodeGen/M68k/null-regsel-switch.ll
diff --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td
index be2d43ce1de3ae..2f32502cd001f3 100644
--- a/llvm/lib/Target/M68k/M68kInstrData.td
+++ b/llvm/lib/Target/M68k/M68kInstrData.td
@@ -421,6 +421,8 @@ class MxMoveFromCCR_M<MxOperand MEMOp, MxEncMemOp DST_ENC>
class MxMoveFromCCRPseudo<MxOperand MEMOp>
: MxPseudo<(outs), (ins MEMOp:$dst, CCRC:$src)>;
+class MxMoveFromCCR_RPseudo<MxOperand MEMOp>
+ : MxPseudo<(outs MEMOp:$dst), (ins CCRC:$src)>;
} // let Uses = [CCR]
let mayStore = 1 in
@@ -436,9 +438,9 @@ foreach AM = MxMoveSupportedAMs in {
} // foreach AM
// Only data register is allowed.
-def MOV32dc : MxMoveFromCCRPseudo<MxOp32AddrMode_d.Op>;
+def MOV32dc : MxMoveFromCCR_RPseudo<MxOp32AddrMode_d.Op>;
def MOV16dc : MxMoveFromCCR_R;
-def MOV8dc : MxMoveFromCCRPseudo<MxOp8AddrMode_d.Op>;
+def MOV8dc : MxMoveFromCCR_RPseudo<MxOp8AddrMode_d.Op>;
//===----------------------------------------------------------------------===//
// LEA
diff --git a/llvm/lib/Target/M68k/M68kInstrInfo.cpp b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
index 53bc981fb4a322..3aeac30e5cebb8 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.cpp
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
@@ -23,12 +23,16 @@
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGenTypes/MachineValueType.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
+#include <cassert>
#include <functional>
+#include <iterator>
using namespace llvm;
@@ -571,6 +575,49 @@ bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB,
}
bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
+ switch (MIB->getOpcode()) {
+ case M68k::MOV32dc: {
+ // We're trying to get an i32 value out of an i16 op
+ // Copy the value to the 16Lo subreg, then zext it
+ auto &Opd = MIB->getOperand(0);
+ auto OriginalReg = Opd.getReg();
+ auto SubReg =
+ getRegisterInfo().getSubReg(Opd.getReg(), M68k::MxSubRegIndex16Lo);
+ Opd.setReg(SubReg);
+ assert(SubReg.id() && "No viable SUB register available");
+
+ MachineBasicBlock::iterator I = MIB.getInstr();
+ { // debugging
+ auto Defs = I->all_defs();
+ for (auto Def : I->all_defs()) {
+ LLVM_DEBUG(dbgs() << "Defining:" << RI.getName(Def.getReg()) << '\n');
+ }
+ int DefsCount = std::distance(Defs.begin(), Defs.end());
+ LLVM_DEBUG(dbgs() << DefsCount << "registers defined" << '\n');
+ assert(DefsCount == 1 && "Unexpected number of defs");
+ }
+ I++;
+ MachineBasicBlock &MBB = *MIB->getParent();
+ DebugLoc DL = MIB->getDebugLoc();
+
+ // Expand the value
+ copyPhysReg(MBB, I, DL, OriginalReg, SubReg, false);
+ // ANDI the expanded value to clear garbage
+ BuildMI(MBB, I, DL, get(M68k::AND32di), OriginalReg)
+ .addReg(OriginalReg)
+ .addImm(0xFFFF);
+ break;
+ }
+ case M68k::MOV8cd: {
+ // Promote used register to the next class
+ auto &Opd = MIB->getOperand(1);
+ Opd.setReg(getRegisterInfo().getMatchingSuperReg(
+ Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));
+ break;
+ }
+ default:
+ break;
+ }
// Replace the pseudo instruction with the real one
if (IsToCCR)
@@ -579,11 +626,6 @@ bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
// FIXME M68010 or later is required
MIB->setDesc(get(M68k::MOV16dc));
- // Promote used register to the next class
- auto &Opd = MIB->getOperand(1);
- Opd.setReg(getRegisterInfo().getMatchingSuperReg(
- Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));
-
return true;
}
@@ -761,12 +803,12 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Opc = M68k::MOV8dc;
else if (M68k::DR16RegClass.contains(DstReg))
Opc = M68k::MOV16dc;
- else if (M68k::DR32RegClass.contains(DstReg))
+ 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 {
+ 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) {
if (M68k::DR8RegClass.contains(SrcReg))
@@ -776,7 +818,8 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
else if (M68k::DR32RegClass.contains(SrcReg))
Opc = M68k::MOV32cd;
else {
- LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to CCR" << '\n');
+ LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to CCR"
+ << '\n');
llvm_unreachable("Invalid register for MOVE to CCR");
}
} else if (FromSR || ToSR)
diff --git a/llvm/test/CodeGen/M68k/null-regsel-switch.ll b/llvm/test/CodeGen/M68k/null-regsel-switch.ll
new file mode 100644
index 00000000000000..16655720f0a5d2
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/null-regsel-switch.ll
@@ -0,0 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc < %s -mtriple=m68k-linux -mcpu=M68020 --verify-machineinstrs | FileCheck %s
+
+define internal void @test_func(i32 %self, ptr nonnull %value) {
+start:
+ %2 = icmp eq i32 %self, 0
+ %3 = select i1 %2, i32 0, i32 1
+ switch i32 %3, label %exit [
+ i32 0, label %nonnull
+ i32 1, label %null
+ ]
+
+nonnull: ; preds = %start
+ store ptr %value, ptr null, align 2
+ br label %exit
+
+null: ; preds = %start
+ store ptr %value, ptr null, align 2
+ br label %exit
+
+exit: ; preds = %nonnull, %null
+ ret void
+}
\ No newline at end of file
More information about the llvm-commits
mailing list