diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt
--- a/compiler-rt/lib/asan/CMakeLists.txt
+++ b/compiler-rt/lib/asan/CMakeLists.txt
@@ -24,6 +24,7 @@
   asan_premap_shadow.cpp
   asan_report.cpp
   asan_rtl.cpp
+  asan_rtl_x86_64.S
   asan_shadow_setup.cpp
   asan_stack.cpp
   asan_stats.cpp
diff --git a/compiler-rt/lib/asan/asan_interface.inc b/compiler-rt/lib/asan/asan_interface.inc
--- a/compiler-rt/lib/asan/asan_interface.inc
+++ b/compiler-rt/lib/asan/asan_interface.inc
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 // Asan interface list.
 //===----------------------------------------------------------------------===//
+
 INTERFACE_FUNCTION(__asan_addr_is_in_fake_stack)
 INTERFACE_FUNCTION(__asan_address_is_poisoned)
 INTERFACE_FUNCTION(__asan_after_dynamic_init)
@@ -179,3 +180,36 @@
 INTERFACE_WEAK_FUNCTION(__asan_default_options)
 INTERFACE_WEAK_FUNCTION(__asan_default_suppressions)
 INTERFACE_WEAK_FUNCTION(__asan_on_error)
+
+#if defined(__x86_64__)
+
+#  define ASAN_MEMORY_ACCESS_CALLBACK_ADD(s, reg, op) \
+    INTERFACE_FUNCTION(__asan_check_##op##_add_##s##_##reg)
+
+#  define ASAN_MEMORY_ACCESS_CALLBACKS_ADD(reg)    \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(1, reg, load)  \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(1, reg, store) \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(2, reg, load)  \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(2, reg, store) \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(4, reg, load)  \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(4, reg, store) \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(8, reg, load)  \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(8, reg, store) \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(16, reg, load) \
+    ASAN_MEMORY_ACCESS_CALLBACK_ADD(16, reg, store)
+
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RAX)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBX)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RCX)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDX)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RSI)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDI)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBP)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R8)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R9)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R12)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R13)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R14)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R15)
+
+#endif  // defined(__x86_64__)
diff --git a/compiler-rt/lib/asan/asan_rtl_x86_64.S b/compiler-rt/lib/asan/asan_rtl_x86_64.S
new file mode 100644
--- /dev/null
+++ b/compiler-rt/lib/asan/asan_rtl_x86_64.S
@@ -0,0 +1,143 @@
+#include "asan_mapping.h"
+#include "sanitizer_common/sanitizer_asm.h"
+
+#if defined(__x86_64__)
+#include "sanitizer_common/sanitizer_platform.h"
+
+.section .text
+.file "asan_rtl_x86_64.S"
+
+#define NAME(n, reg, op, s, i) n##_##op##_##i##_##s##_##reg
+
+#define FNAME(reg, op, s, i) NAME(__asan_check, reg, op, s, i)
+#define RLABEL(reg, op, s, i) NAME(.return, reg, op, s, i)
+#define CLABEL(reg, op, s, i) NAME(.check, reg, op, s, i)
+#define FLABEL(reg, op, s, i) NAME(.fail, reg, op, s, i)
+
+#define BEGINF(reg, op, s, i) \
+.globl  FNAME(reg, op, s, i) ;\
+ASM_TYPE_FUNCTION(FNAME(reg, op, s, i)) ;\
+.cfi_startproc ;\
+FNAME(reg, op, s, i): ;\
+
+#define ENDF .cfi_endproc ;\
+
+// Access check functions for 1,2 and 4 byte types, which require extra checks.
+#define ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, s) \
+        mov    %##reg,%r10 ;\
+        shr    $0x3,%r10 ;\
+        movsbl ASAN_SHADOW_OFFSET_CONST(%r10),%r10d ;\
+        test   %r10d,%r10d ;\
+        jne    CLABEL(reg, op, s, add) ;\
+RLABEL(reg, op, s, add): ;\
+        retq  ;\
+
+#define ASAN_MEMORY_ACCESS_EXTRA_CHECK_1(reg, op, i) \
+CLABEL(reg, op, 1, i): ;\
+        push   %rcx ;\
+        mov    %##reg,%rcx ;\
+        and    $0x7,%ecx ;\
+        cmp    %r10d,%ecx ;\
+        pop    %rcx ;\
+        jl     RLABEL(reg, op, 1, i);\
+        mov    %##reg,%rdi ;\
+        jmp    __asan_report_##op##1 ;\
+
+#define ASAN_MEMORY_ACCESS_EXTRA_CHECK_2(reg, op, i) \
+CLABEL(reg, op, 2, i): ;\
+        push   %rcx ;\
+        mov    %##reg,%rcx ;\
+        and    $0x7,%ecx ;\
+        add    $0x1,%ecx ;\
+        cmp    %r10d,%ecx ;\
+        pop    %rcx ;\
+        jl     RLABEL(reg, op, 2, i);\
+        mov    %##reg,%rdi ;\
+        jmp    __asan_report_##op##2 ;\
+
+#define ASAN_MEMORY_ACCESS_EXTRA_CHECK_4(reg, op, i) \
+CLABEL(reg, op, 4, i): ;\
+        push   %rcx ;\
+        mov    %##reg,%rcx ;\
+        and    $0x7,%ecx ;\
+        add    $0x3,%ecx ;\
+        cmp    %r10d,%ecx ;\
+        pop    %rcx ;\
+        jl     RLABEL(reg, op, 4, i);\
+        mov    %##reg,%rdi ;\
+        jmp    __asan_report_##op##4 ;\
+
+#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, op) \
+BEGINF(reg, op, 1, add) ;\
+        ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 1) ;\
+        ASAN_MEMORY_ACCESS_EXTRA_CHECK_1(reg, op, add) ;\
+ENDF
+
+#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, op) \
+BEGINF(reg, op, 2, add) ;\
+        ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 2) ;\
+        ASAN_MEMORY_ACCESS_EXTRA_CHECK_2(reg, op, add) ;\
+ENDF
+
+#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, op) \
+BEGINF(reg, op, 4, add) ;\
+        ASAN_MEMORY_ACCESS_INITIAL_CHECK_ADD(reg, op, 4) ;\
+        ASAN_MEMORY_ACCESS_EXTRA_CHECK_4(reg, op, add) ;\
+ENDF
+
+// Access check functions for 8 and 16 byte types: no extra checks required.
+#define ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, s, c) \
+        mov    %##reg,%r10 ;\
+        shr    $0x3,%r10 ;\
+        ##c    $0x0,ASAN_SHADOW_OFFSET_CONST(%r10) ;\
+        jne    FLABEL(reg, op, s, add) ;\
+        retq  ;\
+
+#define ASAN_MEMORY_ACCESS_FAIL(reg, op, s, i) \
+FLABEL(reg, op, s, i): ;\
+        mov    %##reg,%rdi ;\
+        jmp    __asan_report_##op##s ;\
+
+#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, op) \
+BEGINF(reg, op, 8, add) ;\
+        ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, 8, cmpb) ;\
+        ASAN_MEMORY_ACCESS_FAIL(reg, op, 8, add) ;\
+ENDF
+
+#define ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, op) \
+BEGINF(reg, op, 16, add) ;\
+        ASAN_MEMORY_ACCESS_CHECK_ADD(reg, op, 16, cmpw) ;\
+        ASAN_MEMORY_ACCESS_FAIL(reg, op, 16, add) ;\
+ENDF
+
+#define ASAN_MEMORY_ACCESS_CALLBACKS_ADD(reg) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, load) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_1(reg, store) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, load) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_2(reg, store) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, load) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_4(reg, store) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, load) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_8(reg, store) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, load) \
+ASAN_MEMORY_ACCESS_CALLBACK_ADD_16(reg, store) \
+
+
+// Instantiate all but R10 and R11 callbacks. We are using PLTSafe class with
+// the intrinsic, which guarantees that the code generation will never emit
+// R10 or R11 callback.
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RAX)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBX)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RCX)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDX)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RSI)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDI)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBP)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R8)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R9)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R12)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R13)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R14)
+ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R15)
+
+#endif
diff --git a/compiler-rt/lib/asan/tests/asan_noinst_test.cpp b/compiler-rt/lib/asan/tests/asan_noinst_test.cpp
--- a/compiler-rt/lib/asan/tests/asan_noinst_test.cpp
+++ b/compiler-rt/lib/asan/tests/asan_noinst_test.cpp
@@ -231,17 +231,8 @@
 }
 
 // Test __asan_load1 & friends.
