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/lower-em-sjlj-alias.ll
Heejin Ahn bdd81f3ef5 [WebAssembly] Compare functions by names in Emscripten Sjlj
Summary:
This removes all string constants for function names and compares
functions by string directly when needed. Many of these constants are
used only once or twice so the benefit of defining them separately is
not very clear, and this actually fixes a bug.

When we already have a `malloc` declaration which is an alias to
something else within the module,
```
@malloc = weak hidden alias i8* (i32), i8* (i32)* @dlmalloc
```
(this happens compiling with emscripten with `-s WASM_OBJECT_FILES=0`
because all bc files are merged before being fed into `wasm-ld` which
runs the backend optimizations as LTO)

`Module::getFunction("malloc")` in `canLongjmp` returns `nullptr`
because `Module::getFunction` dyncasts pointer into `Function`, but the
alias is a `GlobalValue` but not a `Function`. This makes `canLongjmp`
return false for `malloc` in this case, and we end up adding a lot of
longjmp handling code around malloc. This is not only a code size
increase but actually a bug because `malloc` is used in the entry block
when preparing for setjmp tables for emscripten sjlj handling, and this
makes initial setjmp preparation, which has to happen in the entry
block, move to another split block, and this interferes with SSA update
later.

This also adds two more functions, `getTempRet0` and `setTempRet0`, in
the list of not longjmp-able functions.

Fixes https://github.com/emscripten-core/emscripten/issues/8935.

Reviewers: sbc100

Subscribers: mehdi_amini, jgravelle-google, hiraditya, sunfish, dexonsmith, dschuff, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D67129

llvm-svn: 370828
2019-09-03 22:26:49 +00:00

44 lines
1.4 KiB
LLVM

; RUN: opt < %s -wasm-lower-em-ehsjlj -S | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
target triple = "wasm32-unknown-emscripten"
; Tests if an alias to a function (here malloc) is correctly handled as a
; function that cannot longjmp.
%struct.__jmp_buf_tag = type { [6 x i32], i32, [32 x i32] }
@malloc = weak alias i8* (i32), i8* (i32)* @dlmalloc
; CHECK-LABEL: @malloc_test
define void @malloc_test() {
entry:
; CHECK-LABEL: entry
; All setjmp table preparations have to happen within the entry block. These
; check lines list only some of the instructions for that.
; CHECK: call i8* @malloc
; CHECK: call i32* @saveSetjmp
; CHECK: call i32 @getTempRet0
%retval = alloca i32, align 4
%jmp = alloca [1 x %struct.__jmp_buf_tag], align 16
store i32 0, i32* %retval, align 4
%arraydecay = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %jmp, i32 0, i32 0
%call = call i32 @setjmp(%struct.__jmp_buf_tag* %arraydecay) #0
ret void
; CHECK-LABEL: entry.split
; CHECK: call void @free
; CHECK: ret void
}
; This is a dummy dlmalloc implemenation only to make compiler pass, because an
; alias (malloc) has to point an actual definition.
define i8* @dlmalloc(i32) {
%p = inttoptr i32 0 to i8*
ret i8* %p
}
; Function Attrs: returns_twice
declare i32 @setjmp(%struct.__jmp_buf_tag*) #0
attributes #0 = { returns_twice }