[llvm] [RISCV][GISel] Remove unnecessary copy from X0 in G_FCONSTANT selection. (PR #158429)

via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 13 10:35:12 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-globalisel

@llvm/pr-subscribers-backend-risc-v

Author: Craig Topper (topperc)

<details>
<summary>Changes</summary>

Instead of calling materializeImm, just assign GPRReg to X0.

While there, move conversion to APInt to only where it is necessary.

---
Full diff: https://github.com/llvm/llvm-project/pull/158429.diff


3 Files Affected:

- (modified) llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp (+11-5) 
- (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant-f16.mir (+1-2) 
- (modified) llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant.mir (+2-4) 


``````````diff
diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
index 7df1b7e580002..4330d4e91e0ee 100644
--- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
+++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp
@@ -738,12 +738,17 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
     // TODO: Use constant pool for complex constants.
     Register DstReg = MI.getOperand(0).getReg();
     const APFloat &FPimm = MI.getOperand(1).getFPImm()->getValueAPF();
-    APInt Imm = FPimm.bitcastToAPInt();
     unsigned Size = MRI->getType(DstReg).getSizeInBits();
     if (Size == 16 || Size == 32 || (Size == 64 && Subtarget->is64Bit())) {
-      Register GPRReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
-      if (!materializeImm(GPRReg, Imm.getSExtValue(), MIB))
-        return false;
+      Register GPRReg;
+      if (FPimm.isPosZero()) {
+        GPRReg = RISCV::X0;
+      } else {
+        GPRReg = MRI->createVirtualRegister(&RISCV::GPRRegClass);
+        APInt Imm = FPimm.bitcastToAPInt();
+        if (!materializeImm(GPRReg, Imm.getSExtValue(), MIB))
+          return false;
+      }
 
       unsigned Opcode = Size == 64   ? RISCV::FMV_D_X
                         : Size == 32 ? RISCV::FMV_W_X
@@ -756,7 +761,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
       assert(Size == 64 && !Subtarget->is64Bit() &&
              "Unexpected size or subtarget");
 
-      if (Imm.isNonNegative() && Imm.isZero()) {
+      if (FPimm.isPosZero()) {
         // Optimize +0.0 to use fcvt.d.w
         MachineInstrBuilder FCVT =
             MIB.buildInstr(RISCV::FCVT_D_W, {DstReg}, {Register(RISCV::X0)})
@@ -771,6 +776,7 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
       // Split into two pieces and build through the stack.
       Register GPRRegHigh = MRI->createVirtualRegister(&RISCV::GPRRegClass);
       Register GPRRegLow = MRI->createVirtualRegister(&RISCV::GPRRegClass);
+      APInt Imm = FPimm.bitcastToAPInt();
       if (!materializeImm(GPRRegHigh, Imm.extractBits(32, 32).getSExtValue(),
                           MIB))
         return false;
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant-f16.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant-f16.mir
index 3028b6476e20b..a688153d44be5 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant-f16.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant-f16.mir
@@ -57,8 +57,7 @@ body:             |
     ; CHECK-LABEL: name: half_positive_zero
     ; CHECK: liveins: $x10
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x0
-    ; CHECK-NEXT: [[FMV_H_X:%[0-9]+]]:fpr16 = FMV_H_X [[COPY]]
+    ; CHECK-NEXT: [[FMV_H_X:%[0-9]+]]:fpr16 = FMV_H_X $x0
     ; CHECK-NEXT: $f10_h = COPY [[FMV_H_X]]
     ; CHECK-NEXT: PseudoRET implicit $f10_h
     %1:fprb(s16) = G_FCONSTANT half 0.000000e+00
diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant.mir b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant.mir
index 4db80c6c1141f..7dde7771f161b 100644
--- a/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant.mir
+++ b/llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant.mir
@@ -56,8 +56,7 @@ body:             |
     ; CHECK-LABEL: name: float_positive_zero
     ; CHECK: liveins: $x10
     ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x0
-    ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X [[COPY]]
+    ; CHECK-NEXT: [[FMV_W_X:%[0-9]+]]:fpr32 = FMV_W_X $x0
     ; CHECK-NEXT: $f10_f = COPY [[FMV_W_X]]
     ; CHECK-NEXT: PseudoRET implicit $f10_f
     %1:fprb(s32) = G_FCONSTANT float 0.000000e+00
@@ -171,8 +170,7 @@ body:             |
     ; RV64-LABEL: name: double_positive_zero
     ; RV64: liveins: $x10
     ; RV64-NEXT: {{  $}}
-    ; RV64-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x0
-    ; RV64-NEXT: [[FMV_D_X:%[0-9]+]]:fpr64 = FMV_D_X [[COPY]]
+    ; RV64-NEXT: [[FMV_D_X:%[0-9]+]]:fpr64 = FMV_D_X $x0
     ; RV64-NEXT: $f10_d = COPY [[FMV_D_X]]
     ; RV64-NEXT: PseudoRET implicit $f10_d
     %1:fprb(s64) = G_FCONSTANT double 0.000000e+00

``````````

</details>


https://github.com/llvm/llvm-project/pull/158429


More information about the llvm-commits mailing list