[llvm] b899756 - [Mips][GlobalISel] Keep split double arguments live across calls (#225879)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 01:09:45 PDT 2026


Author: Jiaxun Yang
Date: 2026-09-24T09:09:39+01:00
New Revision: b899756b5bf2193ab5d354a53aa7a2e746f4806c

URL: https://github.com/llvm/llvm-project/commit/b899756b5bf2193ab5d354a53aa7a2e746f4806c
DIFF: https://github.com/llvm/llvm-project/commit/b899756b5bf2193ab5d354a53aa7a2e746f4806c.diff

LOG: [Mips][GlobalISel] Keep split double arguments live across calls (#225879)

Mark both GPRs assigned by custom f64 argument lowering as implicit uses
of the call. Without these uses, dead machine instruction elimination
can remove the copies that pass the argument.

Check call operands after IR translation and optimized FPR-to-GPR
argument passing with FP32 and FP64 register modes.

Added: 
    

Modified: 
    llvm/lib/Target/Mips/MipsCallLowering.cpp
    llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Mips/MipsCallLowering.cpp b/llvm/lib/Target/Mips/MipsCallLowering.cpp
index 3054974fa16b5..6a1b14c7982fd 100644
--- a/llvm/lib/Target/Mips/MipsCallLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsCallLowering.cpp
@@ -224,6 +224,9 @@ MipsOutgoingValueHandler::assignCustomValue(CallLowering::ArgInfo &Arg,
   if (!STI.isLittle())
     std::swap(Lo, Hi);
 
+  MIB.addUse(VALo.getLocReg(), RegState::Implicit);
+  MIB.addUse(VAHi.getLocReg(), RegState::Implicit);
+
   // If we can return a thunk, just include the register copies. The unmerge can
   // be emitted earlier.
   if (Thunk) {

diff  --git a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll
index 89367ddf97418..204594eee881c 100644
--- a/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll
+++ b/llvm/test/CodeGen/Mips/GlobalISel/irtranslator/float_args.ll
@@ -245,7 +245,7 @@ define double @call_double_in_gpr(i32 %a, double %b) {
   ; FP32-NEXT:   $a0 = COPY [[COPY]](s32)
   ; FP32-NEXT:   $a2 = COPY [[UV]](s32)
   ; FP32-NEXT:   $a3 = COPY [[UV1]](s32)
-  ; FP32-NEXT:   JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0
+  ; FP32-NEXT:   JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a2, implicit $a3, implicit $a0, implicit-def $d0
   ; FP32-NEXT:   [[COPY3:%[0-9]+]]:_(s64) = COPY $d0
   ; FP32-NEXT:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
   ; FP32-NEXT:   $d0 = COPY [[COPY3]](s64)
@@ -264,7 +264,7 @@ define double @call_double_in_gpr(i32 %a, double %b) {
   ; FP64-NEXT:   $a0 = COPY [[COPY]](s32)
   ; FP64-NEXT:   $a2 = COPY [[UV]](s32)
   ; FP64-NEXT:   $a3 = COPY [[UV1]](s32)
-  ; FP64-NEXT:   JAL @double_in_gpr, csr_o32_fp64, implicit-def $ra, implicit-def $sp, implicit $a0, implicit-def $d0_64
+  ; FP64-NEXT:   JAL @double_in_gpr, csr_o32_fp64, implicit-def $ra, implicit-def $sp, implicit $a2, implicit $a3, implicit $a0, implicit-def $d0_64
   ; FP64-NEXT:   [[COPY3:%[0-9]+]]:_(s64) = COPY $d0_64
   ; FP64-NEXT:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
   ; FP64-NEXT:   $d0_64 = COPY [[COPY3]](s64)
@@ -273,3 +273,44 @@ entry:
   %call = call double @double_in_gpr(i32 %a, double %b)
   ret double %call
 }
+
+; Both outgoing GPR halves must remain live when the incoming double was
+; passed in an FPR.
+define double @call_double_fpr_to_gpr(double %a) {
+  ; FP32-LABEL: name: call_double_fpr_to_gpr
+  ; FP32: bb.1.entry:
+  ; FP32-NEXT:   liveins: $d6
+  ; FP32-NEXT: {{  $}}
+  ; FP32-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $d6
+  ; FP32-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+  ; FP32-NEXT:   ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+  ; FP32-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](s64)
+  ; FP32-NEXT:   $a0 = COPY [[C]](s32)
+  ; FP32-NEXT:   $a2 = COPY [[UV]](s32)
+  ; FP32-NEXT:   $a3 = COPY [[UV1]](s32)
+  ; FP32-NEXT:   JAL @double_in_gpr, csr_o32, implicit-def $ra, implicit-def $sp, implicit $a2, implicit $a3, implicit $a0, implicit-def $d0
+  ; FP32-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY $d0
+  ; FP32-NEXT:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+  ; FP32-NEXT:   $d0 = COPY [[COPY1]](s64)
+  ; FP32-NEXT:   RetRA implicit $d0
+  ;
+  ; FP64-LABEL: name: call_double_fpr_to_gpr
+  ; FP64: bb.1.entry:
+  ; FP64-NEXT:   liveins: $d12_64
+  ; FP64-NEXT: {{  $}}
+  ; FP64-NEXT:   [[COPY:%[0-9]+]]:_(s64) = COPY $d12_64
+  ; FP64-NEXT:   [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
+  ; FP64-NEXT:   ADJCALLSTACKDOWN 16, 0, implicit-def $sp, implicit $sp
+  ; FP64-NEXT:   [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY]](s64)
+  ; FP64-NEXT:   $a0 = COPY [[C]](s32)
+  ; FP64-NEXT:   $a2 = COPY [[UV]](s32)
+  ; FP64-NEXT:   $a3 = COPY [[UV1]](s32)
+  ; FP64-NEXT:   JAL @double_in_gpr, csr_o32_fp64, implicit-def $ra, implicit-def $sp, implicit $a2, implicit $a3, implicit $a0, implicit-def $d0_64
+  ; FP64-NEXT:   [[COPY1:%[0-9]+]]:_(s64) = COPY $d0_64
+  ; FP64-NEXT:   ADJCALLSTACKUP 16, 0, implicit-def $sp, implicit $sp
+  ; FP64-NEXT:   $d0_64 = COPY [[COPY1]](s64)
+  ; FP64-NEXT:   RetRA implicit $d0_64
+entry:
+  %r = call double @double_in_gpr(i32 1, double %a)
+  ret double %r
+}


        


More information about the llvm-commits mailing list