diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1248,6 +1248,9 @@ GISDNodeXFormEquiv; def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">, GISDNodeXFormEquiv; +def gi_fpimm32SIMDModImmType4 : + GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">, + GISDNodeXFormEquiv; // Vector lane operands class AsmVectorIndex : AsmOperandClass { diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -437,6 +437,9 @@ int OpIdx = -1) const; void renderFPImm64(MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx = -1) const; + void renderFPImm32SIMDModImmType4(MachineInstrBuilder &MIB, + const MachineInstr &MI, + int OpIdx = -1) const; // Materialize a GlobalValue or BlockAddress using a movz+movk sequence. void materializeLargeCMVal(MachineInstr &I, const Value *V, unsigned OpFlags); @@ -6854,6 +6857,17 @@ AArch64_AM::getFP64Imm(MI.getOperand(1).getFPImm()->getValueAPF())); } +void AArch64InstructionSelector::renderFPImm32SIMDModImmType4( + MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const { + assert(MI.getOpcode() == TargetOpcode::G_FCONSTANT && OpIdx == -1 && + "Expected G_FCONSTANT"); + MIB.addImm(AArch64_AM::encodeAdvSIMDModImmType4(MI.getOperand(1) + .getFPImm() + ->getValueAPF() + .bitcastToAPInt() + .getZExtValue())); +} + bool AArch64InstructionSelector::isLoadStoreOfNumBytes( const MachineInstr &MI, unsigned NumBytes) const { if (!MI.mayLoadOrStore()) diff --git a/llvm/test/CodeGen/AArch64/fast-isel-const-float.ll b/llvm/test/CodeGen/AArch64/fast-isel-const-float.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/fast-isel-const-float.ll @@ -0,0 +1,21 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel -verify-machineinstrs < %s | FileCheck %s --check-prefix=GISEL +; RUN: llc -mtriple=aarch64-none-linux-gnu -fast-isel -verify-machineinstrs < %s | FileCheck %s --check-prefix=FISEL + +; float foo(void) { return float(2147483648); } +define float @select_fp_const() { +; CHECK-LABEL: select_opt4 +; CHECK: movi v0.2s, #79, lsl #24 +; GISEL-LABEL: select_fp_const: +; GISEL: // %bb.0: // %entry +; GISEL-NEXT: movi v0.2s, #79, lsl #24 +; GISEL-NEXT: ret +; +; FISEL-LABEL: select_fp_const: +; FISEL: // %bb.0: // %entry +; FISEL-NEXT: adrp x8, .LCPI0_0 +; FISEL-NEXT: ldr s0, [x8, :lo12:.LCPI0_0] +; FISEL-NEXT: ret +entry: + ret float 0x41E0000000000000 +}