-TEST(AddressSanitizer, LoadStoreCallbacks) {
-  typedef void (*CB)(uptr p);
-  CB cb[2][5] = {
-      {
-        __asan_load1, __asan_load2, __asan_load4, __asan_load8, __asan_load16,
-      }, {
-        __asan_store1, __asan_store2, __asan_store4, __asan_store8,
-        __asan_store16,
-      }
-  };
-
+typedef void (*CB)(uptr p);
+static void TestLoadStoreCallbacks(CB cb[2][5]) {
   uptr buggy_ptr;
 
   __asan_test_only_reported_buggy_pointer = &buggy_ptr;
@@ -271,3 +262,85 @@
   }
   __asan_test_only_reported_buggy_pointer = 0;
 }
+
+TEST(AddressSanitizer, LoadStoreCallbacks) {
+  CB cb[2][5] = {{
+                     __asan_load1,
+                     __asan_load2,
+                     __asan_load4,
+                     __asan_load8,
+                     __asan_load16,
+                 },
+                 {
+                     __asan_store1,
+                     __asan_store2,
+                     __asan_store4,
+                     __asan_store8,
+                     __asan_store16,
+                 }};
+  TestLoadStoreCallbacks(cb);
+}
+
+// clang-format off
+#if defined(__x86_64__)
+
+#define CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(s, reg, op)        \
+  void CallAsanMemoryAccessAdd##reg##op##s(uptr address) {      \
+  asm("push  %%" #reg " \n"                                     \
+  "mov   %[x], %%" #reg " \n"                                   \
+  "call  __asan_check_" #op "_add_" #s "_" #reg "\n"            \
+  "pop   %%" #reg " \n"                                         \
+  :                                                             \
+  : [x] "r"(address)                                            \
+      : "r8", "rdi");                                           \
+  }
+
+#define TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(reg)            \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(1, reg, load)          \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(1, reg, store)         \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(2, reg, load)          \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(2, reg, store)         \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(4, reg, load)          \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(4, reg, store)         \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(8, reg, load)          \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(8, reg, store)         \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(16, reg, load)         \
+  CALL_ASAN_MEMORY_ACCESS_CALLBACK_ADD(16, reg, store)        \
+                                                              \
+  TEST(AddressSanitizer, LoadStoreCallbacksAddX86##reg) {     \
+    CB cb[2][5] = {{                                          \
+                       CallAsanMemoryAccessAdd##reg##load1,   \
+                       CallAsanMemoryAccessAdd##reg##load2,   \
+                       CallAsanMemoryAccessAdd##reg##load4,   \
+                       CallAsanMemoryAccessAdd##reg##load8,   \
+                       CallAsanMemoryAccessAdd##reg##load16,  \
+                   },                                         \
+                   {                                          \
+                       CallAsanMemoryAccessAdd##reg##store1,  \
+                       CallAsanMemoryAccessAdd##reg##store2,  \
+                       CallAsanMemoryAccessAdd##reg##store4,  \
+                       CallAsanMemoryAccessAdd##reg##store8,  \
+                       CallAsanMemoryAccessAdd##reg##store16, \
+                   }};                                        \
+    TestLoadStoreCallbacks(cb);                               \
+  }
+
+// Instantiate all but R10 and R11 callbacks. We are using PLTSafe class with
+// the intrinsic, which guarantees that the code generation will never emit
+// R10 or R11 callbacks.
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RAX)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBX)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RCX)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDX)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RSI)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RDI)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(RBP)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R8)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R9)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R12)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R13)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R14)
+TEST_ASAN_MEMORY_ACCESS_CALLBACKS_ADD(R15)
+
+#endif  // defined(__x86_64__)
+// clang-format on
diff --git a/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp b/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp
--- a/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp
+++ b/compiler-rt/test/asan/TestCases/Linux/interface_symbols_linux.cpp
@@ -1,5 +1,7 @@
 // Check the presence of interface symbols in compiled file.
 
