@@ -3093,21 +3093,40 @@ static MachineInstr *stripAndAccumulateOffset(const MachineRegisterInfo &MRI,
30933093 return nullptr;
30943094}
30953095
3096- static std::pair<Register, unsigned>
3097- detectBlendComponents(const MachineRegisterInfo &MRI, Register Reg) {
3096+ void AArch64TargetLowering::fixupBlendComponents(
3097+ MachineInstr &MI, MachineBasicBlock *BB, MachineOperand &IntDiscOp,
3098+ MachineOperand &AddrDiscOp, const TargetRegisterClass *AddrDiscRC) const {
3099+ const TargetInstrInfo *TII = Subtarget->getInstrInfo();
3100+ MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
3101+ const DebugLoc &DL = MI.getDebugLoc();
3102+
3103+ Register AddrDisc = AddrDiscOp.getReg();
3104+ int64_t IntDisc = IntDiscOp.getImm();
3105+
3106+ assert(IntDisc == 0 && "Blend components are already expanded");
3107+
30983108 int64_t Offset = 0;
3099- MachineInstr *MaybeBlend = stripAndAccumulateOffset(MRI, Reg, Offset);
3100- // This should be a plain copy, without adding any offset.
3101- if (!MaybeBlend || Offset != 0)
3102- return std::make_pair(Reg, 0);
3109+ MachineInstr *MaybeBlend = stripAndAccumulateOffset(MRI, AddrDisc, Offset);
3110+
3111+ // Detect blend(addr, imm) which is lowered as MOVK addr, #imm, #48.
3112+ // The result of MOVK may be copied, but without adding any offset.
3113+ if (MaybeBlend && Offset == 0 && MaybeBlend->getOpcode() == AArch64::MOVKXi &&
3114+ MaybeBlend->getOperand(3).getImm() == 48) {
3115+ AddrDisc = MaybeBlend->getOperand(1).getReg();
3116+ IntDisc = MaybeBlend->getOperand(2).getImm();
3117+ }
31033118
3104- // Detect blend(addr, imm) which is lowered as MOVK addr, #imm, 48.
3105- if (MaybeBlend->getOpcode() != AArch64::MOVKXi ||
3106- MaybeBlend->getOperand(3).getImm() != 48)
3107- return std::make_pair(Reg, 0);
3119+ if (AddrDisc == AArch64::NoRegister)
3120+ AddrDisc = AArch64::XZR;
31083121
3109- return std::make_pair(MaybeBlend->getOperand(1).getReg(),
3110- MaybeBlend->getOperand(2).getImm());
3122+ if (AddrDisc != AArch64::XZR && MRI.getRegClass(AddrDisc) != AddrDiscRC) {
3123+ Register TmpReg = MRI.createVirtualRegister(AddrDiscRC);
3124+ BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), TmpReg).addReg(AddrDisc);
3125+ AddrDisc = TmpReg;
3126+ }
3127+
3128+ AddrDiscOp.setReg(AddrDisc);
3129+ IntDiscOp.setImm(IntDisc);
31113130}
31123131
31133132MachineBasicBlock *
@@ -3139,26 +3158,17 @@ AArch64TargetLowering::tryRewritingPAC(MachineInstr &MI,
31393158 const GlobalValue *GV = AddrOp.getGlobal();
31403159 AddrOffset += AddrOp.getOffset();
31413160
3142- // Analyze the discriminator operand.
3143- Register OriginalDisc = isPACWithZeroDisc(MI.getOpcode())
3144- ? AArch64::XZR
3145- : MI.getOperand(2).getReg();
3146- auto [AddrDisc, IntDisc] = detectBlendComponents(MRI, OriginalDisc);
3147-
3148- // MOVaddrPAC and LOADgotPAC pseudos are expanded so that they use X16/X17
3149- // internally, thus their restrictions on the register class of $AddrDisc
3150- // operand are stricter than those of MOVKXi and PAC* instructions.
3151- if (AddrDisc != AArch64::XZR) {
3152- Register TmpReg = MRI.createVirtualRegister(&AArch64::GPR64noipRegClass);
3153- BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), TmpReg).addReg(AddrDisc);
3154- AddrDisc = TmpReg;
3155- }
3156-
3157- BuildMI(*BB, MI, DL, TII->get(NewOpcode))
3158- .addGlobalAddress(GV, AddrOffset, TargetFlags)
3159- .addImm(getKeyForPACOpcode(MI.getOpcode()))
3160- .addReg(AddrDisc)
3161- .addImm(IntDisc);
3161+ Register DiscReg = isPACWithZeroDisc(MI.getOpcode())
3162+ ? AArch64::XZR
3163+ : MI.getOperand(2).getReg();
3164+
3165+ MachineInstr *NewMI = BuildMI(*BB, MI, DL, TII->get(NewOpcode))
3166+ .addGlobalAddress(GV, AddrOffset, TargetFlags)
3167+ .addImm(getKeyForPACOpcode(MI.getOpcode()))
3168+ .addReg(DiscReg)
3169+ .addImm(0);
3170+ fixupBlendComponents(*NewMI, BB, NewMI->getOperand(3), NewMI->getOperand(2),
3171+ &AArch64::GPR64noipRegClass);
31623172
31633173 BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), MI.getOperand(0).getReg())
31643174 .addReg(AArch64::X16);
0 commit comments