@@ -230,6 +230,7 @@ class AArch64InstructionSelector : public InstructionSelector {
230230 bool selectMOPS (MachineInstr &I, MachineRegisterInfo &MRI);
231231 bool selectUSMovFromExtend (MachineInstr &I, MachineRegisterInfo &MRI);
232232
233+ bool selectIndexedExtLoad (MachineInstr &I, MachineRegisterInfo &MRI);
233234 bool selectIndexedLoad (MachineInstr &I, MachineRegisterInfo &MRI);
234235 bool selectIndexedStore (GIndexedStore &I, MachineRegisterInfo &MRI);
235236
@@ -3047,6 +3048,9 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
30473048 return constrainSelectedInstRegOperands (*LoadStore, TII, TRI, RBI);
30483049 }
30493050
3051+ case TargetOpcode::G_INDEXED_ZEXTLOAD:
3052+ case TargetOpcode::G_INDEXED_SEXTLOAD:
3053+ return selectIndexedExtLoad (I, MRI);
30503054 case TargetOpcode::G_INDEXED_LOAD:
30513055 return selectIndexedLoad (I, MRI);
30523056 case TargetOpcode::G_INDEXED_STORE:
@@ -5648,6 +5652,93 @@ MachineInstr *AArch64InstructionSelector::tryAdvSIMDModImmFP(
56485652 return &*Mov;
56495653}
56505654
5655+ bool AArch64InstructionSelector::selectIndexedExtLoad (
5656+ MachineInstr &MI, MachineRegisterInfo &MRI) {
5657+ auto &ExtLd = cast<GIndexedExtLoad>(MI);
5658+ Register Dst = ExtLd.getDstReg ();
5659+ Register WriteBack = ExtLd.getWritebackReg ();
5660+ Register Base = ExtLd.getBaseReg ();
5661+ Register Offset = ExtLd.getOffsetReg ();
5662+ LLT Ty = MRI.getType (Dst);
5663+ assert (Ty.getSizeInBits () <= 64 ); // Only for scalar GPRs.
5664+ unsigned MemSizeBits = ExtLd.getMMO ().getMemoryType ().getSizeInBits ();
5665+ bool IsPre = ExtLd.isPre ();
5666+ bool IsSExt = isa<GIndexedSExtLoad>(ExtLd);
5667+ bool InsertIntoXReg = false ;
5668+ bool IsDst64 = Ty.getSizeInBits () == 64 ;
5669+
5670+ unsigned Opc = 0 ;
5671+ LLT NewLdDstTy;
5672+ LLT s32 = LLT::scalar (32 );
5673+ LLT s64 = LLT::scalar (64 );
5674+
5675+ if (MemSizeBits == 8 ) {
5676+ if (IsSExt) {
5677+ if (IsDst64)
5678+ Opc = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost;
5679+ else
5680+ Opc = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost;
5681+ NewLdDstTy = IsDst64 ? s64 : s32;
5682+ } else {
5683+ Opc = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost;
5684+ InsertIntoXReg = IsDst64;
5685+ NewLdDstTy = s32;
5686+ }
5687+ } else if (MemSizeBits == 16 ) {
5688+ if (IsSExt) {
5689+ if (IsDst64)
5690+ Opc = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost;
5691+ else
5692+ Opc = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost;
5693+ NewLdDstTy = IsDst64 ? s64 : s32;
5694+ } else {
5695+ Opc = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost;
5696+ InsertIntoXReg = IsDst64;
5697+ NewLdDstTy = s32;
5698+ }
5699+ } else if (MemSizeBits == 32 ) {
5700+ if (IsSExt) {
5701+ Opc = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost;
5702+ NewLdDstTy = s64;
5703+ } else {
5704+ Opc = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost;
5705+ InsertIntoXReg = IsDst64;
5706+ NewLdDstTy = s32;
5707+ }
5708+ } else {
5709+ llvm_unreachable (" Unexpected size for indexed load" );
5710+ }
5711+
5712+ if (RBI.getRegBank (Dst, MRI, TRI)->getID () == AArch64::FPRRegBankID)
5713+ return false ; // We should be on gpr.
5714+
5715+ auto Cst = getIConstantVRegVal (Offset, MRI);
5716+ if (!Cst)
5717+ return false ; // Shouldn't happen, but just in case.
5718+
5719+ auto LdMI = MIB.buildInstr (Opc, {WriteBack, NewLdDstTy}, {Base})
5720+ .addImm (Cst->getSExtValue ());
5721+ LdMI.cloneMemRefs (ExtLd);
5722+ constrainSelectedInstRegOperands (*LdMI, TII, TRI, RBI);
5723+ // Make sure to select the load with the MemTy as the dest type, and then
5724+ // insert into X reg if needed.
5725+ if (InsertIntoXReg) {
5726+ // Generate a SUBREG_TO_REG.
5727+ auto SubToReg = MIB.buildInstr (TargetOpcode::SUBREG_TO_REG, {Dst}, {})
5728+ .addImm (0 )
5729+ .addUse (LdMI.getReg (1 ))
5730+ .addImm (AArch64::sub_32);
5731+ RBI.constrainGenericRegister (SubToReg.getReg (0 ), AArch64::GPR64RegClass,
5732+ MRI);
5733+ } else {
5734+ auto Copy = MIB.buildCopy (Dst, LdMI.getReg (1 ));
5735+ selectCopy (*Copy, TII, MRI, TRI, RBI);
5736+ }
5737+ MI.eraseFromParent ();
5738+
5739+ return true ;
5740+ }
5741+
56515742bool AArch64InstructionSelector::selectIndexedLoad (MachineInstr &MI,
56525743 MachineRegisterInfo &MRI) {
56535744 // TODO: extending loads.
0 commit comments