From 2b3becb41d2b3f2931f78643af23ce9a3842ab52 Mon Sep 17 00:00:00 2001 From: zhongyunde Date: Tue, 29 Mar 2022 08:39:23 +0800 Subject: [PATCH] [AArch64][GlobalISel] Add new MOVI pattern for fp constants GlobalISel is used in option -O0, so add MOVI pattern for it, which is done similar in gcc.(https://godbolt.org/z/8j6fzG3h6) Fix https://github.com/llvm/llvm-project/issues/53651 Reviewed By: dmgreen, paquette Differential Revision: https://reviews.llvm.org/D122559 --- llvm/lib/Target/AArch64/AArch64InstrFormats.td | 3 +++ .../AArch64/GISel/AArch64InstructionSelector.cpp | 14 ++++++++++++++ llvm/test/CodeGen/AArch64/fast-isel-const-float.ll | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/fast-isel-const-float.ll diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 74dccb8..38049d4 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -1248,6 +1248,9 @@ def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">, 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 index 9c70157..b215678 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -437,6 +437,9 @@ private: 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 @@ void AArch64InstructionSelector::renderFPImm64(MachineInstrBuilder &MIB, 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 index 0000000..4de2c93 --- /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 +} -- 2.7.4