Skip to content

Commit

Permalink
[Mips] Fix compiler crash when returning fp128 after calling a functi…
Browse files Browse the repository at this point in the history
…on 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.
  • Loading branch information
yingopq committed Nov 28, 2024
1 parent ce66b56 commit 6409647
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
4 changes: 2 additions & 2 deletions llvm/lib/Target/Mips/MipsCallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -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]>>,
Expand Down
55 changes: 55 additions & 0 deletions llvm/test/CodeGen/Mips/mips64-f128.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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: {{.*}}
Expand Down

0 comments on commit 6409647

Please sign in to comment.