diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp --- a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp @@ -62,6 +62,8 @@ i32_func_i32_i32_iPTR, i64_func_i64_i64, i64_func_i64_i64_iPTR, + i64_i64_func_i32, + i64_i64_func_i64, i64_i64_func_f32, i64_i64_func_f64, i16_i16_func_i16_i16, @@ -71,20 +73,13 @@ i64_i64_func_i64_i64_i64_i64_iPTR, i64_i64_i64_i64_func_i64_i64_i64_i64, i64_i64_func_i64_i64_i32, + i64_i64_func_i64_i64_i64_i64_i64_i64, iPTR_func_i32, iPTR_func_iPTR_i32_iPTR, iPTR_func_iPTR_iPTR_iPTR, f32_func_f32_f32_f32, f64_func_f64_f64_f64, func_i64_i64_iPTR_iPTR, - func_iPTR_f32, - func_iPTR_f64, - func_iPTR_i32, - func_iPTR_i64, - func_iPTR_i64_i64, - func_iPTR_i64_i64_i32, - func_iPTR_i64_i64_i64_i64, - func_iPTR_i64_i64_i64_i64_i64_i64, i32_func_i64_i64, i32_func_i64_i64_i64_i64, iPTR_func_f32, @@ -156,73 +151,73 @@ // All F80 and PPCF128 routines are unsupported. Table[RTLIB::ADD_F32] = f32_func_f32_f32; Table[RTLIB::ADD_F64] = f64_func_f64_f64; - Table[RTLIB::ADD_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::ADD_F128] = i64_i64_func_i64_i64_i64_i64; Table[RTLIB::SUB_F32] = f32_func_f32_f32; Table[RTLIB::SUB_F64] = f64_func_f64_f64; - Table[RTLIB::SUB_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::SUB_F128] = i64_i64_func_i64_i64_i64_i64; Table[RTLIB::MUL_F32] = f32_func_f32_f32; Table[RTLIB::MUL_F64] = f64_func_f64_f64; - Table[RTLIB::MUL_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::MUL_F128] = i64_i64_func_i64_i64_i64_i64; Table[RTLIB::DIV_F32] = f32_func_f32_f32; Table[RTLIB::DIV_F64] = f64_func_f64_f64; - Table[RTLIB::DIV_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::DIV_F128] = i64_i64_func_i64_i64_i64_i64; Table[RTLIB::REM_F32] = f32_func_f32_f32; Table[RTLIB::REM_F64] = f64_func_f64_f64; - Table[RTLIB::REM_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::REM_F128] = i64_i64_func_i64_i64_i64_i64; Table[RTLIB::FMA_F32] = f32_func_f32_f32_f32; Table[RTLIB::FMA_F64] = f64_func_f64_f64_f64; - Table[RTLIB::FMA_F128] = func_iPTR_i64_i64_i64_i64_i64_i64; + Table[RTLIB::FMA_F128] = i64_i64_func_i64_i64_i64_i64_i64_i64; Table[RTLIB::POWI_F32] = f32_func_f32_i32; Table[RTLIB::POWI_F64] = f64_func_f64_i32; - Table[RTLIB::POWI_F128] = func_iPTR_i64_i64_i32; + Table[RTLIB::POWI_F128] = i64_i64_func_i64_i64_i32; Table[RTLIB::SQRT_F32] = f32_func_f32; Table[RTLIB::SQRT_F64] = f64_func_f64; - Table[RTLIB::SQRT_F128] = func_iPTR_i64_i64; + Table[RTLIB::SQRT_F128] = i64_i64_func_i64_i64; Table[RTLIB::CBRT_F32] = f32_func_f32; Table[RTLIB::CBRT_F64] = f64_func_f64; - Table[RTLIB::CBRT_F128] = func_iPTR_i64_i64; + Table[RTLIB::CBRT_F128] = i64_i64_func_i64_i64; Table[RTLIB::LOG_F32] = f32_func_f32; Table[RTLIB::LOG_F64] = f64_func_f64; - Table[RTLIB::LOG_F128] = func_iPTR_i64_i64; + Table[RTLIB::LOG_F128] = i64_i64_func_i64_i64; Table[RTLIB::LOG2_F32] = f32_func_f32; Table[RTLIB::LOG2_F64] = f64_func_f64; - Table[RTLIB::LOG2_F128] = func_iPTR_i64_i64; + Table[RTLIB::LOG2_F128] = i64_i64_func_i64_i64; Table[RTLIB::LOG10_F32] = f32_func_f32; Table[RTLIB::LOG10_F64] = f64_func_f64; - Table[RTLIB::LOG10_F128] = func_iPTR_i64_i64; + Table[RTLIB::LOG10_F128] = i64_i64_func_i64_i64; Table[RTLIB::EXP_F32] = f32_func_f32; Table[RTLIB::EXP_F64] = f64_func_f64; - Table[RTLIB::EXP_F128] = func_iPTR_i64_i64; + Table[RTLIB::EXP_F128] = i64_i64_func_i64_i64; Table[RTLIB::EXP2_F32] = f32_func_f32; Table[RTLIB::EXP2_F64] = f64_func_f64; - Table[RTLIB::EXP2_F128] = func_iPTR_i64_i64; + Table[RTLIB::EXP2_F128] = i64_i64_func_i64_i64; Table[RTLIB::SIN_F32] = f32_func_f32; Table[RTLIB::SIN_F64] = f64_func_f64; - Table[RTLIB::SIN_F128] = func_iPTR_i64_i64; + Table[RTLIB::SIN_F128] = i64_i64_func_i64_i64; Table[RTLIB::COS_F32] = f32_func_f32; Table[RTLIB::COS_F64] = f64_func_f64; - Table[RTLIB::COS_F128] = func_iPTR_i64_i64; + Table[RTLIB::COS_F128] = i64_i64_func_i64_i64; Table[RTLIB::SINCOS_F32] = func_f32_iPTR_iPTR; Table[RTLIB::SINCOS_F64] = func_f64_iPTR_iPTR; Table[RTLIB::SINCOS_F128] = func_i64_i64_iPTR_iPTR; Table[RTLIB::POW_F32] = f32_func_f32_f32; Table[RTLIB::POW_F64] = f64_func_f64_f64; - Table[RTLIB::POW_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::POW_F128] = i64_i64_func_i64_i64_i64_i64; Table[RTLIB::CEIL_F32] = f32_func_f32; Table[RTLIB::CEIL_F64] = f64_func_f64; - Table[RTLIB::CEIL_F128] = func_iPTR_i64_i64; + Table[RTLIB::CEIL_F128] = i64_i64_func_i64_i64; Table[RTLIB::TRUNC_F32] = f32_func_f32; Table[RTLIB::TRUNC_F64] = f64_func_f64; - Table[RTLIB::TRUNC_F128] = func_iPTR_i64_i64; + Table[RTLIB::TRUNC_F128] = i64_i64_func_i64_i64; Table[RTLIB::RINT_F32] = f32_func_f32; Table[RTLIB::RINT_F64] = f64_func_f64; - Table[RTLIB::RINT_F128] = func_iPTR_i64_i64; + Table[RTLIB::RINT_F128] = i64_i64_func_i64_i64; Table[RTLIB::NEARBYINT_F32] = f32_func_f32; Table[RTLIB::NEARBYINT_F64] = f64_func_f64; - Table[RTLIB::NEARBYINT_F128] = func_iPTR_i64_i64; + Table[RTLIB::NEARBYINT_F128] = i64_i64_func_i64_i64; Table[RTLIB::ROUND_F32] = f32_func_f32; Table[RTLIB::ROUND_F64] = f64_func_f64; - Table[RTLIB::ROUND_F128] = func_iPTR_i64_i64; + Table[RTLIB::ROUND_F128] = i64_i64_func_i64_i64; Table[RTLIB::LROUND_F32] = iPTR_func_f32; Table[RTLIB::LROUND_F64] = iPTR_func_f64; Table[RTLIB::LROUND_F128] = iPTR_func_i64_i64; @@ -237,21 +232,21 @@ Table[RTLIB::LLRINT_F128] = i64_func_i64_i64; Table[RTLIB::FLOOR_F32] = f32_func_f32; Table[RTLIB::FLOOR_F64] = f64_func_f64; - Table[RTLIB::FLOOR_F128] = func_iPTR_i64_i64; + Table[RTLIB::FLOOR_F128] = i64_i64_func_i64_i64; Table[RTLIB::COPYSIGN_F32] = f32_func_f32_f32; Table[RTLIB::COPYSIGN_F64] = f64_func_f64_f64; - Table[RTLIB::COPYSIGN_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::COPYSIGN_F128] = i64_i64_func_i64_i64_i64_i64; Table[RTLIB::FMIN_F32] = f32_func_f32_f32; Table[RTLIB::FMIN_F64] = f64_func_f64_f64; - Table[RTLIB::FMIN_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::FMIN_F128] = i64_i64_func_i64_i64_i64_i64; Table[RTLIB::FMAX_F32] = f32_func_f32_f32; Table[RTLIB::FMAX_F64] = f64_func_f64_f64; - Table[RTLIB::FMAX_F128] = func_iPTR_i64_i64_i64_i64; + Table[RTLIB::FMAX_F128] = i64_i64_func_i64_i64_i64_i64; // Conversion // All F80 and PPCF128 routines are unsupported. - Table[RTLIB::FPEXT_F64_F128] = func_iPTR_f64; - Table[RTLIB::FPEXT_F32_F128] = func_iPTR_f32; + Table[RTLIB::FPEXT_F64_F128] = i64_i64_func_f64; + Table[RTLIB::FPEXT_F32_F128] = i64_i64_func_f32; Table[RTLIB::FPEXT_F32_F64] = f64_func_f32; Table[RTLIB::FPEXT_F16_F32] = f32_func_i16; Table[RTLIB::FPROUND_F32_F16] = i16_func_f32; @@ -280,22 +275,22 @@ Table[RTLIB::FPTOUINT_F128_I128] = i64_i64_func_i64_i64; Table[RTLIB::SINTTOFP_I32_F32] = f32_func_i32; Table[RTLIB::SINTTOFP_I32_F64] = f64_func_i32; - Table[RTLIB::SINTTOFP_I32_F128] = func_iPTR_i32; + Table[RTLIB::SINTTOFP_I32_F128] = i64_i64_func_i32; Table[RTLIB::SINTTOFP_I64_F32] = f32_func_i64; Table[RTLIB::SINTTOFP_I64_F64] = f64_func_i64; - Table[RTLIB::SINTTOFP_I64_F128] = func_iPTR_i64; + Table[RTLIB::SINTTOFP_I64_F128] = i64_i64_func_i64; Table[RTLIB::SINTTOFP_I128_F32] = f32_func_i64_i64; Table[RTLIB::SINTTOFP_I128_F64] = f64_func_i64_i64; - Table[RTLIB::SINTTOFP_I128_F128] = func_iPTR_i64_i64; + Table[RTLIB::SINTTOFP_I128_F128] = i64_i64_func_i64_i64; Table[RTLIB::UINTTOFP_I32_F32] = f32_func_i32; Table[RTLIB::UINTTOFP_I32_F64] = f64_func_i64; - Table[RTLIB::UINTTOFP_I32_F128] = func_iPTR_i32; + Table[RTLIB::UINTTOFP_I32_F128] = i64_i64_func_i32; Table[RTLIB::UINTTOFP_I64_F32] = f32_func_i64; Table[RTLIB::UINTTOFP_I64_F64] = f64_func_i64; - Table[RTLIB::UINTTOFP_I64_F128] = func_iPTR_i64; + Table[RTLIB::UINTTOFP_I64_F128] = i64_i64_func_i64; Table[RTLIB::UINTTOFP_I128_F32] = f32_func_i64_i64; Table[RTLIB::UINTTOFP_I128_F64] = f64_func_i64_i64; - Table[RTLIB::UINTTOFP_I128_F128] = func_iPTR_i64_i64; + Table[RTLIB::UINTTOFP_I128_F128] = i64_i64_func_i64_i64; // Comparison // ALl F80 and PPCF128 routines are unsupported. @@ -820,49 +815,6 @@ Params.push_back(PtrTy); Params.push_back(PtrTy); break; - case func_iPTR_f32: - Params.push_back(PtrTy); - Params.push_back(wasm::ValType::F32); - break; - case func_iPTR_f64: - Params.push_back(PtrTy); - Params.push_back(wasm::ValType::F64); - break; - case func_iPTR_i32: - Params.push_back(PtrTy); - Params.push_back(wasm::ValType::I32); - break; - case func_iPTR_i64: - Params.push_back(PtrTy); - Params.push_back(wasm::ValType::I64); - break; - case func_iPTR_i64_i64: - Params.push_back(PtrTy); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - break; - case func_iPTR_i64_i64_i32: - Params.push_back(PtrTy); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I32); - break; - case func_iPTR_i64_i64_i64_i64: - Params.push_back(PtrTy); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - break; - case func_iPTR_i64_i64_i64_i64_i64_i64: - Params.push_back(PtrTy); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - Params.push_back(wasm::ValType::I64); - break; case i32_func_i64_i64: Rets.push_back(wasm::ValType::I32); Params.push_back(wasm::ValType::I64); @@ -888,6 +840,38 @@ Params.push_back(wasm::ValType::I64); Params.push_back(wasm::ValType::I64); break; + case i64_i64_func_i64_i64_i64_i64_i64_i64: + if (Subtarget.hasMultivalue()) { + 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(wasm::ValType::I64); + Params.push_back(wasm::ValType::I64); + Params.push_back(wasm::ValType::I64); + Params.push_back(wasm::ValType::I64); + break; + case i64_i64_func_i32: + if (Subtarget.hasMultivalue()) { + Rets.push_back(wasm::ValType::I64); + Rets.push_back(wasm::ValType::I64); + } else { + Params.push_back(PtrTy); + } + Params.push_back(wasm::ValType::I32); + break; + case i64_i64_func_i64: + if (Subtarget.hasMultivalue()) { + Rets.push_back(wasm::ValType::I64); + Rets.push_back(wasm::ValType::I64); + } else { + Params.push_back(PtrTy); + } + Params.push_back(wasm::ValType::I64); + break; case unsupported: llvm_unreachable("unsupported runtime library signature"); } diff --git a/llvm/test/CodeGen/WebAssembly/multivalue_libcall.ll b/llvm/test/CodeGen/WebAssembly/multivalue_libcall.ll --- a/llvm/test/CodeGen/WebAssembly/multivalue_libcall.ll +++ b/llvm/test/CodeGen/WebAssembly/multivalue_libcall.ll @@ -6,58 +6,93 @@ target triple = "wasm32-unknown-unknown" -@c = global i128 0, align 16 - -define void @multivalue_sdiv(i128 noundef %a, i128 noundef %b) #0 { +define i128 @multivalue_sdiv(i128 %a, i128 %b) { ; MULTIVALUE-LABEL: multivalue_sdiv: -; MULTIVALUE: .functype multivalue_sdiv (i64, i64, i64, i64) -> () +; MULTIVALUE: .functype multivalue_sdiv (i64, i64, i64, i64) -> (i64, i64) ; MULTIVALUE-NEXT: # %bb.0: ; MULTIVALUE-NEXT: local.get 0 ; MULTIVALUE-NEXT: local.get 1 ; MULTIVALUE-NEXT: local.get 2 ; MULTIVALUE-NEXT: local.get 3 ; MULTIVALUE-NEXT: call __divti3 -; MULTIVALUE-NEXT: local.set 2 -; MULTIVALUE-NEXT: local.set 3 -; MULTIVALUE-NEXT: i32.const c -; MULTIVALUE-NEXT: local.get 2 -; MULTIVALUE-NEXT: i64.store 8 -; MULTIVALUE-NEXT: i32.const 0 -; MULTIVALUE-NEXT: local.get 3 -; MULTIVALUE-NEXT: i64.store c ; MULTIVALUE-NEXT: # fallthrough-return ; ; NO_MULTIVALUE-LABEL: multivalue_sdiv: -; NO_MULTIVALUE: .functype multivalue_sdiv (i64, i64, i64, i64) -> () +; NO_MULTIVALUE: .functype multivalue_sdiv (i32, i64, i64, i64, i64) -> () ; NO_MULTIVALUE-NEXT: .local i32 ; NO_MULTIVALUE-NEXT: # %bb.0: ; NO_MULTIVALUE-NEXT: global.get __stack_pointer ; NO_MULTIVALUE-NEXT: i32.const 16 ; NO_MULTIVALUE-NEXT: i32.sub -; NO_MULTIVALUE-NEXT: local.tee 4 +; NO_MULTIVALUE-NEXT: local.tee 5 ; NO_MULTIVALUE-NEXT: global.set __stack_pointer +; NO_MULTIVALUE-NEXT: local.get 5 +; NO_MULTIVALUE-NEXT: local.get 1 +; NO_MULTIVALUE-NEXT: local.get 2 +; NO_MULTIVALUE-NEXT: local.get 3 ; NO_MULTIVALUE-NEXT: local.get 4 +; NO_MULTIVALUE-NEXT: call __divti3 +; NO_MULTIVALUE-NEXT: local.get 0 +; NO_MULTIVALUE-NEXT: local.get 5 +; NO_MULTIVALUE-NEXT: i32.const 8 +; NO_MULTIVALUE-NEXT: i32.add +; NO_MULTIVALUE-NEXT: i64.load 0 +; NO_MULTIVALUE-NEXT: i64.store 8 ; NO_MULTIVALUE-NEXT: local.get 0 +; NO_MULTIVALUE-NEXT: local.get 5 +; NO_MULTIVALUE-NEXT: i64.load 0 +; NO_MULTIVALUE-NEXT: i64.store 0 +; NO_MULTIVALUE-NEXT: local.get 5 +; NO_MULTIVALUE-NEXT: i32.const 16 +; NO_MULTIVALUE-NEXT: i32.add +; NO_MULTIVALUE-NEXT: global.set __stack_pointer +; NO_MULTIVALUE-NEXT: # fallthrough-return + %div = sdiv i128 %a, %b + ret i128 %div +} + + +define fp128 @multivalue_fsub(fp128 %a, fp128 %b) { +; MULTIVALUE-LABEL: multivalue_fsub: +; MULTIVALUE: .functype multivalue_fsub (i64, i64, i64, i64) -> (i64, i64) +; MULTIVALUE-NEXT: # %bb.0: +; MULTIVALUE-NEXT: local.get 0 +; MULTIVALUE-NEXT: local.get 1 +; MULTIVALUE-NEXT: local.get 2 +; MULTIVALUE-NEXT: local.get 3 +; MULTIVALUE-NEXT: call __subtf3 +; MULTIVALUE-NEXT: # fallthrough-return +; +; NO_MULTIVALUE-LABEL: multivalue_fsub: +; NO_MULTIVALUE: .functype multivalue_fsub (i32, i64, i64, i64, i64) -> () +; NO_MULTIVALUE-NEXT: .local i32 +; NO_MULTIVALUE-NEXT: # %bb.0: +; NO_MULTIVALUE-NEXT: global.get __stack_pointer +; NO_MULTIVALUE-NEXT: i32.const 16 +; NO_MULTIVALUE-NEXT: i32.sub +; NO_MULTIVALUE-NEXT: local.tee 5 +; NO_MULTIVALUE-NEXT: global.set __stack_pointer +; NO_MULTIVALUE-NEXT: local.get 5 ; NO_MULTIVALUE-NEXT: local.get 1 ; NO_MULTIVALUE-NEXT: local.get 2 ; NO_MULTIVALUE-NEXT: local.get 3 -; NO_MULTIVALUE-NEXT: call __divti3 -; NO_MULTIVALUE-NEXT: i32.const c ; NO_MULTIVALUE-NEXT: local.get 4 +; NO_MULTIVALUE-NEXT: call __subtf3 +; NO_MULTIVALUE-NEXT: local.get 0 +; NO_MULTIVALUE-NEXT: local.get 5 ; NO_MULTIVALUE-NEXT: i32.const 8 ; NO_MULTIVALUE-NEXT: i32.add ; NO_MULTIVALUE-NEXT: i64.load 0 ; NO_MULTIVALUE-NEXT: i64.store 8 -; NO_MULTIVALUE-NEXT: i32.const 0 -; NO_MULTIVALUE-NEXT: local.get 4 +; NO_MULTIVALUE-NEXT: local.get 0 +; NO_MULTIVALUE-NEXT: local.get 5 ; NO_MULTIVALUE-NEXT: i64.load 0 -; NO_MULTIVALUE-NEXT: i64.store c -; NO_MULTIVALUE-NEXT: local.get 4 +; NO_MULTIVALUE-NEXT: i64.store 0 +; NO_MULTIVALUE-NEXT: local.get 5 ; NO_MULTIVALUE-NEXT: i32.const 16 ; NO_MULTIVALUE-NEXT: i32.add ; NO_MULTIVALUE-NEXT: global.set __stack_pointer ; NO_MULTIVALUE-NEXT: # fallthrough-return - %div = sdiv i128 %a, %b - store i128 %div, ptr @c, align 16 - ret void + %sub = fsub fp128 %a, %b + ret fp128 %sub }