+// RUN: %clangxx -x c++-header -o - -E %p/../../../../lib/asan/asan_interface.inc  \
+// RUN:  | sed "s/INTERFACE_FUNCTION/\nINTERFACE_FUNCTION/g" >  %t.asan_interface.inc
 // RUN: %clangxx_asan -O2 %s -o %t.exe
 // RUN: nm -D %t.exe | grep " [TWw] "                                          \
 // RUN:  | grep -o "\(__asan_\|__ubsan_\|__sancov_\|__sanitizer_\)[^ ]*"       \
@@ -10,7 +12,7 @@
 // RUN:  > %t.exports
 //
 // RUN: grep -e "INTERFACE_\(WEAK_\)\?FUNCTION"                                \
-// RUN:  %p/../../../../lib/asan/asan_interface.inc                            \
+// RUN:  %t.asan_interface.inc                                                 \
 // RUN:  %p/../../../../lib/ubsan/ubsan_interface.inc                          \
 // RUN:  %p/../../../../lib/sanitizer_common/sanitizer_common_interface.inc    \
 // RUN:  %p/../../../../lib/sanitizer_common/sanitizer_common_interface_posix.inc \
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h
--- a/llvm/lib/Target/X86/X86AsmPrinter.h
+++ b/llvm/lib/Target/X86/X86AsmPrinter.h
@@ -100,20 +100,6 @@
 
   // Address sanitizer specific lowering for X86.
   void LowerASAN_CHECK_MEMACCESS(const MachineInstr &MI);
-  void emitAsanMemaccessSymbols(Module &M);
-  void emitAsanMemaccessPartial(Module &M, unsigned Reg,
-                                const ASanAccessInfo &AccessInfo,
-                                MCSubtargetInfo &STI);
-  void emitAsanMemaccessFull(Module &M, unsigned Reg,
-                             const ASanAccessInfo &AccessInfo,
-                             MCSubtargetInfo &STI);
-  void emitAsanReportError(Module &M, unsigned Reg,
-                           const ASanAccessInfo &AccessInfo,
-                           MCSubtargetInfo &STI);
-
-  typedef std::tuple<unsigned /*Reg*/, uint32_t /*AccessInfo*/>
-      AsanMemaccessTuple;
-  std::map<AsanMemaccessTuple, MCSymbol *> AsanMemaccessSymbols;
 
   // Choose between emitting .seh_ directives and .cv_fpo_ directives.
   void EmitSEHInstruction(const MachineInstr *MI);
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -754,8 +754,6 @@
 void X86AsmPrinter::emitEndOfAsmFile(Module &M) {
   const Triple &TT = TM.getTargetTriple();
 
-  emitAsanMemaccessSymbols(M);
-
   if (TT.isOSBinFormatMachO()) {
     // Mach-O uses non-lazy symbol stubs to encode per-TU information into
     // global table for symbol lookup.
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -48,6 +48,7 @@
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
+#include <string>
 
 using namespace llvm;
 
@@ -1336,235 +1337,26 @@
     return;
   }
 
-  unsigned Reg = MI.getOperand(0).getReg().id();
+  const auto &Reg = MI.getOperand(0).getReg();
   ASanAccessInfo AccessInfo(MI.getOperand(1).getImm());
 
-  MCSymbol *&Sym =
-      AsanMemaccessSymbols[AsanMemaccessTuple(Reg, AccessInfo.Packed)];
-  if (!Sym) {
-    std::string Name = AccessInfo.IsWrite ? "store" : "load";
-    std::string SymName = "__asan_check_" + Name +
-                          utostr(1ULL << AccessInfo.AccessSizeIndex) + "_rn" +
-                          utostr(Reg);
-    Sym = OutContext.getOrCreateSymbol(SymName);
-  }
-
-  EmitAndCountInstruction(
-      MCInstBuilder(X86::CALL64pcrel32)
-          .addExpr(MCSymbolRefExpr::create(Sym, OutContext)));
-}
-
-void X86AsmPrinter::emitAsanMemaccessPartial(Module &M, unsigned Reg,
-                                             const ASanAccessInfo &AccessInfo,
-                                             MCSubtargetInfo &STI) {
-  assert(AccessInfo.AccessSizeIndex == 0 || AccessInfo.AccessSizeIndex == 1 ||
-         AccessInfo.AccessSizeIndex == 2);
-  assert(Reg != X86::R10);
-  assert(Reg != X86::R11);
-
-  uint64_t ShadowBase;
-  int MappingScale;
-  bool OrShadowOffset;
-  getAddressSanitizerParams(
-      Triple(M.getTargetTriple()), M.getDataLayout().getPointerSizeInBits(),
-      AccessInfo.CompileKernel, &ShadowBase, &MappingScale, &OrShadowOffset);
-
-  OutStreamer->emitInstruction(MCInstBuilder(X86::MOV64rr)
-                                   .addReg(X86::R10)
-                                   .addReg(X86::NoRegister + Reg),
-                               STI);
-  OutStreamer->emitInstruction(MCInstBuilder(X86::SHR64ri)
-                                   .addReg(X86::R10)
-                                   .addReg(X86::R10)
-                                   .addImm(MappingScale),
-                               STI);
-  if (OrShadowOffset) {
-    OutStreamer->emitInstruction(MCInstBuilder(X86::OR64ri32)
-                                     .addReg(X86::R10)
-                                     .addReg(X86::R10)
-                                     .addImm(ShadowBase),
-                                 STI);
-    OutStreamer->emitInstruction(MCInstBuilder(X86::MOV8rm)
-                                     .addReg(X86::R10B)
-                                     .addReg(X86::R10)
-                                     .addImm(1)
-                                     .addReg(X86::NoRegister)
-                                     .addImm(0)
-                                     .addReg(X86::NoRegister),
-                                 STI);
-    OutStreamer->emitInstruction(
-        MCInstBuilder(X86::TEST8rr).addReg(X86::R10B).addReg(X86::R10B), STI);
-  } else {
-    OutStreamer->emitInstruction(MCInstBuilder(X86::MOVSX32rm8)
-                                     .addReg(X86::R10D)
-                                     .addReg(X86::R10)
-                                     .addImm(1)
-                                     .addReg(X86::NoRegister)
-                                     .addImm(ShadowBase)
-                                     .addReg(X86::NoRegister),
-                                 STI);
-    OutStreamer->emitInstruction(
-        MCInstBuilder(X86::TEST32rr).addReg(X86::R10D).addReg(X86::R10D), STI);
-  }
-  MCSymbol *AdditionalCheck = OutContext.createTempSymbol();
-  OutStreamer->emitInstruction(
-      MCInstBuilder(X86::JCC_1)
-          .addExpr(MCSymbolRefExpr::create(AdditionalCheck, OutContext))
-          .addImm(X86::COND_NE),
-      STI);
-  MCSymbol *ReturnSym = OutContext.createTempSymbol();
-  OutStreamer->emitLabel(ReturnSym);
-  OutStreamer->emitInstruction(MCInstBuilder(getRetOpcode(*Subtarget)), STI);
-
-  // Shadow byte is non-zero so we need to perform additional checks.
-  OutStreamer->emitLabel(AdditionalCheck);
-  OutStreamer->emitInstruction(MCInstBuilder(X86::MOV64rr)
-                                   .addReg(X86::R11)
-                                   .addReg(X86::NoRegister + Reg),
-                               STI);
-  const size_t Granularity = 1ULL << MappingScale;
-  OutStreamer->emitInstruction(MCInstBuilder(X86::AND32ri8)
-                                   .addReg(X86::NoRegister)
-                                   .addReg(X86::R11D)
-                                   .addImm(Granularity - 1),
-                               STI);
-  if (AccessInfo.AccessSizeIndex == 1) {
-    OutStreamer->emitInstruction(MCInstBuilder(X86::ADD32ri8)
-                                     .addReg(X86::NoRegister)
-                                     .addReg(X86::R11D)
-                                     .addImm(1),
-                                 STI);
-  } else if (AccessInfo.AccessSizeIndex == 2) {
-    OutStreamer->emitInstruction(MCInstBuilder(X86::ADD32ri8)
-                                     .addReg(X86::NoRegister)
-                                     .addReg(X86::R11D)
-                                     .addImm(3),
-                                 STI);
-  }
-
-  OutStreamer->emitInstruction(
-      MCInstBuilder(X86::CMP32rr).addReg(X86::R11D).addReg(X86::R10D).addImm(1),
-      STI);
-  OutStreamer->emitInstruction(
-      MCInstBuilder(X86::JCC_1)
-          .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext))
-          .addImm(X86::COND_L),
-      STI);
-
-  emitAsanReportError(M, Reg, AccessInfo, STI);
-}
-
-void X86AsmPrinter::emitAsanMemaccessFull(Module &M, unsigned Reg,
-                                          const ASanAccessInfo &AccessInfo,
-                                          MCSubtargetInfo &STI) {
-  assert(AccessInfo.AccessSizeIndex == 3 || AccessInfo.AccessSizeIndex == 4);
-  assert(Reg != X86::R10);
-  assert(Reg != X86::R11);
-
   uint64_t ShadowBase;
   int MappingScale;
   bool OrShadowOffset;
-  getAddressSanitizerParams(
-      Triple(M.getTargetTriple()), M.getDataLayout().getPointerSizeInBits(),
-      AccessInfo.CompileKernel, &ShadowBase, &MappingScale, &OrShadowOffset);
-
-  OutStreamer->emitInstruction(MCInstBuilder(X86::MOV64rr)
-                                   .addReg(X86::R10)
-                                   .addReg(X86::NoRegister + Reg),
-                               STI);
-  OutStreamer->emitInstruction(MCInstBuilder(X86::SHR64ri)
-                                   .addReg(X86::R10)
-                                   .addReg(X86::R10)
-                                   .addImm(MappingScale),
-                               STI);
-  if (OrShadowOffset) {
-    OutStreamer->emitInstruction(MCInstBuilder(X86::OR64ri32)
-                                     .addReg(X86::R10)
-                                     .addReg(X86::R10)
-                                     .addImm(ShadowBase),
-                                 STI);
-    auto OpCode = AccessInfo.AccessSizeIndex == 3 ? X86::CMP8mi : X86::CMP16mi8;
-    OutStreamer->emitInstruction(MCInstBuilder(OpCode)
-                                     .addReg(X86::R10)
-                                     .addImm(1)
-                                     .addReg(X86::NoRegister)
-                                     .addImm(0)
-                                     .addReg(X86::NoRegister)
-                                     .addImm(0),
-                                 STI);
-  } else {
-    auto OpCode = AccessInfo.AccessSizeIndex == 3 ? X86::CMP8mi : X86::CMP16mi8;
-    OutStreamer->emitInstruction(MCInstBuilder(OpCode)
-                                     .addReg(X86::R10)
-                                     .addImm(1)
-                                     .addReg(X86::NoRegister)
-                                     .addImm(ShadowBase)
-                                     .addReg(X86::NoRegister)
-                                     .addImm(0),
-                                 STI);
-  }
-  MCSymbol *ReportCode = OutContext.createTempSymbol();
-  OutStreamer->emitInstruction(
-      MCInstBuilder(X86::JCC_1)
-          .addExpr(MCSymbolRefExpr::create(ReportCode, OutContext))
-          .addImm(X86::COND_NE),
-      STI);
-  MCSymbol *ReturnSym = OutContext.createTempSymbol();
-  OutStreamer->emitLabel(ReturnSym);
-  OutStreamer->emitInstruction(MCInstBuilder(getRetOpcode(*Subtarget)), STI);
-
-  OutStreamer->emitLabel(ReportCode);
-  emitAsanReportError(M, Reg, AccessInfo, STI);
-}
+  getAddressSanitizerParams(Triple(TM.getTargetTriple()), 64,
+                            AccessInfo.CompileKernel, &ShadowBase,
+                            &MappingScale, &OrShadowOffset);
 
