Skip to content

Commit 1eac7cd

Browse files
authored
[M68k] always use movem for register spills (#106715)
Fixes #106206 and #106209.
1 parent 5dc8155 commit 1eac7cd

File tree

6 files changed

+524
-52
lines changed

6 files changed

+524
-52
lines changed

llvm/lib/Target/M68k/M68kExpandPseudo.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -193,31 +193,23 @@ bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
193193
case M68k::MOV8dc:
194194
return TII->ExpandCCR(MIB, /*IsToCCR=*/false);
195195

196-
case M68k::MOVM8jm_P:
197-
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32jm), /*IsRM=*/false);
198196
case M68k::MOVM16jm_P:
199-
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32jm), /*IsRM=*/false);
197+
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM16jm), /*IsRM=*/false);
200198
case M68k::MOVM32jm_P:
201199
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32jm), /*IsRM=*/false);
202200

203-
case M68k::MOVM8pm_P:
204-
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32pm), /*IsRM=*/false);
205201
case M68k::MOVM16pm_P:
206-
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32pm), /*IsRM=*/false);
202+
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM16pm), /*IsRM=*/false);
207203
case M68k::MOVM32pm_P:
208204
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32pm), /*IsRM=*/false);
209205

210-
case M68k::MOVM8mj_P:
211-
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mj), /*IsRM=*/true);
212206
case M68k::MOVM16mj_P:
213-
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mj), /*IsRM=*/true);
207+
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM16mj), /*IsRM=*/true);
214208
case M68k::MOVM32mj_P:
215209
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mj), /*IsRM=*/true);
216210

217-
case M68k::MOVM8mp_P:
218-
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mp), /*IsRM=*/true);
219211
case M68k::MOVM16mp_P:
220-
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mp), /*IsRM=*/true);
212+
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM16mp), /*IsRM=*/true);
221213
case M68k::MOVM32mp_P:
222214
return TII->ExpandMOVEM(MIB, TII->get(M68k::MOVM32mp), /*IsRM=*/true);
223215

llvm/lib/Target/M68k/M68kInstrData.td

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -337,20 +337,16 @@ class MxMOVEM_RM_Pseudo<MxType TYPE, MxOperand MEMOp>
337337
: MxPseudo<(outs TYPE.ROp:$dst), (ins MEMOp:$src)>;
338338

339339
// Mem <- Reg
340-
def MOVM8jm_P : MxMOVEM_MR_Pseudo<MxType8d, MxType8.JOp>;
341340
def MOVM16jm_P : MxMOVEM_MR_Pseudo<MxType16r, MxType16.JOp>;
342341
def MOVM32jm_P : MxMOVEM_MR_Pseudo<MxType32r, MxType32.JOp>;
343342

344-
def MOVM8pm_P : MxMOVEM_MR_Pseudo<MxType8d, MxType8.POp>;
345343
def MOVM16pm_P : MxMOVEM_MR_Pseudo<MxType16r, MxType16.POp>;
346344
def MOVM32pm_P : MxMOVEM_MR_Pseudo<MxType32r, MxType32.POp>;
347345

348346
// Reg <- Mem
349-
def MOVM8mj_P : MxMOVEM_RM_Pseudo<MxType8d, MxType8.JOp>;
350347
def MOVM16mj_P : MxMOVEM_RM_Pseudo<MxType16r, MxType16.JOp>;
351348
def MOVM32mj_P : MxMOVEM_RM_Pseudo<MxType32r, MxType32.JOp>;
352349

353-
def MOVM8mp_P : MxMOVEM_RM_Pseudo<MxType8d, MxType8.POp>;
354350
def MOVM16mp_P : MxMOVEM_RM_Pseudo<MxType16r, MxType16.POp>;
355351
def MOVM32mp_P : MxMOVEM_RM_Pseudo<MxType32r, MxType32.POp>;
356352

