From b17de645ea3b536ab3c12b3837fcca6ae25f0343 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 31 May 2018 22:27:24 +0000 Subject: [PATCH] [WebAssembly] Fix the signatures for the __mulo* libcalls. The __mulo* libcalls have an extra i32* to return the overflow value. Fixes PR37401. llvm-svn: 333706 --- .../WebAssemblyRuntimeLibcallSignatures.cpp | 34 +++++++++++++++++-- llvm/test/CodeGen/WebAssembly/muloti4.ll | 19 +++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/WebAssembly/muloti4.ll diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp index 283cecd4b9dc..e5180ad7f2e9 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp @@ -59,13 +59,16 @@ enum RuntimeLibcallSignature { i32_func_f32_f32, i32_func_f64_f64, i32_func_i32_i32, + i32_func_i32_i32_iPTR, i64_func_i64_i64, + i64_func_i64_i64_iPTR, i64_i64_func_f32, i64_i64_func_f64, i16_i16_func_i16_i16, i32_i32_func_i32_i32, i64_i64_func_i64_i64, i64_i64_func_i64_i64_i64_i64, + i64_i64_func_i64_i64_i64_i64_iPTR, i64_i64_i64_i64_func_i64_i64_i64_i64, i64_i64_func_i64_i64_i32, iPTR_func_iPTR_i32_iPTR, @@ -109,9 +112,9 @@ struct RuntimeLibcallSignatureTable { Table[RTLIB::MUL_I32] = i32_func_i32_i32; Table[RTLIB::MUL_I64] = i64_func_i64_i64; Table[RTLIB::MUL_I128] = i64_i64_func_i64_i64_i64_i64; - Table[RTLIB::MULO_I32] = i32_func_i32_i32; - Table[RTLIB::MULO_I64] = i64_func_i64_i64; - Table[RTLIB::MULO_I128] = i64_i64_func_i64_i64_i64_i64; + Table[RTLIB::MULO_I32] = i32_func_i32_i32_iPTR; + Table[RTLIB::MULO_I64] = i64_func_i64_i64_iPTR; + Table[RTLIB::MULO_I128] = i64_i64_func_i64_i64_i64_i64_iPTR; Table[RTLIB::SDIV_I8] = i8_func_i8_i8; Table[RTLIB::SDIV_I16] = i16_func_i16_i16; Table[RTLIB::SDIV_I32] = i32_func_i32_i32; @@ -627,11 +630,23 @@ void llvm::GetSignature(const WebAssemblySubtarget &Subtarget, Params.push_back(wasm::ValType::I32); Params.push_back(wasm::ValType::I32); break; + case i32_func_i32_i32_iPTR: + Rets.push_back(wasm::ValType::I32); + Params.push_back(wasm::ValType::I32); + Params.push_back(wasm::ValType::I32); + Params.push_back(iPTR); + break; case i64_func_i64_i64: Rets.push_back(wasm::ValType::I64); Params.push_back(wasm::ValType::I64); Params.push_back(wasm::ValType::I64); break; + case i64_func_i64_i64_iPTR: + Rets.push_back(wasm::ValType::I64); + Params.push_back(wasm::ValType::I64); + Params.push_back(wasm::ValType::I64); + Params.push_back(iPTR); + break; case i64_i64_func_f32: #if 0 // TODO: Enable this when wasm gets multiple-return-value support. Rets.push_back(wasm::ValType::I64); @@ -692,6 +707,19 @@ void llvm::GetSignature(const WebAssemblySubtarget &Subtarget, Params.push_back(wasm::ValType::I64); Params.push_back(wasm::ValType::I64); break; + case i64_i64_func_i64_i64_i64_i64_iPTR: +#if 0 // TODO: Enable this when wasm gets multiple-return-value support. + Rets.push_back(wasm::ValType::I64); + Rets.push_back(wasm::ValType::I64); +#else + Params.push_back(iPTR); +#endif + 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(iPTR); + break; case i64_i64_i64_i64_func_i64_i64_i64_i64: #if 0 // TODO: Enable this when wasm gets multiple-return-value support. Rets.push_back(wasm::ValType::I64); diff --git a/llvm/test/CodeGen/WebAssembly/muloti4.ll b/llvm/test/CodeGen/WebAssembly/muloti4.ll new file mode 100644 index 000000000000..1e4033428690 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/muloti4.ll @@ -0,0 +1,19 @@ +; RUN: llc -asm-verbose=false < %s | FileCheck %s + +; Test that 128-bit smul.with.overflow assembles as expected. + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +define i128 @call_muloti4(i128 %a, i128 %b) nounwind { +entry: + %smul = tail call { i128, i1 } @llvm.smul.with.overflow.i128(i128 %a, i128 %b) + %cmp = extractvalue { i128, i1 } %smul, 1 + %smul.result = extractvalue { i128, i1 } %smul, 0 + %X = select i1 %cmp, i128 %smul.result, i128 42 + ret i128 %X +} + +; CHECK: call __muloti4@FUNCTION, $pop{{[0-9]*}}, $pop{{[0-9]*}}, $pop{{[0-9]*}}, $pop{{[0-9]*}}, $pop{{[0-9]*}}, $pop{{[0-9]*}}{{$}} + +declare { i128, i1 } @llvm.smul.with.overflow.i128(i128, i128) nounwind readnone