forked from OSchip/llvm-project
[AArch64][GlobalISel] Generalize logic for promoting copies
Generalize the 16-bit FPR to 32-bit GPR logic to work for all cases where destination size is bigger than source size. Also fixed CheckCopy() always returning true instead of the result of isValidCopy(). Differential Revision: https://reviews.llvm.org/D77530 Patch by tambre (Raul Tambre)
This commit is contained in:
parent
68b30bc02b
commit
9f31446c99
|
@ -736,7 +736,6 @@ getRegClassesForCopy(MachineInstr &I, const TargetInstrInfo &TII,
|
||||||
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
|
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
|
||||||
MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
|
MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI,
|
||||||
const RegisterBankInfo &RBI) {
|
const RegisterBankInfo &RBI) {
|
||||||
|
|
||||||
Register DstReg = I.getOperand(0).getReg();
|
Register DstReg = I.getOperand(0).getReg();
|
||||||
Register SrcReg = I.getOperand(1).getReg();
|
Register SrcReg = I.getOperand(1).getReg();
|
||||||
const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
|
const RegisterBank &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI);
|
||||||
|
@ -769,13 +768,12 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
|
||||||
(!Register::isPhysicalRegister(I.getOperand(0).getReg()) &&
|
(!Register::isPhysicalRegister(I.getOperand(0).getReg()) &&
|
||||||
!Register::isPhysicalRegister(I.getOperand(1).getReg()))) &&
|
!Register::isPhysicalRegister(I.getOperand(1).getReg()))) &&
|
||||||
"No phys reg on generic operator!");
|
"No phys reg on generic operator!");
|
||||||
assert(KnownValid || isValidCopy(I, DstRegBank, MRI, TRI, RBI));
|
bool ValidCopy = KnownValid || isValidCopy(I, DstRegBank, MRI, TRI, RBI);
|
||||||
(void)KnownValid;
|
assert(ValidCopy && "Invalid copy.");
|
||||||
return true;
|
return ValidCopy;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Is this a copy? If so, then we may need to insert a subregister copy, or
|
// Is this a copy? If so, then we may need to insert a subregister copy.
|
||||||
// a SUBREG_TO_REG.
|
|
||||||
if (I.isCopy()) {
|
if (I.isCopy()) {
|
||||||
// Yes. Check if there's anything to fix up.
|
// Yes. Check if there's anything to fix up.
|
||||||
if (!SrcRC) {
|
if (!SrcRC) {
|
||||||
|
@ -785,51 +783,43 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
|
||||||
|
|
||||||
unsigned SrcSize = TRI.getRegSizeInBits(*SrcRC);
|
unsigned SrcSize = TRI.getRegSizeInBits(*SrcRC);
|
||||||
unsigned DstSize = TRI.getRegSizeInBits(*DstRC);
|
unsigned DstSize = TRI.getRegSizeInBits(*DstRC);
|
||||||
|
unsigned SubReg;
|
||||||
|
|
||||||
// If the source register is bigger than the destination we need to perform
|
// If the source bank doesn't support a subregister copy small enough,
|
||||||
// a subregister copy.
|
// then we first need to copy to the destination bank.
|
||||||
if (SrcSize > DstSize) {
|
if (getMinSizeForRegBank(SrcRegBank) > DstSize) {
|
||||||
unsigned SubReg = 0;
|
const TargetRegisterClass *DstTempRC =
|
||||||
|
getMinClassForRegBank(DstRegBank, SrcSize, /* GetAllRegSet */ true);
|
||||||
|
getSubRegForClass(DstRC, TRI, SubReg);
|
||||||
|
|
||||||
// If the source bank doesn't support a subregister copy small enough,
|
MachineIRBuilder MIB(I);
|
||||||
// then we first need to copy to the destination bank.
|
auto Copy = MIB.buildCopy({DstTempRC}, {SrcReg});
|
||||||
if (getMinSizeForRegBank(SrcRegBank) > DstSize) {
|
copySubReg(I, MRI, RBI, Copy.getReg(0), DstRC, SubReg);
|
||||||
const TargetRegisterClass *SubregRC = getMinClassForRegBank(
|
} else if (SrcSize > DstSize) {
|
||||||
DstRegBank, SrcSize, /* GetAllRegSet = */ true);
|
// If the source register is bigger than the destination we need to
|
||||||
getSubRegForClass(DstRC, TRI, SubReg);
|
// perform a subregister copy.
|
||||||
|
const TargetRegisterClass *SubRegRC =
|
||||||
|
getMinClassForRegBank(SrcRegBank, DstSize, /* GetAllRegSet */ true);
|
||||||
|
getSubRegForClass(SubRegRC, TRI, SubReg);
|
||||||
|
copySubReg(I, MRI, RBI, SrcReg, DstRC, SubReg);
|
||||||
|
} else if (DstSize > SrcSize) {
|
||||||
|
// If the destination register is bigger than the source we need to do
|
||||||
|
// a promotion using SUBREG_TO_REG.
|
||||||
|
const TargetRegisterClass *PromotionRC =
|
||||||
|
getMinClassForRegBank(SrcRegBank, DstSize, /* GetAllRegSet */ true);
|
||||||
|
getSubRegForClass(SrcRC, TRI, SubReg);
|
||||||
|
|
||||||
MachineIRBuilder MIB(I);
|
Register PromoteReg = MRI.createVirtualRegister(PromotionRC);
|
||||||
auto Copy = MIB.buildCopy({SubregRC}, {SrcReg});
|
BuildMI(*I.getParent(), I, I.getDebugLoc(),
|
||||||
copySubReg(I, MRI, RBI, Copy.getReg(0), DstRC, SubReg);
|
TII.get(AArch64::SUBREG_TO_REG), PromoteReg)
|
||||||
} else {
|
.addImm(0)
|
||||||
const TargetRegisterClass *SubregRC = getMinClassForRegBank(
|
.addUse(SrcReg)
|
||||||
SrcRegBank, DstSize, /* GetAllRegSet = */ true);
|
.addImm(SubReg);
|
||||||
getSubRegForClass(SubregRC, TRI, SubReg);
|
MachineOperand &RegOp = I.getOperand(1);
|
||||||
copySubReg(I, MRI, RBI, SrcReg, DstRC, SubReg);
|
RegOp.setReg(PromoteReg);
|
||||||
}
|
|
||||||
|
|
||||||
return CheckCopy();
|
// Promise that the copy is implicitly validated by the SUBREG_TO_REG.
|
||||||
}
|
KnownValid = true;
|
||||||
|
|
||||||
// Is this a cross-bank copy?
|
|
||||||
if (DstRegBank.getID() != SrcRegBank.getID()) {
|
|
||||||
if (DstRegBank.getID() == AArch64::GPRRegBankID && DstSize == 32 &&
|
|
||||||
SrcSize == 16) {
|
|
||||||
// Special case for FPR16 to GPR32.
|
|
||||||
// FIXME: This can probably be generalized like the above case.
|
|
||||||
Register PromoteReg =
|
|
||||||
MRI.createVirtualRegister(&AArch64::FPR32RegClass);
|
|
||||||
BuildMI(*I.getParent(), I, I.getDebugLoc(),
|
|
||||||
TII.get(AArch64::SUBREG_TO_REG), PromoteReg)
|
|
||||||
.addImm(0)
|
|
||||||
.addUse(SrcReg)
|
|
||||||
.addImm(AArch64::hsub);
|
|
||||||
MachineOperand &RegOp = I.getOperand(1);
|
|
||||||
RegOp.setReg(PromoteReg);
|
|
||||||
|
|
||||||
// Promise that the copy is implicitly validated by the SUBREG_TO_REG.
|
|
||||||
KnownValid = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the destination is a physical register, then there's nothing to
|
// If the destination is a physical register, then there's nothing to
|
||||||
|
|
Loading…
Reference in New Issue