1; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s 2; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s 3 4; Test that basic call operations assemble as expected. 5 6target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 7target triple = "wasm32-unknown-unknown" 8 9declare i32 @i32_nullary() 10declare i32 @i32_unary(i32) 11declare i32 @i32_binary(i32, i32) 12declare i64 @i64_nullary() 13declare float @float_nullary() 14declare double @double_nullary() 15declare void @void_nullary() 16 17; CHECK-LABEL: call_i32_nullary: 18; CHECK-NEXT: .result i32{{$}} 19; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_nullary@FUNCTION{{$}} 20; CHECK-NEXT: return $pop[[NUM]]{{$}} 21define i32 @call_i32_nullary() { 22 %r = call i32 @i32_nullary() 23 ret i32 %r 24} 25 26; CHECK-LABEL: call_i64_nullary: 27; CHECK-NEXT: .result i64{{$}} 28; CHECK-NEXT: {{^}} i64.call $push[[NUM:[0-9]+]]=, i64_nullary@FUNCTION{{$}} 29; CHECK-NEXT: return $pop[[NUM]]{{$}} 30define i64 @call_i64_nullary() { 31 %r = call i64 @i64_nullary() 32 ret i64 %r 33} 34 35; CHECK-LABEL: call_float_nullary: 36; CHECK-NEXT: .result f32{{$}} 37; CHECK-NEXT: {{^}} f32.call $push[[NUM:[0-9]+]]=, float_nullary@FUNCTION{{$}} 38; CHECK-NEXT: return $pop[[NUM]]{{$}} 39define float @call_float_nullary() { 40 %r = call float @float_nullary() 41 ret float %r 42} 43 44; CHECK-LABEL: call_double_nullary: 45; CHECK-NEXT: .result f64{{$}} 46; CHECK-NEXT: {{^}} f64.call $push[[NUM:[0-9]+]]=, double_nullary@FUNCTION{{$}} 47; CHECK-NEXT: return $pop[[NUM]]{{$}} 48define double @call_double_nullary() { 49 %r = call double @double_nullary() 50 ret double %r 51} 52 53; CHECK-LABEL: call_void_nullary: 54; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} 55; CHECK-NEXT: return{{$}} 56define void @call_void_nullary() { 57 call void @void_nullary() 58 ret void 59} 60 61; CHECK-LABEL: call_i32_unary: 62; CHECK-NEXT: .param i32{{$}} 63; CHECK-NEXT: .result i32{{$}} 64; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_unary@FUNCTION, $0{{$}} 65; CHECK-NEXT: return $pop[[NUM]]{{$}} 66define i32 @call_i32_unary(i32 %a) { 67 %r = call i32 @i32_unary(i32 %a) 68 ret i32 %r 69} 70 71; CHECK-LABEL: call_i32_binary: 72; CHECK-NEXT: .param i32, i32{{$}} 73; CHECK-NEXT: .result i32{{$}} 74; CHECK-NEXT: {{^}} i32.call $push[[NUM:[0-9]+]]=, i32_binary@FUNCTION, $0, $1{{$}} 75; CHECK-NEXT: return $pop[[NUM]]{{$}} 76define i32 @call_i32_binary(i32 %a, i32 %b) { 77 %r = call i32 @i32_binary(i32 %a, i32 %b) 78 ret i32 %r 79} 80 81; CHECK-LABEL: call_indirect_void: 82; CHECK-NEXT: .param i32{{$}} 83; CHECK-NEXT: {{^}} call_indirect $0{{$}} 84; CHECK-NEXT: return{{$}} 85define void @call_indirect_void(void ()* %callee) { 86 call void %callee() 87 ret void 88} 89 90; CHECK-LABEL: call_indirect_i32: 91; CHECK-NEXT: .param i32{{$}} 92; CHECK-NEXT: .result i32{{$}} 93; CHECK-NEXT: {{^}} i32.call_indirect $push[[NUM:[0-9]+]]=, $0{{$}} 94; CHECK-NEXT: return $pop[[NUM]]{{$}} 95define i32 @call_indirect_i32(i32 ()* %callee) { 96 %t = call i32 %callee() 97 ret i32 %t 98} 99 100; CHECK-LABEL: call_indirect_arg: 101; CHECK-NEXT: .param i32, i32{{$}} 102; CHECK-NEXT: {{^}} call_indirect $1, $0{{$}} 103; CHECK-NEXT: return{{$}} 104define void @call_indirect_arg(void (i32)* %callee, i32 %arg) { 105 call void %callee(i32 %arg) 106 ret void 107} 108 109; CHECK-LABEL: call_indirect_arg_2: 110; CHECK-NEXT: .param i32, i32, i32{{$}} 111; CHECK-NEXT: {{^}} i32.call_indirect $drop=, $1, $2, $0{{$}} 112; CHECK-NEXT: return{{$}} 113define void @call_indirect_arg_2(i32 (i32, i32)* %callee, i32 %arg, i32 %arg2) { 114 call i32 %callee(i32 %arg, i32 %arg2) 115 ret void 116} 117 118; CHECK-LABEL: tail_call_void_nullary: 119; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} 120; CHECK-NEXT: return{{$}} 121define void @tail_call_void_nullary() { 122 tail call void @void_nullary() 123 ret void 124} 125 126; CHECK-LABEL: fastcc_tail_call_void_nullary: 127; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} 128; CHECK-NEXT: return{{$}} 129define void @fastcc_tail_call_void_nullary() { 130 tail call fastcc void @void_nullary() 131 ret void 132} 133 134; CHECK-LABEL: coldcc_tail_call_void_nullary: 135; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} 136; CHECK-NEXT: return{{$}} 137define void @coldcc_tail_call_void_nullary() { 138 tail call coldcc void @void_nullary() 139 ret void 140} 141 142; TODO: test the following: 143; - More argument combinations. 144; - Tail call. 145; - Interesting returns (struct, multiple). 146; - Vararg. 147