loladiro updated this revision to Diff 214467.
loladiro added a comment.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Accidentally only pushed half the changes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66035/new/

https://reviews.llvm.org/D66035

Files:
  clang/lib/Basic/Targets/WebAssembly.h
  lld/wasm/WriterUtils.cpp
  llvm/include/llvm/BinaryFormat/Wasm.h
  llvm/include/llvm/BinaryFormat/WasmRelocs.def
  llvm/include/llvm/CodeGen/TargetLowering.h
  llvm/include/llvm/CodeGen/ValueTypes.td
  llvm/include/llvm/MC/MCExpr.h
  llvm/include/llvm/MC/MCSymbolWasm.h
  llvm/include/llvm/Object/Wasm.h
  llvm/include/llvm/Support/MachineValueType.h
  llvm/lib/BinaryFormat/Wasm.cpp
  llvm/lib/CodeGen/CodeGenPrepare.cpp
  llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
  llvm/lib/CodeGen/ValueTypes.cpp
  llvm/lib/MC/MCExpr.cpp
  llvm/lib/MC/WasmObjectWriter.cpp
  llvm/lib/Object/WasmObjectFile.cpp
  llvm/lib/ObjectYAML/WasmYAML.cpp
  llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
  llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
  llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
  llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
  llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
  llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
  llvm/lib/Target/WebAssembly/WebAssembly.td
  llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
  llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
  llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
  llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
  llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
  llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
  llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
  llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
  llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
  llvm/tools/yaml2obj/yaml2wasm.cpp
  llvm/utils/TableGen/CodeGenTarget.cpp

Index: llvm/utils/TableGen/CodeGenTarget.cpp
===================================================================
--- llvm/utils/TableGen/CodeGenTarget.cpp
+++ llvm/utils/TableGen/CodeGenTarget.cpp
@@ -192,6 +192,7 @@
   case MVT::iPTRAny:  return "MVT::iPTRAny";
   case MVT::Untyped:  return "MVT::Untyped";
   case MVT::exnref:   return "MVT::exnref";
+  case MVT::anyref:   return "MVT::anyref";
   default: llvm_unreachable("ILLEGAL VALUE TYPE!");
   }
 }
Index: llvm/tools/yaml2obj/yaml2wasm.cpp
===================================================================
--- llvm/tools/yaml2obj/yaml2wasm.cpp
+++ llvm/tools/yaml2obj/yaml2wasm.cpp
@@ -174,6 +174,7 @@
       case wasm::WASM_SYMBOL_TYPE_FUNCTION:
       case wasm::WASM_SYMBOL_TYPE_GLOBAL:
       case wasm::WASM_SYMBOL_TYPE_EVENT:
+      case wasm::WASM_SYMBOL_TYPE_TABLE:
         encodeULEB128(Info.ElementIndex, SubSection.getStream());
         if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
             (Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -109,8 +109,8 @@
     const TargetOptions &Options, Optional<Reloc::Model> RM,
     Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
     : LLVMTargetMachine(T,
-                        TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128"
-                                         : "e-m:e-p:32:32-i64:64-n32:64-S128",
+                        TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128-ni:1"
+                                         : "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1",
                         TT, CPU, FS, Options, getEffectiveRelocModel(RM, TT),
                         getEffectiveCodeModel(CM, CodeModel::Large), OL),
       TLOF(new WebAssemblyTargetObjectFile()) {
Index: llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
+++ 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.
Index: llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
@@ -45,6 +45,8 @@
 
 def EXNREF_0 : WebAssemblyReg<"%exnref.0">;
 
+def ANYREF_0 : WebAssemblyReg<"%anyref.0">;
+
 // The value stack "register". This is an opaque entity which serves to order
 // uses and defs that must remain in LIFO order.
 def VALUE_STACK : WebAssemblyReg<"STACK">;
@@ -65,3 +67,4 @@
 def V128 : WebAssemblyRegClass<[v4f32, v2f64, v2i64, v4i32, v16i8, v8i16], 128,
                                (add V128_0)>;
 def EXNREF : WebAssemblyRegClass<[exnref], 0, (add EXNREF_0)>;
+def ANYREF : WebAssemblyRegClass<[anyref], 0, (add ANYREF_0)>;
Index: llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -64,6 +64,11 @@
     WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
   }
 
+  unsigned TargetFlags = MO.getTargetFlags();
+  if (TargetFlags == WebAssemblyII::MO_TABLE_INDEX) {
+    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
+  }
+
   return WasmSym;
 }
 
@@ -90,6 +95,12 @@
     return WasmSym;
   }
 
