1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Test varargs constructs. 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 6*9880d681SAndroid Build Coastguard Workertarget triple = "wasm32-unknown-unknown" 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; Test va_start. 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker; TODO: Test va_start. 11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: start: 12*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .param i32, i32 13*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: __stack_pointer 14*9880d681SAndroid Build Coastguard Workerdefine void @start(i8** %ap, ...) { 15*9880d681SAndroid Build Coastguard Workerentry: 16*9880d681SAndroid Build Coastguard Worker %0 = bitcast i8** %ap to i8* 17*9880d681SAndroid Build Coastguard Worker; Store the second argument (the hidden vararg buffer pointer) into ap 18*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 0($0), $1 19*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %0) 20*9880d681SAndroid Build Coastguard Worker ret void 21*9880d681SAndroid Build Coastguard Worker} 22*9880d681SAndroid Build Coastguard Worker 23*9880d681SAndroid Build Coastguard Worker; Test va_end. 24*9880d681SAndroid Build Coastguard Worker 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: end: 26*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .param i32{{$}} 27*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: return{{$}} 28*9880d681SAndroid Build Coastguard Workerdefine void @end(i8** %ap) { 29*9880d681SAndroid Build Coastguard Workerentry: 30*9880d681SAndroid Build Coastguard Worker %0 = bitcast i8** %ap to i8* 31*9880d681SAndroid Build Coastguard Worker call void @llvm.va_end(i8* %0) 32*9880d681SAndroid Build Coastguard Worker ret void 33*9880d681SAndroid Build Coastguard Worker} 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker; Test va_copy. 36*9880d681SAndroid Build Coastguard Worker 37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: copy: 38*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .param i32, i32{{$}} 39*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.load $push0=, 0($1){{$}} 40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.store $drop=, 0($0), $pop0{{$}} 41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: return{{$}} 42*9880d681SAndroid Build Coastguard Workerdefine void @copy(i8** %ap, i8** %bp) { 43*9880d681SAndroid Build Coastguard Workerentry: 44*9880d681SAndroid Build Coastguard Worker %0 = bitcast i8** %ap to i8* 45*9880d681SAndroid Build Coastguard Worker %1 = bitcast i8** %bp to i8* 46*9880d681SAndroid Build Coastguard Worker call void @llvm.va_copy(i8* %0, i8* %1) 47*9880d681SAndroid Build Coastguard Worker ret void 48*9880d681SAndroid Build Coastguard Worker} 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker; Test va_arg with an i8 argument. 51*9880d681SAndroid Build Coastguard Worker 52*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: arg_i8: 53*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .param i32{{$}} 54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .result i32{{$}} 55*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .local i32{{$}} 56*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.load $push[[NUM0:[0-9]+]]=, 0($0){{$}} 57*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $1=, $pop[[NUM0]]{{$}} 58*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.const $push[[NUM2:[0-9]+]]=, 4{{$}} 59*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.add $push[[NUM3:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM2]]{{$}} 60*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.store $drop=, 0($0), $pop[[NUM3]]{{$}} 61*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.load $push[[NUM4:[0-9]+]]=, 0($1){{$}} 62*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: return $pop[[NUM4]]{{$}} 63*9880d681SAndroid Build Coastguard Workerdefine i8 @arg_i8(i8** %ap) { 64*9880d681SAndroid Build Coastguard Workerentry: 65*9880d681SAndroid Build Coastguard Worker %t = va_arg i8** %ap, i8 66*9880d681SAndroid Build Coastguard Worker ret i8 %t 67*9880d681SAndroid Build Coastguard Worker} 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker; Test va_arg with an i32 argument. 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: arg_i32: 72*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .param i32{{$}} 73*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .result i32{{$}} 74*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .local i32{{$}} 75*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.load $push[[NUM0:[0-9]+]]=, 0($0){{$}} 76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.const $push[[NUM1:[0-9]+]]=, 3{{$}} 77*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.add $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}} 78*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.const $push[[NUM3:[0-9]+]]=, -4{{$}} 79*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.and $push[[NUM4:[0-9]+]]=, $pop[[NUM2]], $pop[[NUM3]]{{$}} 80*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tee_local $push[[NUM5:[0-9]+]]=, $1=, $pop[[NUM4]]{{$}} 81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.const $push[[NUM6:[0-9]+]]=, 4{{$}} 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.add $push[[NUM7:[0-9]+]]=, $pop[[NUM5]], $pop[[NUM6]]{{$}} 83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.store $drop=, 0($0), $pop[[NUM7]]{{$}} 84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.load $push[[NUM8:[0-9]+]]=, 0($1){{$}} 85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: return $pop[[NUM8]]{{$}} 86*9880d681SAndroid Build Coastguard Workerdefine i32 @arg_i32(i8** %ap) { 87*9880d681SAndroid Build Coastguard Workerentry: 88*9880d681SAndroid Build Coastguard Worker %t = va_arg i8** %ap, i32 89*9880d681SAndroid Build Coastguard Worker ret i32 %t 90*9880d681SAndroid Build Coastguard Worker} 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; Test va_arg with an i128 argument. 93*9880d681SAndroid Build Coastguard Worker 94*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: arg_i128: 95*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .param i32, i32{{$}} 96*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: .local 97*9880d681SAndroid Build Coastguard Worker; CHECK: i32.and 98*9880d681SAndroid Build Coastguard Worker; CHECK: i64.load 99*9880d681SAndroid Build Coastguard Worker; CHECK: i64.load 100*9880d681SAndroid Build Coastguard Worker; CHECK: return{{$}} 101*9880d681SAndroid Build Coastguard Workerdefine i128 @arg_i128(i8** %ap) { 102*9880d681SAndroid Build Coastguard Workerentry: 103*9880d681SAndroid Build Coastguard Worker %t = va_arg i8** %ap, i128 104*9880d681SAndroid Build Coastguard Worker ret i128 %t 105*9880d681SAndroid Build Coastguard Worker} 106*9880d681SAndroid Build Coastguard Worker 107*9880d681SAndroid Build Coastguard Worker; Test a varargs call with no actual arguments. 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Workerdeclare void @callee(...) 110*9880d681SAndroid Build Coastguard Worker 111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_none: 112*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.const $push0=, 0 113*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call callee@FUNCTION, $pop0 114*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: return{{$}} 115*9880d681SAndroid Build Coastguard Workerdefine void @caller_none() { 116*9880d681SAndroid Build Coastguard Worker call void (...) @callee() 117*9880d681SAndroid Build Coastguard Worker ret void 118*9880d681SAndroid Build Coastguard Worker} 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Worker; Test a varargs call with some actual arguments. 121*9880d681SAndroid Build Coastguard Worker; Note that the store of 2.0 is converted to an i64 store; this optimization 122*9880d681SAndroid Build Coastguard Worker; is not needed on WebAssembly, but there isn't currently a convenient hook for 123*9880d681SAndroid Build Coastguard Worker; disabling it. 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: caller_some 126*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store 127*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store 128*9880d681SAndroid Build Coastguard Workerdefine void @caller_some() { 129*9880d681SAndroid Build Coastguard Worker call void (...) @callee(i32 0, double 2.0) 130*9880d681SAndroid Build Coastguard Worker ret void 131*9880d681SAndroid Build Coastguard Worker} 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker; Test a va_start call in a non-entry block 134*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: startbb: 135*9880d681SAndroid Build Coastguard Worker; CHECK: .param i32, i32, i32 136*9880d681SAndroid Build Coastguard Workerdefine void @startbb(i1 %cond, i8** %ap, ...) { 137*9880d681SAndroid Build Coastguard Workerentry: 138*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %bb0, label %bb1 139*9880d681SAndroid Build Coastguard Workerbb0: 140*9880d681SAndroid Build Coastguard Worker ret void 141*9880d681SAndroid Build Coastguard Workerbb1: 142*9880d681SAndroid Build Coastguard Worker %0 = bitcast i8** %ap to i8* 143*9880d681SAndroid Build Coastguard Worker; Store the second argument (the hidden vararg buffer pointer) into ap 144*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 0($1), $2 145*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %0) 146*9880d681SAndroid Build Coastguard Worker ret void 147*9880d681SAndroid Build Coastguard Worker} 148*9880d681SAndroid Build Coastguard Worker 149*9880d681SAndroid Build Coastguard Worker 150*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_start(i8*) 151*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_end(i8*) 152*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_copy(i8*, i8*) 153