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 6 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 7 target triple = "wasm32-unknown-unknown" 8 9 declare i32 @i32_nullary() 10 declare i32 @i32_unary(i32) 11 declare i32 @i32_binary(i32, i32) 12 declare i64 @i64_nullary() 13 declare float @float_nullary() 14 declare double @double_nullary() 15 declare 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]]{{$}} 21 define 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]]{{$}} 30 define 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]]{{$}} 39 define 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]]{{$}} 48 define 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{{$}} 56 define 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]]{{$}} 66 define 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]]{{$}} 76 define 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{{$}} 85 define 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]]{{$}} 95 define 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{{$}} 103 define 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{{$}} 111 define 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{{$}} 119 define 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