+  unsigned TargetFlags = MO.getTargetFlags();
+  if (TargetFlags == WebAssemblyII::MO_TABLE_INDEX) {
+    WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
+    return WasmSym;
+  }
+
   SmallVector<wasm::ValType, 4> Returns;
   SmallVector<wasm::ValType, 4> Params;
   if (strcmp(Name, "__cpp_exception") == 0) {
@@ -130,6 +141,9 @@
   switch (TargetFlags) {
     case WebAssemblyII::MO_NO_FLAG:
       break;
+    case WebAssemblyII::MO_TABLE_INDEX:
+      Kind = MCSymbolRefExpr::VK_WASM_TABLEINDEX;
+      break;
     case WebAssemblyII::MO_GOT:
       Kind = MCSymbolRefExpr::VK_GOT;
       break;
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
===================================================================
--- /dev/null
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
@@ -0,0 +1,12 @@
+multiclass WebAssemblyTableGet<WebAssemblyRegClass rc, string Name, int Opcode> {
+  let mayLoad = 1, UseNamedOperandTable = 1 in
+  defm "": I<(outs rc:$dst),
+             (ins table_op: $table, I32:$offset),
+             (outs), (ins table_op: $table),
+             [], !strconcat(Name, "\t$dst, ${offset}(${table})"),
+             !strconcat(Name, "\t${table}"), Opcode>;
+}
+
+defm TABLE_GET : WebAssemblyTableGet<ANYREF, "table.get", 0x25>;
+
+def : Pat<(anyref (load (WebAssemblywrapper anyref:$addr))), (TABLE_GET anyref:$addr, (CONST_I32 0))>;
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ 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.
 //===----------------------------------------------------------------------===//
@@ -140,6 +144,9 @@
 let OperandType = "OPERAND_GLOBAL" in
 def global_op : Operand<i32>;
 
+let OperandType = "OPERAND_TABLE" in
+def table_op : Operand<anyref>;
+
 let OperandType = "OPERAND_I32IMM" in
 def i32imm_op : Operand<i32>;
 
@@ -225,6 +232,7 @@
 defm "": ARGUMENT<F32, f32>;
 defm "": ARGUMENT<F64, f64>;
 defm "": ARGUMENT<EXNREF, exnref>;
+defm "": ARGUMENT<ANYREF, anyref>;
 
 // local.get and local.set are not generated by instruction selection; they
 // are implied by virtual register uses and defs.
@@ -295,6 +303,7 @@
 defm "" : LOCAL<F64>;
 defm "" : LOCAL<V128>, Requires<[HasSIMD128]>;
 defm "" : LOCAL<EXNREF>, Requires<[HasExceptionHandling]>;
+defm "" : LOCAL<ANYREF>, Requires<[HasReferenceTypes]>;
 
 let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
 defm CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
@@ -347,3 +356,4 @@
 include "WebAssemblyInstrSIMD.td"
 include "WebAssemblyInstrRef.td"
 include "WebAssemblyInstrBulkMemory.td"
+include "WebAssemblyInstrTable.td"
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
@@ -115,6 +115,7 @@
   defm "": RETURN<F32>;
   defm "": RETURN<F64>;
   defm "": RETURN<EXNREF>;
+  defm "": RETURN<ANYREF>;
   defm "": SIMD_RETURN<v16i8>;
   defm "": SIMD_RETURN<v8i16>;
   defm "": SIMD_RETURN<v4i32>;
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
@@ -60,6 +60,7 @@
 defm "" : CALL<f32, F32, "f32.">;
 defm "" : CALL<f64, F64, "f64.">;
 defm "" : CALL<exnref, EXNREF, "exnref.", [HasExceptionHandling]>;
+defm "" : CALL<anyref, ANYREF, "anyref.", [HasReferenceTypes]>;
 defm "" : CALL<v16i8, V128, "v128.", [HasSIMD128]>;
 defm "" : CALL<v8i16, V128, "v128.", [HasSIMD128]>;
 defm "" : CALL<v4i32, V128, "v128.", [HasSIMD128]>;
@@ -171,6 +172,9 @@
 def : Pat<(exnref (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
           (CALL_exnref texternalsym:$callee)>,
       Requires<[HasExceptionHandling]>;
+def : Pat<(anyref (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
+          (CALL_anyref texternalsym:$callee)>,
+      Requires<[HasReferenceTypes]>;
 def : Pat<(WebAssemblycall0 (WebAssemblywrapper texternalsym:$callee)),
           (CALL_VOID texternalsym:$callee)>;
 def : Pat<(WebAssemblyretcall (WebAssemblywrapper texternalsym:$callee)),
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -43,6 +43,16 @@
   /// right decision when generating code for different targets.
   const WebAssemblySubtarget *Subtarget;
 
+  MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override {
+    return AS == 1 ? MVT::anyref :
+      MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
+  }
+
+  MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override {
+    return AS == 1 ? MVT::anyref :
+      MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
+  }
+
   AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *) const override;
   FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,
                            const TargetLibraryInfo *LibInfo) const override;
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -65,6 +65,10 @@
     addRegisterClass(MVT::v2i64, &WebAssembly::V128RegClass);
     addRegisterClass(MVT::v2f64, &WebAssembly::V128RegClass);
   }
+  if (Subtarget->hasReferenceTypes()) {
+    addRegisterClass(MVT::anyref, &WebAssembly::ANYREFRegClass);
+    setOperationAction(ISD::GlobalAddress, MVT::anyref, Custom);
+  }
   // Compute derived properties from the register classes.
   computeRegisterProperties(Subtarget->getRegisterInfo());
 
@@ -1083,8 +1087,8 @@
   EVT VT = Op.getValueType();
   assert(GA->getTargetFlags() == 0 &&
          "Unexpected target flags on generic GlobalAddressSDNode");
-  if (GA->getAddressSpace() != 0)
-    fail(DL, DAG, "WebAssembly only expects the 0 address space");
+  if (GA->getAddressSpace() != 0 && GA->getAddressSpace() != 1)
+    fail(DL, DAG, "WebAssembly only expects the 0 or 1 address space");
 
   unsigned OperandFlags = 0;
   if (isPositionIndependent()) {
@@ -1116,6 +1120,10 @@
     }
   }
 
+  if (GA->getAddressSpace() == 1) {
+    OperandFlags = WebAssemblyII::MO_TABLE_INDEX;
+  }
+
   return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
                      DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
                                                 GA->getOffset(), OperandFlags));
Index: llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
@@ -92,6 +92,8 @@
     return WebAssembly::DROP_V128;
   if (RC == &WebAssembly::EXNREFRegClass)
     return WebAssembly::DROP_EXNREF;
+  if (RC == &WebAssembly::ANYREFRegClass)
+    return WebAssembly::DROP_ANYREF;
   llvm_unreachable("Unexpected register class");
 }
 
@@ -109,6 +111,8 @@
     return WebAssembly::LOCAL_GET_V128;
   if (RC == &WebAssembly::EXNREFRegClass)
     return WebAssembly::LOCAL_GET_EXNREF;
+  if (RC == &WebAssembly::ANYREFRegClass)
+    return WebAssembly::LOCAL_GET_ANYREF;
   llvm_unreachable("Unexpected register class");
 }
 
@@ -126,6 +130,8 @@
     return WebAssembly::LOCAL_SET_V128;
   if (RC == &WebAssembly::EXNREFRegClass)
     return WebAssembly::LOCAL_SET_EXNREF;
+  if (RC == &WebAssembly::EXNREFRegClass)
+    return WebAssembly::LOCAL_SET_ANYREF;
   llvm_unreachable("Unexpected register class");
 }
 
@@ -143,6 +149,8 @@
     return WebAssembly::LOCAL_TEE_V128;
   if (RC == &WebAssembly::EXNREFRegClass)
     return WebAssembly::LOCAL_TEE_EXNREF;
+  if (RC == &WebAssembly::ANYREFRegClass)
+    return WebAssembly::LOCAL_TEE_ANYREF;
   llvm_unreachable("Unexpected register class");
 }
 
@@ -160,6 +168,8 @@
     return MVT::v16i8;
   if (RC == &WebAssembly::EXNREFRegClass)
     return MVT::exnref;
+  if (RC == &WebAssembly::ANYREFRegClass)
+    return MVT::anyref;
   llvm_unreachable("unrecognized register class");
 }
 
Index: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -329,6 +329,7 @@
   case WebAssembly::ARGUMENT_v4f32_S:
   case WebAssembly::ARGUMENT_v2f64:
   case WebAssembly::ARGUMENT_v2f64_S:
+  case WebAssembly::ARGUMENT_anyref:
     // These represent values which are live into the function entry, so there's
     // no instruction to emit.
     break;
Index: llvm/lib/Target/WebAssembly/WebAssembly.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssembly.td
+++ 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 referenceTypes">;
+
 //===----------------------------------------------------------------------===//
 // Architectures.
 //===----------------------------------------------------------------------===//
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
@@ -72,6 +72,8 @@
   switch (Modifier) {
     case MCSymbolRefExpr::VK_GOT:
       return wasm::R_WASM_GLOBAL_INDEX_LEB;
+    case MCSymbolRefExpr::VK_WASM_TABLEINDEX:
+      return wasm::R_WASM_TABLE_INDEX_LEB;
     case MCSymbolRefExpr::VK_WASM_TBREL:
       assert(SymA.isFunction());
       return wasm::R_WASM_TABLE_INDEX_REL_SLEB;
@@ -98,6 +100,8 @@
       return wasm::R_WASM_FUNCTION_INDEX_LEB;
     if (SymA.isEvent())
       return wasm::R_WASM_EVENT_INDEX_LEB;
+    if (SymA.isTable())
+      return wasm::R_WASM_TABLE_INDEX_LEB;
     return wasm::R_WASM_MEMORY_ADDR_LEB;
   case FK_Data_4:
     if (SymA.isFunction())
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -48,6 +48,8 @@
   OPERAND_LOCAL,
   /// Global index.
   OPERAND_GLOBAL,
+  /// Global index.
+  OPERAND_TABLE,
   /// 32-bit integer immediates.
   OPERAND_I32IMM,
   /// 64-bit integer immediates.
@@ -102,6 +104,9 @@
   // address relative the __table_base wasm global.
   // Only applicable to function symbols.
   MO_TABLE_BASE_REL,
+
+  // On a symbol operand this indicates that this operand is a table index.
+  MO_TABLE_INDEX,
 };
 
 } // end namespace WebAssemblyII
@@ -131,6 +136,7 @@
   F64 = 0x7C,
   V128 = 0x7B,
   Exnref = 0x68,
+  Anyref = 0x6F,
   Invalid = 0x00
 };
 
@@ -387,6 +393,8 @@
   case WebAssembly::ARGUMENT_v2f64_S:
   case WebAssembly::ARGUMENT_exnref:
   case WebAssembly::ARGUMENT_exnref_S:
+  case WebAssembly::ARGUMENT_anyref:
+  case WebAssembly::ARGUMENT_anyref_S:
     return true;
   default:
     return false;
@@ -407,6 +415,8 @@
   case WebAssembly::COPY_V128_S:
   case WebAssembly::COPY_EXNREF:
   case WebAssembly::COPY_EXNREF_S:
+  case WebAssembly::COPY_ANYREF:
+  case WebAssembly::COPY_ANYREF_S:
     return true;
   default:
     return false;
@@ -427,6 +437,8 @@
   case WebAssembly::TEE_V128_S:
   case WebAssembly::TEE_EXNREF:
   case WebAssembly::TEE_EXNREF_S:
+  case WebAssembly::TEE_ANYREF:
+  case WebAssembly::TEE_ANYREF_S:
     return true;
   default:
     return false;
@@ -459,6 +471,8 @@
   case WebAssembly::CALL_v2f64_S:
   case WebAssembly::CALL_exnref:
   case WebAssembly::CALL_exnref_S:
+  case WebAssembly::CALL_anyref:
+  case WebAssembly::CALL_anyref_S:
   case WebAssembly::RET_CALL:
   case WebAssembly::RET_CALL_S:
     return true;
@@ -493,6 +507,8 @@
   case WebAssembly::CALL_INDIRECT_v2f64_S:
   case WebAssembly::CALL_INDIRECT_exnref:
   case WebAssembly::CALL_INDIRECT_exnref_S:
+  case WebAssembly::CALL_INDIRECT_anyref:
+  case WebAssembly::CALL_INDIRECT_anyref_S:
   case WebAssembly::RET_CALL_INDIRECT:
   case WebAssembly::RET_CALL_INDIRECT_S:
     return true;
@@ -536,6 +552,8 @@
   case WebAssembly::CALL_v2f64_S:
   case WebAssembly::CALL_exnref:
   case WebAssembly::CALL_exnref_S:
+  case WebAssembly::CALL_anyref:
+  case WebAssembly::CALL_anyref_S:
   case WebAssembly::CALL_INDIRECT_i32:
   case WebAssembly::CALL_INDIRECT_i32_S:
   case WebAssembly::CALL_INDIRECT_i64:
@@ -556,6 +574,8 @@
   case WebAssembly::CALL_INDIRECT_v4f32_S:
   case WebAssembly::CALL_INDIRECT_v2f64:
   case WebAssembly::CALL_INDIRECT_v2f64_S:
+  case WebAssembly::CALL_INDIRECT_anyref:
+  case WebAssembly::CALL_INDIRECT_anyref_S:
   case WebAssembly::CALL_INDIRECT_exnref:
   case WebAssembly::CALL_INDIRECT_exnref_S:
     return 1;
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
@@ -148,6 +148,8 @@
     return wasm::ValType::V128;
   case MVT::exnref:
     return wasm::ValType::EXNREF;
+  case MVT::anyref:
+    return wasm::ValType::ANYREF;
   default:
     llvm_unreachable("unexpected type");
   }
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
@@ -154,6 +154,7 @@
       case WebAssembly::OPERAND_OFFSET32:
       case WebAssembly::OPERAND_TYPEINDEX:
       case WebAssembly::OPERAND_GLOBAL:
+      case WebAssembly::OPERAND_TABLE:
       case WebAssembly::OPERAND_EVENT:
         FixupKind = MCFixupKind(WebAssembly::fixup_uleb128_i32);
         break;
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -290,6 +290,8 @@
     return "v128";
   case wasm::WASM_TYPE_FUNCREF:
     return "funcref";
+  case wasm::WASM_TYPE_ANYREF:
+    return "anyref";
   case wasm::WASM_TYPE_FUNC:
     return "func";
   case wasm::WASM_TYPE_EXNREF:
Index: llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
+++ llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
@@ -196,6 +196,7 @@
     case WebAssembly::OPERAND_BASIC_BLOCK:
     case WebAssembly::OPERAND_LOCAL:
     case WebAssembly::OPERAND_GLOBAL:
+    case WebAssembly::OPERAND_TABLE:
     case WebAssembly::OPERAND_FUNCTION32:
     case WebAssembly::OPERAND_OFFSET32:
     case WebAssembly::OPERAND_P2ALIGN:
Index: llvm/lib/ObjectYAML/WasmYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/WasmYAML.cpp
+++ llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -493,6 +493,8 @@
     IO.mapRequired("Global", Info.ElementIndex);
   } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT) {
     IO.mapRequired("Event", Info.ElementIndex);
+  } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE) {
+    IO.mapRequired("Table", Info.ElementIndex);
   } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
     if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
       IO.mapRequired("Segment", Info.DataRef.Segment);
@@ -546,6 +548,7 @@
   ECase(GLOBAL);
   ECase(SECTION);
   ECase(EVENT);
+  ECase(TABLE);
 #undef ECase
 }
 
@@ -558,6 +561,7 @@
   ECase(F64);
   ECase(V128);
   ECase(FUNCREF);
+  ECase(ANYREF);
   ECase(FUNC);
   ECase(NORESULT);
 #undef ECase
@@ -590,6 +594,7 @@
     IO &IO, WasmYAML::TableType &Type) {
 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
   ECase(FUNCREF);
+  ECase(ANYREF);
 #undef ECase
 }
 
Index: llvm/lib/Object/WasmObjectFile.cpp
===================================================================
--- llvm/lib/Object/WasmObjectFile.cpp
+++ llvm/lib/Object/WasmObjectFile.cpp
@@ -470,9 +470,11 @@
   std::vector<wasm::WasmImport *> ImportedGlobals;
   std::vector<wasm::WasmImport *> ImportedFunctions;
   std::vector<wasm::WasmImport *> ImportedEvents;
+  std::vector<wasm::WasmImport *> ImportedTables;
   ImportedGlobals.reserve(Imports.size());
   ImportedFunctions.reserve(Imports.size());
   ImportedEvents.reserve(Imports.size());
+  ImportedTables.reserve(Imports.size());
   for (auto &I : Imports) {
     if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
       ImportedFunctions.emplace_back(&I);
@@ -480,6 +482,8 @@
       ImportedGlobals.emplace_back(&I);
     else if (I.Kind == wasm::WASM_EXTERNAL_EVENT)
       ImportedEvents.emplace_back(&I);
+    else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
+      ImportedTables.emplace_back(&I);
   }
 
   while (Count--) {
@@ -609,6 +613,27 @@
       break;
     }
 
+    case wasm::WASM_SYMBOL_TYPE_TABLE: {
+      Info.ElementIndex = readVaruint32(Ctx);
+      if (!isValidTableIndex(Info.ElementIndex) ||
+          IsDefined != isDefinedTableIndex(Info.ElementIndex))
+        return make_error<GenericBinaryError>("invalid table symbol index",
+                                              object_error::parse_failed);
+      if (IsDefined) {
+        Info.Name = readString(Ctx);
+        unsigned TableIndex = Info.ElementIndex - NumImportedTables;
+      } else {
+        wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
+        if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+          Info.Name = readString(Ctx);
+        else
+          Info.Name = Import.Field;
+        Info.ImportName = Import.Field;
+        Info.ImportModule = Import.Module;
+      }
+      break;
+    }
+
     default:
       return make_error<GenericBinaryError>("Invalid symbol type",
                                             object_error::parse_failed);
@@ -793,6 +818,11 @@
         return make_error<GenericBinaryError>("Bad relocation event index",
                                               object_error::parse_failed);
       break;
+    case wasm::R_WASM_TABLE_INDEX_LEB:
+      if (!isValidTableSymbol(Reloc.Index))
+        return make_error<GenericBinaryError>("Bad relocation event index",
+                                              object_error::parse_failed);
+      break;
     case wasm::R_WASM_MEMORY_ADDR_LEB:
     case wasm::R_WASM_MEMORY_ADDR_SLEB:
     case wasm::R_WASM_MEMORY_ADDR_I32:
@@ -918,8 +948,10 @@
       Im.Memory = readLimits(Ctx);
       break;
     case wasm::WASM_EXTERNAL_TABLE:
+      NumImportedTables++;
       Im.Table = readTable(Ctx);
-      if (Im.Table.ElemType != wasm::WASM_TYPE_FUNCREF)
+      if (Im.Table.ElemType != wasm::WASM_TYPE_FUNCREF &&
+          Im.Table.ElemType != wasm::WASM_TYPE_ANYREF)
         return make_error<GenericBinaryError>("Invalid table element type",
                                               object_error::parse_failed);
       break;
@@ -962,7 +994,9 @@
   Tables.reserve(Count);
   while (Count--) {
     Tables.push_back(readTable(Ctx));
-    if (Tables.back().ElemType != wasm::WASM_TYPE_FUNCREF) {
+    if (Tables.back().ElemType != wasm::WASM_TYPE_FUNCREF &&
+        // TODO: Only allow anyref here when reference-types is enabled?
+        Tables.back().ElemType != wasm::WASM_TYPE_ANYREF) {
       return make_error<GenericBinaryError>("Invalid table element type",
                                             object_error::parse_failed);
     }
@@ -1085,6 +1119,14 @@
   return Index >= NumImportedEvents && isValidEventIndex(Index);
 }
 
+bool WasmObjectFile::isValidTableIndex(uint32_t Index) const {
+  return Index < NumImportedTables + Tables.size();
+}
+
+bool WasmObjectFile::isDefinedTableIndex(uint32_t Index) const {
+  return Index >= NumImportedTables && isValidTableIndex(Index);
+}
+
 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
   return Index < Symbols.size() && Symbols[Index].isTypeFunction();
 }
@@ -1097,6 +1139,10 @@
   return Index < Symbols.size() && Symbols[Index].isTypeEvent();
 }
 
+bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
+  return Index < Symbols.size() && Symbols[Index].isTypeTable();
+}
+
 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
   return Index < Symbols.size() && Symbols[Index].isTypeData();
 }
Index: llvm/lib/MC/WasmObjectWriter.cpp
===================================================================
--- llvm/lib/MC/WasmObjectWriter.cpp
+++ llvm/lib/MC/WasmObjectWriter.cpp
@@ -254,6 +254,7 @@
   unsigned NumFunctionImports = 0;
   unsigned NumGlobalImports = 0;
   unsigned NumEventImports = 0;
+  unsigned NumTableImports = 0;
   uint32_t SectionCount = 0;
 
   // TargetObjectWriter wrappers.
@@ -584,6 +585,7 @@
   case wasm::R_WASM_FUNCTION_INDEX_LEB:
   case wasm::R_WASM_GLOBAL_INDEX_LEB:
   case wasm::R_WASM_EVENT_INDEX_LEB:
+  case wasm::R_WASM_TABLE_INDEX_LEB:
     // Provisional value is function/global/event Wasm index
     assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index space");
     return WasmIndices[RelEntry.Symbol];
@@ -681,6 +683,7 @@
     case wasm::R_WASM_GLOBAL_INDEX_LEB:
     case wasm::R_WASM_MEMORY_ADDR_LEB:
     case wasm::R_WASM_EVENT_INDEX_LEB:
+    case wasm::R_WASM_TABLE_INDEX_LEB:
       writePatchableLEB(Stream, Value, Offset);
       break;
     case wasm::R_WASM_TABLE_INDEX_I32:
@@ -974,6 +977,7 @@
       case wasm::WASM_SYMBOL_TYPE_FUNCTION:
       case wasm::WASM_SYMBOL_TYPE_GLOBAL:
       case wasm::WASM_SYMBOL_TYPE_EVENT:
+      case wasm::WASM_SYMBOL_TYPE_TABLE:
         encodeULEB128(Sym.ElementIndex, W.OS);
         if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
             (Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
@@ -1166,6 +1170,7 @@
   TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
   TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF;
   Imports.push_back(TableImport);
+  NumTableImports++;
 
   // Populate SignatureIndices, and Imports and WasmIndices for undefined
   // symbols.  This must be done before populating WasmIndices for defined
@@ -1220,6 +1225,15 @@
         Imports.push_back(Import);
         assert(WasmIndices.count(&WS) == 0);
         WasmIndices[&WS] = NumEventImports++;
+      } else if (WS.isTable()) {
+        wasm::WasmImport Import;
+        Import.Module = WS.getImportModule();
+        Import.Field = WS.getImportName();
+        Import.Kind = wasm::WASM_EXTERNAL_TABLE;
+        Import.Table.ElemType = wasm::WASM_TYPE_ANYREF;
+        Imports.push_back(Import);
+        assert(WasmIndices.count(&WS) == 0);
+        WasmIndices[&WS] = NumTableImports++;
       }
     }
   }
@@ -1416,7 +1430,16 @@
       }
       LLVM_DEBUG(dbgs() << "  -> event index: " << WasmIndices.find(&WS)->second
                         << "\n");
-
+    } else if (WS.isTable()) {
+      unsigned Index;
+      if (WS.isDefined()) {
+        report_fatal_error("Defined tables are not supported yet");
+      } else {
+        // An import; the index was assigned above.
+        assert(WasmIndices.count(&WS) > 0);
+      }
+      LLVM_DEBUG(dbgs() << "  -> table index: " << WasmIndices.find(&WS)->second
+                        << "\n");
     } else {
       assert(WS.isSection());
     }
Index: llvm/lib/MC/MCExpr.cpp
===================================================================
--- llvm/lib/MC/MCExpr.cpp
+++ llvm/lib/MC/MCExpr.cpp
@@ -310,6 +310,7 @@
   case VK_Hexagon_IE: return "IE";
   case VK_Hexagon_IE_GOT: return "IEGOT";
   case VK_WASM_TYPEINDEX: return "TYPEINDEX";
+  case VK_WASM_TABLEINDEX: return "TABLEINDEX";
   case VK_WASM_MBREL: return "MBREL";
   case VK_WASM_TBREL: return "TBREL";
   case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
@@ -427,6 +428,7 @@
     .Case("hi8", VK_AVR_HI8)
     .Case("hlo8", VK_AVR_HLO8)
     .Case("typeindex", VK_WASM_TYPEINDEX)
+    .Case("tableindex", VK_WASM_TABLEINDEX)
     .Case("tbrel", VK_WASM_TBREL)
     .Case("mbrel", VK_WASM_MBREL)
     .Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
Index: llvm/lib/CodeGen/ValueTypes.cpp
===================================================================
--- llvm/lib/CodeGen/ValueTypes.cpp
+++ llvm/lib/CodeGen/ValueTypes.cpp
@@ -250,6 +250,7 @@
   case MVT::Metadata:return "Metadata";
   case MVT::Untyped: return "Untyped";
   case MVT::exnref : return "exnref";
+  case MVT::anyref : return "anyref";
   }
 }
 
@@ -344,91 +345,92 @@
   case MVT::v2f64:   return VectorType::get(Type::getDoubleTy(Context), 2);
   case MVT::v4f64:   return VectorType::get(Type::getDoubleTy(Context), 4);
   case MVT::v8f64:   return VectorType::get(Type::getDoubleTy(Context), 8);
-  case MVT::nxv1i1:  
+  case MVT::nxv1i1:
     return VectorType::get(Type::getInt1Ty(Context), 1, /*Scalable=*/ true);
-  case MVT::nxv2i1:  
+  case MVT::nxv2i1:
     return VectorType::get(Type::getInt1Ty(Context), 2, /*Scalable=*/ true);
-  case MVT::nxv4i1:  
+  case MVT::nxv4i1:
     return VectorType::get(Type::getInt1Ty(Context), 4, /*Scalable=*/ true);
-  case MVT::nxv8i1:  
+  case MVT::nxv8i1:
     return VectorType::get(Type::getInt1Ty(Context), 8, /*Scalable=*/ true);
-  case MVT::nxv16i1: 
+  case MVT::nxv16i1:
     return VectorType::get(Type::getInt1Ty(Context), 16, /*Scalable=*/ true);
-  case MVT::nxv32i1: 
+  case MVT::nxv32i1:
     return VectorType::get(Type::getInt1Ty(Context), 32, /*Scalable=*/ true);
-  case MVT::nxv1i8:  
+  case MVT::nxv1i8:
     return VectorType::get(Type::getInt8Ty(Context), 1, /*Scalable=*/ true);
-  case MVT::nxv2i8:  
+  case MVT::nxv2i8:
     return VectorType::get(Type::getInt8Ty(Context), 2, /*Scalable=*/ true);
-  case MVT::nxv4i8:  
+  case MVT::nxv4i8:
     return VectorType::get(Type::getInt8Ty(Context), 4, /*Scalable=*/ true);
-  case MVT::nxv8i8:  
+  case MVT::nxv8i8:
     return VectorType::get(Type::getInt8Ty(Context), 8, /*Scalable=*/ true);
-  case MVT::nxv16i8: 
+  case MVT::nxv16i8:
     return VectorType::get(Type::getInt8Ty(Context), 16, /*Scalable=*/ true);
-  case MVT::nxv32i8: 
+  case MVT::nxv32i8:
     return VectorType::get(Type::getInt8Ty(Context), 32, /*Scalable=*/ true);
-  case MVT::nxv1i16: 
+  case MVT::nxv1i16:
     return VectorType::get(Type::getInt16Ty(Context), 1, /*Scalable=*/ true);
-  case MVT::nxv2i16: 
+  case MVT::nxv2i16:
     return VectorType::get(Type::getInt16Ty(Context), 2, /*Scalable=*/ true);
-  case MVT::nxv4i16: 
+  case MVT::nxv4i16:
     return VectorType::get(Type::getInt16Ty(Context), 4, /*Scalable=*/ true);
-  case MVT::nxv8i16: 
+  case MVT::nxv8i16:
     return VectorType::get(Type::getInt16Ty(Context), 8, /*Scalable=*/ true);
   case MVT::nxv16i16:
     return VectorType::get(Type::getInt16Ty(Context), 16, /*Scalable=*/ true);
   case MVT::nxv32i16:
     return VectorType::get(Type::getInt16Ty(Context), 32, /*Scalable=*/ true);
-  case MVT::nxv1i32: 
+  case MVT::nxv1i32:
     return VectorType::get(Type::getInt32Ty(Context), 1, /*Scalable=*/ true);
-  case MVT::nxv2i32: 
+  case MVT::nxv2i32:
     return VectorType::get(Type::getInt32Ty(Context), 2, /*Scalable=*/ true);
-  case MVT::nxv4i32: 
+  case MVT::nxv4i32:
     return VectorType::get(Type::getInt32Ty(Context), 4, /*Scalable=*/ true);
-  case MVT::nxv8i32: 
+  case MVT::nxv8i32:
     return VectorType::get(Type::getInt32Ty(Context), 8, /*Scalable=*/ true);
   case MVT::nxv16i32:
     return VectorType::get(Type::getInt32Ty(Context), 16,/*Scalable=*/ true);
   case MVT::nxv32i32:
     return VectorType::get(Type::getInt32Ty(Context), 32,/*Scalable=*/ true);
-  case MVT::nxv1i64: 
+  case MVT::nxv1i64:
     return VectorType::get(Type::getInt64Ty(Context), 1, /*Scalable=*/ true);
-  case MVT::nxv2i64: 
+  case MVT::nxv2i64:
     return VectorType::get(Type::getInt64Ty(Context), 2, /*Scalable=*/ true);
-  case MVT::nxv4i64: 
+  case MVT::nxv4i64:
     return VectorType::get(Type::getInt64Ty(Context), 4, /*Scalable=*/ true);
-  case MVT::nxv8i64: 
+  case MVT::nxv8i64:
     return VectorType::get(Type::getInt64Ty(Context), 8, /*Scalable=*/ true);
   case MVT::nxv16i64:
     return VectorType::get(Type::getInt64Ty(Context), 16, /*Scalable=*/ true);
   case MVT::nxv32i64:
     return VectorType::get(Type::getInt64Ty(Context), 32, /*Scalable=*/ true);
-  case MVT::nxv2f16: 
+  case MVT::nxv2f16:
     return VectorType::get(Type::getHalfTy(Context), 2, /*Scalable=*/ true);
-  case MVT::nxv4f16: 
+  case MVT::nxv4f16:
     return VectorType::get(Type::getHalfTy(Context), 4, /*Scalable=*/ true);
-  case MVT::nxv8f16: 
+  case MVT::nxv8f16:
     return VectorType::get(Type::getHalfTy(Context), 8, /*Scalable=*/ true);
-  case MVT::nxv1f32: 
+  case MVT::nxv1f32:
     return VectorType::get(Type::getFloatTy(Context), 1, /*Scalable=*/ true);
-  case MVT::nxv2f32: 
+  case MVT::nxv2f32:
     return VectorType::get(Type::getFloatTy(Context), 2, /*Scalable=*/ true);
-  case MVT::nxv4f32: 
+  case MVT::nxv4f32:
     return VectorType::get(Type::getFloatTy(Context), 4, /*Scalable=*/ true);
-  case MVT::nxv8f32: 
+  case MVT::nxv8f32:
     return VectorType::get(Type::getFloatTy(Context), 8, /*Scalable=*/ true);
   case MVT::nxv16f32:
     return VectorType::get(Type::getFloatTy(Context), 16, /*Scalable=*/ true);
-  case MVT::nxv1f64: 
+  case MVT::nxv1f64:
     return VectorType::get(Type::getDoubleTy(Context), 1, /*Scalable=*/ true);
-  case MVT::nxv2f64: 
+  case MVT::nxv2f64:
     return VectorType::get(Type::getDoubleTy(Context), 2, /*Scalable=*/ true);
-  case MVT::nxv4f64: 
+  case MVT::nxv4f64:
     return VectorType::get(Type::getDoubleTy(Context), 4, /*Scalable=*/ true);
-  case MVT::nxv8f64: 
+  case MVT::nxv8f64:
     return VectorType::get(Type::getDoubleTy(Context), 8, /*Scalable=*/ true);
   case MVT::Metadata: return Type::getMetadataTy(Context);
+  case MVT::anyref: return PointerType::get(Type::getInt8Ty(Context), 1);
   }
 }
 
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4064,10 +4064,12 @@
       Root = Chain;
       ChainI = 0;
     }
-    SDValue A = DAG.getNode(ISD::ADD, dl,
-                            PtrVT, Ptr,
-                            DAG.getConstant(Offsets[i], dl, PtrVT),
-                            Flags);
+    SDValue A = Ptr;
+    if (Offsets[i] != 0)
+      A = DAG.getNode(ISD::ADD, dl,
+                      PtrVT, Ptr,
+                      DAG.getConstant(Offsets[i], dl, PtrVT),
+                      Flags);
     auto MMOFlags = MachineMemOperand::MONone;
     if (isVolatile)
       MMOFlags |= MachineMemOperand::MOVolatile;
Index: llvm/lib/CodeGen/CodeGenPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -1856,7 +1856,7 @@
     case Intrinsic::experimental_widenable_condition: {
       // Give up on future widening oppurtunties so that we can fold away dead
       // paths and merge blocks before going into block-local instruction
-      // selection.   
+      // selection.
       if (II->use_empty()) {
         II->eraseFromParent();
         return true;
@@ -5733,6 +5733,9 @@
 
   EVT LoadResultVT = TLI->getValueType(*DL, Load->getType());
   unsigned BitWidth = LoadResultVT.getSizeInBits();
+  if (!BitWidth)
+    return false;
+
   APInt DemandBits(BitWidth, 0);
   APInt WidestAndBits(BitWidth, 0);
 
Index: llvm/lib/BinaryFormat/Wasm.cpp
===================================================================
--- llvm/lib/BinaryFormat/Wasm.cpp
+++ llvm/lib/BinaryFormat/Wasm.cpp
@@ -20,6 +20,8 @@
     return "WASM_SYMBOL_TYPE_SECTION";
   case wasm::WASM_SYMBOL_TYPE_EVENT:
     return "WASM_SYMBOL_TYPE_EVENT";
+  case wasm::WASM_SYMBOL_TYPE_TABLE:
+    return "WASM_SYMBOL_TYPE_TABLE";
   }
   llvm_unreachable("unknown symbol type");
 }
Index: llvm/include/llvm/Support/MachineValueType.h
===================================================================
--- llvm/include/llvm/Support/MachineValueType.h
+++ llvm/include/llvm/Support/MachineValueType.h
@@ -208,9 +208,10 @@
                                // will be determined by the opcode.
 
       exnref         =  129,   // WebAssembly's exnref type
+      anyref         =  130,   // WebAssembly's anyref type
 
       FIRST_VALUETYPE = 1,     // This is always the beginning of the list.
-      LAST_VALUETYPE =  130,   // This always remains at the end of the list.
+      LAST_VALUETYPE =  131,   // This always remains at the end of the list.
 
       // This is the current maximum for LAST_VALUETYPE.
       // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
@@ -777,7 +778,8 @@
       case v1024f32:  return 32768;
       case v2048i32:
       case v2048f32:  return 65536;
-      case exnref: return 0; // opaque type
+      case exnref:
+      case anyref: return 0; // opaque type
       }
     }
 
Index: llvm/include/llvm/Object/Wasm.h
===================================================================
--- llvm/include/llvm/Object/Wasm.h
+++ llvm/include/llvm/Object/Wasm.h
@@ -63,6 +63,8 @@
 
   bool isTypeEvent() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT; }
 
