From a3a82cfc834f98f8bc0693bb1eae515b94fd2936 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 23 May 2019 17:26:47 +0000 Subject: [PATCH] [WebAssembly] Add multivalue and tail-call target features Summary: These features will both be implemented soon, so I thought I would save time by adding the boilerplate for both of them at the same time. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D62047 llvm-svn: 361516 --- lib/Target/WebAssembly/WebAssembly.td | 11 ++++++++ .../WebAssembly/WebAssemblyInstrInfo.td | 14 +++++----- lib/Target/WebAssembly/WebAssemblySubtarget.h | 4 +++ test/CodeGen/WebAssembly/multivalue.ll | 28 +++++++++++++++++++ test/CodeGen/WebAssembly/tailcall.ll | 21 ++++++++++++++ 5 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 test/CodeGen/WebAssembly/multivalue.ll create mode 100644 test/CodeGen/WebAssembly/tailcall.ll diff --git a/lib/Target/WebAssembly/WebAssembly.td b/lib/Target/WebAssembly/WebAssembly.td index 813c7e652e4..b0b8a9b996a 100644 --- a/lib/Target/WebAssembly/WebAssembly.td +++ b/lib/Target/WebAssembly/WebAssembly.td @@ -33,6 +33,7 @@ def FeatureUnimplementedSIMD128 : def FeatureAtomics : SubtargetFeature<"atomics", "HasAtomics", "true", "Enable Atomics">; + def FeatureNontrappingFPToInt : SubtargetFeature<"nontrapping-fptoint", "HasNontrappingFPToInt", "true", @@ -43,6 +44,11 @@ def FeatureSignExt : "HasSignExt", "true", "Enable sign extension operators">; +def FeatureTailCall : + SubtargetFeature<"tail-call", + "HasTailCall", "true", + "Enable tail call instructions">; + def FeatureExceptionHandling : SubtargetFeature<"exception-handling", "HasExceptionHandling", "true", "Enable Wasm exception handling">; @@ -51,6 +57,11 @@ def FeatureBulkMemory : SubtargetFeature<"bulk-memory", "HasBulkMemory", "true", "Enable bulk memory operations">; +def FeatureMultivalue : + SubtargetFeature<"multivalue", + "HasMultivalue", "true", + "Enable multivalue blocks, instructions, and functions">; + def FeatureMutableGlobals : SubtargetFeature<"mutable-globals", "HasMutableGlobals", "true", "Enable mutable globals">; diff --git a/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/lib/Target/WebAssembly/WebAssemblyInstrInfo.td index 40a8f6089c2..a15bb2cce0b 100644 --- a/lib/Target/WebAssembly/WebAssemblyInstrInfo.td +++ b/lib/Target/WebAssembly/WebAssemblyInstrInfo.td @@ -34,6 +34,10 @@ def HasAtomics : Predicate<"Subtarget->hasAtomics()">, AssemblerPredicate<"FeatureAtomics", "atomics">; +def HasMultivalue : + Predicate<"Subtarget->hasMultivalue()">, + AssemblerPredicate<"FeatureMultivalue", "multivalue">; + def HasNontrappingFPToInt : Predicate<"Subtarget->hasNontrappingFPToInt()">, AssemblerPredicate<"FeatureNontrappingFPToInt", "nontrapping-fptoint">; @@ -46,18 +50,14 @@ def HasSignExt : Predicate<"Subtarget->hasSignExt()">, AssemblerPredicate<"FeatureSignExt", "sign-ext">; -def NotHasSignExt : - Predicate<"!Subtarget->hasSignExt()">, - AssemblerPredicate<"!FeatureSignExt", "sign-ext">; +def HasTailCall : + Predicate<"Subtarget->hasTailCall()">, + AssemblerPredicate<"FeatureTailCall", "tail-call">; def HasExceptionHandling : Predicate<"Subtarget->hasExceptionHandling()">, AssemblerPredicate<"FeatureExceptionHandling", "exception-handling">; -def NotHasExceptionHandling : - Predicate<"!Subtarget->hasExceptionHandling()">, - AssemblerPredicate<"!FeatureExceptionHandling", "exception-handling">; - def HasBulkMemory : Predicate<"Subtarget->hasBulkMemory()">, AssemblerPredicate<"FeatureBulkMemory", "bulk-memory">; diff --git a/lib/Target/WebAssembly/WebAssemblySubtarget.h b/lib/Target/WebAssembly/WebAssemblySubtarget.h index 22e11726f33..c5d9cf1eb95 100644 --- a/lib/Target/WebAssembly/WebAssemblySubtarget.h +++ b/lib/Target/WebAssembly/WebAssemblySubtarget.h @@ -44,7 +44,9 @@ class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo { bool HasSignExt = false; bool HasExceptionHandling = false; bool HasBulkMemory = false; + bool HasMultivalue = false; bool HasMutableGlobals = false; + bool HasTailCall = false; /// String name of used CPU. std::string CPUString; @@ -98,7 +100,9 @@ public: bool hasSignExt() const { return HasSignExt; } bool hasExceptionHandling() const { return HasExceptionHandling; } bool hasBulkMemory() const { return HasBulkMemory; } + bool hasMultivalue() const { return HasMultivalue; } bool hasMutableGlobals() const { return HasMutableGlobals; } + bool hasTailCall() const { return HasTailCall; } /// Parses features string setting specified subtarget options. Definition of /// function is auto generated by tblgen. diff --git a/test/CodeGen/WebAssembly/multivalue.ll b/test/CodeGen/WebAssembly/multivalue.ll new file mode 100644 index 00000000000..cbf8d4e0a0d --- /dev/null +++ b/test/CodeGen/WebAssembly/multivalue.ll @@ -0,0 +1,28 @@ +; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+multivalue | FileCheck %s + +; Test that the multivalue attribute is accepted +; TODO(tlively): implement multivalue + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +%pair = type { i32, i32 } +%packed_pair = type <{ i32, i32 }> + +; CHECK-LABEL: sret: +; CHECK-NEXT: sret (i32, i32, i32) -> () +define %pair @sret(%pair %p) { + ret %pair %p +} + +; CHECK-LABEL: packed_sret: +; CHECK-NEXT: packed_sret (i32, i32, i32) -> () +define %packed_pair @packed_sret(%packed_pair %p) { + ret %packed_pair %p +} + +; CHECK-LABEL: .section .custom_section.target_features +; CHECK-NEXT: .int8 1 +; CHECK-NEXT: .int8 43 +; CHECK-NEXT: .int8 10 +; CHECK-NEXT: .ascii "multivalue" diff --git a/test/CodeGen/WebAssembly/tailcall.ll b/test/CodeGen/WebAssembly/tailcall.ll new file mode 100644 index 00000000000..809d46ae4a4 --- /dev/null +++ b/test/CodeGen/WebAssembly/tailcall.ll @@ -0,0 +1,21 @@ +; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+tail-call | FileCheck %s + +; Test that the tail-call attribute is accepted +; TODO(tlively): implement tail call + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +; CHECK-LABEL: recursive_tail: +; CHECK: i32.call $push[[L0:[0-9]+]]=, recursive_tail{{$}} +; CHECK-NEXT: return $pop[[L0]]{{$}} +define i32 @recursive_tail() { + %v = tail call i32 @recursive_tail() + ret i32 %v +} + +; CHECK-LABEL: .section .custom_section.target_features +; CHECK-NEXT: .int8 1 +; CHECK-NEXT: .int8 43 +; CHECK-NEXT: .int8 9 +; CHECK-NEXT: .ascii "tail-call"