; Function Attrs: norecurse nounwind readnone
-define i32 @foo() #0 {
+define i32 @direct_fn() #0 {
entry:
ret i32 0
}
-@bar = weak alias i32 (), i32 ()* @foo
+@alias_fn = weak alias i32 (), i32 ()* @direct_fn
-define i32 @call_bar() #0 {
+define i32 @call_direct() #0 {
entry:
- %call = call i32 @bar()
+ %call = call i32 @direct_fn()
+ ret i32 %call
+}
+
+define i32 @call_alias() #0 {
+entry:
+ %call = call i32 @alias_fn()
+ ret i32 %call
+}
+
+define i32 @call_alias_ptr() #0 {
+entry:
+; TODO(sbc): This code currently causes linker failures:
+; LLVM ERROR: symbol not found table index space: alias_fn
+; See: https://github.com/WebAssembly/tool-conventions/issues/34#
+; %fnptr = alloca i32 ()*, align 8
+; store i32 ()* @alias_fn, i32 ()** %fnptr, align 8
+; %0 = load i32 ()*, i32 ()** %fnptr, align 8
+; %call = call i32 %0()
+; ret i32 %call
+ ret i32 1
+}
+
+define i32 @call_direct_ptr() #0 {
+entry:
+ %fnptr = alloca i32 ()*, align 8
+ store i32 ()* @direct_fn, i32 ()** %fnptr, align 8
+ %0 = load i32 ()*, i32 ()** %fnptr, align 8
+ %call = call i32 %0()
ret i32 %call
}
; RUN: lld -flavor wasm %t.o %t2.o -o %t.wasm
; RUN: obj2yaml %t.wasm | FileCheck %s
-; Test that the strongly defined bar is used correctly despite the existence
-; of the weak alias
+; Test that the strongly defined alias_fn from this file is used both here
+; and in call_alias.
-define i32 @bar() local_unnamed_addr #1 {
+define i32 @alias_fn() local_unnamed_addr #1 {
ret i32 1
}
; Function Attrs: nounwind uwtable
define void @_start() local_unnamed_addr #1 {
entry:
- %call = tail call i32 @bar() #2
+ %call = tail call i32 @alias_fn() #2
ret void
}
; CHECK-NEXT: ReturnType: NORESULT
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - Type: FUNCTION
-; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0 ]
+; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 0, 0, 0, 0 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
; CHECK-NEXT: - ElemType: ANYFUNC
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
-; CHECK-NEXT: Initial: 0x00000001
-; CHECK-NEXT: Maximum: 0x00000001
+; CHECK-NEXT: Initial: 0x00000002
+; CHECK-NEXT: Maximum: 0x00000002
; CHECK-NEXT: - Type: MEMORY
; CHECK-NEXT: Memories:
; CHECK-NEXT: - Initial: 0x00000002
; CHECK-NEXT: - Name: _start
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: bar
+; CHECK-NEXT: - Name: alias_fn
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 0
-; CHECK-NEXT: - Name: foo
+; CHECK-NEXT: - Name: direct_fn
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 2
-; CHECK-NEXT: - Name: call_bar
+; CHECK-NEXT: - Name: call_direct
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 3
+; CHECK-NEXT: - Name: call_alias
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 4
+; CHECK-NEXT: - Name: call_alias_ptr
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 5
+; CHECK-NEXT: - Name: call_direct_ptr
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 6
+; CHECK-NEXT: - Type: ELEM
+; CHECK-NEXT: Segments:
+; CHECK-NEXT: - Offset:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 1
+; CHECK-NEXT: Functions: [ 0 ]
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Functions:
; CHECK-NEXT: - Locals:
; CHECK-NEXT: Body: 41000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: Body: 1080808080000B
+; CHECK-NEXT: - Locals:
+; CHECK-NEXT: Body: 1080808080000B
+; CHECK-NEXT: - Locals:
+; CHECK-NEXT: Body: 41010B
+; CHECK-NEXT: - Locals:
+; CHECK-NEXT: - Type: I32
+; CHECK-NEXT: Count: 2
+; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081080808080002101200041106A24808080800020010B
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 0
; CHECK-NEXT: Name: name
; CHECK-NEXT: FunctionNames:
; CHECK-NEXT: - Index: 0
-; CHECK-NEXT: Name: bar
+; CHECK-NEXT: Name: alias_fn
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Name: _start
; CHECK-NEXT: - Index: 2
-; CHECK-NEXT: Name: foo
+; CHECK-NEXT: Name: direct_fn
; CHECK-NEXT: - Index: 3
-; CHECK-NEXT: Name: call_bar
+; CHECK-NEXT: Name: call_direct
+; CHECK-NEXT: - Index: 4
+; CHECK-NEXT: Name: call_alias
+; CHECK-NEXT: - Index: 5
+; CHECK-NEXT: Name: call_alias_ptr
+; CHECK-NEXT: - Index: 6
+; CHECK-NEXT: Name: call_direct_ptr
; CHECK-NEXT: ...
; RUN: lld -flavor wasm %t.o %t2.o -o %t.wasm
; RUN: obj2yaml %t.wasm | FileCheck %s
-; Test that weak aliases (bar is a weak alias of foo) are linked correctly
+; Test that weak aliases (alias_fn is a weak alias of direct_fn) are linked correctly
-declare i32 @bar() local_unnamed_addr #1
+declare i32 @alias_fn() local_unnamed_addr #1
; Function Attrs: nounwind uwtable
define i32 @_start() local_unnamed_addr #1 {
entry:
- %call = tail call i32 @bar() #2
+ %call = tail call i32 @alias_fn() #2
ret i32 %call
}
; CHECK-NEXT: ReturnType: I32
; CHECK-NEXT: ParamTypes:
; CHECK-NEXT: - Type: FUNCTION
-; CHECK-NEXT: FunctionTypes: [ 0, 0, 0 ]
+; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0 ]
; CHECK-NEXT: - Type: TABLE
; CHECK-NEXT: Tables:
; CHECK-NEXT: - ElemType: ANYFUNC
; CHECK-NEXT: Limits:
; CHECK-NEXT: Flags: [ HAS_MAX ]
-; CHECK-NEXT: Initial: 0x00000001
-; CHECK-NEXT: Maximum: 0x00000001
+; CHECK-NEXT: Initial: 0x00000002
+; CHECK-NEXT: Maximum: 0x00000002
; CHECK-NEXT: - Type: MEMORY
; CHECK-NEXT: Memories:
; CHECK-NEXT: - Initial: 0x00000002
; CHECK-NEXT: - Name: _start
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 0
-; CHECK-NEXT: - Name: bar
+; CHECK-NEXT: - Name: alias_fn
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: foo
+; CHECK-NEXT: - Name: direct_fn
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 1
-; CHECK-NEXT: - Name: call_bar
+; CHECK-NEXT: - Name: call_direct
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: Index: 2
+; CHECK-NEXT: - Name: call_alias
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 3
+; CHECK-NEXT: - Name: call_alias_ptr
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 4
+; CHECK-NEXT: - Name: call_direct_ptr
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 5
+; CHECK-NEXT: - Type: ELEM
+; CHECK-NEXT: Segments:
+; CHECK-NEXT: - Offset:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 1
+; CHECK-NEXT: Functions: [ 1 ]
; CHECK-NEXT: - Type: CODE
; CHECK-NEXT: Functions:
; CHECK-NEXT: - Locals:
; CHECK-NEXT: Body: 41000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: Body: 1081808080000B
+; CHECK-NEXT: - Locals:
+; CHECK-NEXT: Body: 1081808080000B
+; CHECK-NEXT: - Locals:
+; CHECK-NEXT: Body: 41010B
+; CHECK-NEXT: - Locals:
+; CHECK-NEXT: - Type: I32
+; CHECK-NEXT: Count: 2
+; CHECK-NEXT: Body: 23808080800041106B220024808080800020004181808080003602081081808080002101200041106A24808080800020010B
; CHECK-NEXT: - Type: CUSTOM
; CHECK-NEXT: Name: linking
; CHECK-NEXT: DataSize: 0
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Name: _start
; CHECK-NEXT: - Index: 1
-; CHECK-NEXT: Name: foo
+; CHECK-NEXT: Name: direct_fn
; CHECK-NEXT: - Index: 2
-; CHECK-NEXT: Name: call_bar
+; CHECK-NEXT: Name: call_direct
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Name: call_alias
+; CHECK-NEXT: - Index: 4
+; CHECK-NEXT: Name: call_alias_ptr
+; CHECK-NEXT: - Index: 5
+; CHECK-NEXT: Name: call_direct_ptr
; CHECK-NEXT: ...