1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00
llvm-mirror/test/CodeGen/WebAssembly/swiftcc.ll
Yuta Saito e102360e48 [WebAssembly] Support swiftself and swifterror for WebAssembly target
Summary:
Swift ABI is based on basic C ABI described here https://github.com/WebAssembly/tool-conventions/blob/master/BasicCABI.md
Swift Calling Convention on WebAssembly is a little deffer from swiftcc
on another architectures.

On non WebAssembly arch, swiftcc accepts extra parameters that are
attributed with swifterror or swiftself by caller. Even if callee
doesn't have these parameters, the invocation succeed ignoring extra
parameters.

But WebAssembly strictly checks that callee and caller signatures are
same. https://github.com/WebAssembly/design/blob/master/Semantics.md#calls
So at WebAssembly level, all swiftcc functions end up extra arguments
and all function definitions and invocations explicitly have additional
parameters to fill swifterror and swiftself.

This patch support signature difference for swiftself and swifterror cc
is swiftcc.

e.g.
```
declare swiftcc void @foo(i32, i32)
@data = global i8* bitcast (void (i32, i32)* @foo to i8*)
define swiftcc void @bar() {
  %1 = load i8*, i8** @data
  %2 = bitcast i8* %1 to void (i32, i32, i32)*
  call swiftcc void %2(i32 1, i32 2, i32 swiftself 3)
  ret void
}
```

For swiftcc, emit additional swiftself and swifterror parameters
if there aren't while lowering. These additional parameters are added
for both callee and caller.
They are necessary to match callee and caller signature for direct and
indirect function call.

Differential Revision: https://reviews.llvm.org/D76049
2020-03-19 17:39:52 -07:00

47 lines
1.7 KiB
LLVM

; RUN: llc < %s -asm-verbose=false -wasm-keep-registers | FileCheck %s --check-prefix=REG
; RUN: llc < %s -asm-verbose=false | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-unknown"
; Test direct and indirect function call between mismatched signatures
; CHECK-LABEL: foo:
; CHECK-NEXT: .functype foo (i32, i32, i32, i32) -> ()
define swiftcc void @foo(i32, i32) {
ret void
}
@data = global i8* bitcast (void (i32, i32)* @foo to i8*)
; CHECK-LABEL: bar:
; CHECK-NEXT: .functype bar (i32, i32) -> ()
define swiftcc void @bar() {
%1 = load i8*, i8** @data
; REG: call foo, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
call swiftcc void @foo(i32 1, i32 2)
%2 = bitcast i8* %1 to void (i32, i32)*
; REG: call_indirect $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
; CHECK: call_indirect (i32, i32, i32, i32) -> ()
call swiftcc void %2(i32 1, i32 2)
%3 = bitcast i8* %1 to void (i32, i32, i32)*
; REG: call_indirect $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
; CHECK: call_indirect (i32, i32, i32, i32) -> ()
call swiftcc void %3(i32 1, i32 2, i32 swiftself 3)
%err = alloca swifterror i32*, align 4
%4 = bitcast i8* %1 to void (i32, i32, i32**)*
; REG: call_indirect $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
; CHECK: call_indirect (i32, i32, i32, i32) -> ()
call swiftcc void %4(i32 1, i32 2, i32** swifterror %err)
%5 = bitcast i8* %1 to void (i32, i32, i32, i32**)*
; REG: call_indirect $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}
; CHECK: call_indirect (i32, i32, i32, i32) -> ()
call swiftcc void %5(i32 1, i32 2, i32 swiftself 3, i32** swifterror %err)
ret void
}