[llvm] 4e408aa - [AArch64][GlobalISel] Select full-fp16 s16 G_FCONSTANT as a constant pool load
Jessica Paquette via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 10 19:38:16 PDT 2021
Author: Jessica Paquette
Date: 2021-09-10T19:36:34-07:00
New Revision: 4e408aae2c55a8fd71b5a96eb86db350a7acc443
URL: https://github.com/llvm/llvm-project/commit/4e408aae2c55a8fd71b5a96eb86db350a7acc443
DIFF: https://github.com/llvm/llvm-project/commit/4e408aae2c55a8fd71b5a96eb86db350a7acc443.diff
LOG: [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
Added:
Modified:
llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index 0904a7ecce76..6634a197df69 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -2475,10 +2475,10 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
// FIXME: Redundant check, but even less readable when factored out.
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
- << " constant, expected: " << s32 << " or " << s64
- << " or " << s128 << '\n');
+ << " constant, expected: " << s16 << " or " << s32
+ << " or " << s64 << " or " << s128 << '\n');
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) {
- // Either emit a FMOV, or emit a copy to emit a normal mov.
- const TargetRegisterClass &GPRRC =
- DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass;
- const TargetRegisterClass &FPRRC =
- DefSize == 32 ? AArch64::FPR32RegClass
- : (DefSize == 64 ? AArch64::FPR64RegClass
- : AArch64::FPR128RegClass);
-
- // For 64b values, emit a constant pool load instead.
- // For s32, use a cp load if we have optsize/minsize.
- if (DefSize == 64 || DefSize == 128 ||
- (DefSize == 32 && shouldOptForSize(&MF))) {
+ const TargetRegisterClass &FPRRC = *getMinClassForRegBank(RB, DefSize);
+ // For 16, 64, and 128b values, emit a constant pool load.
+ switch (DefSize) {
+ default:
+ llvm_unreachable("Unexpected destination size for G_FCONSTANT?");
+ case 32:
+ // For s32, use a cp load if we have optsize/minsize.
+ if (!shouldOptForSize(&MF))
+ break;
+ LLVM_FALLTHROUGH;
+ case 16:
+ case 64:
+ case 128: {
auto *FPImm = I.getOperand(1).getFPImm();
auto *LoadMI = emitLoadFromConstantPool(FPImm, MIB);
if (!LoadMI) {
@@ -2539,9 +2536,13 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
I.eraseFromParent();
return RBI.constrainGenericRegister(DefReg, FPRRC, MRI);
}
+ }
- // Nope. Emit a copy and use a normal mov instead.
- const Register DefGPRReg = MRI.createVirtualRegister(&GPRRC);
+ // Either emit a FMOV, or emit a copy to emit a normal mov.
+ 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);
RegOp.setReg(DefGPRReg);
MIB.setInsertPt(MIB.getMBB(), std::next(I.getIterator()));
@@ -2564,6 +2565,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
I.getOperand(1).ChangeToImmediate(Val);
}
+ const unsigned MovOpc =
+ DefSize == 64 ? AArch64::MOVi64imm : AArch64::MOVi32imm;
I.setDesc(TII.get(MovOpc));
constrainSelectedInstRegOperands(I, TII, TRI, RBI);
return true;
@@ -4236,6 +4239,13 @@ MachineInstr *AArch64InstructionSelector::emitLoadFromConstantPool(
.addConstantPoolIndex(CPIdx, 0,
AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
break;
+ case 2:
+ LoadMI =
+ &*MIRBuilder
+ .buildInstr(AArch64::LDRHui, {&AArch64::FPR16RegClass}, {Adrp})
+ .addConstantPoolIndex(CPIdx, 0,
+ AArch64II::MO_PAGEOFF | AArch64II::MO_NC);
+ break;
default:
LLVM_DEBUG(dbgs() << "Could not load from constant pool of type "
<< *CPVal->getType());
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir
index f7ad8fa0121e..18f907813de5 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-fp16-fconstant.mir
@@ -30,3 +30,19 @@ body: |
%0:fpr(s16) = G_FCONSTANT half 1.0
$h0 = COPY %0(s16)
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
More information about the llvm-commits
mailing list