[llvm] [AArch64][GlobalISel] Remove fconstant_to_constant, moving it to reg-bank-select. (PR #194778)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Wed May 6 07:15:09 PDT 2026
https://github.com/davemgreen updated https://github.com/llvm/llvm-project/pull/194778
>From cdf21415b7add0e0081ab82fa478e5461d79fe8d Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Wed, 6 May 2026 15:14:50 +0100
Subject: [PATCH] [AArch64][GlobalISel] Remove fconstant_to_constant, moving it
to reg-bank-select.
This removes the fconstant_to_constant post-legalizer lowering combine, moving
it to where it belongs in reg bank select. The result should be mostly be no
change in generated code.
---
llvm/lib/Target/AArch64/AArch64Combine.td | 8 +-
.../GISel/AArch64PostLegalizerLowering.cpp | 26 ------
.../AArch64/GISel/AArch64RegisterBankInfo.cpp | 8 ++
.../AArch64/GlobalISel/combine-fconstant.mir | 80 -------------------
.../GlobalISel/regbankselect-default.mir | 1 +
5 files changed, 10 insertions(+), 113 deletions(-)
delete mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/combine-fconstant.mir
diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index 287d15dfc7384..85dc140136b2a 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -11,12 +11,6 @@
include "llvm/Target/GlobalISel/Combine.td"
-def fconstant_to_constant : GICombineRule<
- (defs root:$root),
- (match (G_FCONSTANT $dst, $src):$root,
- [{ return matchFConstantToConstant(*${root}, MRI); }]),
- (apply [{ applyFConstantToConstant(*${root}); }])>;
-
def icmp_redundant_trunc : GICombineRule<
(defs root:$root, register_matchinfo:$matchinfo),
(match (G_ICMP $dst, $tst, $src1, $src2):$root,
@@ -359,7 +353,7 @@ def AArch64PostLegalizerLowering
: GICombiner<"AArch64PostLegalizerLoweringImpl",
[shuffle_vector_lowering, vashr_vlshr_imm,
icmp_lowering, build_vector_lowering,
- lower_vector_fcmp, form_truncstore, fconstant_to_constant,
+ lower_vector_fcmp, form_truncstore,
vector_sext_inreg_to_shift,
unmerge_ext_to_unmerge, lower_mulv2s64,
vector_unmerge_lowering, insertelt_nonconst,
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
index f4e5649b9f449..44da0ca5ad8ba 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64PostLegalizerLowering.cpp
@@ -77,32 +77,6 @@ struct ShuffleVectorPseudo {
ShuffleVectorPseudo() = default;
};
-/// Return true if a G_FCONSTANT instruction is known to be better-represented
-/// as a G_CONSTANT.
-bool matchFConstantToConstant(MachineInstr &MI, MachineRegisterInfo &MRI) {
- assert(MI.getOpcode() == TargetOpcode::G_FCONSTANT);
- Register DstReg = MI.getOperand(0).getReg();
- const unsigned DstSize = MRI.getType(DstReg).getSizeInBits();
- if (DstSize != 16 && DstSize != 32 && DstSize != 64)
- return false;
-
- // When we're storing a value, it doesn't matter what register bank it's on.
- // Since not all floating point constants can be materialized using a fmov,
- // it makes more sense to just use a GPR.
- return all_of(MRI.use_nodbg_instructions(DstReg),
- [](const MachineInstr &Use) { return Use.mayStore(); });
-}
-
-/// Change a G_FCONSTANT into a G_CONSTANT.
-void applyFConstantToConstant(MachineInstr &MI) {
- assert(MI.getOpcode() == TargetOpcode::G_FCONSTANT);
- MachineIRBuilder MIB(MI);
- const APFloat &ImmValAPF = MI.getOperand(1).getFPImm()->getValueAPF();
- const Register DstReg = MI.getOperand(0).getReg();
- MIB.buildConstant(DstReg, ImmValAPF.bitcastToAPInt());
- MI.eraseFromParent();
-}
-
/// Check if a G_EXT instruction can handle a shuffle mask \p M when the vector
/// sources of the shuffle are different.
std::optional<std::pair<bool, uint64_t>> getExtMask(ArrayRef<int> M,
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index 947a3a5ea170b..f1a8f8d4c65c5 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "AArch64RegisterBankInfo.h"
+#include "AArch64ExpandImm.h"
#include "AArch64RegisterInfo.h"
#include "AArch64Subtarget.h"
#include "MCTargetDesc/AArch64AddressingModes.h"
@@ -379,6 +380,13 @@ static bool preferGPRForFPImm(const MachineInstr &MI,
const APFloat Imm = MI.getOperand(1).getFPImm()->getValueAPF();
const APInt ImmBits = Imm.bitcastToAPInt();
+ // If all the uses are stores use a gpr constant
+ if (all_of(MRI.use_nodbg_instructions(Dst), [&](const MachineInstr &UseMI) {
+ return UseMI.getOpcode() == TargetOpcode::G_STORE &&
+ UseMI.getOperand(0).getReg() == Dst;
+ }))
+ return true;
+
// Check if we can encode this as a movi. Note, we only have one pattern so
// far for movis, hence the one check.
if (Size == 32) {
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-fconstant.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-fconstant.mir
deleted file mode 100644
index 9381f0f41bbbc..0000000000000
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-fconstant.mir
+++ /dev/null
@@ -1,80 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -run-pass=aarch64-postlegalizer-lowering -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
-# RUN: llc -debugify-and-strip-all-safe -run-pass=aarch64-postlegalizer-lowering -verify-machineinstrs -mtriple aarch64-unknown-unknown %s -o - | FileCheck %s
-...
----
-name: fconstant_to_constant_s32
-alignment: 4
-tracksRegLiveness: true
-legalized: true
-frameInfo:
- maxAlignment: 1
-machineFunctionInfo: {}
-body: |
- bb.0:
- liveins: $x0
- ; Only feeding into stores here. Also, the value can't be materialized using
- ; fmov, so it's strictly better to use a mov.
- ; CHECK-LABEL: name: fconstant_to_constant_s32
- ; CHECK: liveins: $x0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1028443341
- ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 524
- ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C1]](s64)
- ; CHECK-NEXT: G_STORE [[C]](s32), [[PTR_ADD]](p0) :: (store (s32))
- ; CHECK-NEXT: RET_ReallyLR
- %0:_(p0) = COPY $x0
- %1:_(s32) = G_FCONSTANT float 0x3FA99999A0000000
- %2:_(s64) = G_CONSTANT i64 524
- %3:_(p0) = G_PTR_ADD %0, %2(s64)
- G_STORE %1(s32), %3(p0) :: (store (s32))
- RET_ReallyLR
-...
----
-name: fconstant_to_constant_s64
-alignment: 4
-tracksRegLiveness: true
-legalized: true
-frameInfo:
- maxAlignment: 1
-machineFunctionInfo: {}
-body: |
- bb.0:
- liveins: $x0
- ; CHECK-LABEL: name: fconstant_to_constant_s64
- ; CHECK: liveins: $x0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %ptr:_(p0) = COPY $x0
- ; CHECK-NEXT: %c:_(s64) = G_CONSTANT i64 0
- ; CHECK-NEXT: G_STORE %c(s64), %ptr(p0) :: (store (s64))
- ; CHECK-NEXT: RET_ReallyLR
- %ptr:_(p0) = COPY $x0
- %c:_(s64) = G_FCONSTANT double 0.000000e+00
- G_STORE %c(s64), %ptr(p0) :: (store (s64))
- RET_ReallyLR
-...
----
-name: no_store_means_no_combine
-alignment: 4
-tracksRegLiveness: true
-legalized: true
-frameInfo:
- maxAlignment: 1
-machineFunctionInfo: {}
-body: |
- bb.0:
- liveins: $x0, $x1
- ; When we aren't feeding into a store, the combine shouldn't happen.
- ; CHECK-LABEL: name: no_store_means_no_combine
- ; CHECK: liveins: $x0, $x1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: %v:_(s64) = COPY $x0
- ; CHECK-NEXT: %c:_(s64) = G_FCONSTANT double 0.000000e+00
- ; CHECK-NEXT: %add:_(s64) = G_FADD %v, %c
- ; CHECK-NEXT: RET_ReallyLR implicit %add(s64)
- %v:_(s64) = COPY $x0
- %c:_(s64) = G_FCONSTANT double 0.000000e+00
- %add:_(s64) = G_FADD %v, %c
- RET_ReallyLR implicit %add(s64)
-...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir
index 8178cb0a1297b..649ed536a23b6 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir
@@ -747,6 +747,7 @@ body: |
; CHECK-LABEL: name: test_fconstant_s32
; CHECK: [[C:%[0-9]+]]:fpr(s32) = G_FCONSTANT float 1.000000e+00
%0(s32) = G_FCONSTANT float 1.0
+ $s0 = COPY %0
...
---
More information about the llvm-commits
mailing list