llvm/lib/Target/M68k/M68kInstrInfo.cpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,6 @@ bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
593593
bool M68kInstrInfo::ExpandMOVEM(MachineInstrBuilder &MIB,
594594
const MCInstrDesc &Desc, bool IsRM) const {
595595
int Reg = 0, Offset = 0, Base = 0;
596-
auto XR32 = RI.getRegClass(M68k::XR32RegClassID);
597596
auto DL = MIB->getDebugLoc();
598597
auto MI = MIB.getInstr();
599598
auto &MBB = *MIB->getParent();
@@ -608,13 +607,6 @@ bool M68kInstrInfo::ExpandMOVEM(MachineInstrBuilder &MIB,
608607
Reg = MIB->getOperand(2).getReg();
609608
}
610609

611-
// If the register is not in XR32 then it is smaller than 32 bit, we
612-
// implicitly promote it to 32
613-
if (!XR32->contains(Reg)) {
614-
Reg = RI.getMatchingMegaReg(Reg, XR32);
615-
assert(Reg && "Has not meaningful MEGA register");
616-
}
617-
618610
unsigned Mask = 1 << RI.getSpillRegisterOrder(Reg);
619611
if (IsRM) {
620612
BuildMI(MBB, MI, DL, Desc)
@@ -799,22 +791,25 @@ namespace {
799791
unsigned getLoadStoreRegOpcode(unsigned Reg, const TargetRegisterClass *RC,
800792
const TargetRegisterInfo *TRI,
801793
const M68kSubtarget &STI, bool load) {
802-
switch (TRI->getRegSizeInBits(*RC)) {
794+
switch (TRI->getSpillSize(*RC)) {
803795
default:
796+
LLVM_DEBUG(
797+
dbgs() << "Cannot determine appropriate opcode for load/store to/from "
798+
<< TRI->getName(Reg) << " of class " << TRI->getRegClassName(RC)
799+
<< " with spill size " << TRI->getSpillSize(*RC) << '\n');
804800
llvm_unreachable("Unknown spill size");
805-
case 8:
801+
case 2:
802+
if (M68k::XR16RegClass.hasSubClassEq(RC))
803+
return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
806804
if (M68k::DR8RegClass.hasSubClassEq(RC))
807-
return load ? M68k::MOV8dp : M68k::MOV8pd;
805+
return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
808806
if (M68k::CCRCRegClass.hasSubClassEq(RC))
809-
return load ? M68k::MOV16cp : M68k::MOV16pc;
810-
811-
llvm_unreachable("Unknown 1-byte regclass");
812-
case 16:
813-
assert(M68k::XR16RegClass.hasSubClassEq(RC) && "Unknown 2-byte regclass");
814-
return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
815-
case 32:
816-
assert(M68k::XR32RegClass.hasSubClassEq(RC) && "Unknown 4-byte regclass");
817-
return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;
807+
return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
808+
llvm_unreachable("Unknown 2-byte regclass");
809+
case 4:
810+
if (M68k::XR32RegClass.hasSubClassEq(RC))
811+
return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;
812+
llvm_unreachable("Unknown 4-byte regclass");
818813
}
819814
}
820815

llvm/lib/Target/M68k/M68kRegisterInfo.td

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,52 +99,77 @@ class MxRegClass<list<ValueType> regTypes, int alignment, dag regList>
9999
: RegisterClass<"M68k", regTypes, alignment, regList>;
100100

101101
// Data Registers
102+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<8,16,16>]> in
102103
def DR8 : MxRegClass<[i8], 16, (sequence "BD%u", 0, 7)>;
104+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<16,16,16>]> in
103105
def DR16 : MxRegClass<[i16], 16, (sequence "WD%u", 0, 7)>;
106+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
104107
def DR32 : MxRegClass<[i32], 32, (sequence "D%u", 0, 7)>;
105108

106109
// Address Registers
110+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<16,16,16>]> in
107111
def AR16 : MxRegClass<[i16], 16, (add (sequence "WA%u", 0, 6), WSP)>;
112+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
108113
def AR32 : MxRegClass<[i32], 32, (add (sequence "A%u", 0, 6), SP)>;
109114

115+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
110116
def AR32_NOSP : MxRegClass<[i32], 32, (sequence "A%u", 0, 6)>;
111117

112118
// Index Register Classes
113119
// FIXME try alternative ordering like `D0, D1, A0, A1, ...`
120+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<16,16,16>]> in
114121
def XR16 : MxRegClass<[i16], 16, (add DR16, AR16)>;
122+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
115123
def XR32 : MxRegClass<[i32], 32, (add DR32, AR32)>;
116124

125+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
117126
def SPC : MxRegClass<[i32], 32, (add SP)>;
118127

119128
// Floating Point Data Registers
129+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
120130
def FPDR32 : MxRegClass<[f32], 32, (sequence "FP%u", 0, 7)>;
131+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<64,64,32>]> in
121132
def FPDR64 : MxRegClass<[f64], 32, (add FPDR32)>;
133+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<80,128,32>]> in
122134
def FPDR80 : MxRegClass<[f80], 32, (add FPDR32)>;
123135

124136
let CopyCost = -1 in {
137+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<8,16,16>]> in
125138
def CCRC : MxRegClass<[i8], 16, (add CCR)>;
139+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<16,16,16>]> in
126140
def SRC : MxRegClass<[i16], 16, (add SR)>;
127141

128142
// Float Point System Control Registers
129-
def FPIC : MxRegClass<[i32], 32, (add FPIAR)>;
130-
def FPCSC : MxRegClass<[i32], 32, (add FPC, FPS)>;
131-
def FPSYSC : MxRegClass<[i32], 32, (add FPCSC, FPIC)>;
143+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in {
144+
def FPIC : MxRegClass<[i32], 32, (add FPIAR)>;
145+
def FPCSC : MxRegClass<[i32], 32, (add FPC, FPS)>;
146+
def FPSYSC : MxRegClass<[i32], 32, (add FPCSC, FPIC)>;
147+
}
132148
}
133149

134150
let isAllocatable = 0 in {
151+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
135152
def PCC : MxRegClass<[i32], 32, (add PC)>;
136153
}
137154

