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: tail_call_void_nullary: 101; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} 102; CHECK-NEXT: return{{$}} 103define void @tail_call_void_nullary() { 104 tail call void @void_nullary() 105 ret void 106} 107 108; CHECK-LABEL: fastcc_tail_call_void_nullary: 109; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} 110; CHECK-NEXT: return{{$}} 111define void @fastcc_tail_call_void_nullary() { 112 tail call fastcc void @void_nullary() 113 ret void 114} 115 116; CHECK-LABEL: coldcc_tail_call_void_nullary: 117; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} 118; CHECK-NEXT: return{{$}} 119define void @coldcc_tail_call_void_nullary() { 120 tail call coldcc void @void_nullary() 121 ret void 122} 123 124; TODO: test the following: 125; - More argument combinations. 126; - Tail call. 127; - Interesting returns (struct, multiple). 128; - Vararg. 129