@@ -3093,21 +3093,40 @@ static MachineInstr *stripAndAccumulateOffset(const MachineRegisterInfo &MRI,
3093
3093
return nullptr;
3094
3094
}
3095
3095
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
+
3098
3108
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
+ }
3103
3118
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;
3108
3121
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);
3111
3130
}
3112
3131
3113
3132
MachineBasicBlock *
@@ -3139,26 +3158,17 @@ AArch64TargetLowering::tryRewritingPAC(MachineInstr &MI,
3139
3158
const GlobalValue *GV = AddrOp.getGlobal();
3140
3159
AddrOffset += AddrOp.getOffset();
3141
3160
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);
3162
3172
3163
3173
BuildMI(*BB, MI, DL, TII->get(AArch64::COPY), MI.getOperand(0).getReg())
3164
3174
.addReg(AArch64::X16);
0 commit comments