138155
// Register used with tail call
156+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<16,16,16>]> in
139157
def DR16_TC : MxRegClass<[i16], 16, (add D0, D1)>;
158+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
140159
def DR32_TC : MxRegClass<[i32], 32, (add D0, D1)>;
141160

161+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<16,16,16>]> in
142162
def AR16_TC : MxRegClass<[i16], 16, (add A0, A1)>;
163+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
143164
def AR32_TC : MxRegClass<[i32], 32, (add A0, A1)>;
144165

166+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<16,16,16>]> in
145167
def XR16_TC : MxRegClass<[i16], 16, (add DR16_TC, AR16_TC)>;
168+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in
146169
def XR32_TC : MxRegClass<[i32], 32, (add DR32_TC, AR32_TC)>;
147170

148171
// These classes provide spill/restore order if used with MOVEM instruction
149-
def SPILL : MxRegClass<[i32], 32, (add XR32)>;
150-
def SPILL_R : MxRegClass<[i32], 32, (add SP, (sequence "A%u", 6, 0), (sequence "D%u", 7, 0))>;
172+
let RegInfos = RegInfoByHwMode<[DefaultMode], [RegInfo<32,32,32>]> in {
173+
def SPILL : MxRegClass<[i32], 32, (add XR32)>;
174+
def SPILL_R : MxRegClass<[i32], 32, (add SP, (sequence "A%u", 6, 0), (sequence "D%u", 7, 0))>;
175+
}

llvm/test/CodeGen/M68k/PR57660.ll

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ define dso_local void @foo1() {
88
; CHECK-NEXT: suba.l #2, %sp
99
; CHECK-NEXT: .cfi_def_cfa_offset -6
1010
; CHECK-NEXT: moveq #0, %d0
11-
; CHECK-NEXT: move.b %d0, (0,%sp) ; 1-byte Folded Spill
11+
; CHECK-NEXT: movem.w %d0, (0,%sp)
1212
; CHECK-NEXT: .LBB0_1: ; %do.body
1313
; CHECK-NEXT: ; =>This Inner Loop Header: Depth=1
14-
; CHECK-NEXT: move.b (0,%sp), %d0 ; 1-byte Folded Reload
14+
; CHECK-NEXT: movem.w (0,%sp), %d0
1515
; CHECK-NEXT: cmpi.b #0, %d0
1616
; CHECK-NEXT: bne .LBB0_1
1717
; CHECK-NEXT: ; %bb.2: ; %do.end
@@ -39,24 +39,24 @@ define i32 @foo2(ptr noundef %0) {
3939
; CHECK-NEXT: .cfi_def_cfa_offset -8
4040
; CHECK-NEXT: move.l (8,%sp), %a0
4141
; CHECK-NEXT: move.b (%a0), %d0
42-
; CHECK-NEXT: move.b %d0, (0,%sp) ; 1-byte Folded Spill
42+
; CHECK-NEXT: movem.w %d0, (0,%sp)
4343
; CHECK-NEXT: and.b #1, %d0
44-
; CHECK-NEXT: move.b %d0, (2,%sp) ; 1-byte Folded Spill
44+
; CHECK-NEXT: movem.w %d0, (2,%sp)
4545
; CHECK-NEXT: sub.b #1, %d0
4646
; CHECK-NEXT: bgt .LBB1_2
4747
; CHECK-NEXT: ; %bb.1: ; %if
48-
; CHECK-NEXT: move.b (2,%sp), %d0 ; 1-byte Folded Reload
49-
; CHECK-NEXT: move.b (0,%sp), %d1 ; 1-byte Folded Reload
48+
; CHECK-NEXT: movem.w (2,%sp), %d0
49+
; CHECK-NEXT: movem.w (0,%sp), %d1
5050
; CHECK-NEXT: add.b %d1, %d0
5151
; CHECK-NEXT: bra .LBB1_3
5252
; CHECK-NEXT: .LBB1_2: ; %else
53-
; CHECK-NEXT: move.b (2,%sp), %d1 ; 1-byte Folded Reload
54-
; CHECK-NEXT: move.b (0,%sp), %d0 ; 1-byte Folded Reload
53+
; CHECK-NEXT: movem.w (2,%sp), %d1
54+
; CHECK-NEXT: movem.w (0,%sp), %d0
5555
; CHECK-NEXT: sub.b %d1, %d0
56-
; CHECK-NEXT: move.b %d0, (0,%sp) ; 1-byte Folded Spill
56+
; CHECK-NEXT: movem.w %d0, (0,%sp)
5757
; CHECK-NEXT: .LBB1_3: ; %cont
58-
; CHECK-NEXT: move.b %d0, (2,%sp) ; 1-byte Folded Spill
59-
; CHECK-NEXT: move.b (2,%sp), %d0 ; 1-byte Folded Reload
58+
; CHECK-NEXT: movem.w %d0, (2,%sp)
59+
; CHECK-NEXT: movem.w (2,%sp), %d0
6060
; CHECK-NEXT: ext.w %d0
6161
; CHECK-NEXT: ext.l %d0
6262
; CHECK-NEXT: adda.l #4, %sp

0 commit comments

Comments
 (0)