[llvm] [AArch64][GlobalISel] Use GPR for illegal fconstants and extend < 32 bit GPR constants to 32 bits (PR #178692)
Ryan Cowan via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 5 02:21:39 PST 2026
================
@@ -358,12 +360,79 @@ AArch64RegisterBankInfo::getInstrAlternativeMappings(
return RegisterBankInfo::getInstrAlternativeMappings(MI);
}
+static bool isLegalFPImm(const MachineInstr &MI, const MachineRegisterInfo &MRI,
+ const AArch64Subtarget &STI) {
+ assert(MI.getOpcode() == TargetOpcode::G_FCONSTANT);
+ Register Dst = MI.getOperand(0).getReg();
+ LLT Ty = MRI.getType(Dst);
+ if (!Ty.isScalar())
+ return false;
+
+ unsigned Bits = Ty.getSizeInBits();
+ if (Bits != 16 && Bits != 32 && Bits != 64)
+ return false;
+
+ EVT VT = EVT::getFloatingPointVT(Bits);
+ bool OptForSize = MI.getMF()->getFunction().hasOptSize() ||
+ MI.getMF()->getFunction().hasMinSize();
+ const AArch64TargetLowering *TLI = STI.getTargetLowering();
+ return TLI->isFPImmLegal(MI.getOperand(1).getFPImm()->getValueAPF(), VT,
+ OptForSize);
+}
+
void AArch64RegisterBankInfo::applyMappingImpl(
MachineIRBuilder &Builder, const OperandsMapper &OpdMapper) const {
MachineInstr &MI = OpdMapper.getMI();
MachineRegisterInfo &MRI = OpdMapper.getMRI();
switch (MI.getOpcode()) {
+ case TargetOpcode::G_CONSTANT: {
+ Register Dst = MI.getOperand(0).getReg();
+ LLT DstTy = MRI.getType(Dst);
+ if (MRI.getRegBank(Dst) == &AArch64::GPRRegBank && DstTy.isScalar() &&
+ DstTy.getSizeInBits() < 32) {
+ Builder.setInsertPt(*MI.getParent(), std::next(MI.getIterator()));
+ Register ExtReg = MRI.createGenericVirtualRegister(LLT::scalar(32));
+ Builder.buildTrunc(Dst, ExtReg);
+
+ auto Val = MI.getOperand(1).getCImm()->getValue().zext(32);
+ LLVMContext &Ctx = Builder.getMF().getFunction().getContext();
+ MI.getOperand(1).setCImm(ConstantInt::get(Ctx, Val));
+ MI.getOperand(0).setReg(ExtReg);
+ MRI.setRegBank(ExtReg, AArch64::GPRRegBank);
+
+ for (MachineInstr &UseMI :
+ make_early_inc_range(MRI.use_nodbg_instructions(Dst))) {
+ if (UseMI.getOpcode() != AArch64::G_DUP)
+ continue;
+ for (MachineOperand &Op : UseMI.operands()) {
+ if (Op.isReg() && Op.getReg() == Dst)
+ Op.setReg(ExtReg);
+ }
+ }
+ }
+ return applyDefaultMapping(OpdMapper);
+ }
+ case TargetOpcode::G_FCONSTANT: {
+ Register Dst = MI.getOperand(0).getReg();
+ if (MRI.getRegBank(Dst) == &AArch64::GPRRegBank) {
----------------
HolyMolyCowMan wrote:
By the time this is reached, `getInstrMapping` has forced the regbank to be a GPR so it looks like I can change this to an assert.
Thanks again!
https://github.com/llvm/llvm-project/pull/178692
More information about the llvm-commits
mailing list