[llvm] M68k ccr mov (PR #114714)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 3 09:53:09 PST 2024
https://github.com/knickish created https://github.com/llvm/llvm-project/pull/114714
None
>From 5356e6c775ad4b030525a4ce344279b71936acb4 Mon Sep 17 00:00:00 2001
From: TechnoElf <technoelf at undertheprinter.com>
Date: Fri, 6 Sep 2024 16:04:22 +0200
Subject: [PATCH 1/2] [M68k] allow 16-bit registers for MOVE to/from CCR
---
llvm/lib/Target/M68k/M68kInstrInfo.cpp | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/M68k/M68kInstrInfo.cpp b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
index 23c5c76a47479b..dac0663f2fa67e 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.cpp
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
@@ -709,13 +709,27 @@ 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::MOV16dc;
+ else {
+ LLVM_DEBUG(dbgs() << "Cannot copy CCR to " << RI.getName(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::MOV16cd;
+ 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 383f1b99177cdc7f6abdbfc5800cdb1494314131 Mon Sep 17 00:00:00 2001
From: kirk <knickish at gmail.com>
Date: Fri, 13 Sep 2024 14:34:06 +0000
Subject: [PATCH 2/2] add test and change default copy size for ccr
---
llvm/lib/Target/M68k/M68kExpandPseudo.cpp | 1 +
llvm/lib/Target/M68k/M68kInstrData.td | 8 +-
llvm/lib/Target/M68k/M68kInstrInfo.cpp | 36 +++--
llvm/lib/Target/M68k/M68kRegisterInfo.h | 2 +-
.../CodeGen/M68k/Control/non-cmov-switch.ll | 126 ++++++++++++++++++
5 files changed, 158 insertions(+), 15 deletions(-)
create mode 100644 llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
diff --git a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
index c7fdd7d7c35023..0e9878b9a8ff93 100644
--- a/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
+++ b/llvm/lib/Target/M68k/M68kExpandPseudo.cpp
@@ -190,6 +190,7 @@ bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
case M68k::MOV8cd:
return TII->ExpandCCR(MIB, /*IsToCCR=*/true);
+
case M68k::MOV8dc:
return TII->ExpandCCR(MIB, /*IsToCCR=*/false);
diff --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td
index dc777a933e2786..af12c079a4741a 100644
--- a/llvm/lib/Target/M68k/M68kInstrData.td
+++ b/llvm/lib/Target/M68k/M68kInstrData.td
@@ -385,6 +385,7 @@ 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>;
@@ -419,10 +420,15 @@ 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
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)>;
@@ -432,7 +438,7 @@ foreach AM = MxMoveSupportedAMs in {
// Only data register is allowed.
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 dac0663f2fa67e..046fdcab36819a 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;
@@ -523,6 +527,17 @@ bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB,
}
bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
+ switch (MIB->getOpcode()) {
+ 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)
@@ -531,11 +546,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;
}
@@ -709,24 +719,24 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
bool ToSR = DstReg == M68k::SR;
if (FromCCR) {
- if (M68k::DR8RegClass.contains(DstReg))
+ if (M68k::DR8RegClass.contains(DstReg)) {
Opc = M68k::MOV8dc;
- else if (M68k::DR16RegClass.contains(DstReg))
+ } else if (M68k::DR16RegClass.contains(DstReg)) {
Opc = M68k::MOV16dc;
- else if (M68k::DR32RegClass.contains(DstReg))
+ } else if (M68k::DR32RegClass.contains(DstReg)) {
Opc = M68k::MOV16dc;
- else {
+ } else {
LLVM_DEBUG(dbgs() << "Cannot copy CCR to " << RI.getName(DstReg) << '\n');
llvm_unreachable("Invalid register for MOVE from CCR");
}
} else if (ToCCR) {
- if (M68k::DR8RegClass.contains(SrcReg))
+ if (M68k::DR8RegClass.contains(SrcReg)) {
Opc = M68k::MOV8cd;
- else if (M68k::DR16RegClass.contains(SrcReg))
+ } else if (M68k::DR16RegClass.contains(SrcReg)) {
Opc = M68k::MOV16cd;
- else if (M68k::DR32RegClass.contains(SrcReg))
+ } else if (M68k::DR32RegClass.contains(SrcReg)) {
Opc = M68k::MOV16cd;
- else {
+ } else {
LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to CCR\n");
llvm_unreachable("Invalid register for MOVE to CCR");
}
diff --git a/llvm/lib/Target/M68k/M68kRegisterInfo.h b/llvm/lib/Target/M68k/M68kRegisterInfo.h
index 0cfab150d0c84b..51317683453666 100644
--- a/llvm/lib/Target/M68k/M68kRegisterInfo.h
+++ b/llvm/lib/Target/M68k/M68kRegisterInfo.h
@@ -101,7 +101,7 @@ class M68kRegisterInfo : public M68kGenRegisterInfo {
const TargetRegisterClass *
getCrossCopyRegClass(const TargetRegisterClass *RC) const override {
if (RC == &M68k::CCRCRegClass)
- return &M68k::DR32RegClass;
+ return &M68k::DR16RegClass;
return RC;
}
diff --git a/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll b/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
new file mode 100644
index 00000000000000..90d2be017ecdb2
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
@@ -0,0 +1,126 @@
+; 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 @select_i32(i32 %self, ptr nonnull %value) {
+; CHECK-LABEL: select_i32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %start
+; CHECK-NEXT: suba.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: cmpi.l #0, (8,%sp)
+; CHECK-NEXT: move.w %ccr, %d2
+; CHECK-NEXT: sne %d1
+; CHECK-NEXT: move.l (12,%sp), %d0
+; CHECK-NEXT: move.w %d2, %ccr
+; CHECK-NEXT: bne .LBB0_2
+; CHECK-NEXT: ; %bb.1: ; %start
+; CHECK-NEXT: and.l #255, %d1
+; CHECK-NEXT: cmpi.l #0, %d1
+; CHECK-NEXT: bne .LBB0_3
+; CHECK-NEXT: .LBB0_2: ; %null
+; CHECK-NEXT: suba.l %a0, %a0
+; CHECK-NEXT: move.l %d0, (%a0)
+; CHECK-NEXT: .LBB0_3: ; %exit
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: adda.l #4, %sp
+; CHECK-NEXT: rts
+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
+}
+
+define internal void @select_i16(i16 %self, ptr nonnull %value) {
+; CHECK-LABEL: select_i16:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %start
+; CHECK-NEXT: suba.l #4, %sp
+; CHECK-NEXT: .cfi_def_cfa_offset -8
+; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; CHECK-NEXT: cmpi.w #0, (10,%sp)
+; CHECK-NEXT: move.w %ccr, %d2
+; CHECK-NEXT: sne %d1
+; CHECK-NEXT: move.l (12,%sp), %d0
+; CHECK-NEXT: move.w %d2, %ccr
+; CHECK-NEXT: bne .LBB1_2
+; CHECK-NEXT: ; %bb.1: ; %start
+; CHECK-NEXT: and.l #255, %d1
+; CHECK-NEXT: cmpi.w #0, %d1
+; CHECK-NEXT: bne .LBB1_3
+; CHECK-NEXT: .LBB1_2: ; %null
+; CHECK-NEXT: suba.l %a0, %a0
+; CHECK-NEXT: move.l %d0, (%a0)
+; CHECK-NEXT: .LBB1_3: ; %exit
+; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; CHECK-NEXT: adda.l #4, %sp
+; CHECK-NEXT: rts
+start:
+ %2 = icmp eq i16 %self, 0
+ %3 = select i1 %2, i16 0, i16 1
+ switch i16 %3, label %exit [
+ i16 0, label %nonnull
+ i16 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
+}
+
+define internal void @select_i8(i8 %self, ptr nonnull %value) {
+; CHECK-LABEL: select_i8:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0: ; %start
+; CHECK-NEXT: move.l (8,%sp), %d0
+; CHECK-NEXT: cmpi.b #0, (7,%sp)
+; CHECK-NEXT: sne %d1
+; CHECK-NEXT: bne .LBB2_2
+; CHECK-NEXT: ; %bb.1: ; %start
+; CHECK-NEXT: cmpi.b #0, %d1
+; CHECK-NEXT: bne .LBB2_3
+; CHECK-NEXT: .LBB2_2: ; %null
+; CHECK-NEXT: suba.l %a0, %a0
+; CHECK-NEXT: move.l %d0, (%a0)
+; CHECK-NEXT: .LBB2_3: ; %exit
+; CHECK-NEXT: rts
+start:
+ %2 = icmp eq i8 %self, 0
+ %3 = select i1 %2, i8 0, i8 1
+ switch i8 %3, label %exit [
+ i8 0, label %nonnull
+ i8 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
+}
More information about the llvm-commits
mailing list