From 6f21a136755e5bce0c58a8f0fab56612821390ba Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 20 Sep 2018 22:04:44 +0000 Subject: [PATCH] [WebAssembly] Add V128 value type to binary format Summary: Adds the necessary support to lib/ObjectYAML and fixes SIMD calls to allow the tests to work. Also removes some dead code that would otherwise have to have been updated. Reviewers: aheejin, dschuff, sbc100 Subscribers: jgravelle-google, sunfish, llvm-commits Differential Revision: https://reviews.llvm.org/D52105 llvm-svn: 342689 --- llvm/include/llvm/BinaryFormat/Wasm.h | 2 + llvm/lib/ObjectYAML/WasmYAML.cpp | 1 + .../InstPrinter/WebAssemblyInstPrinter.cpp | 16 ------- .../InstPrinter/WebAssemblyInstPrinter.h | 1 - .../MCTargetDesc/WebAssemblyMCTargetDesc.cpp | 7 +++ .../lib/Target/WebAssembly/WebAssemblyInstrCall.td | 12 ++--- .../Target/WebAssembly/WebAssemblyMCInstLower.cpp | 2 + llvm/test/CodeGen/WebAssembly/call.ll | 25 ++++++++++- llvm/test/MC/WebAssembly/types.ll | 52 ++++++++++++++++++++++ 9 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 llvm/test/MC/WebAssembly/types.ll diff --git a/llvm/include/llvm/BinaryFormat/Wasm.h b/llvm/include/llvm/BinaryFormat/Wasm.h index 20bcb02..aca56af 100644 --- a/llvm/include/llvm/BinaryFormat/Wasm.h +++ b/llvm/include/llvm/BinaryFormat/Wasm.h @@ -191,6 +191,7 @@ enum : unsigned { WASM_TYPE_I64 = 0x7E, WASM_TYPE_F32 = 0x7D, WASM_TYPE_F64 = 0x7C, + WASM_TYPE_V128 = 0x7B, WASM_TYPE_ANYFUNC = 0x70, WASM_TYPE_EXCEPT_REF = 0x68, WASM_TYPE_FUNC = 0x60, @@ -225,6 +226,7 @@ enum class ValType { I64 = WASM_TYPE_I64, F32 = WASM_TYPE_F32, F64 = WASM_TYPE_F64, + V128 = WASM_TYPE_V128, EXCEPT_REF = WASM_TYPE_EXCEPT_REF, }; diff --git a/llvm/lib/ObjectYAML/WasmYAML.cpp b/llvm/lib/ObjectYAML/WasmYAML.cpp index 8de25dd..2e7a1d6 100644 --- a/llvm/lib/ObjectYAML/WasmYAML.cpp +++ b/llvm/lib/ObjectYAML/WasmYAML.cpp @@ -452,6 +452,7 @@ void ScalarEnumerationTraits::enumeration( ECase(I64); ECase(F32); ECase(F64); + ECase(V128); ECase(ANYFUNC); ECase(FUNC); ECase(NORESULT); diff --git a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp index ad0a045..045d4fb 100644 --- a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.cpp @@ -258,19 +258,3 @@ const char *llvm::WebAssembly::TypeToString(MVT Ty) { llvm_unreachable("unsupported type"); } } - -const char *llvm::WebAssembly::TypeToString(wasm::ValType Type) { - switch (Type) { - case wasm::ValType::I32: - return "i32"; - case wasm::ValType::I64: - return "i64"; - case wasm::ValType::F32: - return "f32"; - case wasm::ValType::F64: - return "f64"; - case wasm::ValType::EXCEPT_REF: - return "except_ref"; - } - llvm_unreachable("unsupported type"); -} diff --git a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h index f5b890a..2bb6dce 100644 --- a/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/InstPrinter/WebAssemblyInstPrinter.h @@ -51,7 +51,6 @@ public: namespace WebAssembly { const char *TypeToString(MVT Ty); -const char *TypeToString(wasm::ValType Type); } // end namespace WebAssembly diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp index 5547835..24dd523 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp @@ -133,6 +133,13 @@ wasm::ValType WebAssembly::toValType(const MVT &Ty) { return wasm::ValType::F32; case MVT::f64: return wasm::ValType::F64; + case MVT::v16i8: + case MVT::v8i16: + case MVT::v4i32: + case MVT::v2i64: + case MVT::v4f32: + case MVT::v2f64: + return wasm::ValType::V128; case MVT::ExceptRef: return wasm::ValType::EXCEPT_REF; default: diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td index 1de783a..3c9caa3 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td @@ -89,12 +89,12 @@ let Uses = [SP32, SP64], isCall = 1 in { defm "" : CALL; defm "" : CALL; defm "" : CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; - defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; + defm "" : SIMD_CALL; defm CALL_VOID : I<(outs), (ins function32_op:$callee, variable_ops), (outs), (ins function32_op:$callee), diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index db4fb5c..c55308b 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -149,6 +149,8 @@ static wasm::ValType getType(const TargetRegisterClass *RC) { return wasm::ValType::F32; if (RC == &WebAssembly::F64RegClass) return wasm::ValType::F64; + if (RC == &WebAssembly::V128RegClass) + return wasm::ValType::V128; llvm_unreachable("Unexpected register class"); } diff --git a/llvm/test/CodeGen/WebAssembly/call.ll b/llvm/test/CodeGen/WebAssembly/call.ll index 87bcc8a..9ed4341 100644 --- a/llvm/test/CodeGen/WebAssembly/call.ll +++ b/llvm/test/CodeGen/WebAssembly/call.ll @@ -1,5 +1,5 @@ -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-temporary-workarounds=false | FileCheck %s -; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -wasm-temporary-workarounds=false -mattr=+sign-ext,+simd128 | FileCheck %s +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-keep-registers -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false -mattr=+sign-ext,+simd128 | FileCheck %s ; Test that basic call operations assemble as expected. @@ -12,6 +12,7 @@ declare i32 @i32_binary(i32, i32) declare i64 @i64_nullary() declare float @float_nullary() declare double @double_nullary() +declare <16 x i8> @v128_nullary() declare void @void_nullary() ; CHECK-LABEL: call_i32_nullary: @@ -50,6 +51,15 @@ define double @call_double_nullary() { ret double %r } +; CHECK-LABEL: call_v128_nullary: +; CHECK-NEXT: .result v128{{$}} +; CHECK-NEXT: {{^}} v128.call $push[[NUM:[0-9]+]]=, v128_nullary@FUNCTION{{$}} +; CHECK-NEXT: return $pop[[NUM]]{{$}} +define <16 x i8> @call_v128_nullary() { + %r = call <16 x i8> @v128_nullary() + ret <16 x i8> %r +} + ; CHECK-LABEL: call_void_nullary: ; CHECK-NEXT: {{^}} call void_nullary@FUNCTION{{$}} ; CHECK-NEXT: return{{$}} @@ -102,6 +112,17 @@ define i32 @call_indirect_i32(i32 ()* %callee) { ret i32 %t } +; CHECK-LABEL: call_indirect_v128: +; CHECK-NEXT: .param i32{{$}} +; CHECK-NEXT: .result v128{{$}} +; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 0{{$}} +; CHECK-NEXT: {{^}} v128.call_indirect $push[[NUM:[0-9]+]]=, $pop[[L0]]{{$}} +; CHECK-NEXT: return $pop[[NUM]]{{$}} +define <16 x i8> @call_indirect_v128(<16 x i8> ()* %callee) { + %t = call <16 x i8> %callee() + ret <16 x i8> %t +} + ; CHECK-LABEL: call_indirect_arg: ; CHECK-NEXT: .param i32, i32{{$}} ; CHECK-NEXT: get_local $push[[L0:[0-9]+]]=, 1{{$}} diff --git a/llvm/test/MC/WebAssembly/types.ll b/llvm/test/MC/WebAssembly/types.ll new file mode 100644 index 0000000..1f85f85 --- /dev/null +++ b/llvm/test/MC/WebAssembly/types.ll @@ -0,0 +1,52 @@ +; RUN: llc -wasm-enable-unimplemented-simd -mattr=+sign-ext,+simd128 -filetype=obj %s -o - | obj2yaml | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +declare i32 @i32() +declare i64 @i64() +declare float @f32() +declare double @f64() +declare <16 x i8> @v16i8() +declare <8 x i16> @v8i16() +declare <4 x i32> @v4i32() +declare <2 x i64> @v2i64() +declare <4 x float> @v4f32() +declare <2 x double> @v2f64() + +define void @f1() { +entry: + %tmp1 = call i32 @i32() + %tmp2 = call i64 @i64() + %tmp3 = call float @f32() + %tmp4 = call double @f64() + %tmp5 = call <16 x i8> @v16i8() + %tmp6 = call <8 x i16> @v8i16() + %tmp7 = call <4 x i32> @v4i32() + %tmp8 = call <2 x i64> @v2i64() + %tmp9 = call <4 x float> @v4f32() + %tmp10 = call <2 x double> @v2f64() + ret void +} + +; CHECK-LABEL: - Type: TYPE +; CHECK-NEXT: Signatures: +; CHECK-NEXT: - Index: 0 +; CHECK-NEXT: ReturnType: NORESULT +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 1 +; CHECK-NEXT: ReturnType: I32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 2 +; CHECK-NEXT: ReturnType: I64 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 3 +; CHECK-NEXT: ReturnType: F32 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 4 +; CHECK-NEXT: ReturnType: F64 +; CHECK-NEXT: ParamTypes: +; CHECK-NEXT: - Index: 5 +; CHECK-NEXT: ReturnType: V128 +; CHECK-NEXT: ParamTypes: +; should be no additional types +; CHECK-NOT: ReturnType -- 2.7.4