mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
bdd81f3ef5
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
44 lines
1.4 KiB
LLVM
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 }
|