-void X86AsmPrinter::emitAsanReportError(Module &M, unsigned Reg,
-                                        const ASanAccessInfo &AccessInfo,
-                                        MCSubtargetInfo &STI) {
   std::string Name = AccessInfo.IsWrite ? "store" : "load";
-  MCSymbol *ReportError = OutContext.getOrCreateSymbol(
-      "__asan_report_" + Name + utostr(1ULL << AccessInfo.AccessSizeIndex));
-  OutStreamer->emitInstruction(MCInstBuilder(X86::MOV64rr)
-                                   .addReg(X86::RDI)
-                                   .addReg(X86::NoRegister + Reg),
-                               STI);
-  OutStreamer->emitInstruction(
-      MCInstBuilder(X86::JMP_4)
-          .addExpr(MCSymbolRefExpr::create(ReportError, MCSymbolRefExpr::VK_PLT,
-                                           OutContext)),
-      STI);
-}
+  std::string Op = OrShadowOffset ? "or" : "add";
+  std::string SymName = "__asan_check_" + Name + "_" + Op + "_" +
+                        utostr(1ULL << AccessInfo.AccessSizeIndex) + "_" +
+                        TM.getMCRegisterInfo()->getName(Reg.asMCReg());
 
-void X86AsmPrinter::emitAsanMemaccessSymbols(Module &M) {
-  if (AsanMemaccessSymbols.empty())
-    return;
-
-  const Triple &TT = TM.getTargetTriple();
-  assert(TT.isOSBinFormatELF());
-  std::unique_ptr<MCSubtargetInfo> STI(
-      TM.getTarget().createMCSubtargetInfo(TT.str(), "", ""));
-  assert(STI && "Unable to create subtarget info");
-
-  for (auto &P : AsanMemaccessSymbols) {
-    MCSymbol *Sym = P.second;
-    OutStreamer->SwitchSection(OutContext.getELFSection(
-        ".text.hot", ELF::SHT_PROGBITS,
-        ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, Sym->getName(),
-        /*IsComdat=*/true));
-
-    OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
-    OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);
-    OutStreamer->emitSymbolAttribute(Sym, MCSA_Hidden);
-    OutStreamer->emitLabel(Sym);
-
-    unsigned Reg = std::get<0>(P.first);
-    ASanAccessInfo AccessInfo(std::get<1>(P.first));
-
-    if (AccessInfo.AccessSizeIndex < 3) {
-      emitAsanMemaccessPartial(M, Reg, AccessInfo, *STI);
-    } else {
-      emitAsanMemaccessFull(M, Reg, AccessInfo, *STI);
-    }
-  }
+  EmitAndCountInstruction(
+      MCInstBuilder(X86::CALL64pcrel32)
+          .addExpr(MCSymbolRefExpr::create(
+              OutContext.getOrCreateSymbol(SymName), OutContext)));
 }
 
 void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI,
