@@ -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