Skip to content

Commit 423f9ab

Browse files
committed
[M68k] Improve logic for expanding MOVZX pseudos
This implements an optimization for MOVZX. If the destination is different from the source, the extended destination is first cleared, and then the non-extended source is moved to the destination. Previously, the move always occurred first, and then the high bits were cleared using an AND immediate instruction, which is both slower and larger in size than using CLR.
1 parent 4d66760 commit 423f9ab

File tree

1 file changed

+63
-24
lines changed

1 file changed

+63
-24
lines changed

llvm/lib/Target/M68k/M68kInstrInfo.cpp

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -473,13 +473,6 @@ bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,
473473
MVT MVTDst, MVT MVTSrc) const {
474474
LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
475475

476-
unsigned Move;
477-
478-
if (MVTDst == MVT::i16)
479-
Move = M68k::MOV16rr;
480-
else // i32
481-
Move = M68k::MOV32rr;
482-
483476
Register Dst = MIB->getOperand(0).getReg();
484477
Register Src = MIB->getOperand(1).getReg();
485478

@@ -501,17 +494,45 @@ bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,
501494
MachineBasicBlock &MBB = *MIB->getParent();
502495
DebugLoc DL = MIB->getDebugLoc();
503496

504-
if (Dst != SSrc) {
505-
LLVM_DEBUG(dbgs() << "Move and " << '\n');
506-
BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);
497+
// It's more efficient to clear the destination and *then* move, rather than
498+
// move and zext.
499+
if (Dst != SSrc && !IsSigned) {
500+
501+
unsigned Move;
502+
if (MVTSrc == MVT::i8)
503+
Move = M68k::MOV8dd;
504+
else // i16
505+
Move = M68k::MOV16dd;
506+
unsigned Clr;
507+
if (MVTDst == MVT::i16)
508+
Clr = M68k::CLR16d;
509+
else // i32
510+
Clr = M68k::CLR32d;
511+
512+
LLVM_DEBUG(dbgs() << "Clear and Zero Extend" << '\n');
513+
BuildMI(MBB, MIB.getInstr(), DL, get(Clr), Dst);
514+
BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(Src);
507515
}
516+
else {
508517

509-
if (IsSigned) {
510-
LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
511-
AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
512-
} else {
513-
LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
514-
AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
518+
unsigned Move;
519+
if (MVTDst == MVT::i16)
520+
Move = M68k::MOV16dd;
521+
else // i32
522+
Move = M68k::MOV32dd;
523+
524+
if (Dst != SSrc) {
525+
LLVM_DEBUG(dbgs() << "Move and " << '\n');
526+
BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);
527+
}
528+
529+
if (IsSigned) {
530+
LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
531+
AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
532+
} else {
533+
LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
534+
AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
535+
}
515536
}
516537

517538
MIB->eraseFromParent();
@@ -522,7 +543,7 @@ bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,
522543
bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
523544
const MCInstrDesc &Desc, MVT MVTDst,
524545
MVT MVTSrc) const {
525-
LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD and ");
546+
LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
526547

527548
Register Dst = MIB->getOperand(0).getReg();
528549

@@ -541,16 +562,34 @@ bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
541562
MIB->getOperand(0).setReg(SubDst);
542563

543564
MachineBasicBlock::iterator I = MIB.getInstr();
544-
I++;
545565
MachineBasicBlock &MBB = *MIB->getParent();
546566
DebugLoc DL = MIB->getDebugLoc();
547567

548-
if (IsSigned) {
549-
LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
550-
AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
551-
} else {
552-
LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
553-
AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
568+
// We can only clear before loading if the destination register isn't being
569+
// used as an index for the load.
570+
if (!IsSigned && !MIB->readsRegister(Dst, Subtarget.getRegisterInfo())) {
571+
unsigned Clr;
572+
if (MVTDst == MVT::i16) {
573+
Clr = M68k::CLR16d;
574+
} else { // i32
575+
Clr = M68k::CLR32d;
576+
}
577+
578+
// Clear before load
579+
LLVM_DEBUG(dbgs() << "Clear and LOAD" << '\n');
580+
BuildMI(MBB, MIB.getInstr(), DL, get(Clr), Dst);
581+
I++;
582+
}
583+
else {
584+
// Extend after load
585+
I++;
586+
if (IsSigned) {
587+
LLVM_DEBUG(dbgs() << "LOAD and Sign Extend" << '\n');
588+
AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
589+
} else {
590+
LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
591+
AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
592+
}
554593
}
555594

556595
return true;

0 commit comments

Comments
 (0)