Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ enum RuntimeLibcallSignature {
i64_func_i64,
f32_func_f32_f32,
f32_func_f32_i32,
f32_func_f32_iPTR,
f32_func_i64_i64,
f64_func_f64_f64,
f64_func_f64_i32,
f64_func_f64_iPTR,
f64_func_i64_i64,
i16_func_f32,
i16_func_f64,
Expand All @@ -69,6 +71,7 @@ enum RuntimeLibcallSignature {
i16_i16_func_i16_i16,
i32_i32_func_i32_i32,
i64_i64_func_i64_i64,
i64_i64_func_i64_i64_iPTR,
i64_i64_func_i64_i64_i64_i64,
i64_i64_func_i64_i64_i64_i64_iPTR,
i64_i64_i64_i64_func_i64_i64_i64_i64,
Expand Down Expand Up @@ -278,6 +281,9 @@ struct RuntimeLibcallSignatureTable {
Table[RTLIB::FREXP_F32] = f32_func_f32_i32;
Table[RTLIB::FREXP_F64] = f64_func_f64_i32;
Table[RTLIB::FREXP_F128] = i64_i64_func_i64_i64_i32;
Table[RTLIB::MODF_F32] = f32_func_f32_iPTR;
Table[RTLIB::MODF_F64] = f64_func_f64_iPTR;
Table[RTLIB::MODF_F128] = i64_i64_func_i64_i64_iPTR;

// Conversion
// All F80 and PPCF128 routines are unsupported.
Expand Down Expand Up @@ -628,6 +634,11 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
Params.push_back(wasm::ValType::F32);
Params.push_back(wasm::ValType::I32);
break;
case f32_func_f32_iPTR:
Rets.push_back(wasm::ValType::F32);
Params.push_back(wasm::ValType::F32);
Params.push_back(PtrTy);
break;
case f32_func_i64_i64:
Rets.push_back(wasm::ValType::F32);
Params.push_back(wasm::ValType::I64);
Expand All @@ -648,6 +659,11 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
Params.push_back(wasm::ValType::I64);
Params.push_back(wasm::ValType::I64);
break;
case f64_func_f64_iPTR:
Rets.push_back(wasm::ValType::F64);
Params.push_back(wasm::ValType::F64);
Params.push_back(PtrTy);
break;
case i16_func_f32:
Rets.push_back(wasm::ValType::I32);
Params.push_back(wasm::ValType::F32);
Expand Down Expand Up @@ -761,6 +777,17 @@ void WebAssembly::getLibcallSignature(const WebAssemblySubtarget &Subtarget,
Params.push_back(wasm::ValType::I64);
Params.push_back(wasm::ValType::I64);
break;
case i64_i64_func_i64_i64_iPTR:
if (WebAssembly::canLowerMultivalueReturn(&Subtarget)) {
Rets.push_back(wasm::ValType::I64);
Rets.push_back(wasm::ValType::I64);
} else {
Params.push_back(PtrTy);
}
Params.push_back(wasm::ValType::I64);
Params.push_back(wasm::ValType::I64);
Params.push_back(PtrTy);
break;
case i64_i64_func_i64_i64_i64_i64:
if (WebAssembly::canLowerMultivalueReturn(&Subtarget)) {
Rets.push_back(wasm::ValType::I64);
Expand Down
53 changes: 31 additions & 22 deletions llvm/test/CodeGen/WebAssembly/libcalls.ll
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ declare double @llvm.exp10.f64(double)
declare double @llvm.ldexp.f64.i32(double, i32)
declare {double, i32} @llvm.frexp.f64.i32(double)
declare i32 @llvm.lround(double)
declare {double, double} @llvm.modf.f64(double)

declare void @escape_value(i32)

Expand Down Expand Up @@ -203,38 +204,44 @@ define double @f64libcalls(double %x, double %y, i32 %z) {
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push12=, __stack_pointer
; CHECK-NEXT: i32.const $push13=, 16
; CHECK-NEXT: i32.sub $push19=, $pop12, $pop13
; CHECK-NEXT: local.tee $push18=, 3, $pop19
; CHECK-NEXT: global.set __stack_pointer, $pop18
; CHECK-NEXT: local.get $push23=, 0
; CHECK-NEXT: local.get $push20=, 0
; CHECK-NEXT: call $push0=, tan, $pop20
; CHECK-NEXT: i32.sub $push21=, $pop12, $pop13
; CHECK-NEXT: local.tee $push20=, 3, $pop21
; CHECK-NEXT: global.set __stack_pointer, $pop20
; CHECK-NEXT: local.get $push25=, 0
; CHECK-NEXT: local.get $push22=, 0
; CHECK-NEXT: call $push0=, tan, $pop22
; CHECK-NEXT: call $push1=, cos, $pop0
; CHECK-NEXT: call $push2=, log10, $pop1
; CHECK-NEXT: local.get $push21=, 1
; CHECK-NEXT: call $push3=, pow, $pop2, $pop21
; CHECK-NEXT: local.get $push22=, 2
; CHECK-NEXT: call $push4=, __powidf2, $pop3, $pop22
; CHECK-NEXT: local.get $push23=, 1
; CHECK-NEXT: call $push3=, pow, $pop2, $pop23
; CHECK-NEXT: local.get $push24=, 2
; CHECK-NEXT: call $push4=, __powidf2, $pop3, $pop24
; CHECK-NEXT: call $push5=, log, $pop4
; CHECK-NEXT: call $push6=, exp, $pop5
; CHECK-NEXT: call $push7=, exp10, $pop6
; CHECK-NEXT: call $push8=, cbrt, $pop7
; CHECK-NEXT: call $push9=, lround, $pop8
; CHECK-NEXT: call $push10=, ldexp, $pop23, $pop9
; CHECK-NEXT: local.get $push24=, 3
; CHECK-NEXT: i32.const $push16=, 12
; CHECK-NEXT: i32.add $push17=, $pop24, $pop16
; CHECK-NEXT: call $push25=, frexp, $pop10, $pop17
; CHECK-NEXT: local.set 0, $pop25
; CHECK-NEXT: call $push10=, ldexp, $pop25, $pop9
; CHECK-NEXT: local.get $push26=, 3
; CHECK-NEXT: i32.load $push11=, 12($pop26)
; CHECK-NEXT: i32.const $push18=, 4
; CHECK-NEXT: i32.add $push19=, $pop26, $pop18
; CHECK-NEXT: call $push27=, frexp, $pop10, $pop19
; CHECK-NEXT: local.set 0, $pop27
; CHECK-NEXT: local.get $push28=, 3
; CHECK-NEXT: i32.load $push11=, 4($pop28)
; CHECK-NEXT: call escape_value, $pop11
; CHECK-NEXT: local.get $push27=, 3
; CHECK-NEXT: local.get $push31=, 0
; CHECK-NEXT: local.get $push29=, 3
; CHECK-NEXT: i32.const $push16=, 8
; CHECK-NEXT: i32.add $push17=, $pop29, $pop16
; CHECK-NEXT: call $push30=, modf, $pop31, $pop17
; CHECK-NEXT: local.set 0, $pop30
; CHECK-NEXT: local.get $push32=, 3
; CHECK-NEXT: i32.const $push14=, 16
; CHECK-NEXT: i32.add $push15=, $pop27, $pop14
; CHECK-NEXT: i32.add $push15=, $pop32, $pop14
; CHECK-NEXT: global.set __stack_pointer, $pop15
; CHECK-NEXT: local.get $push28=, 0
; CHECK-NEXT: return $pop28
; CHECK-NEXT: local.get $push33=, 0
; CHECK-NEXT: return $pop33


%k = call double @llvm.tan.f64(double %x)
Expand All @@ -251,8 +258,10 @@ define double @f64libcalls(double %x, double %y, i32 %z) {
%result = call {double, i32} @llvm.frexp.f64.i32(double %j)
%result.0 = extractvalue { double, i32 } %result, 0
%result.1 = extractvalue { double, i32 } %result, 1
%resultModf = call {double, double} @llvm.modf.f64(double %result.0)
%resultModf.0 = extractvalue { double, double } %resultModf, 0
call void @escape_value(i32 %result.1)
ret double %result.0
ret double %resultModf.0
}

; fcmp ord and unord (RTLIB::O_F32 / RTLIB::UO_F32 etc) are a special case (see
Expand Down