summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/WebAssembly/indirect-import.ll
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@google.com>2016-06-02 21:34:18 +0000
committerDerek Schuff <dschuff@google.com>2016-06-02 21:34:18 +0000
commit23b7d65fe5b93bf7161b3d7ebd54eb9b1f41e291 (patch)
treecf42c2e90fb308a21127e29bd39d19d8430be137 /llvm/test/CodeGen/WebAssembly/indirect-import.ll
parentb820edd58ab40a10a3c2f86fd99af97dda2ee63f (diff)
downloadbcm5719-llvm-23b7d65fe5b93bf7161b3d7ebd54eb9b1f41e291.tar.gz
bcm5719-llvm-23b7d65fe5b93bf7161b3d7ebd54eb9b1f41e291.zip
[WebAssembly] Emit type signatures for declared functions
Under emscripten, C code can take the address of a function implemented in Javascript (which is exposed via an import in wasm). Because imports do not have linear memory address in wasm, we need to generate a thunk to be the target of the indirect call; it call the import directly. To make this possible, LLVM needs to emit the type signatures for these functions, because they may not be called directly or referred to other than where the address is taken. This uses s new .s directive (.functype) which specifies the signature. Differential Revision: http://reviews.llvm.org/D20891 llvm-svn: 271599
Diffstat (limited to 'llvm/test/CodeGen/WebAssembly/indirect-import.ll')
-rw-r--r--llvm/test/CodeGen/WebAssembly/indirect-import.ll70
1 files changed, 70 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/WebAssembly/indirect-import.ll b/llvm/test/CodeGen/WebAssembly/indirect-import.ll
new file mode 100644
index 00000000000..fad7c0b23b6
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/indirect-import.ll
@@ -0,0 +1,70 @@
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs -fast-isel | FileCheck %s
+
+; ModuleID = 'test/dot_s/indirect-import.c'
+source_filename = "test/dot_s/indirect-import.c"
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32"
+
+%struct.big = type { float, double, i32 }
+
+; Function Attrs: nounwind
+; CHECK: bar:
+define hidden i32 @bar() #0 {
+entry:
+ %fd = alloca float (double)*, align 4
+ %vj = alloca void (i64)*, align 4
+ %v = alloca void ()*, align 4
+ %ijidf = alloca i32 (i64, i32, double, float)*, align 4
+ %vs = alloca void (%struct.big*)*, align 4
+ %s = alloca void (%struct.big*)*, align 4
+
+; CHECK: i32.const {{.+}}=, extern_fd@FUNCTION
+ store float (double)* @extern_fd, float (double)** %fd, align 4
+; CHECK: i32.const {{.+}}=, extern_vj@FUNCTION
+ store void (i64)* @extern_vj, void (i64)** %vj, align 4
+ %0 = load void (i64)*, void (i64)** %vj, align 4
+ call void %0(i64 1)
+
+; CHECK: i32.const {{.+}}=, extern_v@FUNCTION
+ store void ()* @extern_v, void ()** %v, align 4
+ %1 = load void ()*, void ()** %v, align 4
+ call void %1()
+
+; CHECK: i32.const {{.+}}=, extern_ijidf@FUNCTION
+ store i32 (i64, i32, double, float)* @extern_ijidf, i32 (i64, i32, double, float)** %ijidf, align 4
+ %2 = load i32 (i64, i32, double, float)*, i32 (i64, i32, double, float)** %ijidf, align 4
+ %call = call i32 %2(i64 1, i32 2, double 3.000000e+00, float 4.000000e+00)
+
+; CHECK: i32.const {{.+}}=, extern_struct@FUNCTION
+ store void (%struct.big*)* @extern_struct, void (%struct.big*)** %vs, align 4
+
+; CHECK: i32.const {{.+}}=, extern_sret@FUNCTION
+ store void (%struct.big*)* @extern_sret, void (%struct.big*)** %s, align 4
+ %3 = load float (double)*, float (double)** %fd, align 4
+ %4 = ptrtoint float (double)* %3 to i32
+ ret i32 %4
+}
+
+declare float @extern_fd(double) #1
+
+declare void @extern_vj(i64) #1
+
+declare void @extern_v() #1
+
+declare i32 @extern_ijidf(i64, i32, double, float) #1
+
+declare void @extern_struct(%struct.big* byval align 8) #1
+
+declare void @extern_sret(%struct.big* sret) #1
+
+attributes #0 = { nounwind "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+
+; CHECK: .functype extern_fd, f32, f64
+; CHECK: .functype extern_vj, void, i64
+; CHECK: .functype extern_v, void
+; CHECK: .functype extern_ijidf, i32, i64, i32, f64, f32
+; CHECK: .functype extern_struct, void, i32
+; CHECK: .functype extern_sret, void, i32
OpenPOWER on IntegriCloud