From 1e0cfd69bbb7c83fcd2ca9bf6d8fb52b0ea80073 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 22 May 2018 04:58:36 +0000 Subject: [PATCH] [WebAssembly] Fix fast-isel lowering illegal argument and return types. For both argument and return types, promote illegal types like i24 to i32, and if a type can't be easily promoted, clear out the signature before bailing out, so avoid leaving it in a partially complete state. Fixes PR37546. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332947 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../WebAssembly/WebAssemblyFastISel.cpp | 18 +++++++--- .../WebAssemblyMachineFunctionInfo.h | 2 ++ test/CodeGen/WebAssembly/fast-isel-i24.ll | 12 +++++++ test/CodeGen/WebAssembly/fast-isel-i256.ll | 33 +++++++++++++++++++ 4 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/WebAssembly/fast-isel-i256.ll diff --git a/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index 7165fe8b0470..a34dfc74f70c 100644 --- a/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -695,14 +695,22 @@ bool WebAssemblyFastISel::fastLowerArguments() { MRI.addLiveIn(WebAssembly::ARGUMENTS); auto *MFI = MF->getInfo(); - for (auto const &Arg : F->args()) - MFI->addParam(getLegalType(getSimpleType(Arg.getType()))); + for (auto const &Arg : F->args()) { + MVT::SimpleValueType ArgTy = getLegalType(getSimpleType(Arg.getType())); + if (ArgTy == MVT::INVALID_SIMPLE_VALUE_TYPE) { + MFI->clearParamsAndResults(); + return false; + } + MFI->addParam(ArgTy); + } if (!F->getReturnType()->isVoidTy()) { - MVT::SimpleValueType RetTy = getSimpleType(F->getReturnType()); - if (RetTy == MVT::INVALID_SIMPLE_VALUE_TYPE) + MVT::SimpleValueType RetTy = getLegalType(getSimpleType(F->getReturnType())); + if (RetTy == MVT::INVALID_SIMPLE_VALUE_TYPE) { + MFI->clearParamsAndResults(); return false; - MFI->addResult(getLegalType(RetTy)); + } + MFI->addResult(RetTy); } return true; diff --git a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h index 1fcbb7791d4e..9ecc0e3a9b28 100644 --- a/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h +++ b/lib/Target/WebAssembly/WebAssemblyMachineFunctionInfo.h @@ -60,6 +60,8 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo { void addResult(MVT VT) { Results.push_back(VT); } const std::vector &getResults() const { return Results; } + void clearParamsAndResults() { Params.clear(); Results.clear(); } + void setNumLocals(size_t NumLocals) { Locals.resize(NumLocals, MVT::i32); } void setLocal(size_t i, MVT VT) { Locals[i] = VT; } void addLocal(MVT VT) { Locals.push_back(VT); } diff --git a/test/CodeGen/WebAssembly/fast-isel-i24.ll b/test/CodeGen/WebAssembly/fast-isel-i24.ll index d3823f9869bf..be9a5dd96d98 100644 --- a/test/CodeGen/WebAssembly/fast-isel-i24.ll +++ b/test/CodeGen/WebAssembly/fast-isel-i24.ll @@ -1,16 +1,28 @@ ; RUN: llc < %s -O0 ; PR36564 +; PR37546 ; Test that fast-isel properly copes with i24 arguments and return types. target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-unknown-wasm" +; CHECK-LABEL: add: +; CHECK-NEXT: .param i32, i32{{$}} +; CHECK-NEXT: .result i32{{$}} +; CHECK-NEXT: get_local $push2=, 0{{$}} +; CHECK-NEXT: get_local $push1=, 1{{$}} +; CHECK-NEXT: i32.add $push0=, $pop2, $pop1{{$}} +; CHECK-NEXT: end_function define i24 @add(i24 %x, i24 %y) { %z = add i24 %x, %y ret i24 %z } +; CHECK-LABEL: return_zero: +; CHECK-NEXT: .result i32{{$}} +; CHECK-NEXT: i32.const $push0=, 0{{$}} +; CHECK-NEXT: end_function define i24 @return_zero() { ret i24 0 } diff --git a/test/CodeGen/WebAssembly/fast-isel-i256.ll b/test/CodeGen/WebAssembly/fast-isel-i256.ll new file mode 100644 index 000000000000..a30ea353701a --- /dev/null +++ b/test/CodeGen/WebAssembly/fast-isel-i256.ll @@ -0,0 +1,33 @@ +; RUN: llc < %s -O0 +; PR36564 +; PR37546 + +; Test that fast-isel properly copes with i256 arguments and return types. + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +; CHECK-LABEL: add: +; CHECK-NEXT: .param i32, i64, i64, i64, i64, i64, i64, i64, i64{{$}} +; CHECK-NOT: .result +; CHECK: end_function +define i256 @add(i256 %x, i256 %y) { + %z = add i256 %x, %y + ret i256 %z +} + +; CHECK-LABEL: return_zero: +; CHECK-NEXT: .param i32{{$}} +; CHECK-NOT: .result +; CHECK: end_function +define i256 @return_zero() { + ret i256 0 +} + +; CHECK-LABEL: return_zero_with_params: +; CHECK-NEXT: .param i32, f32{{$}} +; CHECK-NOT: .result +; CHECK: end_function +define i256 @return_zero_with_params(float %x) { + ret i256 0 +}