mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-13 14:46:53 +00:00
5393254646
It looks like there are two versions of LowerCallTo here: the SelectionDAGBuilder one is designed to operate on LLVM IR, and the TargetLowering one in the case where everything is at DAG level. Previously, only the SelectionDAGBuilder variant could handle demoting an impossible return to sret semantics (before delegating to the TargetLowering version), but this functionality is also useful for certain libcalls (e.g. 128-bit operations on 32-bit x86). So this commit moves the sret handling down a level. rdar://problem/17242889 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211155 91177308-0d34-0410-b5e6-96231b3b80d8
29 lines
987 B
LLVM
29 lines
987 B
LLVM
; RUN: llc -mtriple=i686-linux-gnu -o - %s | FileCheck %s
|
|
|
|
@var = global i128 0
|
|
|
|
; We were trying to convert the i128 operation into a libcall, but failing to
|
|
; perform sret demotion when we couldn't return the result in registers. Make
|
|
; sure we marshal the return properly:
|
|
|
|
define void @test_sret_libcall(i128 %l, i128 %r) {
|
|
; CHECK-LABEL: test_sret_libcall:
|
|
|
|
; Stack for call: 4(sret ptr), 16(i128 %l), 16(128 %r). So next logical
|
|
; (aligned) place for the actual sret data is %esp + 40.
|
|
; CHECK: leal 40(%esp), [[SRET_ADDR:%[a-z]+]]
|
|
; CHECK: movl [[SRET_ADDR]], (%esp)
|
|
; CHECK: calll __multi3
|
|
; CHECK-DAG: movl 40(%esp), [[RES0:%[a-z]+]]
|
|
; CHECK-DAG: movl 44(%esp), [[RES1:%[a-z]+]]
|
|
; CHECK-DAG: movl 48(%esp), [[RES2:%[a-z]+]]
|
|
; CHECK-DAG: movl 52(%esp), [[RES3:%[a-z]+]]
|
|
; CHECK-DAG: movl [[RES0]], var
|
|
; CHECK-DAG: movl [[RES1]], var+4
|
|
; CHECK-DAG: movl [[RES2]], var+8
|
|
; CHECK-DAG: movl [[RES3]], var+12
|
|
%prod = mul i128 %l, %r
|
|
store i128 %prod, i128* @var
|
|
ret void
|
|
}
|