Skip to content

Conversation

@lenary
Copy link
Member

@lenary lenary commented Nov 25, 2025

This is noted by the specification, and should save a dynamic instruction.

Code size should be no worse than before, as the pairs of moves can usually be turned into two 16-bit moves, but fmv.d is always a 32-bit instruction.

LLVM can look through a FSGNJ_D_IN32X, in
RISCVInstrInfo::isCopyInstrImpl which helps copy propagation.

This is noted by the specification, and should save a dynamic
instruction.

Code size should be no worse than before, as the pairs of moves can
usually be turned into two 16-bit moves, but `fmv.d` is always a 32-bit
instruction.

LLVM can look through a `FSGNJ_D_IN32X`, in
`RISCVInstrInfo::isCopyInstrImpl` which helps copy propagation.
@llvmbot
Copy link
Member

llvmbot commented Nov 25, 2025

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

Author: Sam Elliott (lenary)

Changes

This is noted by the specification, and should save a dynamic instruction.

Code size should be no worse than before, as the pairs of moves can usually be turned into two 16-bit moves, but fmv.d is always a 32-bit instruction.

LLVM can look through a FSGNJ_D_IN32X, in
RISCVInstrInfo::isCopyInstrImpl which helps copy propagation.


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

6 Files Affected:

  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+9)
  • (modified) llvm/test/CodeGen/RISCV/double-maximum-minimum.ll (+9-21)
  • (modified) llvm/test/CodeGen/RISCV/double-select-fcmp.ll (+16-32)
  • (modified) llvm/test/CodeGen/RISCV/double-select-icmp.ll (+10-20)
  • (modified) llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll (+2-4)
  • (modified) llvm/test/CodeGen/RISCV/make-compressible-zilsd.mir (+2-4)
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index fb914e97e2229..900cf3f4c7d6e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -531,6 +531,15 @@ void RISCVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
   }
 
   if (RISCV::GPRPairRegClass.contains(DstReg, SrcReg)) {
+    if (STI.isRV32() && STI.hasStdExtZdinx()) {
+      // On RV32_Zdinx, FMV.D will move a pair of registers to another pair of
+      // registers, in one instruction.
+      BuildMI(MBB, MBBI, DL, get(RISCV::FSGNJ_D_IN32X), DstReg)
+        .addReg(SrcReg, getRenamableRegState(RenamableSrc))
+        .addReg(SrcReg, KillFlag | getRenamableRegState(RenamableSrc));
+      return;
+    }
+
     MCRegister EvenReg = TRI->getSubReg(SrcReg, RISCV::sub_gpr_even);
     MCRegister OddReg = TRI->getSubReg(SrcReg, RISCV::sub_gpr_odd);
     // We need to correct the odd register of X0_Pair.
diff --git a/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll b/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll
index 4ee01cc48b9f0..6202e92b4dc65 100644
--- a/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll
+++ b/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll
@@ -37,8 +37,7 @@ define double @fminimum_f64(double %a, double %b) nounwind {
 ; RV32IZFINXZDINX-LABEL: fminimum_f64:
 ; RV32IZFINXZDINX:       # %bb.0:
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a0, a0
-; RV32IZFINXZDINX-NEXT:    mv a4, a2
-; RV32IZFINXZDINX-NEXT:    mv a5, a3
+; RV32IZFINXZDINX-NEXT:    fmv.d a4, a2
 ; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB0_3
 ; RV32IZFINXZDINX-NEXT:  # %bb.1:
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
@@ -47,14 +46,11 @@ define double @fminimum_f64(double %a, double %b) nounwind {
 ; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a4
 ; RV32IZFINXZDINX-NEXT:    ret
 ; RV32IZFINXZDINX-NEXT:  .LBB0_3:
-; RV32IZFINXZDINX-NEXT:    mv a4, a0
-; RV32IZFINXZDINX-NEXT:    mv a5, a1
+; RV32IZFINXZDINX-NEXT:    fmv.d a4, a0
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
 ; RV32IZFINXZDINX-NEXT:    bnez a6, .LBB0_2
 ; RV32IZFINXZDINX-NEXT:  .LBB0_4:
-; RV32IZFINXZDINX-NEXT:    mv a0, a2
-; RV32IZFINXZDINX-NEXT:    mv a1, a3
-; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a4
+; RV32IZFINXZDINX-NEXT:    fmin.d a0, a2, a4
 ; RV32IZFINXZDINX-NEXT:    ret
 ;
 ; RV64IZFINXZDINX-LABEL: fminimum_f64:
@@ -104,8 +100,7 @@ define double @fmaximum_f64(double %a, double %b) nounwind {
 ; RV32IZFINXZDINX-LABEL: fmaximum_f64:
 ; RV32IZFINXZDINX:       # %bb.0:
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a0, a0
-; RV32IZFINXZDINX-NEXT:    mv a4, a2
-; RV32IZFINXZDINX-NEXT:    mv a5, a3
+; RV32IZFINXZDINX-NEXT:    fmv.d a4, a2
 ; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB1_3
 ; RV32IZFINXZDINX-NEXT:  # %bb.1:
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
@@ -114,14 +109,11 @@ define double @fmaximum_f64(double %a, double %b) nounwind {
 ; RV32IZFINXZDINX-NEXT:    fmax.d a0, a0, a4
 ; RV32IZFINXZDINX-NEXT:    ret
 ; RV32IZFINXZDINX-NEXT:  .LBB1_3:
-; RV32IZFINXZDINX-NEXT:    mv a4, a0
-; RV32IZFINXZDINX-NEXT:    mv a5, a1
+; RV32IZFINXZDINX-NEXT:    fmv.d a4, a0
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
 ; RV32IZFINXZDINX-NEXT:    bnez a6, .LBB1_2
 ; RV32IZFINXZDINX-NEXT:  .LBB1_4:
-; RV32IZFINXZDINX-NEXT:    mv a0, a2
-; RV32IZFINXZDINX-NEXT:    mv a1, a3
-; RV32IZFINXZDINX-NEXT:    fmax.d a0, a0, a4
+; RV32IZFINXZDINX-NEXT:    fmax.d a0, a2, a4
 ; RV32IZFINXZDINX-NEXT:    ret
 ;
 ; RV64IZFINXZDINX-LABEL: fmaximum_f64:
@@ -188,8 +180,7 @@ define double @fmaximum_nnan_f64(double %a, double %b) nounwind {
 ; RV32IZFINXZDINX-LABEL: fmaximum_nnan_f64:
 ; RV32IZFINXZDINX:       # %bb.0:
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a0, a0
-; RV32IZFINXZDINX-NEXT:    mv a4, a2
-; RV32IZFINXZDINX-NEXT:    mv a5, a3
+; RV32IZFINXZDINX-NEXT:    fmv.d a4, a2
 ; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB3_3
 ; RV32IZFINXZDINX-NEXT:  # %bb.1:
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
@@ -198,14 +189,11 @@ define double @fmaximum_nnan_f64(double %a, double %b) nounwind {
 ; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a4
 ; RV32IZFINXZDINX-NEXT:    ret
 ; RV32IZFINXZDINX-NEXT:  .LBB3_3:
-; RV32IZFINXZDINX-NEXT:    mv a4, a0
-; RV32IZFINXZDINX-NEXT:    mv a5, a1
+; RV32IZFINXZDINX-NEXT:    fmv.d a4, a0
 ; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
 ; RV32IZFINXZDINX-NEXT:    bnez a6, .LBB3_2
 ; RV32IZFINXZDINX-NEXT:  .LBB3_4:
-; RV32IZFINXZDINX-NEXT:    mv a0, a2
-; RV32IZFINXZDINX-NEXT:    mv a1, a3
-; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a4
+; RV32IZFINXZDINX-NEXT:    fmin.d a0, a2, a4
 ; RV32IZFINXZDINX-NEXT:    ret
 ;
 ; RV64IZFINXZDINX-LABEL: fmaximum_nnan_f64:
diff --git a/llvm/test/CodeGen/RISCV/double-select-fcmp.ll b/llvm/test/CodeGen/RISCV/double-select-fcmp.ll
index cd3ff779d8cd3..7fd559c05764a 100644
--- a/llvm/test/CodeGen/RISCV/double-select-fcmp.ll
+++ b/llvm/test/CodeGen/RISCV/double-select-fcmp.ll
@@ -44,8 +44,7 @@ define double @select_fcmp_oeq(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    feq.d a4, a0, a2
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB1_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB1_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -77,8 +76,7 @@ define double @select_fcmp_ogt(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    flt.d a4, a2, a0
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB2_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB2_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -110,8 +108,7 @@ define double @select_fcmp_oge(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    fle.d a4, a2, a0
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB3_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB3_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -143,8 +140,7 @@ define double @select_fcmp_olt(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    flt.d a4, a0, a2
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB4_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB4_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -176,8 +172,7 @@ define double @select_fcmp_ole(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    fle.d a4, a0, a2
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB5_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB5_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -213,8 +208,7 @@ define double @select_fcmp_one(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    or a4, a5, a4
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB6_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB6_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -252,8 +246,7 @@ define double @select_fcmp_ord(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    and a4, a5, a4
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB7_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB7_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -291,8 +284,7 @@ define double @select_fcmp_ueq(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    or a4, a5, a4
 ; CHECKRV32ZDINX-NEXT:    beqz a4, .LBB8_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB8_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -326,8 +318,7 @@ define double @select_fcmp_ugt(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    fle.d a4, a0, a2
 ; CHECKRV32ZDINX-NEXT:    beqz a4, .LBB9_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB9_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -359,8 +350,7 @@ define double @select_fcmp_uge(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    flt.d a4, a0, a2
 ; CHECKRV32ZDINX-NEXT:    beqz a4, .LBB10_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB10_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -392,8 +382,7 @@ define double @select_fcmp_ult(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    fle.d a4, a2, a0
 ; CHECKRV32ZDINX-NEXT:    beqz a4, .LBB11_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB11_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -425,8 +414,7 @@ define double @select_fcmp_ule(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    flt.d a4, a2, a0
 ; CHECKRV32ZDINX-NEXT:    beqz a4, .LBB12_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB12_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -458,8 +446,7 @@ define double @select_fcmp_une(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    feq.d a4, a0, a2
 ; CHECKRV32ZDINX-NEXT:    beqz a4, .LBB13_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB13_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -495,8 +482,7 @@ define double @select_fcmp_uno(double %a, double %b) nounwind {
 ; CHECKRV32ZDINX-NEXT:    and a4, a5, a4
 ; CHECKRV32ZDINX-NEXT:    beqz a4, .LBB14_2
 ; CHECKRV32ZDINX-NEXT:  # %bb.1:
-; CHECKRV32ZDINX-NEXT:    mv a0, a2
-; CHECKRV32ZDINX-NEXT:    mv a1, a3
+; CHECKRV32ZDINX-NEXT:    fmv.d a0, a2
 ; CHECKRV32ZDINX-NEXT:  .LBB14_2:
 ; CHECKRV32ZDINX-NEXT:    ret
 ;
@@ -683,12 +669,10 @@ define double @CascadedSelect(double noundef %a) {
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB20_3
 ; CHECKRV32ZDINX-NEXT:  # %bb.1: # %entry
 ; CHECKRV32ZDINX-NEXT:    flt.d a4, a0, zero
-; CHECKRV32ZDINX-NEXT:    li a2, 0
-; CHECKRV32ZDINX-NEXT:    li a3, 0
+; CHECKRV32ZDINX-NEXT:    fmv.d a2, zero
 ; CHECKRV32ZDINX-NEXT:    bnez a4, .LBB20_3
 ; CHECKRV32ZDINX-NEXT:  # %bb.2: # %entry
-; CHECKRV32ZDINX-NEXT:    mv a2, a0
-; CHECKRV32ZDINX-NEXT:    mv a3, a1
+; CHECKRV32ZDINX-NEXT:    fmv.d a2, a0
 ; CHECKRV32ZDINX-NEXT:  .LBB20_3: # %entry
 ; CHECKRV32ZDINX-NEXT:    mv a0, a2
 ; CHECKRV32ZDINX-NEXT:    mv a1, a3
diff --git a/llvm/test/CodeGen/RISCV/double-select-icmp.ll b/llvm/test/CodeGen/RISCV/double-select-icmp.ll
index 929ffc578f5b4..75fa8e513026d 100644
--- a/llvm/test/CodeGen/RISCV/double-select-icmp.ll
+++ b/llvm/test/CodeGen/RISCV/double-select-icmp.ll
@@ -22,8 +22,7 @@ define double @select_icmp_eq(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    beq a0, a1, .LBB0_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB0_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -55,8 +54,7 @@ define double @select_icmp_ne(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    bne a0, a1, .LBB1_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB1_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -88,8 +86,7 @@ define double @select_icmp_ugt(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    bltu a1, a0, .LBB2_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB2_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -121,8 +118,7 @@ define double @select_icmp_uge(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    bgeu a0, a1, .LBB3_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB3_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -154,8 +150,7 @@ define double @select_icmp_ult(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    bltu a0, a1, .LBB4_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB4_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -187,8 +182,7 @@ define double @select_icmp_ule(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    bgeu a1, a0, .LBB5_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB5_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -220,8 +214,7 @@ define double @select_icmp_sgt(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    blt a1, a0, .LBB6_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB6_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -253,8 +246,7 @@ define double @select_icmp_sge(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    bge a0, a1, .LBB7_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB7_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -286,8 +278,7 @@ define double @select_icmp_slt(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    blt a0, a1, .LBB8_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB8_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
@@ -319,8 +310,7 @@ define double @select_icmp_sle(i32 signext %a, i32 signext %b, double %c, double
 ; RV32ZDINX:       # %bb.0:
 ; RV32ZDINX-NEXT:    bge a1, a0, .LBB9_2
 ; RV32ZDINX-NEXT:  # %bb.1:
-; RV32ZDINX-NEXT:    mv a2, a4
-; RV32ZDINX-NEXT:    mv a3, a5
+; RV32ZDINX-NEXT:    fmv.d a2, a4
 ; RV32ZDINX-NEXT:  .LBB9_2:
 ; RV32ZDINX-NEXT:    mv a0, a2
 ; RV32ZDINX-NEXT:    mv a1, a3
diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll
index a719e1ee5a831..c01248fa42480 100644
--- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll
+++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore-zilsd.ll
@@ -44,8 +44,7 @@ define double @fold_addi_from_different_bb(i32 %k, i32 %n, ptr %a) nounwind {
 ; CHECK-NEXT:  # %bb.1: # %for.body.lr.ph
 ; CHECK-NEXT:    mv s2, a2
 ; CHECK-NEXT:    mv s3, a1
-; CHECK-NEXT:    li s0, 0
-; CHECK-NEXT:    li s1, 0
+; CHECK-NEXT:    fmv.d s0, zero
 ; CHECK-NEXT:    slli a0, a0, 4
 ; CHECK-NEXT:    add s4, a2, a0
 ; CHECK-NEXT:  .LBB2_2: # %for.body
@@ -58,8 +57,7 @@ define double @fold_addi_from_different_bb(i32 %k, i32 %n, ptr %a) nounwind {
 ; CHECK-NEXT:    bnez s3, .LBB2_2
 ; CHECK-NEXT:    j .LBB2_4
 ; CHECK-NEXT:  .LBB2_3:
-; CHECK-NEXT:    li s0, 0
-; CHECK-NEXT:    li s1, 0
+; CHECK-NEXT:    fmv.d s0, zero
 ; CHECK-NEXT:  .LBB2_4: # %for.cond.cleanup
 ; CHECK-NEXT:    mv a0, s0
 ; CHECK-NEXT:    mv a1, s1
diff --git a/llvm/test/CodeGen/RISCV/make-compressible-zilsd.mir b/llvm/test/CodeGen/RISCV/make-compressible-zilsd.mir
index e9a5fe0b18a7a..6dc6cf7d1393e 100644
--- a/llvm/test/CodeGen/RISCV/make-compressible-zilsd.mir
+++ b/llvm/test/CodeGen/RISCV/make-compressible-zilsd.mir
@@ -121,8 +121,7 @@ body:             |
     ; RV32-LABEL: name: store_common_value_double
     ; RV32: liveins: $x10, $x11, $x12, $x16, $x17
     ; RV32-NEXT: {{  $}}
-    ; RV32-NEXT: $x14 = ADDI $x16, 0
-    ; RV32-NEXT: $x15 = ADDI $x17, 0
+    ; RV32-NEXT: $x14_x15 = FSGNJ_D_IN32X $x16_x17, $x16_x17
     ; RV32-NEXT: SD_RV32 $x14_x15, killed renamable $x10, 0 :: (store (s64) into %ir.a)
     ; RV32-NEXT: SD_RV32 $x14_x15, killed renamable $x11, 0 :: (store (s64) into %ir.b)
     ; RV32-NEXT: SD_RV32 killed $x14_x15, killed renamable $x12, 0 :: (store (s64) into %ir.c)
@@ -143,8 +142,7 @@ body:             |
     ; RV32-LABEL: name: store_common_value_double_zero
     ; RV32: liveins: $x10, $x11, $x12
     ; RV32-NEXT: {{  $}}
-    ; RV32-NEXT: $x14 = ADDI $x0, 0
-    ; RV32-NEXT: $x15 = ADDI $x0, 0
+    ; RV32-NEXT: $x14_x15 = FSGNJ_D_IN32X $x0_pair, $x0_pair
     ; RV32-NEXT: SD_RV32 $x14_x15, killed renamable $x10, 0 :: (store (s64) into %ir.a)
     ; RV32-NEXT: SD_RV32 $x14_x15, killed renamable $x11, 0 :: (store (s64) into %ir.b)
     ; RV32-NEXT: SD_RV32 $x14_x15, killed renamable $x12, 0 :: (store (s64) into %ir.c)

@github-actions
Copy link

github-actions bot commented Nov 25, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@lenary lenary enabled auto-merge (squash) November 25, 2025 19:56
@lenary lenary merged commit 8d92072 into llvm:main Nov 25, 2025
7 of 9 checks passed
@lenary lenary deleted the pr/riscv-fmv-d-gprpair branch November 25, 2025 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants