diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -38,6 +38,7 @@ bool HasMutableGlobals = false; bool HasMultivalue = false; bool HasTailCall = false; + bool HasReferenceTypes = false; public: explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &) diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -45,6 +45,7 @@ .Case("mutable-globals", HasMutableGlobals) .Case("multivalue", HasMultivalue) .Case("tail-call", HasTailCall) + .Case("reference-types", HasReferenceTypes) .Default(false); } @@ -80,6 +81,8 @@ Builder.defineMacro("__wasm_multivalue__"); if (HasTailCall) Builder.defineMacro("__wasm_tail_call__"); + if (HasReferenceTypes) + Builder.defineMacro("__wasm_reference_types__"); } void WebAssemblyTargetInfo::setSIMDLevel(llvm::StringMap &Features, @@ -126,6 +129,8 @@ Features["multivalue"] = true; if (HasTailCall) Features["tail-call"] = true; + if (HasReferenceTypes) + Features["reference-types"] = true; return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); } @@ -213,6 +218,14 @@ HasTailCall = false; continue; } + if (Feature == "+reference-types") { + HasReferenceTypes = true; + continue; + } + if (Feature == "-reference-types") { + HasReferenceTypes = false; + continue; + } Diags.Report(diag::err_opt_not_valid_with_opt) << Feature << "-target-feature"; diff --git a/clang/test/Preprocessor/wasm-target-features.c b/clang/test/Preprocessor/wasm-target-features.c --- a/clang/test/Preprocessor/wasm-target-features.c +++ b/clang/test/Preprocessor/wasm-target-features.c @@ -96,6 +96,15 @@ // RUN: | FileCheck %s -check-prefix=TAIL-CALL // // TAIL-CALL:#define __wasm_tail_call__ 1{{$}} +// +// RUN: %clang -E -dM %s -o - 2>&1 \ +// RUN: -target wasm32-unknown-unknown -mreference-types \ +// RUN: | FileCheck %s -check-prefix=REFERENCE-TYPES +// RUN: %clang -E -dM %s -o - 2>&1 \ +// RUN: -target wasm64-unknown-unknown -mreference-types \ +// RUN: | FileCheck %s -check-prefix=REFERENCE-TYPES +// +// REFERENCE-TYPES:#define __wasm_reference_types__ 1{{$}} // RUN: %clang -E -dM %s -o - 2>&1 \ // RUN: -target wasm32-unknown-unknown -mcpu=mvp \ @@ -114,6 +123,7 @@ // MVP-NOT:#define __wasm_mutable_globals__ // MVP-NOT:#define __wasm_multivalue__ // MVP-NOT:#define __wasm_tail_call__ +// MVP-NOT:#define __wasm_reference_types__ // RUN: %clang -E -dM %s -o - 2>&1 \ // RUN: -target wasm32-unknown-unknown -mcpu=bleeding-edge \ @@ -130,6 +140,7 @@ // BLEEDING-EDGE-NOT:#define __wasm_unimplemented_simd128__ 1{{$}} // BLEEDING-EDGE-NOT:#define __wasm_multivalue__ 1{{$}} // BLEEDING-EDGE-NOT:#define __wasm_tail_call__ 1{{$}} +// BLEEDING-EDGE-NOT:#define __wasm_reference_types__ 1{{$}} // RUN: %clang -E -dM %s -o - 2>&1 \ // RUN: -target wasm32-unknown-unknown -mcpu=bleeding-edge -mno-simd128 \ diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.td b/llvm/lib/Target/WebAssembly/WebAssembly.td --- a/llvm/lib/Target/WebAssembly/WebAssembly.td +++ b/llvm/lib/Target/WebAssembly/WebAssembly.td @@ -66,6 +66,10 @@ SubtargetFeature<"mutable-globals", "HasMutableGlobals", "true", "Enable mutable globals">; +def FeatureReferenceTypes : + SubtargetFeature<"reference-types", "HasReferenceTypes", "true", + "Enable reference types">; + //===----------------------------------------------------------------------===// // Architectures. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td @@ -62,6 +62,10 @@ Predicate<"Subtarget->hasBulkMemory()">, AssemblerPredicate<"FeatureBulkMemory", "bulk-memory">; +def HasReferenceTypes : + Predicate<"Subtarget->hasReferenceTypes()">, + AssemblerPredicate<"FeatureReferenceTypes", "reference-types">; + //===----------------------------------------------------------------------===// // WebAssembly-specific DAG Node Types. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h --- a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h @@ -47,6 +47,7 @@ bool HasMultivalue = false; bool HasMutableGlobals = false; bool HasTailCall = false; + bool HasReferenceTypes = false; /// String name of used CPU. std::string CPUString; @@ -104,6 +105,7 @@ bool hasMultivalue() const { return HasMultivalue; } bool hasMutableGlobals() const { return HasMutableGlobals; } bool hasTailCall() const { return HasTailCall; } + bool hasReferenceTypes() const { return HasReferenceTypes; } /// Parses features string setting specified subtarget options. Definition of /// function is auto generated by tblgen. diff --git a/llvm/test/CodeGen/WebAssembly/reference-types.ll b/llvm/test/CodeGen/WebAssembly/reference-types.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/reference-types.ll @@ -0,0 +1,12 @@ +; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -mattr=+reference-types | FileCheck %s + +; This currently only tests if the command line argument for reference types +; feature is accepted by llc. + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +; CHECK-LABEL: dummy +define void @dummy() { + ret void +}