diff --git a/llvm/test/CodeGen/X86/asan-check-memaccess-add.ll b/llvm/test/CodeGen/X86/asan-check-memaccess-add.ll
--- a/llvm/test/CodeGen/X86/asan-check-memaccess-add.ll
+++ b/llvm/test/CodeGen/X86/asan-check-memaccess-add.ll
@@ -5,8 +5,8 @@
 define void @load1(i8* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load1_rn[[RN1:.*]]
-; CHECK:              callq   __asan_check_store1_rn[[RN1]]
+; CHECK:              callq   __asan_check_load_add_1_[[REG1:.*]]
+; CHECK:              callq   __asan_check_store_add_1_[[REG1]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   call void @llvm.asan.check.memaccess(i8* %x, i32 0)
@@ -17,8 +17,8 @@
 define void @load2(i16* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load2_rn[[RN2:.*]]
-; CHECK:              callq   __asan_check_store2_rn[[RN2]]
+; CHECK:              callq   __asan_check_load_add_2_[[REG2:.*]]
+; CHECK:              callq   __asan_check_store_add_2_[[REG2]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   %1 = ptrtoint i16* %x to i64
@@ -31,8 +31,8 @@
 define void @load4(i32* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load4_rn[[RN4:.*]]
-; CHECK:              callq   __asan_check_store4_rn[[RN4]]
+; CHECK:              callq   __asan_check_load_add_4_[[REG4:.*]]
+; CHECK:              callq   __asan_check_store_add_4_[[REG4]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   %1 = ptrtoint i32* %x to i64
@@ -44,8 +44,8 @@
 define void @load8(i64* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load8_rn[[RN8:.*]]
-; CHECK:              callq   __asan_check_store8_rn[[RN8]]
+; CHECK:              callq   __asan_check_load_add_8_[[REG8:.*]]
+; CHECK:              callq   __asan_check_store_add_8_[[REG8]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   %1 = ptrtoint i64* %x to i64
@@ -58,8 +58,8 @@
 define void @load16(i128* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load16_rn[[RN16:.*]]
-; CHECK:              callq   __asan_check_store16_rn[[RN16]]
+; CHECK:              callq   __asan_check_load_add_16_[[REG16:.*]]
+; CHECK:              callq   __asan_check_store_add_16_[[REG16]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   %1 = ptrtoint i128* %x to i64
@@ -69,178 +69,4 @@
   ret void
 }
 
-; CHECK:              .type   __asan_check_load1_rn[[RN1]],@function
-; CHECK-NEXT:         .weak   __asan_check_load1_rn[[RN1]]
-; CHECK-NEXT:         .hidden __asan_check_load1_rn[[RN1]]
-; CHECK-NEXT: __asan_check_load1_rn[[RN1]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         movsbl  2147450880(%r10), %r10d
-; CHECK-NEXT:         testl   %r10d, %r10d
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load1
-
-; CHECK:              .type   __asan_check_load2_rn[[RN2]],@function
-; CHECK-NEXT:         .weak   __asan_check_load2_rn[[RN2]]
-; CHECK-NEXT:         .hidden __asan_check_load2_rn[[RN2]]
-; CHECK-NEXT: __asan_check_load2_rn[[RN2]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         movsbl  2147450880(%r10), %r10d
-; CHECK-NEXT:         testl   %r10d, %r10d
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         addl    $1, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load2
-
-; CHECK:              .type   __asan_check_load4_rn[[RN4]],@function
-; CHECK-NEXT:         .weak   __asan_check_load4_rn[[RN4]]
-; CHECK-NEXT:         .hidden __asan_check_load4_rn[[RN4]]
-; CHECK-NEXT: __asan_check_load4_rn[[RN4]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         movsbl  2147450880(%r10), %r10d
-; CHECK-NEXT:         testl   %r10d, %r10d
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         addl    $3, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load4
-
-; CHECK:              .type   __asan_check_load8_rn[[RN8]],@function
-; CHECK-NEXT:         .weak   __asan_check_load8_rn[[RN8]]
-; CHECK-NEXT:         .hidden __asan_check_load8_rn[[RN8]]
-; CHECK-NEXT: __asan_check_load8_rn[[RN8]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         cmpb    $0, 2147450880(%r10)
-; CHECK-NEXT:         jne     [[FAIL:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[FAIL]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load8
-
-; CHECK:              .type   __asan_check_load16_rn[[RN16]],@function
-; CHECK-NEXT:         .weak   __asan_check_load16_rn[[RN16]]
-; CHECK-NEXT:         .hidden __asan_check_load16_rn[[RN16]]
-; CHECK-NEXT: __asan_check_load16_rn[[RN16]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         cmpw    $0, 2147450880(%r10)
-; CHECK-NEXT:         jne     [[FAIL:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[FAIL]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load16
-
-; CHECK:              .type   __asan_check_store1_rn[[RN1]],@function
-; CHECK-NEXT:         .weak   __asan_check_store1_rn[[RN1]]
-; CHECK-NEXT:         .hidden __asan_check_store1_rn[[RN1]]
-; CHECK-NEXT: __asan_check_store1_rn[[RN1]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         movsbl  2147450880(%r10), %r10d
-; CHECK-NEXT:         testl   %r10d, %r10d
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store1@PLT
-
-; CHECK:              .type   __asan_check_store2_rn[[RN2]],@function
-; CHECK-NEXT:         .weak   __asan_check_store2_rn[[RN2]]
-; CHECK-NEXT:         .hidden __asan_check_store2_rn[[RN2]]
-; CHECK-NEXT: __asan_check_store2_rn[[RN2]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         movsbl  2147450880(%r10), %r10d
-; CHECK-NEXT:         testl   %r10d, %r10d
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         addl    $1, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store2@PLT
-
-; CHECK:              .type   __asan_check_store4_rn[[RN4]],@function
-; CHECK-NEXT:         .weak   __asan_check_store4_rn[[RN4]]
-; CHECK-NEXT:         .hidden __asan_check_store4_rn[[RN4]]
-; CHECK-NEXT: __asan_check_store4_rn[[RN4]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         movsbl  2147450880(%r10), %r10d
-; CHECK-NEXT:         testl   %r10d, %r10d
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         addl    $3, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store4@PLT
-
-; CHECK:              .type   __asan_check_store8_rn[[RN8]],@function
-; CHECK-NEXT:         .weak   __asan_check_store8_rn[[RN8]]
-; CHECK-NEXT:         .hidden __asan_check_store8_rn[[RN8]]
-; CHECK-NEXT: __asan_check_store8_rn[[RN8]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         cmpb    $0, 2147450880(%r10)
-; CHECK-NEXT:         jne     [[FAIL:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[FAIL]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store8@PLT
-
-; CHECK:              .type   __asan_check_store16_rn[[RN16]],@function
-; CHECK-NEXT:         .weak   __asan_check_store16_rn[[RN16]]
-; CHECK-NEXT:         .hidden __asan_check_store16_rn[[RN16]]
-; CHECK-NEXT: __asan_check_store16_rn[[RN16]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         cmpw    $0, 2147450880(%r10)
-; CHECK-NEXT:         jne     [[FAIL:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[FAIL]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store16@PLT
-
 declare void @llvm.asan.check.memaccess(i8*, i32 immarg)
diff --git a/llvm/test/CodeGen/X86/asan-check-memaccess-or.ll b/llvm/test/CodeGen/X86/asan-check-memaccess-or.ll
--- a/llvm/test/CodeGen/X86/asan-check-memaccess-or.ll
+++ b/llvm/test/CodeGen/X86/asan-check-memaccess-or.ll
@@ -5,8 +5,8 @@
 define void @load1(i8* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load1_rn[[RN1:.*]]
-; CHECK:              callq   __asan_check_store1_rn[[RN1]]
+; CHECK:              callq   __asan_check_load_or_1_[[REG1:.*]]
+; CHECK:              callq   __asan_check_store_or_1_[[REG1]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   call void @llvm.asan.check.memaccess(i8* %x, i32 0)
@@ -17,8 +17,8 @@
 define void @load2(i16* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load2_rn[[RN2:.*]]
-; CHECK:              callq   __asan_check_store2_rn[[RN2]]
+; CHECK:              callq   __asan_check_load_or_2_[[REG2:.*]]
+; CHECK:              callq   __asan_check_store_or_2_[[REG2]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   %1 = ptrtoint i16* %x to i64
@@ -31,8 +31,8 @@
 define void @load4(i32* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load4_rn[[RN4:.*]]
-; CHECK:              callq   __asan_check_store4_rn[[RN4]]
+; CHECK:              callq   __asan_check_load_or_4_[[REG4:.*]]
+; CHECK:              callq   __asan_check_store_or_4_[[REG4]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   %1 = ptrtoint i32* %x to i64
@@ -44,8 +44,8 @@
 define void @load8(i64* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load8_rn[[RN8:.*]]
-; CHECK:              callq   __asan_check_store8_rn[[RN8]]
+; CHECK:              callq   __asan_check_load_or_8_[[REG8:.*]]
+; CHECK:              callq   __asan_check_store_or_8_[[REG8]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   %1 = ptrtoint i64* %x to i64
@@ -58,8 +58,8 @@
 define void @load16(i128* nocapture readonly %x) {
 ; CHECK:              pushq   %rax
 ; CHECK-NOT:          push    %rbp
-; CHECK:              callq   __asan_check_load16_rn[[RN16:.*]]
-; CHECK:              callq   __asan_check_store16_rn[[RN16]]
+; CHECK:              callq   __asan_check_load_or_16_[[REG16:.*]]
+; CHECK:              callq   __asan_check_store_or_16_[[REG16]]
 ; CHECK-NOT:          pop     %rbp
 ; CHECK:              popq    %rax
   %1 = ptrtoint i128* %x to i64
@@ -69,188 +69,4 @@
   ret void
 }
 
-; CHECK:              .type   __asan_check_load1_rn[[RN1]],@function
-; CHECK-NEXT:         .weak   __asan_check_load1_rn[[RN1]]
-; CHECK-NEXT:         .hidden __asan_check_load1_rn[[RN1]]
-; CHECK-NEXT: __asan_check_load1_rn[[RN1]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10{{.*}}
-; CHECK-NEXT:         movb    (%r10), %r10b
-; CHECK-NEXT:         testb   %r10b, %r10b
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load1
-
-; CHECK:              .type   __asan_check_load2_rn[[RN2]],@function
-; CHECK-NEXT:         .weak   __asan_check_load2_rn[[RN2]]
-; CHECK-NEXT:         .hidden __asan_check_load2_rn[[RN2]]
-; CHECK-NEXT: __asan_check_load2_rn[[RN2]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10{{.*}}
-; CHECK-NEXT:         movb    (%r10), %r10b
-; CHECK-NEXT:         testb   %r10b, %r10b
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         addl    $1, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load2
-
-; CHECK:              .type   __asan_check_load4_rn[[RN4]],@function
-; CHECK-NEXT:         .weak   __asan_check_load4_rn[[RN4]]
-; CHECK-NEXT:         .hidden __asan_check_load4_rn[[RN4]]
-; CHECK-NEXT: __asan_check_load4_rn[[RN4]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10{{.*}}
-; CHECK-NEXT:         movb    (%r10), %r10b
-; CHECK-NEXT:         testb   %r10b, %r10b
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         addl    $3, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load4
-
-; CHECK:              .type   __asan_check_load8_rn[[RN8]],@function
-; CHECK-NEXT:         .weak   __asan_check_load8_rn[[RN8]]
-; CHECK-NEXT:         .hidden __asan_check_load8_rn[[RN8]]
-; CHECK-NEXT: __asan_check_load8_rn[[RN8]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10{{.*}}
-; CHECK-NEXT:         cmpb    $0, (%r10)
-; CHECK-NEXT:         jne     [[FAIL:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[FAIL]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load8
-
-; CHECK:              .type   __asan_check_load16_rn[[RN16]],@function
-; CHECK-NEXT:         .weak   __asan_check_load16_rn[[RN16]]
-; CHECK-NEXT:         .hidden __asan_check_load16_rn[[RN16]]
-; CHECK-NEXT: __asan_check_load16_rn[[RN16]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10{{.*}}
-; CHECK-NEXT:         cmpw    $0, (%r10)
-; CHECK-NEXT:         jne     [[FAIL:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[FAIL]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_load16
-
-; CHECK:              .type   __asan_check_store1_rn[[RN1]],@function
-; CHECK-NEXT:         .weak   __asan_check_store1_rn[[RN1]]
-; CHECK-NEXT:         .hidden __asan_check_store1_rn[[RN1]]
-; CHECK-NEXT: __asan_check_store1_rn[[RN1]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10
-; CHECK-NEXT:         movb    (%r10), %r10b
-; CHECK-NEXT:         testb   %r10b, %r10b
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store1@PLT
-
-; CHECK:              .type   __asan_check_store2_rn[[RN2]],@function
-; CHECK-NEXT:         .weak   __asan_check_store2_rn[[RN2]]
-; CHECK-NEXT:         .hidden __asan_check_store2_rn[[RN2]]
-; CHECK-NEXT: __asan_check_store2_rn[[RN2]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10
-; CHECK-NEXT:         movb    (%r10), %r10b
-; CHECK-NEXT:         testb   %r10b, %r10b
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         addl    $1, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store2@PLT
-
-; CHECK:              .type   __asan_check_store4_rn[[RN4]],@function
-; CHECK-NEXT:         .weak   __asan_check_store4_rn[[RN4]]
-; CHECK-NEXT:         .hidden __asan_check_store4_rn[[RN4]]
-; CHECK-NEXT: __asan_check_store4_rn[[RN4]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10
-; CHECK-NEXT:         movb    (%r10), %r10b
-; CHECK-NEXT:         testb   %r10b, %r10b
-; CHECK-NEXT:         jne     [[EXTRA:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[EXTRA]]:
-; CHECK-NEXT:         movq    [[REG]], %r11
-; CHECK-NEXT:         andl    $7, %r11d
-; CHECK-NEXT:         addl    $3, %r11d
-; CHECK-NEXT:         cmpl    %r10d, %r11d
-; CHECK-NEXT:         jl      [[RET]]
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store4@PLT
-
-; CHECK:              .type   __asan_check_store8_rn[[RN8]],@function
-; CHECK-NEXT:         .weak   __asan_check_store8_rn[[RN8]]
-; CHECK-NEXT:         .hidden __asan_check_store8_rn[[RN8]]
-; CHECK-NEXT: __asan_check_store8_rn[[RN8]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10{{.*}}
-; CHECK-NEXT:         cmpb    $0, (%r10)
-; CHECK-NEXT:         jne     [[FAIL:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[FAIL]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store8@PLT
-
-; CHECK:              .type   __asan_check_store16_rn[[RN16]],@function
-; CHECK-NEXT:         .weak   __asan_check_store16_rn[[RN16]]
-; CHECK-NEXT:         .hidden __asan_check_store16_rn[[RN16]]
-; CHECK-NEXT: __asan_check_store16_rn[[RN16]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %r10
-; CHECK-NEXT:         shrq    $3, %r10
-; CHECK-NEXT:         orq     $17592186044416, %r10{{.*}}
-; CHECK-NEXT:         cmpw    $0, (%r10)
-; CHECK-NEXT:         jne     [[FAIL:.*]]
-; CHECK-NEXT: [[RET:.*]]:
-; CHECK-NEXT:         retq
-; CHECK-NEXT: [[FAIL]]:
-; CHECK-NEXT:         movq    [[REG:.*]], %rdi
-; CHECK-NEXT:         jmp     __asan_report_store16@PLT
-
 declare void @llvm.asan.check.memaccess(i8*, i32 immarg)