@@ -3384,21 +3384,40 @@ static MachineInstr *stripAndAccumulateOffset(const MachineRegisterInfo &MRI,
3384
3384
return nullptr;
3385
3385
}
3386
3386
3387
- static std::pair<Register, unsigned>
3388
- detectBlendComponents(const MachineRegisterInfo &MRI, Register Reg) {
3387
+ void AArch64TargetLowering::fixupBlendComponents(
3388
+ MachineInstr &MI, MachineBasicBlock *BB, MachineOperand &IntDiscOp,
3389
+ MachineOperand &AddrDiscOp, const TargetRegisterClass *AddrDiscRC) const {
3390
+ const TargetInstrInfo *TII = Subtarget->getInstrInfo();
3391
+ MachineRegisterInfo &MRI = MI.getMF()->getRegInfo();
3392
+ const DebugLoc &DL = MI.getDebugLoc();
3393
+
3394
+ Register AddrDisc = AddrDiscOp.getReg();
3395
+ int64_t IntDisc = IntDiscOp.getImm();
3396
+
3397
+ assert(IntDisc == 0 && "Blend components are already expanded");
3398
+
3389
3399
int64_t Offset = 0;
3390
- MachineInstr *MaybeBlend = stripAndAccumulateOffset(MRI, Reg, Offset);
3391
- // This should be a plain copy, without adding any offset.
3392
- if (!MaybeBlend || Offset != 0)
3393
- return std::make_pair(Reg, 0);
3400
+ MachineInstr *MaybeBlend = stripAndAccumulateOffset(MRI, AddrDisc, Offset);
3401
+
3402
+ // Detect blend(addr, imm) which is lowered as MOVK addr, #imm, #48.
3403
+ // The result of MOVK may be copied, but without adding any offset.
3404
+ if (MaybeBlend && Offset == 0 && MaybeBlend->getOpcode() == AArch64::MOVKXi &&
3405
+ MaybeBlend->getOperand(3).getImm() == 48) {
3406
+ AddrDisc = MaybeBlend->getOperand(1).getReg();
3407
+ IntDisc = MaybeBlend->getOperand(2).getImm();
3408
+ }
3394
3409
3395
- // Detect blend(addr, imm) which is lowered as MOVK addr, #imm, 48.
3396
- if (MaybeBlend->getOpcode() != AArch64::MOVKXi ||
3397
- MaybeBlend->getOperand(3).getImm() != 48)
3398
- return std::make_pair(Reg, 0);
3410
+ if (AddrDisc == AArch64::NoRegister)
3411
+ AddrDisc = AArch64::XZR;
3399
3412
3400
- return std::make_pair(MaybeBlend->getOperand(1).getReg(),
3401
- MaybeBlend->getOperand(2).getImm());
3413
+ if (AddrDisc != AArch64::XZR && MRI.getRegClass(AddrDisc) != AddrDiscRC) {
3414
+ Register TmpReg = MRI.createVirtualRegister(AddrDiscRC);
3415
+ BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), TmpReg).addReg(AddrDisc);
3416
+ AddrDisc = TmpReg;
3417
+ }
3418
+
3419
+ AddrDiscOp.setReg(AddrDisc);
3420
+ IntDiscOp.setImm(IntDisc);
3402
3421
}
3403
3422
3404
3423
MachineBasicBlock *
@@ -3430,26 +3449,17 @@ AArch64TargetLowering::tryRewritingPAC(MachineInstr &MI,
3430
3449
const GlobalValue *GV = AddrOp.getGlobal();
3431
3450
AddrOffset += AddrOp.getOffset();
3432
3451
3433
- // Analyze the discriminator operand.
3434
- Register OriginalDisc = isPACWithZeroDisc(MI.getOpcode())
3435
- ? AArch64::XZR
3436
- : MI.getOperand(2).getReg();
3437
- auto [AddrDisc, IntDisc] = detectBlendComponents(MRI, OriginalDisc);
3438
-
3439
- // MOVaddrPAC and LOADgotPAC pseudos are expanded so that they use X16/X17
3440
- // internally, thus their restrictions on the register class of $AddrDisc
3441
- // operand are stricter than those of MOVKXi and PAC* instructions.
3442
- if (AddrDisc != AArch64::XZR) {
3443
- Register TmpReg = MRI.createVirtualRegister(&AArch64::GPR64noipRegClass);
3444
- BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), TmpReg).addReg(AddrDisc);
3445
- AddrDisc = TmpReg;
3446
- }
3447
-
3448
- BuildMI(*BB, MI, DL, TII->get(NewOpcode))
3449
- .addGlobalAddress(GV, AddrOffset, TargetFlags)
3450
- .addImm(getKeyForPACOpcode(MI.getOpcode()))
3451
- .addReg(AddrDisc)
3452
- .addImm(IntDisc);
3452
+ Register DiscReg = isPACWithZeroDisc(MI.getOpcode())
3453
+ ? AArch64::XZR
3454
+ : MI.getOperand(2).getReg();
3455
+
3456
+ MachineInstr *NewMI = BuildMI(*BB, MI, DL, TII->get(NewOpcode))
3457
+ .addGlobalAddress(GV, AddrOffset, TargetFlags)
3458
+ .addImm(getKeyForPACOpcode(MI.getOpcode()))
3459
+ .addReg(DiscReg)
3460
+ .addImm(0);
3461
+ fixupBlendComponents(*NewMI, BB, NewMI->getOperand(3), NewMI->getOperand(2),
3462
+ &AArch64::GPR64noipRegClass);
3453
3463
3454
3464
BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), MI.getOperand(0).getReg())
3455
3465
.addReg(AArch64::X16);
0 commit comments