+  bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
+
   bool isDefined() const { return !isUndefined(); }
 
   bool isUndefined() const {
@@ -217,9 +219,12 @@
   bool isDefinedGlobalIndex(uint32_t Index) const;
   bool isValidEventIndex(uint32_t Index) const;
   bool isDefinedEventIndex(uint32_t Index) const;
+  bool isValidTableIndex(uint32_t Index) const;
+  bool isDefinedTableIndex(uint32_t Index) const;
   bool isValidFunctionSymbol(uint32_t Index) const;
   bool isValidGlobalSymbol(uint32_t Index) const;
   bool isValidEventSymbol(uint32_t Index) const;
+  bool isValidTableSymbol(uint32_t Index) const;
   bool isValidDataSymbol(uint32_t Index) const;
   bool isValidSectionSymbol(uint32_t Index) const;
   wasm::WasmFunction &getDefinedFunction(uint32_t Index);
@@ -284,6 +289,7 @@
   uint32_t NumImportedGlobals = 0;
   uint32_t NumImportedFunctions = 0;
   uint32_t NumImportedEvents = 0;
+  uint32_t NumImportedTables = 0;
   uint32_t CodeSection = 0;
   uint32_t DataSection = 0;
   uint32_t GlobalSection = 0;
Index: llvm/include/llvm/MC/MCSymbolWasm.h
===================================================================
--- llvm/include/llvm/MC/MCSymbolWasm.h
+++ llvm/include/llvm/MC/MCSymbolWasm.h
@@ -44,6 +44,7 @@
   bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
   bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
   bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; }
+  bool isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; }
   wasm::WasmSymbolType getType() const { return Type; }
   void setType(wasm::WasmSymbolType type) { Type = type; }
 
Index: llvm/include/llvm/MC/MCExpr.h
===================================================================
--- llvm/include/llvm/MC/MCExpr.h
+++ llvm/include/llvm/MC/MCExpr.h
@@ -293,6 +293,7 @@
     VK_Hexagon_IE_GOT,
 
     VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
+    VK_WASM_TABLEINDEX,// Reference to a table
     VK_WASM_MBREL,     // Memory address relative to memory base
     VK_WASM_TBREL,     // Table index relative to table bare
 
Index: llvm/include/llvm/CodeGen/ValueTypes.td
===================================================================
--- llvm/include/llvm/CodeGen/ValueTypes.td
+++ llvm/include/llvm/CodeGen/ValueTypes.td
@@ -161,6 +161,7 @@
 def isVoid : ValueType<0  , 127>;   // Produces no value
 def untyped: ValueType<8  , 128>;   // Produces an untyped value
 def exnref: ValueType<0, 129>;      // WebAssembly's exnref type
+def anyref: ValueType<0, 130>;      // WebAssembly's anyref type
 def token  : ValueType<0  , 248>;   // TokenTy
 def MetadataVT: ValueType<0, 249>;  // Metadata
 
Index: llvm/include/llvm/CodeGen/TargetLowering.h
===================================================================
--- llvm/include/llvm/CodeGen/TargetLowering.h
+++ llvm/include/llvm/CodeGen/TargetLowering.h
@@ -247,7 +247,7 @@
   /// Return the in-memory pointer type for the given address space, defaults to
   /// the pointer type from the data layout.  FIXME: The default needs to be
   /// removed once all the code is updated.
-  MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
+  virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
     return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
   }
 
@@ -1036,7 +1036,7 @@
     const bool OptForSize = SI->getParent()->getParent()->hasOptSize();
     const unsigned MinDensity = getMinimumJumpTableDensity(OptForSize);
     const unsigned MaxJumpTableSize = getMaximumJumpTableSize();
-    
+
     // Check whether the number of cases is small enough and
     // the range is dense enough for a jump table.
     if ((OptForSize || Range <= MaxJumpTableSize) &&
Index: llvm/include/llvm/BinaryFormat/WasmRelocs.def
===================================================================
--- llvm/include/llvm/BinaryFormat/WasmRelocs.def
+++ llvm/include/llvm/BinaryFormat/WasmRelocs.def
@@ -15,3 +15,4 @@
 WASM_RELOC(R_WASM_EVENT_INDEX_LEB,      10)
 WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11)
 WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12)
+WASM_RELOC(R_WASM_TABLE_INDEX_LEB,      13)
Index: llvm/include/llvm/BinaryFormat/Wasm.h
===================================================================
--- llvm/include/llvm/BinaryFormat/Wasm.h
+++ llvm/include/llvm/BinaryFormat/Wasm.h
@@ -224,6 +224,7 @@
   WASM_TYPE_F64 = 0x7C,
   WASM_TYPE_V128 = 0x7B,
   WASM_TYPE_FUNCREF = 0x70,
+  WASM_TYPE_ANYREF = 0x6F,
   WASM_TYPE_EXNREF = 0x68,
   WASM_TYPE_FUNC = 0x60,
   WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
@@ -300,6 +301,7 @@
   WASM_SYMBOL_TYPE_GLOBAL = 0x2,
   WASM_SYMBOL_TYPE_SECTION = 0x3,
   WASM_SYMBOL_TYPE_EVENT = 0x4,
+  WASM_SYMBOL_TYPE_TABLE = 0x5,
 };
 
 // Kinds of event attributes.
@@ -334,6 +336,8 @@
   F32 = WASM_TYPE_F32,
   F64 = WASM_TYPE_F64,
   V128 = WASM_TYPE_V128,
+  FUNCREF = WASM_TYPE_FUNCREF,
+  ANYREF = WASM_TYPE_ANYREF,
   EXNREF = WASM_TYPE_EXNREF,
 };
 
Index: lld/wasm/WriterUtils.cpp
===================================================================
--- lld/wasm/WriterUtils.cpp
+++ lld/wasm/WriterUtils.cpp
@@ -182,6 +182,10 @@
     return "f64";
   case ValType::V128:
     return "v128";
+  case ValType::FUNCREF:
+    return "func";
+  case ValType::ANYREF:
+    return "anyref";
   case ValType::EXNREF:
     return "exnref";
   }
Index: clang/lib/Basic/Targets/WebAssembly.h
===================================================================
--- clang/lib/Basic/Targets/WebAssembly.h
+++ 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 &)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to