[AArch64][GlobalISel] Emit constant pool loads for 64 bit fp immediates.

Note: don't do this for integer 64 bit materialization to match SDAG.

Differential Revision: https://reviews.llvm.org/D81893
This commit is contained in:
Amara Emerson 2020-06-15 16:14:47 -07:00
parent 8d2acfc40e
commit 1035a416a6
2 changed files with 46 additions and 4 deletions

View File

@ -144,8 +144,9 @@ private:
bool selectBrJT(MachineInstr &I, MachineRegisterInfo &MRI) const;
bool selectTLSGlobalValue(MachineInstr &I, MachineRegisterInfo &MRI) const;
unsigned emitConstantPoolEntry(Constant *CPVal, MachineFunction &MF) const;
MachineInstr *emitLoadFromConstantPool(Constant *CPVal,
unsigned emitConstantPoolEntry(const Constant *CPVal,
MachineFunction &MF) const;
MachineInstr *emitLoadFromConstantPool(const Constant *CPVal,
MachineIRBuilder &MIRBuilder) const;
// Emit a vector concat operation.
@ -2046,6 +2047,20 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
if (emitFMovForFConstant(I, MRI))
return true;
// For 64b values, emit a constant pool load instead.
if (DefSize == 64) {
auto *FPImm = I.getOperand(1).getFPImm();
MachineIRBuilder MIB(I);
auto *LoadMI = emitLoadFromConstantPool(FPImm, MIB);
if (!LoadMI) {
LLVM_DEBUG(dbgs() << "Failed to load double constant pool entry\n");
return false;
}
MIB.buildCopy({DefReg}, {LoadMI->getOperand(0).getReg()});
I.eraseFromParent();
return RBI.constrainGenericRegister(DefReg, FPRRC, MRI);
}
// Nope. Emit a copy and use a normal mov instead.
const Register DefGPRReg = MRI.createVirtualRegister(&GPRRC);
MachineOperand &RegOp = I.getOperand(0);
@ -3572,7 +3587,7 @@ bool AArch64InstructionSelector::selectConcatVectors(
}
unsigned
AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal,
AArch64InstructionSelector::emitConstantPoolEntry(const Constant *CPVal,
MachineFunction &MF) const {
Type *CPTy = CPVal->getType();
Align Alignment = MF.getDataLayout().getPrefTypeAlign(CPTy);
@ -3582,7 +3597,7 @@ AArch64InstructionSelector::emitConstantPoolEntry(Constant *CPVal,
}
MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool(
Constant *CPVal, MachineIRBuilder &MIRBuilder) const {
const Constant *CPVal, MachineIRBuilder &MIRBuilder) const {
unsigned CPIdx = emitConstantPoolEntry(CPVal, MIRBuilder.getMF());
auto Adrp =

View File

@ -6,6 +6,7 @@
define void @imm_s32_gpr() { ret void }
define void @imm_s64_gpr() { ret void }
define void @test_f64_cp() { ret void }
...
@ -49,3 +50,29 @@ body: |
%0(s64) = G_CONSTANT i64 1234
$x0 = COPY %0(s64)
...
# 64b FP immediates need to be loaded.
---
name: test_f64_cp
legalized: true
regBankSelected: true
liveins:
- { reg: '$d0' }
body: |
bb.1 (%ir-block.0):
liveins: $d0
; CHECK-LABEL: name: test_f64_cp
; CHECK: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
; CHECK: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0
; CHECK: [[FADDDrr:%[0-9]+]]:fpr64 = FADDDrr [[COPY]], [[LDRDui]]
; CHECK: $d0 = COPY [[FADDDrr]]
; CHECK: RET_ReallyLR implicit $d0
%0:fpr(s64) = COPY $d0
%1:fpr(s64) = G_FCONSTANT double 0x3FEFF7CED916872B
%2:fpr(s64) = G_FADD %0, %1
$d0 = COPY %2(s64)
RET_ReallyLR implicit $d0
...