Skip to content

Commit 3cec745

Browse files
committed
Fix invalid memoperand access for small memset.
1 parent 0127b6a commit 3cec745

File tree

1 file changed

+99
-80
lines changed

1 file changed

+99
-80
lines changed

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

Lines changed: 99 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ Z80LegalizerInfo::legalizeVAStart(LegalizerHelper &Helper,
400400
LLT p0 = LLT::pointer(0, TM.getPointerSizeInBits(0));
401401
Helper.MIRBuilder.buildStore(Helper.MIRBuilder.buildFrameIndex(p0, FrameIdx),
402402
MI.getOperand(0).getReg(),
403-
**MI.memoperands_begin());
403+
*MI.memoperands().front());
404404
MI.eraseFromParent();
405405
return LegalizerHelper::Legalized;
406406
}
@@ -572,95 +572,114 @@ LegalizerHelper::LegalizeResult Z80LegalizerInfo::legalizeMemIntrinsic(
572572
// We need to make sure the number of bytes is non-zero for this lowering to
573573
// be correct. Since we only need to lower constant-length intrinsics for
574574
// now, just support those.
575-
if (auto ConstLen = getIConstantVRegValWithLookThrough(LenReg, MRI)) {
576-
// Doing something with zero bytes is a noop anyway.
577-
if (!ConstLen->Value) {
578-
MI.eraseFromParent();
579-
return LegalizerHelper::Legalized;
580-
}
581-
// Lowering memmove generates a lot of code...
582-
if (!MF.getFunction().hasOptSize() || Opc != TargetOpcode::G_MEMMOVE) {
583-
if (Opc == TargetOpcode::G_MEMSET) {
584-
// Store the first byte.
585-
MIRBuilder.buildStore(SrcReg, DstReg, *MI.memoperands().front());
586-
587-
// Use stores if 4 bytes or less
588-
if (ConstLen->Value.ule(4)) {
589-
for (unsigned int Offset = 1; ConstLen->Value.ugt(Offset); ++Offset) {
590-
auto OffConst = MIRBuilder.buildConstant(LenTy, Offset);
591-
auto AddrReg = MIRBuilder.buildPtrAdd(DstTy, DstReg, OffConst);
592-
MIRBuilder.buildStore(SrcReg, AddrReg, *MF.getMachineMemOperand(
593-
MI.memoperands()[0], Offset,
594-
LLT::scalar(8)));
575+
if (!MF.getFunction().hasOptNone()) {
576+
if (auto ConstLen = getIConstantVRegValWithLookThrough(LenReg, MRI)) {
577+
// Doing something with zero bytes is a noop anyway.
578+
if (!ConstLen->Value) {
579+
MI.eraseFromParent();
580+
return LegalizerHelper::Legalized;
581+
}
582+
// Lowering memmove generates a lot of code...
583+
if (!MF.getFunction().hasOptSize() || Opc != TargetOpcode::G_MEMMOVE) {
584+
MachineMemOperand *StoreMMO = MI.memoperands().front();
585+
MachineMemOperand *LoadMMO;
586+
587+
if (Opc == TargetOpcode::G_MEMSET) {
588+
// Store the first byte.
589+
MIRBuilder.buildStore(SrcReg, DstReg, *StoreMMO);
590+
591+
// Use stores if 4 bytes or less
592+
if (ConstLen->Value.ule(4)) {
593+
for (unsigned int Offset = 1; ConstLen->Value.ugt(Offset);
594+
++Offset) {
595+
auto OffConst = MIRBuilder.buildConstant(LenTy, Offset);
596+
auto AddrReg = MIRBuilder.buildPtrAdd(DstTy, DstReg, OffConst);
597+
MIRBuilder.buildStore(
598+
SrcReg, AddrReg,
599+
*MF.getMachineMemOperand(StoreMMO, Offset, LLT::scalar(8)));
600+
}
601+
MI.eraseFromParent();
602+
return LegalizerHelper::Legalized;
595603
}
604+
605+
// Read starting at the stored byte.
606+
SrcTy = DstTy;
607+
SrcReg = DstReg;
608+
LoadMMO = MF.getMachineMemOperand(
609+
StoreMMO->getPointerInfo(),
610+
(StoreMMO->getFlags() & ~MachineMemOperand::MOStore) |
611+
MachineMemOperand::MOLoad,
612+
StoreMMO->getMemoryType(), StoreMMO->getAlign(),
613+
StoreMMO->getAAInfo(), StoreMMO->getRanges(),
614+
StoreMMO->getSyncScopeID(), StoreMMO->getSuccessOrdering(),
615+
StoreMMO->getFailureOrdering());
616+
// Write starting at the following byte.
617+
auto One = MIRBuilder.buildConstant(LenTy, 1);
618+
DstReg = MIRBuilder.buildPtrAdd(DstTy, DstReg, One).getReg(0);
619+
// Copy one less byte.
620+
LenReg = MIRBuilder.buildConstant(LenTy, --ConstLen->Value).getReg(0);
621+
// Now it's just an ldir.
622+
} else
623+
LoadMMO = MI.memoperands().back();
624+
625+
Register DE = Is24Bit ? Z80::UDE : Z80::DE;
626+
Register HL = Is24Bit ? Z80::UHL : Z80::HL;
627+
Register BC = Is24Bit ? Z80::UBC : Z80::BC;
628+
auto ConstSrc = getIConstantVRegValWithLookThrough(SrcReg, MRI);
629+
auto ConstDst = getIConstantVRegValWithLookThrough(DstReg, MRI);
630+
bool ConstAddr = ConstSrc && ConstDst;
631+
if (!MI.hasOrderedMemoryRef() && ConstAddr &&
632+
ConstSrc->Value == ConstDst->Value) {
596633
MI.eraseFromParent();
597634
return LegalizerHelper::Legalized;
598635
}
599-
600-
// Read starting at the stored byte.
601-
SrcReg = DstReg;
602-
// Write starting at the following byte.
603-
auto One = MIRBuilder.buildConstant(LenTy, 1);
604-
DstReg = MIRBuilder.buildPtrAdd(DstTy, DstReg, One).getReg(0);
605-
// Copy one less byte.
606-
LenReg = MIRBuilder.buildConstant(LenTy, --ConstLen->Value).getReg(0);
607-
// Now it's just an ldir.
608-
}
609-
610-
Register DE = Is24Bit ? Z80::UDE : Z80::DE;
611-
Register HL = Is24Bit ? Z80::UHL : Z80::HL;
612-
Register BC = Is24Bit ? Z80::UBC : Z80::BC;
613-
auto ConstSrc = getIConstantVRegValWithLookThrough(SrcReg, MRI);
614-
auto ConstDst = getIConstantVRegValWithLookThrough(DstReg, MRI);
615-
bool ConstAddr = ConstSrc && ConstDst;
616-
if (!MI.hasOrderedMemoryRef() && ConstAddr &&
617-
ConstSrc->Value == ConstDst->Value) {
618-
MI.eraseFromParent();
619-
return LegalizerHelper::Legalized;
620-
}
621-
if (Opc == TargetOpcode::G_MEMMOVE && !ConstAddr) {
622-
MIRBuilder.buildCopy(HL, SrcReg);
623-
MIRBuilder.buildInstr(Is24Bit ? Z80::CP24ao : Z80::CP16ao, {},
624-
{DstReg});
625-
MIRBuilder.buildInstr(Is24Bit ? Z80::LDR24 : Z80::LDR16, {},
626-
{DstReg, SrcReg, LenReg}).cloneMemRefs(MI);
627-
} else if (Opc != TargetOpcode::G_MEMMOVE ||
628-
(ConstAddr &&
629-
(ConstDst->Value.ule(ConstSrc->Value) ||
630-
(ConstDst->Value - ConstSrc->Value).uge(ConstLen->Value)))) {
631-
// Use loads/stores if 4 bytes or less
632-
if (ConstLen->Value.ule(4)) {
633-
for (unsigned int Offset = 0; ConstLen->Value.ugt(Offset); ++Offset) {
634-
auto OffConst = MIRBuilder.buildConstant(LenTy, Offset);
635-
auto SrcAddrI = MIRBuilder.buildPtrAdd(SrcTy, SrcReg, OffConst);
636-
auto LoadReg = MIRBuilder.buildLoad(LLT::scalar(8), SrcAddrI,
637-
*MF.getMachineMemOperand(
638-
MI.memoperands()[1], Offset,
639-
LLT::scalar(8)));
640-
auto DstAddrI = MIRBuilder.buildPtrAdd(DstTy, DstReg, OffConst);
641-
MIRBuilder.buildStore(LoadReg, DstAddrI, *MF.getMachineMemOperand(
642-
MI.memoperands()[0], Offset,
643-
LLT::scalar(8)));
636+
if (Opc == TargetOpcode::G_MEMMOVE && !ConstAddr) {
637+
MIRBuilder.buildCopy(HL, SrcReg);
638+
MIRBuilder.buildInstr(Is24Bit ? Z80::CP24ao : Z80::CP16ao, {},
639+
{DstReg});
640+
MIRBuilder
641+
.buildInstr(Is24Bit ? Z80::LDR24 : Z80::LDR16, {},
642+
{DstReg, SrcReg, LenReg})
643+
.cloneMemRefs(MI);
644+
} else if (Opc != TargetOpcode::G_MEMMOVE ||
645+
(ConstAddr && (ConstDst->Value.ule(ConstSrc->Value) ||
646+
(ConstDst->Value - ConstSrc->Value)
647+
.uge(ConstLen->Value)))) {
648+
// Use loads/stores if 4 bytes or less
649+
if (ConstLen->Value.ule(4)) {
650+
for (unsigned int Offset = 0; ConstLen->Value.ugt(Offset);
651+
++Offset) {
652+
auto OffConst = MIRBuilder.buildConstant(LenTy, Offset);
653+
auto SrcAddrI = MIRBuilder.buildPtrAdd(SrcTy, SrcReg, OffConst);
654+
auto LoadReg = MIRBuilder.buildLoad(
655+
LLT::scalar(8), SrcAddrI,
656+
*MF.getMachineMemOperand(LoadMMO, Offset, LLT::scalar(8)));
657+
auto DstAddrI = MIRBuilder.buildPtrAdd(DstTy, DstReg, OffConst);
658+
MIRBuilder.buildStore(
659+
LoadReg, DstAddrI,
660+
*MF.getMachineMemOperand(StoreMMO, Offset, LLT::scalar(8)));
661+
}
662+
} else {
663+
MIRBuilder.buildCopy(DE, DstReg);
664+
MIRBuilder.buildCopy(HL, SrcReg);
665+
MIRBuilder.buildCopy(BC, LenReg);
666+
MIRBuilder.buildInstr(Is24Bit ? Z80::LDIR24 : Z80::LDIR16)
667+
.cloneMemRefs(MI);
644668
}
645669
} else {
646-
MIRBuilder.buildCopy(DE, DstReg);
647-
MIRBuilder.buildCopy(HL, SrcReg);
670+
auto LenMinusOne =
671+
MIRBuilder.buildConstant(LenTy, ConstLen->Value - 1);
672+
MIRBuilder.buildCopy(
673+
DE, MIRBuilder.buildPtrAdd(DstTy, DstReg, LenMinusOne));
674+
MIRBuilder.buildCopy(
675+
HL, MIRBuilder.buildPtrAdd(SrcTy, SrcReg, LenMinusOne));
648676
MIRBuilder.buildCopy(BC, LenReg);
649-
MIRBuilder.buildInstr(Is24Bit ? Z80::LDIR24 : Z80::LDIR16)
677+
MIRBuilder.buildInstr(Is24Bit ? Z80::LDDR24 : Z80::LDDR16)
650678
.cloneMemRefs(MI);
651679
}
652-
} else {
653-
auto LenMinusOne = MIRBuilder.buildConstant(LenTy, ConstLen->Value - 1);
654-
MIRBuilder.buildCopy(
655-
DE, MIRBuilder.buildPtrAdd(DstTy, DstReg, LenMinusOne));
656-
MIRBuilder.buildCopy(
657-
HL, MIRBuilder.buildPtrAdd(SrcTy, SrcReg, LenMinusOne));
658-
MIRBuilder.buildCopy(BC, LenReg);
659-
MIRBuilder.buildInstr(Is24Bit ? Z80::LDDR24 : Z80::LDDR16)
660-
.cloneMemRefs(MI);
680+
MI.eraseFromParent();
681+
return LegalizerHelper::Legalized;
661682
}
662-
MI.eraseFromParent();
663-
return LegalizerHelper::Legalized;
664683
}
665684
}
666685

0 commit comments

Comments
 (0)