[llvm] [Mips] Fix compiler crash when returning fp128 after calling a functi… (PR #117525)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 27 19:19:50 PST 2024


https://github.com/yingopq updated https://github.com/llvm/llvm-project/pull/117525

>From 64096473b40739d8177ea3d3d793b1ea0d80492c Mon Sep 17 00:00:00 2001
From: Ying Huang <ying.huang at oss.cipunited.com>
Date: Mon, 25 Nov 2024 02:28:07 -0500
Subject: [PATCH] [Mips] Fix compiler crash when returning fp128 after calling
 a function returning { i8, i128 }

issue description:
When process CanLowerReturn in function lowcall, Mips implements
this hook using CheckReturn with CCAssignFn RetCC_Mips. In
CheckReturn, Mips would check whether lowered value was originated
from f128, this step would check whether MF function return type
was f128. In this issue, function return type was just fp128. In
CCAssignFn RetCC_Mips, CCIfType i64 would be CCAssignToReg V0_64,
A0_64 for soft-float.
Then Mips process LowerCallResult which use CCAssignFn RetCC_Mips.
It would also check whether lowered value was originated from f128.
In this issue, call function return type was structure type and not
{f128}, so in CCAssignFn RetCC_Mips, CCIfType i64 would be CCAssignToReg
V0_64, V1_64. And in this issue, structure type return value was
three i64, so when check the third i64, would report error "Call
result #2 has unhandled type i64" due to there are no register
available for it.
---
 llvm/lib/Target/Mips/MipsCallingConv.td |  4 +-
 llvm/test/CodeGen/Mips/mips64-f128.ll   | 55 +++++++++++++++++++++++++
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/Mips/MipsCallingConv.td b/llvm/lib/Target/Mips/MipsCallingConv.td
index 25384a3fe8de37..f997dcf2ece2e7 100644
--- a/llvm/lib/Target/Mips/MipsCallingConv.td
+++ b/llvm/lib/Target/Mips/MipsCallingConv.td
@@ -207,8 +207,8 @@ def RetCC_MipsN : CallingConv<[
       CCIfType<[i8, i16, i32, i64],
           CCIfInReg<CCPromoteToUpperBitsInType<i64>>>>,
 
-  // i64 are returned in registers V0_64, V1_64
-  CCIfType<[i64], CCAssignToReg<[V0_64, V1_64]>>,
+  // i64 are returned in registers V0_64, V1_64, A0_64
+  CCIfType<[i64], CCAssignToReg<[V0_64, V1_64, A0_64]>>,
 
   // f32 are returned in registers F0, F2
   CCIfType<[f32], CCAssignToReg<[F0, F2]>>,
diff --git a/llvm/test/CodeGen/Mips/mips64-f128.ll b/llvm/test/CodeGen/Mips/mips64-f128.ll
index ac29154579c500..9633cdcd484a73 100644
--- a/llvm/test/CodeGen/Mips/mips64-f128.ll
+++ b/llvm/test/CodeGen/Mips/mips64-f128.ll
@@ -2903,6 +2903,61 @@ entry:
   %cond = select i1 %cmp, fp128 %c, fp128 %d
   ret fp128 %cond
 }
+
+define { i8, i128 } @bar() {
+  ret { i8, i128 } zeroinitializer
+}
+
+define fp128 @call_retFP128() {
+; C_CC_FMT-LABEL: call_retFP128:
+; C_CC_FMT:       # %bb.0: # %entry
+; C_CC_FMT-NEXT:    daddiu $sp, $sp, -16
+; C_CC_FMT-NEXT:    .cfi_def_cfa_offset 16
+; C_CC_FMT-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
+; C_CC_FMT-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
+; C_CC_FMT-NEXT:    .cfi_offset 31, -8
+; C_CC_FMT-NEXT:    .cfi_offset 28, -16
+; C_CC_FMT-NEXT:    lui $1, %hi(%neg(%gp_rel(call_retFP128)))
+; C_CC_FMT-NEXT:    daddu $1, $1, $25
+; C_CC_FMT-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(call_retFP128)))
+; C_CC_FMT-NEXT:    ld $25, %call16(bar)($gp)
+; C_CC_FMT-NEXT:    .reloc .Ltmp51, R_MIPS_JALR, bar
+; C_CC_FMT-NEXT:  .Ltmp51:
+; C_CC_FMT-NEXT:    jalr $25
+; C_CC_FMT-NEXT:    nop
+; C_CC_FMT-NEXT:    daddiu $2, $zero, 0
+; C_CC_FMT-NEXT:    daddiu $4, $zero, 0
+; C_CC_FMT-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
+; C_CC_FMT-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
+; C_CC_FMT-NEXT:    daddiu $sp, $sp, 16
+; C_CC_FMT-NEXT:    jr $ra
+; C_CC_FMT-NEXT:    nop
+;
+; CMP_CC_FMT-LABEL: call_retFP128:
+; CMP_CC_FMT:       # %bb.0: # %entry
+; CMP_CC_FMT-NEXT:    daddiu $sp, $sp, -16
+; CMP_CC_FMT-NEXT:    .cfi_def_cfa_offset 16
+; CMP_CC_FMT-NEXT:    sd $ra, 8($sp) # 8-byte Folded Spill
+; CMP_CC_FMT-NEXT:    sd $gp, 0($sp) # 8-byte Folded Spill
+; CMP_CC_FMT-NEXT:    .cfi_offset 31, -8
+; CMP_CC_FMT-NEXT:    .cfi_offset 28, -16
+; CMP_CC_FMT-NEXT:    lui $1, %hi(%neg(%gp_rel(call_retFP128)))
+; CMP_CC_FMT-NEXT:    daddu $1, $1, $25
+; CMP_CC_FMT-NEXT:    daddiu $gp, $1, %lo(%neg(%gp_rel(call_retFP128)))
+; CMP_CC_FMT-NEXT:    ld $25, %call16(bar)($gp)
+; CMP_CC_FMT-NEXT:    .reloc .Ltmp51, R_MIPS_JALR, bar
+; CMP_CC_FMT-NEXT:  .Ltmp51:
+; CMP_CC_FMT-NEXT:    jalrc $25
+; CMP_CC_FMT-NEXT:    daddiu $2, $zero, 0
+; CMP_CC_FMT-NEXT:    daddiu $4, $zero, 0
+; CMP_CC_FMT-NEXT:    ld $gp, 0($sp) # 8-byte Folded Reload
+; CMP_CC_FMT-NEXT:    ld $ra, 8($sp) # 8-byte Folded Reload
+; CMP_CC_FMT-NEXT:    daddiu $sp, $sp, 16
+; CMP_CC_FMT-NEXT:    jrc $ra
+entry:
+  call { i8, i128 } @bar()
+  ret fp128 0xL00000000000000000000000000000000
+}
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
 ; ALL: {{.*}}
 ; PRER6: {{.*}}



More information about the llvm-commits mailing list