Merge pull request #2368 from GMNGeoffrey:main-to-google

PiperOrigin-RevId: 319237170
diff --git a/SUBMODULE_VERSIONS b/SUBMODULE_VERSIONS
index 137a304..bba5bb7 100644
--- a/SUBMODULE_VERSIONS
+++ b/SUBMODULE_VERSIONS
@@ -3,7 +3,7 @@
 4c13807b7d43ff0946b7ffea0ae3aee9e611d778 third_party/dear_imgui
 a5d9d0f7d368054fd1691aedf1db4116efcc233e third_party/flatbuffers
 f2fb48c3b3d79a75a88a99fba6576b25d42ec528 third_party/googletest
-e34523c87c3f1cfabcf741568dede026bbb12d3a third_party/llvm-project
+7d9518c8000bcd742b364a390bc79560f736dc96 third_party/llvm-project
 17b12a4481daa150e2d1ea3ada086b551b856707 third_party/marl
 67f3ccebee84f3488b46a8d3ac005178c52ff264 third_party/mlir-emitc
 80d452484c5409444b0ec19383faa84bb7a4d351 third_party/pybind11
diff --git a/bindings/python/build_defs.oss.bzl b/bindings/python/build_defs.oss.bzl
index d8cf789..7e51827 100644
--- a/bindings/python/build_defs.oss.bzl
+++ b/bindings/python/build_defs.oss.bzl
@@ -22,6 +22,7 @@
 NUMPY_DEPS = []
 PLATFORM_VULKAN_DEPS = _PLATFORM_VULKAN_DEPS
 PYTHON_HEADERS_DEPS = ["@iree_native_python//:python_headers"]
+PYTHON_CPP_EXTRA_DEPS = []
 
 PYBIND_COPTS = [
     "-fexceptions",
diff --git a/bindings/python/pyiree/compiler/BUILD b/bindings/python/pyiree/compiler/BUILD
index a6560f9..3f4cf09 100644
--- a/bindings/python/pyiree/compiler/BUILD
+++ b/bindings/python/pyiree/compiler/BUILD
@@ -19,6 +19,7 @@
     "PYBIND_EXTENSION_COPTS",
     "PYBIND_FEATURES",
     "PYBIND_REGISTER_MLIR_PASSES",
+    "PYTHON_CPP_EXTRA_DEPS",
     "iree_py_extension",
     "iree_py_library",
     "iree_py_test",
@@ -54,7 +55,7 @@
         "__init__.py",
     ],
     srcs_version = "PY3",
-    deps = [
+    deps = PYTHON_CPP_EXTRA_DEPS + [
         ":binding",
         "//bindings/python:pathsetup",  # build_cleaner: keep
     ],
@@ -89,6 +90,7 @@
         "//iree/tools:init_compiler_modules",
         "//iree/tools:init_iree_passes_and_dialects",
         "//iree/tools:init_mlir_passes_and_dialects",
+        "//iree/base:localfile",
         "//iree/tools:init_targets",
         "@llvm-project//llvm:Support",
         "@llvm-project//mlir:AllPassesAndDialectsNoRegistration",
diff --git a/bindings/python/pyiree/rt/BUILD b/bindings/python/pyiree/rt/BUILD
index fb00167..db48f43 100644
--- a/bindings/python/pyiree/rt/BUILD
+++ b/bindings/python/pyiree/rt/BUILD
@@ -82,6 +82,7 @@
     deps = [
         "//bindings/python/pyiree/common",
         "//iree/base:api",
+        "//iree/base:localfile",
         "//iree/base:signature_mangle",
         "//iree/hal:api",
         "//iree/modules/hal",
diff --git a/build_tools/bazel/build_bindings.sh b/build_tools/bazel/build_bindings.sh
index 56aef23..e79cade 100755
--- a/build_tools/bazel/build_bindings.sh
+++ b/build_tools/bazel/build_bindings.sh
@@ -39,9 +39,11 @@
 if ! [[ -v IREE_VULKAN_DISABLE ]]; then
   IREE_VULKAN_DISABLE=1
 fi
+
 declare -a test_env_args=(
   --test_env=IREE_LLVMJIT_DISABLE=$IREE_LLVMJIT_DISABLE
   --test_env=IREE_VULKAN_DISABLE=$IREE_VULKAN_DISABLE
+  --test_env=IREE_LLVMAOT_LINKER_PATH
 )
 
 declare -a default_build_tag_filters=("-nokokoro")
diff --git a/build_tools/bazel/third_party_import/llvm-project/overlay/llvm/BUILD.bazel b/build_tools/bazel/third_party_import/llvm-project/overlay/llvm/BUILD.bazel
index 9a98f69..4722ad3 100644
--- a/build_tools/bazel/third_party_import/llvm-project/overlay/llvm/BUILD.bazel
+++ b/build_tools/bazel/third_party_import/llvm-project/overlay/llvm/BUILD.bazel
@@ -2,13 +2,8 @@
 #
 # This BUILD file is auto-generated; do not edit!
 
-licenses(["notice"])
-
-exports_files(["LICENSE.TXT"])
-
 load(
     "@org_tensorflow//third_party/llvm:llvm.bzl",
-    "cmake_var_string",
     "expand_cmake_vars",
     "gentbl",
     "llvm_all_cmake_vars",
@@ -22,6 +17,10 @@
     "template_rule",
 )
 
+licenses(["notice"])
+
+exports_files(["LICENSE.TXT"])
+
 package(default_visibility = ["//visibility:public"])
 
 llvm_host_triple = "x86_64-unknown-linux_gnu"
@@ -669,7 +668,18 @@
 
 gentbl(
     name = "omp_gen",
-    tbl_outs = [("--gen-directive-decls", "include/llvm/Frontend/OpenMP/OMP.h.inc")],
+    tbl_outs = [("--gen-directive-decl", "include/llvm/Frontend/OpenMP/OMP.h.inc")],
+    tblgen = ":llvm-tblgen",
+    td_file = "include/llvm/Frontend/OpenMP/OMP.td",
+    td_srcs = glob([
+        "include/llvm/Frontend/OpenMP/*.td",
+        "include/llvm/Frontend/Directive/*.td",
+    ]),
+)
+
+gentbl(
+    name = "omp_gen_impl",
+    tbl_outs = [("--gen-directive-impl", "include/llvm/Frontend/OpenMP/OMP.cpp.inc")],
     tblgen = ":llvm-tblgen",
     td_file = "include/llvm/Frontend/OpenMP/OMP.td",
     td_srcs = glob([
@@ -2074,6 +2084,7 @@
         ":TransformUtils",
         ":config",
         ":omp_gen",
+        ":omp_gen_impl",
     ],
 )
 
diff --git a/build_tools/cmake/iree_copts.cmake b/build_tools/cmake/iree_copts.cmake
index 542536b..63776ef 100644
--- a/build_tools/cmake/iree_copts.cmake
+++ b/build_tools/cmake/iree_copts.cmake
@@ -149,7 +149,8 @@
 set(LLVM_ENABLE_IDE ON CACHE BOOL "" FORCE)
 set(LLVM_ENABLE_RTTI ON CACHE BOOL "" FORCE)
 
-set(LLVM_TARGETS_TO_BUILD "WebAssembly;X86" CACHE STRING "" FORCE)
+# TODO(ataei): Use optional build time targets selection for LLVMAOT.
+set(LLVM_TARGETS_TO_BUILD "WebAssembly;X86;ARM;AArch64" CACHE STRING "" FORCE)
 
 set(LLVM_ENABLE_PROJECTS "mlir" CACHE STRING "" FORCE)
 set(LLVM_ENABLE_BINDINGS OFF CACHE BOOL "" FORCE)
diff --git a/docs/GetStarted/cmake_options_and_variables.md b/docs/GetStarted/cmake_options_and_variables.md
index 3316a59..cd179d4 100644
--- a/docs/GetStarted/cmake_options_and_variables.md
+++ b/docs/GetStarted/cmake_options_and_variables.md
@@ -97,8 +97,8 @@
 
 ## Cross-compilation
 
-[TODO(#2111): The following explanation is developer oriented. Move it to
-the developer build doc once we've created that.]
+[TODO(#2111): The following explanation is developer oriented. Move it to the
+developer build doc once we've created that.]
 
 Cross-compilation involves both a *host* platform and a *target* platform. One
 invokes compiler toolchains on the host platform to generate libraries and
@@ -120,28 +120,31 @@
 When CMake is invoked with a toolchain file, e.g.,
 [`android.toolchain.cmake`](https://android.googlesource.com/platform/ndk/+/master/build/cmake/android.toolchain.cmake),
 we get the compiler toolchain for the target platform from the toolchain file.
-IREE under the hood will [create another CMake invocation](https://github.com/google/iree/blob/main/build_tools/cmake/iree_cross_compile.cmake)
+IREE under the hood will
+[create another CMake invocation](https://github.com/google/iree/blob/main/build_tools/cmake/iree_cross_compile.cmake)
 using host platform's compiler toolchain. The inner CMake invocation will be
 placed under `IREE_HOST_BINARY_ROOT`.
 
 The tricky part is to set up target artifacts' dependencies on host executables.
 Normally in CMake we define targets and `target_link_libraries` to express the
-dependency relationship between targets. The optimal way is to [`export`](https://cmake.org/cmake/help/latest/command/export.html)
-targets under host configuration and then [`import`](https://cmake.org/cmake/help/latest/command/add_executable.html?highlight=import#imported-executables)
+dependency relationship between targets. The optimal way is to
+[`export`](https://cmake.org/cmake/help/latest/command/export.html) targets
+under host configuration and then
+[`import`](https://cmake.org/cmake/help/latest/command/add_executable.html?highlight=import#imported-executables)
 into target configuration. But that is not playing well with LLVM's TableGen
-configurations. LLVM's cross-compilation uses on files for dependencies. So
-here we need to do the same. This results in reverting the relationship between
-IREE artifact output names (e.g., `iree-translate`) and IREE package-prefixed
-CMake target names (e.g., `iree_tools_iree-translate`).
+configurations. LLVM's cross-compilation uses on files for dependencies. So here
+we need to do the same. This results in reverting the relationship between IREE
+artifact output names (e.g., `iree-translate`) and IREE package-prefixed CMake
+target names (e.g., `iree_tools_iree-translate`).
 
 When not cross-compiling, IREE uses the CMake target names as the real unique
 identification inside CMake for defining the object and expressing dependencies;
 the artifact output names are just used for naming the build artifacts. When
 cross-compiling, it's the artifact names being load-bearing. The artifact names
 are used to express dependencies across CMake invocation boundary (remember that
-we cannot access targets defined in another CMake invocation);
-the package-prefixed CMake target names are just cutom targets depending on
-the host artfact.
+we cannot access targets defined in another CMake invocation); the
+package-prefixed CMake target names are just cutom targets depending on the host
+artfact.
 
 #### `IREE_HOST_BINARY_ROOT`:FILEPATH
 
diff --git a/docs/GetStarted/getting_started_android_cmake.md b/docs/GetStarted/getting_started_android_cmake.md
index 2378f1f..c46bd0e 100644
--- a/docs/GetStarted/getting_started_android_cmake.md
+++ b/docs/GetStarted/getting_started_android_cmake.md
@@ -39,14 +39,13 @@
 After downloading, it is recommended to set the `ANDROID_NDK` environment
 variable pointing to the directory. For Linux, you can `export` in your shell's
 rc file. For Windows, you can search "environment variable" in the taskbar or
-use `Windows` + `R` to open the "Run" dialog to run
-`rundll32 sysdm.cpl,EditEnvironmentVariables`.
-
+use `Windows` + `R` to open the "Run" dialog to run `rundll32
+sysdm.cpl,EditEnvironmentVariables`.
 
 ### Install Android Debug Bridge (ADB)
 
-For Linux, search your the distro's package manager to install `adb`.
-For example, on Ubuntu:
+For Linux, search your the distro's package manager to install `adb`. For
+example, on Ubuntu:
 
 ```shell
 $ sudo apt install adb
@@ -82,8 +81,8 @@
     for your target device. You can also refer to Android NDK's
     [CMake documentation](https://developer.android.com/ndk/guides/cmake) for
     more toolchain arguments.
-*   Building IREE compilers and samples for Android is not supported at
-    the moment; they will be enabled soon.
+*   Building IREE compilers and samples for Android is not supported at the
+    moment; they will be enabled soon.
 *   We need to define `IREE_HOST_{C|CXX}_COMPILER` to Clang here because IREE
     does [not support](https://github.com/google/iree/issues/1269) GCC well at
     the moment.
@@ -91,8 +90,9 @@
 ### Configure on Windows
 
 On Windows, we will need the full path to the `cl.exe` compiler. This can be
-obtained by [opening a developer command prompt window](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=vs-2019#developer_command_prompt) and type
-`where cl.exe`. Then in a command prompt (`cmd.exe`):
+obtained by
+[opening a developer command prompt window](https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=vs-2019#developer_command_prompt)
+and type `where cl.exe`. Then in a command prompt (`cmd.exe`):
 
 ```cmd
 REM Assuming in IREE source root
@@ -105,10 +105,10 @@
     -DLLVM_HOST_TRIPLE="x86_64-pc-windows-msvc"
 ```
 
-* See the Linux section in the above for explanations of the used arguments.
-* We need to define `LLVM_HOST_TRIPLE` in the above because LLVM cannot properly
-  detect host triple under Android CMake toolchain file. This might be fixed
-  later.
+*   See the Linux section in the above for explanations of the used arguments.
+*   We need to define `LLVM_HOST_TRIPLE` in the above because LLVM cannot
+    properly detect host triple under Android CMake toolchain file. This might
+    be fixed later.
 
 ### Build all targets
 
diff --git a/experimental/ModelBuilder/ModelBuilder.cpp b/experimental/ModelBuilder/ModelBuilder.cpp
index 1cbac11..315d79b 100644
--- a/experimental/ModelBuilder/ModelBuilder.cpp
+++ b/experimental/ModelBuilder/ModelBuilder.cpp
@@ -291,14 +291,14 @@
 }
 SmallVector<Value, 4> mlir::edsc::extensions::std_max(ValueRange a,
                                                       ValueRange b) {
-  using edsc::op::operator<;
-  auto fun = [](Value va, Value vb) { return (va < vb) ? vb : va; };
+  using edsc::op::slt;
+  auto fun = [](Value va, Value vb) { return slt(va, vb) ? vb : va; };
   return valueRangeOperatorImpl(fun, a, b);
 }
 SmallVector<Value, 4> mlir::edsc::extensions::std_min(ValueRange a,
                                                       ValueRange b) {
-  using edsc::op::operator<;
-  auto fun = [](Value va, Value vb) { return (va < vb) ? va : vb; };
+  using edsc::op::slt;
+  auto fun = [](Value va, Value vb) { return slt(va, vb) ? va : vb; };
   return valueRangeOperatorImpl(fun, a, b);
 }
 SmallVector<Value, 4> mlir::edsc::extensions::affine_max(ValueRange a,
diff --git a/integrations/tensorflow/compiler/dialect/tf_strings/ir/types.h b/integrations/tensorflow/compiler/dialect/tf_strings/ir/types.h
index fb607c5..a7f4fe3 100644
--- a/integrations/tensorflow/compiler/dialect/tf_strings/ir/types.h
+++ b/integrations/tensorflow/compiler/dialect/tf_strings/ir/types.h
@@ -47,7 +47,8 @@
   }
 };
 
-class StringType : public Type::TypeBase<StringType, TFStringsType> {
+class StringType
+    : public Type::TypeBase<StringType, TFStringsType, TypeStorage> {
  public:
   using Base::Base;
   static StringType get(MLIRContext* context) {
diff --git a/integrations/tensorflow/compiler/dialect/tf_tensorlist/ir/tf_tensorlist_types.h b/integrations/tensorflow/compiler/dialect/tf_tensorlist/ir/tf_tensorlist_types.h
index 3da0be3..f9602cb 100644
--- a/integrations/tensorflow/compiler/dialect/tf_tensorlist/ir/tf_tensorlist_types.h
+++ b/integrations/tensorflow/compiler/dialect/tf_tensorlist/ir/tf_tensorlist_types.h
@@ -26,7 +26,8 @@
 };
 }  // namespace TypeKind
 
-class TensorListType : public Type::TypeBase<TensorListType, Type> {
+class TensorListType
+    : public Type::TypeBase<TensorListType, Type, TypeStorage> {
  public:
   using Base::Base;
   static bool kindof(unsigned kind) { return kind == TypeKind::kTensorList; }
diff --git a/integrations/tensorflow/e2e/BUILD b/integrations/tensorflow/e2e/BUILD
index bf6a8d0..31fb578 100644
--- a/integrations/tensorflow/e2e/BUILD
+++ b/integrations/tensorflow/e2e/BUILD
@@ -188,12 +188,12 @@
     name = "explicit_backend_test",
     srcs = ["explicit_backend_test.py"],
     main = "explicit_backend_test.py",
+    python_version = "PY3",
     tags = [
-        "driver=vmla",
         "driver=llvmjit",
+        "driver=vmla",
         "driver=vulkan",
     ],
-    python_version = "PY3",
     deps = INTREE_TENSORFLOW_PY_DEPS + NUMPY_DEPS + [
         "//integrations/tensorflow/bindings/python/pyiree/tf/support",
     ],
diff --git a/iree/compiler/Dialect/HAL/IR/HALTypes.h b/iree/compiler/Dialect/HAL/IR/HALTypes.h
index 7755774..3df35e1 100644
--- a/iree/compiler/Dialect/HAL/IR/HALTypes.h
+++ b/iree/compiler/Dialect/HAL/IR/HALTypes.h
@@ -57,7 +57,7 @@
 // RefObject types
 //===----------------------------------------------------------------------===//
 
-class AllocatorType : public Type::TypeBase<AllocatorType, Type> {
+class AllocatorType : public Type::TypeBase<AllocatorType, Type, TypeStorage> {
  public:
   using Base::Base;
   static AllocatorType get(MLIRContext *context) {
@@ -66,7 +66,7 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::Allocator; }
 };
 
-class BufferType : public Type::TypeBase<BufferType, Type> {
+class BufferType : public Type::TypeBase<BufferType, Type, TypeStorage> {
  public:
   using Base::Base;
   static BufferType get(MLIRContext *context) {
@@ -75,7 +75,8 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::Buffer; }
 };
 
-class BufferViewType : public Type::TypeBase<BufferViewType, Type> {
+class BufferViewType
+    : public Type::TypeBase<BufferViewType, Type, TypeStorage> {
  public:
   using Base::Base;
   static BufferViewType get(MLIRContext *context) {
@@ -84,7 +85,8 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::BufferView; }
 };
 
-class CommandBufferType : public Type::TypeBase<CommandBufferType, Type> {
+class CommandBufferType
+    : public Type::TypeBase<CommandBufferType, Type, TypeStorage> {
  public:
   using Base::Base;
   static CommandBufferType get(MLIRContext *context) {
@@ -93,7 +95,8 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::CommandBuffer; }
 };
 
-class DescriptorSetType : public Type::TypeBase<DescriptorSetType, Type> {
+class DescriptorSetType
+    : public Type::TypeBase<DescriptorSetType, Type, TypeStorage> {
  public:
   using Base::Base;
   static DescriptorSetType get(MLIRContext *context) {
@@ -103,7 +106,7 @@
 };
 
 class DescriptorSetLayoutType
-    : public Type::TypeBase<DescriptorSetLayoutType, Type> {
+    : public Type::TypeBase<DescriptorSetLayoutType, Type, TypeStorage> {
  public:
   using Base::Base;
   static DescriptorSetLayoutType get(MLIRContext *context) {
@@ -114,7 +117,7 @@
   }
 };
 
-class DeviceType : public Type::TypeBase<DeviceType, Type> {
+class DeviceType : public Type::TypeBase<DeviceType, Type, TypeStorage> {
  public:
   using Base::Base;
   static DeviceType get(MLIRContext *context) {
@@ -123,7 +126,7 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::Device; }
 };
 
-class EventType : public Type::TypeBase<EventType, Type> {
+class EventType : public Type::TypeBase<EventType, Type, TypeStorage> {
  public:
   using Base::Base;
   static EventType get(MLIRContext *context) {
@@ -132,7 +135,8 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::Event; }
 };
 
-class ExecutableType : public Type::TypeBase<ExecutableType, Type> {
+class ExecutableType
+    : public Type::TypeBase<ExecutableType, Type, TypeStorage> {
  public:
   using Base::Base;
   static ExecutableType get(MLIRContext *context) {
@@ -141,7 +145,8 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::Executable; }
 };
 
-class ExecutableCacheType : public Type::TypeBase<ExecutableCacheType, Type> {
+class ExecutableCacheType
+    : public Type::TypeBase<ExecutableCacheType, Type, TypeStorage> {
  public:
   using Base::Base;
   static ExecutableCacheType get(MLIRContext *context) {
@@ -152,7 +157,8 @@
   }
 };
 
-class ExecutableLayoutType : public Type::TypeBase<ExecutableLayoutType, Type> {
+class ExecutableLayoutType
+    : public Type::TypeBase<ExecutableLayoutType, Type, TypeStorage> {
  public:
   using Base::Base;
   static ExecutableLayoutType get(MLIRContext *context) {
@@ -163,7 +169,8 @@
   }
 };
 
-class RingBufferType : public Type::TypeBase<RingBufferType, Type> {
+class RingBufferType
+    : public Type::TypeBase<RingBufferType, Type, TypeStorage> {
  public:
   using Base::Base;
   static RingBufferType get(MLIRContext *context) {
@@ -172,7 +179,7 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::RingBuffer; }
 };
 
-class SemaphoreType : public Type::TypeBase<SemaphoreType, Type> {
+class SemaphoreType : public Type::TypeBase<SemaphoreType, Type, TypeStorage> {
  public:
   using Base::Base;
   static SemaphoreType get(MLIRContext *context) {
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/BUILD b/iree/compiler/Dialect/HAL/Target/LLVM/BUILD
index ee7d12f..20d26ae 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/BUILD
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/BUILD
@@ -11,6 +11,8 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+#
+load("//iree:build_defs.oss.bzl", "platform_trampoline_deps")
 
 package(
     default_visibility = ["//visibility:public"],
@@ -48,13 +50,20 @@
         "LLVMAOTTarget.h",
     ],
     deps = [
+        ":LLVMAOTTargetLinker",
         ":LLVMIRPasses",
         ":LLVMTargetOptions",
         "//iree/compiler/Conversion/LinalgToLLVM",
         "//iree/compiler/Dialect/HAL/Target",
         "//iree/schemas:dylib_executable_def_cc_fbs",
+        "@llvm-project//llvm:AArch64AsmParser",
+        "@llvm-project//llvm:AArch64CodeGen",
+        "@llvm-project//llvm:ARMAsmParser",
+        "@llvm-project//llvm:ARMCodeGen",
         "@llvm-project//llvm:Core",
         "@llvm-project//llvm:Support",
+        "@llvm-project//llvm:X86AsmParser",
+        "@llvm-project//llvm:X86CodeGen",
         "@llvm-project//mlir:TargetLLVMIR",
     ],
 )
@@ -88,5 +97,23 @@
     deps = [
         "@llvm-project//llvm:Passes",
         "@llvm-project//llvm:Support",
+        "@llvm-project//llvm:Target",
+    ],
+)
+
+cc_library(
+    name = "LLVMAOTTargetLinker",
+    hdrs = ["LLVMAOTTargetLinker.h"],
+    deps = [
+        "//iree/base:file_io",
+    ] + platform_trampoline_deps("LLVMAOTTargetLinker", "compiler/Dialect/HAL/Target/LLVM"),
+)
+
+cc_library(
+    name = "LLVMAOTTargetLinker_hdrs",
+    hdrs = ["LLVMAOTTargetLinker.h"],
+    deps = [
+        ":LLVMTargetOptions",
+        "//iree/base:file_io",
     ],
 )
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/CMakeLists.txt b/iree/compiler/Dialect/HAL/Target/LLVM/CMakeLists.txt
index 3916453..4aa0ad3 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/CMakeLists.txt
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/CMakeLists.txt
@@ -42,10 +42,17 @@
   SRCS
     "LLVMAOTTarget.cpp"
   DEPS
+    ::LLVMAOTTargetLinker
     ::LLVMIRPasses
     ::LLVMTargetOptions
+    LLVMAArch64AsmParser
+    LLVMAArch64CodeGen
+    LLVMARMAsmParser
+    LLVMARMCodeGen
     LLVMCore
     LLVMSupport
+    LLVMX86AsmParser
+    LLVMX86CodeGen
     MLIRTargetLLVMIR
     iree::compiler::Conversion::LinalgToLLVM
     iree::compiler::Dialect::HAL::Target
@@ -80,5 +87,28 @@
   DEPS
     LLVMPasses
     LLVMSupport
+    LLVMTarget
+  PUBLIC
+)
+
+iree_cc_library(
+  NAME
+    LLVMAOTTargetLinker
+  HDRS
+    "LLVMAOTTargetLinker.h"
+  DEPS
+    iree::base::file_io
+    iree::compiler::Dialect::HAL::Target::LLVM::internal::LLVMAOTTargetLinker_internal
+  PUBLIC
+)
+
+iree_cc_library(
+  NAME
+    LLVMAOTTargetLinker_hdrs
+  HDRS
+    "LLVMAOTTargetLinker.h"
+  DEPS
+    ::LLVMTargetOptions
+    iree::base::file_io
   PUBLIC
 )
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp
index c2b8d9f..7269089 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.cpp
@@ -14,7 +14,10 @@
 
 #include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTarget.h"
 
+#include <cstdlib>
+
 #include "iree/compiler/Conversion/LinalgToLLVM/Passes.h"
+#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTargetLinker.h"
 #include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.h"
 #include "iree/compiler/Dialect/HAL/Target/TargetRegistry.h"
 #include "iree/schemas/dylib_executable_def_generated.h"
@@ -54,6 +57,9 @@
     // At this moment we are leaving MLIR LLVM dialect land translating module
     // into target independent LLVMIR.
     auto llvmModule = mlir::translateModuleToLLVMIR(targetOp.getInnerModule());
+    if (!llvmModule) {
+      return failure();
+    }
 
     // Create invocation function an populate entry_points.
     auto executableOp = cast<ExecutableOp>(targetOp.getParentOp());
@@ -64,16 +70,55 @@
       std::string funcName =
           addCInterface ? "_mlir_ciface_" + std::string(entryPointOp.sym_name())
                         : std::string(entryPointOp.sym_name());
-      dyLibExecutableDef.entry_points.push_back(funcName);
+      dyLibExecutableDef.entry_points.push_back("invoke_" + funcName);
       createLLVMInvocationFunc(funcName, llvmModule.get());
     }
 
-    if (!llvmModule) {
+    // LLVMIR opt passes.
+    auto targetMachine = createTargetMachine(options_);
+    if (!targetMachine) {
+      targetOp.emitError("Can't create target machine for target triple: " +
+                         options_.targetTriple);
       return failure();
     }
 
-    // TODO(scotttodd): LLVM AOT compilation to
-    //   dyLibExecutableDef.library_embedded.assign(...)
+    llvmModule->setDataLayout(targetMachine->createDataLayout());
+    llvmModule->setTargetTriple(targetMachine->getTargetTriple().str());
+
+    if (failed(
+            runLLVMIRPasses(options_, targetMachine.get(), llvmModule.get()))) {
+      return targetOp.emitError(
+          "Can't build LLVMIR opt passes for ExecutableOp module");
+    }
+
+    std::string objData;
+    if (failed(runEmitObjFilePasses(targetMachine.get(), llvmModule.get(),
+                                    &objData))) {
+      return targetOp.emitError("Can't compile LLVMIR module to an obj");
+    }
+
+    std::string sharedLibData;
+    const char* linkerToolPath = std::getenv("IREE_LLVMAOT_LINKER_PATH");
+    if (linkerToolPath != nullptr) {
+      auto sharedLibDataStatus = linkLLVMAOTObjects(linkerToolPath, objData);
+      if (!sharedLibDataStatus.ok()) {
+        return targetOp.emitError(
+            "Can't link executable and generate target dylib, using linker "
+            "toolchain: '" +
+            std::string(linkerToolPath) + "'");
+      }
+      sharedLibData = sharedLibDataStatus.value();
+    } else {
+      auto sharedLibDataStatus = linkLLVMAOTObjectsWithLLDElf(objData);
+      if (!sharedLibDataStatus.ok()) {
+        return targetOp.emitError(
+            "Can't link executable and generate target dylib using "
+            "lld::elf::link");
+      }
+      sharedLibData = sharedLibDataStatus.value();
+    }
+    dyLibExecutableDef.library_embedded = {sharedLibData.begin(),
+                                           sharedLibData.end()};
 
     ::flatbuffers::FlatBufferBuilder fbb;
     auto executableOffset =
@@ -109,8 +154,15 @@
     std::function<LLVMTargetOptions()> queryOptions) {
   getLLVMTargetOptionsFromFlags();
   static TargetBackendRegistration registration("dylib-llvm-aot", [=]() {
-    // Initalize registered targets.
-    llvm::InitializeNativeTarget();
+#define INIT_LLVM_TARGET(TargetName)        \
+  LLVMInitialize##TargetName##Target();     \
+  LLVMInitialize##TargetName##TargetMC();   \
+  LLVMInitialize##TargetName##TargetInfo(); \
+  LLVMInitialize##TargetName##AsmPrinter(); \
+  LLVMInitialize##TargetName##AsmParser();
+    INIT_LLVM_TARGET(X86)
+    INIT_LLVM_TARGET(ARM)
+    INIT_LLVM_TARGET(AArch64)
     return std::make_unique<LLVMAOTTargetBackend>(queryOptions());
   });
 }
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTargetLinker.h b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTargetLinker.h
new file mode 100644
index 0000000..764ad02
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTargetLinker.h
@@ -0,0 +1,41 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef IREE_COMPILER_DIALECT_HAL_TARGET_LLVM_AOT_TARGET_LINKER_H_
+#define IREE_COMPILER_DIALECT_HAL_TARGET_LLVM_AOT_TARGET_LINKER_H_
+
+#include <string>
+
+#include "iree/base/file_io.h"
+#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+// Calls linker tool to link objData and returns shared library blob.
+iree::StatusOr<std::string> linkLLVMAOTObjects(
+    const std::string& linkerToolPath, const std::string& objData);
+// Use lld::elf::link for linking objData and returns shared library blob.
+iree::StatusOr<std::string> linkLLVMAOTObjectsWithLLDElf(
+    const std::string& objData);
+
+}  // namespace HAL
+}  // namespace IREE
+}  // namespace iree_compiler
+}  // namespace mlir
+
+#endif  // IREE_COMPILER_DIALECT_HAL_TARGET_LLVM_AOT_TARGET_LINKER_H_
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.cpp b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.cpp
index ede5f9d..cb2a526 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.cpp
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.cpp
@@ -15,6 +15,7 @@
 #include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.h"
 
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/Verifier.h"
@@ -31,15 +32,15 @@
 namespace HAL {
 
 std::unique_ptr<llvm::TargetMachine> createTargetMachine(
-    const LLVMTargetOptions& options) {
+    const LLVMTargetOptions& targetOptions) {
   std::string errorMessage;
-  auto target =
-      llvm::TargetRegistry::lookupTarget(options.targetTriple, errorMessage);
+  auto target = llvm::TargetRegistry::lookupTarget(targetOptions.targetTriple,
+                                                   errorMessage);
   if (!target) return nullptr;
   // TODO(ataei): Once we have an AOT backend pass cpu and cpu-features
   std::unique_ptr<llvm::TargetMachine> machine(target->createTargetMachine(
-      options.targetTriple, "generic" /* cpu e.g k8*/,
-      "" /* cpu features e.g avx512fma*/, {}, {}));
+      targetOptions.targetTriple, "generic" /* cpu e.g k8*/,
+      "" /* cpu features e.g avx512fma*/, targetOptions.options, {}));
   return machine;
 }
 
@@ -82,7 +83,7 @@
 }
 
 LogicalResult runLLVMIRPasses(const LLVMTargetOptions& options,
-                              std::unique_ptr<llvm::TargetMachine> machine,
+                              llvm::TargetMachine* machine,
                               llvm::Module* module) {
   llvm::LoopAnalysisManager loopAnalysisManager;
   llvm::FunctionAnalysisManager functionAnalysisManager;
@@ -93,8 +94,8 @@
   llvm::StandardInstrumentations standardInstrumentations;
   standardInstrumentations.registerCallbacks(passInstrumentationCallbacks);
 
-  llvm::PassBuilder passBuilder(machine.get(), options.pipelineTuningOptions,
-                                {}, &passInstrumentationCallbacks);
+  llvm::PassBuilder passBuilder(machine, options.pipelineTuningOptions, {},
+                                &passInstrumentationCallbacks);
   llvm::AAManager aa = passBuilder.buildDefaultAAPipeline();
   functionAnalysisManager.registerPass([&] { return std::move(aa); });
 
@@ -114,6 +115,28 @@
   return success();
 }
 
+LogicalResult runEmitObjFilePasses(llvm::TargetMachine* machine,
+                                   llvm::Module* module, std::string* objData) {
+  llvm::SmallVector<char, 0> stream_buffer;
+  {
+    // TODO(ataei): Use non legacy pass mamanger for this.
+    llvm::legacy::PassManager passManager;
+    passManager.add(
+        new llvm::TargetLibraryInfoWrapperPass(machine->getTargetTriple()));
+    llvm::raw_svector_ostream ostream(stream_buffer);
+    if (machine->addPassesToEmitFile(passManager, ostream,
+                                     /*DwoOut=*/nullptr,
+                                     llvm::CGFT_ObjectFile)) {
+      return failure();
+    }
+    passManager.run(*module);
+  }
+  // TODO(ataei): This is a work around stream truncation when directly write to
+  // string.
+  *objData = std::string(stream_buffer.begin(), stream_buffer.end());
+  return success();
+}
+
 }  // namespace HAL
 }  // namespace IREE
 }  // namespace iree_compiler
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.h b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.h
index 99fa937..199e36f 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.h
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRPasses.h
@@ -36,9 +36,13 @@
 
 // Creates and runs LLVMIR optimization passes defined in LLVMTargetOptions.
 LogicalResult runLLVMIRPasses(const LLVMTargetOptions& options,
-                              std::unique_ptr<llvm::TargetMachine> machine,
+                              llvm::TargetMachine* machine,
                               llvm::Module* module);
 
+// Emits compiled module obj for the target machine.
+LogicalResult runEmitObjFilePasses(llvm::TargetMachine* machine,
+                                   llvm::Module* module, std::string* objData);
+
 }  // namespace HAL
 }  // namespace IREE
 }  // namespace iree_compiler
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRTarget.cpp b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRTarget.cpp
index af5f3b2..98c0bf4 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRTarget.cpp
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMIRTarget.cpp
@@ -74,8 +74,8 @@
                          options_.targetTriple);
       return failure();
     }
-    if (failed(runLLVMIRPasses(options_, std::move(targetMachine),
-                               llvmModule.get()))) {
+    if (failed(
+            runLLVMIRPasses(options_, targetMachine.get(), llvmModule.get()))) {
       return targetOp.emitError(
           "Can't build LLVMIR opt passes for ExecutableOp module");
     }
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.cpp b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.cpp
index c82e7d0..e71beac 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.cpp
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.cpp
@@ -14,7 +14,10 @@
 
 #include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h"
 
+#include "llvm/ADT/APFloat.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Host.h"
+#include "llvm/Target/TargetOptions.h"
 
 namespace mlir {
 namespace iree_compiler {
@@ -33,12 +36,27 @@
   targetOptions.pipelineTuningOptions.SLPVectorization = true;
   // LLVM -O3.
   targetOptions.optLevel = llvm::PassBuilder::OptimizationLevel::O3;
+  targetOptions.options.FloatABIType = llvm::FloatABI::Hard;
   return targetOptions;
 }
 
 LLVMTargetOptions getLLVMTargetOptionsFromFlags() {
-  // TODO(ataei): Add flags and construct options.
-  return getDefaultLLVMTargetOptions();
+  auto llvmTargetOptions = getDefaultLLVMTargetOptions();
+
+  static llvm::cl::opt<std::string> clTargetTriple(
+      "iree-llvm-target-triple", llvm::cl::desc("LLVM target machine triple"),
+      llvm::cl::init(llvmTargetOptions.targetTriple));
+  static llvm::cl::opt<bool> clSoftFloat(
+      "iree-llvm-enable-msoft-float-abi",
+      llvm::cl::desc("LLVM target codegen enables soft float abi e.g "
+                     "-mfloat-abi=softfp"),
+      llvm::cl::init(false));
+
+  llvmTargetOptions.targetTriple = clTargetTriple;
+  if (clSoftFloat) {
+    llvmTargetOptions.options.FloatABIType = llvm::FloatABI::Soft;
+  }
+  return llvmTargetOptions;
 }
 
 }  // namespace HAL
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h
index d07dbe0..4893566 100644
--- a/iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/LLVMTargetOptions.h
@@ -16,6 +16,7 @@
 #define IREE_COMPILER_DIALECT_HAL_TARGET_LLVM_LLVMTARGETOPTIONS_H_
 
 #include "llvm/Passes/PassBuilder.h"
+#include "llvm/Target/TargetOptions.h"
 
 namespace mlir {
 namespace iree_compiler {
@@ -25,6 +26,7 @@
 struct LLVMTargetOptions {
   llvm::PipelineTuningOptions pipelineTuningOptions;
   llvm::PassBuilder::OptimizationLevel optLevel;
+  llvm::TargetOptions options;
   std::string targetTriple;
 };
 
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/internal/BUILD b/iree/compiler/Dialect/HAL/Target/LLVM/internal/BUILD
new file mode 100644
index 0000000..97cc95a
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/internal/BUILD
@@ -0,0 +1,27 @@
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+package(
+    default_visibility = ["//visibility:public"],
+    licenses = ["notice"],  # Apache 2.0
+)
+
+cc_library(
+    name = "LLVMAOTTargetLinker_internal",
+    srcs = ["LLVMAOTTargetLinker.cpp"],
+    deps = [
+        "//iree/base:file_io",
+        "//iree/compiler/Dialect/HAL/Target/LLVM:LLVMAOTTargetLinker_hdrs",
+    ],
+)
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/internal/CMakeLists.txt b/iree/compiler/Dialect/HAL/Target/LLVM/internal/CMakeLists.txt
new file mode 100644
index 0000000..3bb63dd
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/internal/CMakeLists.txt
@@ -0,0 +1,26 @@
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+iree_add_all_subdirs()
+
+iree_cc_library(
+  NAME
+    LLVMAOTTargetLinker_internal
+  SRCS
+    "LLVMAOTTargetLinker.cpp"
+  DEPS
+    iree::base::file_io
+    iree::compiler::Dialect::HAL::Target::LLVM::LLVMAOTTargetLinker_hdrs
+  PUBLIC
+)
diff --git a/iree/compiler/Dialect/HAL/Target/LLVM/internal/LLVMAOTTargetLinker.cpp b/iree/compiler/Dialect/HAL/Target/LLVM/internal/LLVMAOTTargetLinker.cpp
new file mode 100644
index 0000000..b883ef7
--- /dev/null
+++ b/iree/compiler/Dialect/HAL/Target/LLVM/internal/LLVMAOTTargetLinker.cpp
@@ -0,0 +1,43 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "iree/compiler/Dialect/HAL/Target/LLVM/LLVMAOTTargetLinker.h"
+
+namespace mlir {
+namespace iree_compiler {
+namespace IREE {
+namespace HAL {
+
+iree::StatusOr<std::string> linkLLVMAOTObjects(
+    const std::string& linkerToolPath, const std::string& objData) {
+  std::string archiveFile, sharedLibFile;
+  ASSIGN_OR_RETURN(archiveFile, iree::file_io::GetTempFile("objfile"));
+  RETURN_IF_ERROR(iree::file_io::SetFileContents(archiveFile, objData));
+  ASSIGN_OR_RETURN(sharedLibFile, iree::file_io::GetTempFile("dylibfile"));
+  std::string linkingCmd =
+      linkerToolPath + " -shared " + archiveFile + " -o " + sharedLibFile;
+  system(linkingCmd.c_str());
+  return iree::file_io::GetFileContents(sharedLibFile);
+}
+
+iree::StatusOr<std::string> linkLLVMAOTObjectsWithLLDElf(
+    const std::string& objData) {
+  return iree::UnimplementedErrorBuilder(IREE_LOC)
+         << "linkLLVMAOTObjectsWithLLD not implemented yet!";
+}
+
+}  // namespace HAL
+}  // namespace IREE
+}  // namespace iree_compiler
+}  // namespace mlir
diff --git a/iree/compiler/Dialect/IREE/IR/IREETypes.h b/iree/compiler/Dialect/IREE/IR/IREETypes.h
index 808433b..891e866 100644
--- a/iree/compiler/Dialect/IREE/IR/IREETypes.h
+++ b/iree/compiler/Dialect/IREE/IR/IREETypes.h
@@ -141,7 +141,8 @@
 };
 
 /// A buffer of constant mapped memory.
-class ByteBufferType : public Type::TypeBase<ByteBufferType, Type> {
+class ByteBufferType
+    : public Type::TypeBase<ByteBufferType, Type, TypeStorage> {
  public:
   using Base::Base;
 
@@ -154,7 +155,7 @@
 
 /// A buffer of read-write memory.
 class MutableByteBufferType
-    : public Type::TypeBase<MutableByteBufferType, Type> {
+    : public Type::TypeBase<MutableByteBufferType, Type, TypeStorage> {
  public:
   using Base::Base;
 
diff --git a/iree/compiler/Dialect/Modules/Strings/IR/Types.h b/iree/compiler/Dialect/Modules/Strings/IR/Types.h
index 2545e65..d67078e 100644
--- a/iree/compiler/Dialect/Modules/Strings/IR/Types.h
+++ b/iree/compiler/Dialect/Modules/Strings/IR/Types.h
@@ -24,7 +24,7 @@
 namespace IREE {
 namespace Strings {
 
-class StringType : public Type::TypeBase<StringType, Type> {
+class StringType : public Type::TypeBase<StringType, Type, TypeStorage> {
  public:
   using Base::Base;
   static StringType get(MLIRContext *context) {
@@ -33,7 +33,8 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::String; }
 };
 
-class StringTensorType : public Type::TypeBase<StringTensorType, Type> {
+class StringTensorType
+    : public Type::TypeBase<StringTensorType, Type, TypeStorage> {
  public:
   using Base::Base;
   static StringTensorType get(MLIRContext *context) {
diff --git a/iree/compiler/Dialect/Modules/TensorList/IR/TensorListTypes.h b/iree/compiler/Dialect/Modules/TensorList/IR/TensorListTypes.h
index 800127f..bc76f9c 100644
--- a/iree/compiler/Dialect/Modules/TensorList/IR/TensorListTypes.h
+++ b/iree/compiler/Dialect/Modules/TensorList/IR/TensorListTypes.h
@@ -30,7 +30,8 @@
 };
 }  // namespace TypeKind
 
-class TensorListType : public Type::TypeBase<TensorListType, Type> {
+class TensorListType
+    : public Type::TypeBase<TensorListType, Type, TypeStorage> {
  public:
   using Base::Base;
   static TensorListType get(MLIRContext *context) {
diff --git a/iree/compiler/Dialect/VM/IR/VMTypes.h b/iree/compiler/Dialect/VM/IR/VMTypes.h
index 27f96b2..67bc785 100644
--- a/iree/compiler/Dialect/VM/IR/VMTypes.h
+++ b/iree/compiler/Dialect/VM/IR/VMTypes.h
@@ -69,7 +69,7 @@
 };
 
 /// An opaque ref object that comes from an external source.
-class OpaqueType : public Type::TypeBase<OpaqueType, Type> {
+class OpaqueType : public Type::TypeBase<OpaqueType, Type, TypeStorage> {
  public:
   using Base::Base;
 
diff --git a/iree/compiler/Dialect/VMLA/IR/VMLATypes.h b/iree/compiler/Dialect/VMLA/IR/VMLATypes.h
index 139f565..634b903 100644
--- a/iree/compiler/Dialect/VMLA/IR/VMLATypes.h
+++ b/iree/compiler/Dialect/VMLA/IR/VMLATypes.h
@@ -43,7 +43,7 @@
 // RefObject types
 //===----------------------------------------------------------------------===//
 
-class BufferType : public Type::TypeBase<BufferType, Type> {
+class BufferType : public Type::TypeBase<BufferType, Type, TypeStorage> {
  public:
   using Base::Base;
   static BufferType get(MLIRContext *context) {
@@ -52,7 +52,7 @@
   static bool kindof(unsigned kind) { return kind == TypeKind::Buffer; }
 };
 
-class InterfaceType : public Type::TypeBase<InterfaceType, Type> {
+class InterfaceType : public Type::TypeBase<InterfaceType, Type, TypeStorage> {
  public:
   using Base::Base;
   static InterfaceType get(MLIRContext *context) {
diff --git a/iree/samples/custom_modules/dialect/custom_dialect.h b/iree/samples/custom_modules/dialect/custom_dialect.h
index f112cfe..7a5c9b1 100644
--- a/iree/samples/custom_modules/dialect/custom_dialect.h
+++ b/iree/samples/custom_modules/dialect/custom_dialect.h
@@ -41,7 +41,7 @@
   void printType(Type type, DialectAsmPrinter &p) const override;
 };
 
-class MessageType : public Type::TypeBase<MessageType, Type> {
+class MessageType : public Type::TypeBase<MessageType, Type, TypeStorage> {
  public:
   using Base::Base;
   static MessageType get(MLIRContext *context) {
diff --git a/third_party/llvm-project b/third_party/llvm-project
index e34523c..7d9518c 160000
--- a/third_party/llvm-project
+++ b/third_party/llvm-project
@@ -1 +1 @@
-Subproject commit e34523c87c3f1cfabcf741568dede026bbb12d3a
+Subproject commit 7d9518c8000bcd742b364a390bc79560f736dc96