[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