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,14 @@ +; RUN: llc < %s -mattr=+reference-types | FileCheck %s + +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown" + +; CHECK-LABEL: reference-types +define void @reference-types() { + ret void +} + +; CHECK: .int8 1 +; CHECK-NEXT: .int8 43 +; CHECK-NEXT: .int8 15 +; CHECK-NEXT: .ascii "reference-types" diff --git a/llvm/test/CodeGen/WebAssembly/target-features.ll b/llvm/test/CodeGen/WebAssembly/target-features.ll --- a/llvm/test/CodeGen/WebAssembly/target-features.ll +++ b/llvm/test/CodeGen/WebAssembly/target-features.ll @@ -23,8 +23,13 @@ ret void } +define void @fn_reference_types() #2 { + ret void +} + attributes #0 = { "target-features"="+atomics" } attributes #1 = { "target-features"="+nontrapping-fptoint" } +attributes #2 = { "target-features"="+reference-types" } ; CHECK-LABEL: fn_atomics: @@ -51,29 +56,36 @@ ; CHECK-LABEL: .custom_section.target_features,"",@ -; +atomics, +nontrapping-fptoint -; ATTRS-NEXT: .int8 2 +; +atomics, +nontrapping-fptoint, +reference-types +; ATTRS-NEXT: .int8 3 ; ATTRS-NEXT: .int8 43 ; ATTRS-NEXT: .int8 7 ; ATTRS-NEXT: .ascii "atomics" ; ATTRS-NEXT: .int8 43 ; ATTRS-NEXT: .int8 19 ; ATTRS-NEXT: .ascii "nontrapping-fptoint" +; ATTRS-NEXT: .int8 43 +; ATTRS-NEXT: .int8 15 +; ATTRS-NEXT: .ascii "reference-types" -; +atomics, +simd128 -; SIMD128-NEXT: .int8 3 +; +atomics, +nontrapping-fptoint, +reference-types, +simd128 +; SIMD128-NEXT: .int8 4 ; SIMD128-NEXT: .int8 43 ; SIMD128-NEXT: .int8 7 ; SIMD128-NEXT: .ascii "atomics" ; SIMD128-NEXT: .int8 43 ; SIMD128-NEXT: .int8 19 -; SIMD128-NEXT: .ascii "nontrapping-fptoint" +; SIMD128-NEXT: .ascii "nontrapping-fptoint" +; SIMD128-NEXT: .int8 43 +; SIMD128-NEXT: .int8 15 +; SIMD128-NEXT: .ascii "reference-types" ; SIMD128-NEXT: .int8 43 ; SIMD128-NEXT: .int8 7 ; SIMD128-NEXT: .ascii "simd128" -; +atomics, +nontrapping-fptoint, +sign-ext, +simd128 -; BLEEDING-EDGE-NEXT: .int8 5 +; +atomics, +mutable-globals, +nontrapping-fptoint, +reference-types, +sign-ext, +; +simd128 +; BLEEDING-EDGE-NEXT: .int8 6 ; BLEEDING-EDGE-NEXT: .int8 43 ; BLEEDING-EDGE-NEXT: .int8 7 ; BLEEDING-EDGE-NEXT: .ascii "atomics" @@ -84,6 +96,9 @@ ; BLEEDING-EDGE-NEXT: .int8 19 ; BLEEDING-EDGE-NEXT: .ascii "nontrapping-fptoint" ; BLEEDING-EDGE-NEXT: .int8 43 +; BLEEDING-EDGE-NEXT: .int8 15 +; BLEEDING-EDGE-NEXT: .ascii "reference-types" +; BLEEDING-EDGE-NEXT: .int8 43 ; BLEEDING-EDGE-NEXT: .int8 8 ; BLEEDING-EDGE-NEXT: .ascii "sign-ext" ; BLEEDING-EDGE-NEXT: .int8 43