forked from OSchip/llvm-project
[AArch64][GlobalISel] Select full-fp16 s16 G_FCONSTANT as a constant pool load
When we have full-fp16 support, we should (manually select) s16 G_FCONSTANT to a constant pool load. Add support for that to `emitLoadFromConstantPool` + the existing constant selection code. Also tidy up the constant selection code a little. There were some out-of-date comments + some dead code. Differential Revision: https://reviews.llvm.org/D108957
This commit is contained in:
parent
e972e49b11
commit
4e408aae2c
|
@ -2475,10 +2475,10 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
||||||
|
|
||||||
// FIXME: Redundant check, but even less readable when factored out.
|
// FIXME: Redundant check, but even less readable when factored out.
|
||||||
if (isFP) {
|
if (isFP) {
|
||||||
if (Ty != s32 && Ty != s64 && Ty != s128) {
|
if (Ty != s16 && Ty != s32 && Ty != s64 && Ty != s128) {
|
||||||
LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
|
LLVM_DEBUG(dbgs() << "Unable to materialize FP " << Ty
|
||||||
<< " constant, expected: " << s32 << " or " << s64
|
<< " constant, expected: " << s16 << " or " << s32
|
||||||
<< " or " << s128 << '\n');
|
<< " or " << s64 << " or " << s128 << '\n');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2512,23 +2512,20 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We allow G_CONSTANT of types < 32b.
|
|
||||||
const unsigned MovOpc =
|
|
||||||
DefSize == 64 ? AArch64::MOVi64imm : AArch64::MOVi32imm;
|
|
||||||
|
|
||||||
if (isFP) {
|
if (isFP) {
|
||||||
// Either emit a FMOV, or emit a copy to emit a normal mov.
|
const TargetRegisterClass &FPRRC = *getMinClassForRegBank(RB, DefSize);
|
||||||
const TargetRegisterClass &GPRRC =
|
// For 16, 64, and 128b values, emit a constant pool load.
|
||||||
DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
|
switch (DefSize) {
|
||||||
const TargetRegisterClass &FPRRC =
|
default:
|
||||||
DefSize == 32 ? AArch64::FPR32RegClass
|
llvm_unreachable("Unexpected destination size for G_FCONSTANT?");
|
||||||
: (DefSize == 64 ? AArch64::FPR64RegClass
|
case 32:
|
||||||
: AArch64::FPR128RegClass);
|
// For s32, use a cp load if we have optsize/minsize.
|
||||||
|
if (!shouldOptForSize(&MF))
|
||||||
// For 64b values, emit a constant pool load instead.
|
break;
|
||||||
// For s32, use a cp load if we have optsize/minsize.
|
LLVM_FALLTHROUGH;
|
||||||
if (DefSize == 64 || DefSize == 128 ||
|
case 16:
|
||||||
(DefSize == 32 && shouldOptForSize(&MF))) {
|
case 64:
|
||||||
|
case 128: {
|
||||||
auto *FPImm = I.getOperand(1).getFPImm();
|
auto *FPImm = I.getOperand(1).getFPImm();
|
||||||
auto *LoadMI = emitLoadFromConstantPool(FPImm, MIB);
|
auto *LoadMI = emitLoadFromConstantPool(FPImm, MIB);
|
||||||
if (!LoadMI) {
|
if (!LoadMI) {
|
||||||
|
@ -2539,9 +2536,13 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
||||||
I.eraseFromParent();
|
I.eraseFromParent();
|
||||||
return RBI.constrainGenericRegister(DefReg, FPRRC, MRI);
|
return RBI.constrainGenericRegister(DefReg, FPRRC, MRI);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Nope. Emit a copy and use a normal mov instead.
|
// Either emit a FMOV, or emit a copy to emit a normal mov.
|
||||||
const Register DefGPRReg = MRI.createVirtualRegister(&GPRRC);
|
assert(DefSize == 32 &&
|
||||||
|
"Expected constant pool loads for all sizes other than 32!");
|
||||||
|
const Register DefGPRReg =
|
||||||
|
MRI.createVirtualRegister(&AArch64::GPR32RegClass);
|
||||||
MachineOperand &RegOp = I.getOperand(0);
|
MachineOperand &RegOp = I.getOperand(0);
|
||||||
RegOp.setReg(DefGPRReg);
|
RegOp.setReg(DefGPRReg);
|
||||||
MIB.setInsertPt(MIB.getMBB(), std::next(I.getIterator()));
|
MIB.setInsertPt(MIB.getMBB(), std::next(I.getIterator()));
|
||||||
|
@ -2564,6 +2565,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
|
||||||
I.getOperand(1).ChangeToImmediate(Val);
|
I.getOperand(1).ChangeToImmediate(Val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const unsigned MovOpc =
|
||||||
|
DefSize == 64 ? AArch64::MOVi64imm : AArch64::MOVi32imm;
|
||||||
I.setDesc(TII.get(MovOpc));
|
I.setDesc(TII.get(MovOpc));
|
||||||
constrainSelectedInstRegOperands(I, TII, TRI, RBI);
|
constrainSelectedInstRegOperands(I, TII, TRI, RBI);
|
||||||
return true;
|
return true;
|
||||||
|
@ -4236,6 +4239,13 @@ MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool(
|
||||||
.addConstantPoolIndex(CPIdx, 0,
|
.addConstantPoolIndex(CPIdx, 0,
|
||||||
AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
|
AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
|
||||||
break;
|
break;
|
||||||
|
case 2:
|
||||||
|
LoadMI =
|
||||||
|
&*MIRBuilder
|
||||||
|
.buildInstr(AArch64::LDRHui, {&AArch64::FPR16RegClass}, {Adrp})
|
||||||
|
.addConstantPoolIndex(CPIdx, 0,
|
||||||
|
AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LLVM_DEBUG(dbgs() << "Could not load from constant pool of type "
|
LLVM_DEBUG(dbgs() << "Could not load from constant pool of type "
|
||||||
<< *CPVal->getType());
|
<< *CPVal->getType());
|
||||||
|
|
|
@ -30,3 +30,19 @@ body: |
|
||||||
%0:fpr(s16) = G_FCONSTANT half 1.0
|
%0:fpr(s16) = G_FCONSTANT half 1.0
|
||||||
$h0 = COPY %0(s16)
|
$h0 = COPY %0(s16)
|
||||||
RET_ReallyLR implicit $h0
|
RET_ReallyLR implicit $h0
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: constant_pool_load
|
||||||
|
legalized: true
|
||||||
|
regBankSelected: true
|
||||||
|
tracksRegLiveness: true
|
||||||
|
body: |
|
||||||
|
bb.0:
|
||||||
|
; CHECK-LABEL: name: constant_pool_load
|
||||||
|
; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
|
||||||
|
; CHECK: [[LDRHui:%[0-9]+]]:fpr16 = LDRHui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s16) from constant-pool)
|
||||||
|
; CHECK: $h0 = COPY [[LDRHui]]
|
||||||
|
; CHECK: RET_ReallyLR implicit $h0
|
||||||
|
%0:fpr(s16) = G_FCONSTANT half 0xH000B
|
||||||
|
$h0 = COPY %0(s16)
|
||||||
|
RET_ReallyLR implicit $h0
|
||||||
|
|
Loading…
Reference in New Issue