Skip to content

Commit 629b8d7

Browse files
committed
Fix invalid comparison codegen for inlined memmove, optimize LDDR path
1 parent 1cbcc3b commit 629b8d7

File tree

2 files changed

+34
-15
lines changed

2 files changed

+34
-15
lines changed

llvm/lib/Target/Z80/GISel/Z80LegalizerInfo.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,9 +1021,6 @@ LegalizerHelper::LegalizeResult Z80LegalizerInfo::legalizeMemIntrinsic(
10211021
return LegalizerHelper::Legalized;
10221022
}
10231023
if (Opc == G_MEMMOVE && !ConstAddr) {
1024-
MIRBuilder.buildCopy(HL, SrcReg);
1025-
MIRBuilder.buildInstr(Is24Bit ? Z80::Cmp24ao : Z80::Cmp16ao, {},
1026-
{DstReg});
10271024
MIRBuilder
10281025
.buildInstr(Is24Bit ? Z80::LDR24 : Z80::LDR16, {},
10291026
{DstReg, SrcReg, LenReg})

llvm/lib/Target/Z80/Z80ISelLowering.cpp

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,10 @@ Z80TargetLowering::EmitLoweredMemMove(MachineInstr &MI,
506506
Register HL = Is24Bit ? Z80::UHL : Z80::HL;
507507
Register BC = Is24Bit ? Z80::UBC : Z80::BC;
508508
Register PhysRegs[] = { DE, HL, BC };
509+
Register VirtRegs[3] = {};
509510
assert((Is24Bit || MI.getOpcode() == Z80::LDR16) && "Unexpected opcode");
510511

512+
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
511513
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
512514
DebugLoc DL = MI.getDebugLoc();
513515

@@ -516,12 +518,13 @@ Z80TargetLowering::EmitLoweredMemMove(MachineInstr &MI,
516518
MachineFunction::iterator I = ++BB->getIterator();
517519

518520
MachineFunction *F = BB->getParent();
521+
MachineRegisterInfo &MRI = F->getRegInfo();
519522
MachineBasicBlock *LDIR_BB = F->CreateMachineBasicBlock(LLVM_BB);
520523
MachineBasicBlock *LDDR_BB = F->CreateMachineBasicBlock(LLVM_BB);
521524
MachineBasicBlock *NextBB = F->CreateMachineBasicBlock(LLVM_BB);
522525
for (auto *MBB : {LDIR_BB, LDDR_BB}) {
523526
F->insert(I, MBB);
524-
for (auto LiveIn : {BC, DE, HL})
527+
for (auto LiveIn : PhysRegs)
525528
MBB->addLiveIn(LiveIn);
526529
}
527530
F->insert(I, NextBB);
@@ -533,47 +536,66 @@ Z80TargetLowering::EmitLoweredMemMove(MachineInstr &MI,
533536
NextBB->transferSuccessorsAndUpdatePHIs(BB);
534537

535538
// BB:
539+
// SUB HL,DE
536540
// JP C,LDDR_BB
537541
// fallthrough --> LDIR_BB
542+
for (int I = 0; I != 3; ++I)
543+
BuildMI(BB, DL, TII->get(Z80::COPY), PhysRegs[I])
544+
.add(MI.getOperand(I));
545+
BuildMI(BB, DL, TII->get(Is24Bit ? Z80::Sub24ao : Z80::Sub16ao))
546+
.addReg(DE);
547+
// Preserve physical registers for the successors.
548+
for (int I = 0; I != 3; ++I) {
549+
VirtRegs[I] = MRI.createVirtualRegister(TRI->getRegClass(PhysRegs[I]));
550+
BuildMI(BB, DL, TII->get(Z80::COPY), VirtRegs[I]).addReg(PhysRegs[I]);
551+
}
538552
BuildMI(BB, DL, TII->get(Z80::JQCC)).addMBB(LDDR_BB)
539553
.addImm(Z80::COND_C);
540554
// Next, add the LDIR and LDDR blocks as its successors.
541555
BB->addSuccessor(LDIR_BB);
542556
BB->addSuccessor(LDDR_BB);
543557

544558
// LDIR_BB:
559+
// ADD HL,DE
545560
// LDIR
546561
// JP NextBB
547562
for (int I = 0; I != 3; ++I)
548563
BuildMI(LDIR_BB, DL, TII->get(Z80::COPY), PhysRegs[I])
549-
.add(MI.getOperand(I));
564+
.addReg(VirtRegs[I]);
565+
BuildMI(LDIR_BB, DL, TII->get(Is24Bit ? Z80::ADD24ao : Z80::ADD16ao), HL)
566+
.addReg(HL).addReg(DE);
550567
BuildMI(LDIR_BB, DL, TII->get(Is24Bit ? Z80::LDIR24 : Z80::LDIR16));
551568
BuildMI(LDIR_BB, DL, TII->get(Z80::JQ)).addMBB(NextBB);
552569
// Update machine-CFG edges
553570
LDIR_BB->addSuccessor(NextBB);
554571

555572
// LDDR_BB:
556-
// ADD HL,BC
557-
// DEC HL
558573
// EX DE,HL
559574
// ADD HL,BC
560575
// DEC HL
561576
// EX DE,HL
577+
// ADD HL,DE
562578
// LDDR
563579
// # Fallthrough to Next MBB
564580
for (int I = 0; I != 3; ++I)
565581
BuildMI(LDDR_BB, DL, TII->get(Z80::COPY), PhysRegs[I])
566-
.add(MI.getOperand(I));
567-
for (int I = 0; I != 2; ++I) {
568-
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::ADD24ao : Z80::ADD16ao), HL)
569-
.addReg(HL).addReg(BC);
570-
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::DEC24r : Z80::DEC16r), HL)
571-
.addReg(HL);
572-
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::EX24DE : Z80::EX16DE));
573-
}
582+
.addReg(VirtRegs[I]);
583+
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::EX24DE : Z80::EX16DE));
584+
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::ADD24ao : Z80::ADD16ao), HL)
585+
.addReg(HL).addReg(BC);
586+
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::DEC24r : Z80::DEC16r), HL)
587+
.addReg(HL);
588+
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::EX24DE : Z80::EX16DE));
589+
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::ADD24ao : Z80::ADD16ao), HL)
590+
.addReg(HL).addReg(DE);
574591
BuildMI(LDDR_BB, DL, TII->get(Is24Bit ? Z80::LDDR24 : Z80::LDDR16));
575592
LDDR_BB->addSuccessor(NextBB);
576593

594+
// Replace virtual register usages with the corresponding physical
595+
// registers to ensure no-op copies.
596+
for (int I = 0; I != 3; ++I)
597+
MRI.replaceRegWith(VirtRegs[I], PhysRegs[I]);
598+
577599
MI.eraseFromParent(); // The pseudo instruction is gone now.
578600
LLVM_DEBUG(F->dump());
579601
return NextBB;

0 commit comments

Comments
 (0)