1; RUN: llc -filetype=obj %s -o %t.o 2; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/call-indirect.s -o %t2.o 3; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o 4; RUN: obj2yaml %t.wasm | FileCheck %s 5 6; bitcode generated from the following C code: 7; int foo(void) { return 1; } 8; int (*indirect_func)(void) = &foo; 9; void _start(void) { indirect_func(); } 10 11target triple = "wasm32-unknown-unknown" 12 13@indirect_func = local_unnamed_addr global i32 ()* @foo, align 4 14 15; Function Attrs: norecurse nounwind readnone 16define i32 @foo() #0 { 17entry: 18 ret i32 2 19} 20 21; Function Attrs: nounwind 22define void @_start() local_unnamed_addr #1 { 23entry: 24 %0 = load i32 ()*, i32 ()** @indirect_func, align 4 25 %call = call i32 %0() #2 26 ret void 27} 28 29; Indirect function call where no function actually has this type. 30; Ensures that the type entry is still created in this case. 31define void @call_ptr(i64 (i64)* %arg) { 32 %1 = call i64 %arg(i64 1) 33 ret void 34} 35 36; CHECK: !WASM 37; CHECK-NEXT: FileHeader: 38; CHECK-NEXT: Version: 0x1 39; CHECK-NEXT: Sections: 40; CHECK-NEXT: - Type: TYPE 41; CHECK-NEXT: Signatures: 42; CHECK-NEXT: - Index: 0 43; CHECK-NEXT: ParamTypes: 44; CHECK-NEXT: ReturnTypes: 45; CHECK-NEXT: - I64 46; CHECK-NEXT: - Index: 1 47; CHECK-NEXT: ParamTypes: 48; CHECK-NEXT: ReturnTypes: 49; CHECK-NEXT: - I32 50; CHECK-NEXT: - Index: 2 51; CHECK-NEXT: ParamTypes: 52; CHECK-NEXT: - I64 53; CHECK-NEXT: ReturnTypes: 54; CHECK-NEXT: - I64 55; CHECK-NEXT: - Index: 3 56; CHECK-NEXT: ParamTypes: 57; CHECK-NEXT: ReturnTypes: [] 58; CHECK-NEXT: - Index: 4 59; CHECK-NEXT: ParamTypes: 60; CHECK-NEXT: - I32 61; CHECK-NEXT: ReturnTypes: [] 62; CHECK-NEXT: - Type: FUNCTION 63; CHECK-NEXT: FunctionTypes: [ 0, 3, 1, 3, 4 ] 64; CHECK-NEXT: - Type: TABLE 65; CHECK-NEXT: Tables: 66; CHECK-NEXT: - Index: 0 67; CHECK-NEXT: ElemType: FUNCREF 68; CHECK-NEXT: Limits: 69; CHECK-NEXT: Flags: [ HAS_MAX ] 70; CHECK-NEXT: Initial: 0x3 71; CHECK-NEXT: Maximum: 0x3 72; CHECK-NEXT: - Type: MEMORY 73; CHECK-NEXT: Memories: 74; CHECK-NEXT: - Initial: 0x2 75; CHECK-NEXT: - Type: GLOBAL 76; CHECK-NEXT: Globals: 77; CHECK-NEXT: - Index: 0 78; CHECK-NEXT: Type: I32 79; CHECK-NEXT: Mutable: true 80; CHECK-NEXT: InitExpr: 81; CHECK-NEXT: Opcode: I32_CONST 82; CHECK-NEXT: Value: 66576 83; CHECK-NEXT: - Index: 1 84; CHECK-NEXT: Type: I32 85; CHECK-NEXT: Mutable: false 86; CHECK-NEXT: InitExpr: 87; CHECK-NEXT: Opcode: I32_CONST 88; CHECK-NEXT: Value: 1032 89; CHECK-NEXT: - Type: EXPORT 90; CHECK-NEXT: Exports: 91; CHECK-NEXT: - Name: memory 92; CHECK-NEXT: Kind: MEMORY 93; CHECK-NEXT: Index: 0 94; CHECK-NEXT: - Name: bar 95; CHECK-NEXT: Kind: FUNCTION 96; CHECK-NEXT: Index: 0 97; CHECK-NEXT: - Name: call_bar_indirect 98; CHECK-NEXT: Kind: FUNCTION 99; CHECK-NEXT: Index: 1 100; CHECK-NEXT: - Name: foo 101; CHECK-NEXT: Kind: FUNCTION 102; CHECK-NEXT: Index: 2 103; CHECK-NEXT: - Name: _start 104; CHECK-NEXT: Kind: FUNCTION 105; CHECK-NEXT: Index: 3 106; CHECK-NEXT: - Name: indirect_func 107; CHECK-NEXT: Kind: GLOBAL 108; CHECK-NEXT: Index: 1 109; CHECK-NEXT: - Name: call_ptr 110; CHECK-NEXT: Kind: FUNCTION 111; CHECK-NEXT: Index: 4 112; CHECK-NEXT: - Type: ELEM 113; CHECK-NEXT: Segments: 114; CHECK-NEXT: - Offset: 115; CHECK-NEXT: Opcode: I32_CONST 116; CHECK-NEXT: Value: 1 117; CHECK-NEXT: Functions: [ 0, 2 ] 118; CHECK-NEXT: - Type: CODE 119; CHECK-NEXT: Functions: 120; CHECK-NEXT: - Index: 0 121; CHECK-NEXT: Locals: 122; CHECK-NEXT: Body: 42010B 123; CHECK-NEXT: - Index: 1 124; CHECK-NEXT: Locals: 125; CHECK-NEXT: Body: 28028088808000118080808000001A28028488808000118180808000001A0B 126; CHECK-NEXT: - Index: 2 127; CHECK-NEXT: Locals: 128; CHECK-NEXT: Body: 41020B 129; CHECK-NEXT: - Index: 3 130; CHECK-NEXT: Locals: 131; CHECK-NEXT: Body: 410028028888808000118180808000001A0B 132; CHECK-NEXT: - Index: 4 133; CHECK-NEXT: Locals: 134; CHECK-NEXT: Body: 42012000118280808000001A0B 135; CHECK-NEXT: - Type: DATA 136; CHECK-NEXT: Segments: 137; CHECK-NEXT: - SectionOffset: 7 138; CHECK-NEXT: InitFlags: 0 139; CHECK-NEXT: Offset: 140; CHECK-NEXT: Opcode: I32_CONST 141; CHECK-NEXT: Value: 1024 142; CHECK-NEXT: Content: '010000000200000002000000' 143; CHECK-NEXT: - Type: CUSTOM 144; CHECK-NEXT: Name: name 145; CHECK-NEXT: FunctionNames: 146; CHECK-NEXT: - Index: 0 147; CHECK-NEXT: Name: bar 148; CHECK-NEXT: - Index: 1 149; CHECK-NEXT: Name: call_bar_indirect 150; CHECK-NEXT: - Index: 2 151; CHECK-NEXT: Name: foo 152; CHECK-NEXT: - Index: 3 153; CHECK-NEXT: Name: _start 154; CHECK-NEXT: - Index: 4 155; CHECK-NEXT: Name: call_ptr 156; CHECK-NEXT: GlobalNames: 157; CHECK-NEXT: - Index: 0 158; CHECK-NEXT: Name: __stack_pointer 159; CHECK-NEXT: ... 160