[compiler-rt] [compiler-rt] Implement address sanitizer on AIX (3/3) (PR #130028)

Jake Egan via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 6 01:30:44 PST 2025


https://github.com/jakeegan created https://github.com/llvm/llvm-project/pull/130028

The PR includes compiler-rt changes needed for the address sanitizer on AIX.

clang PR: https://github.com/llvm/llvm-project/pull/129925
llvm PR: https://github.com/llvm/llvm-project/pull/129926

>From e9e590e350df5877d717bb667f20bbc60a9de0ee Mon Sep 17 00:00:00 2001
From: Jake Egan <jake.egan at ibm.com>
Date: Thu, 6 Mar 2025 04:17:37 -0500
Subject: [PATCH] [compiler-rt] Implement address sanitizer on AIX (3/3)

---
 compiler-rt/cmake/Modules/AddCompilerRT.cmake |  17 +
 .../cmake/Modules/AllSupportedArchDefs.cmake  |   4 +-
 compiler-rt/cmake/base-config-ix.cmake        |   6 +-
 compiler-rt/cmake/config-ix.cmake             |   3 +-
 compiler-rt/lib/asan/CMakeLists.txt           |  12 +
 .../lib/asan/asan.link_with_main_exec.txt     | 115 ++++
 compiler-rt/lib/asan/asan_aix.cpp             |  44 ++
 compiler-rt/lib/asan/asan_allocator.cpp       |  13 +-
 compiler-rt/lib/asan/asan_allocator.h         |   4 +
 .../lib/asan/asan_cxx.link_with_main_exec.txt |  21 +
 compiler-rt/lib/asan/asan_descriptions.cpp    |  21 +-
 compiler-rt/lib/asan/asan_interceptors.cpp    |  45 +-
 compiler-rt/lib/asan/asan_interceptors.h      |  28 +-
 .../asan/asan_interceptors_memintrinsics.cpp  |   4 +-
 compiler-rt/lib/asan/asan_malloc_linux.cpp    |  21 +-
 compiler-rt/lib/asan/asan_mapping.h           |  10 +-
 compiler-rt/lib/asan/asan_mapping_aix64.h     | 184 +++++++
 compiler-rt/lib/asan/asan_poisoning.h         |   4 +-
 compiler-rt/lib/asan/asan_posix.cpp           |   6 +-
 compiler-rt/lib/asan/asan_rtl.cpp             |  45 +-
 compiler-rt/lib/asan/asan_shadow_setup.cpp    |  23 +-
 .../lib/asan/scripts/asan_symbolize.py        |   3 +-
 compiler-rt/lib/asan/tests/CMakeLists.txt     |   8 +-
 compiler-rt/lib/interception/CMakeLists.txt   |   2 +
 compiler-rt/lib/interception/interception.h   |  19 +-
 .../lib/interception/interception_aix.cpp     |  45 ++
 .../lib/interception/interception_aix.h       |  36 ++
 .../lib/sanitizer_common/CMakeLists.txt       |   9 +
 .../lib/sanitizer_common/sanitizer_aix.cpp    | 499 ++++++++++++++++++
 .../lib/sanitizer_common/sanitizer_aix.h      |  47 ++
 .../sanitizer_allocator_internal.h            |   5 +
 .../sanitizer_allocator_primary32.h           |   1 +
 .../lib/sanitizer_common/sanitizer_common.cpp |   6 +
 .../lib/sanitizer_common/sanitizer_common.h   |   7 +-
 .../sanitizer_common_interceptors.inc         |  52 +-
 .../sanitizer_common_interceptors_ioctl.inc   |   2 +
 ...izer_common_interceptors_memintrinsics.inc |   2 +
 .../sanitizer_common_libcdep.cpp              |   7 +-
 .../lib/sanitizer_common/sanitizer_errno.h    |   2 +
 .../lib/sanitizer_common/sanitizer_file.cpp   |   4 +-
 .../lib/sanitizer_common/sanitizer_file.h     |   3 +-
 .../lib/sanitizer_common/sanitizer_flags.inc  |   3 +
 .../lib/sanitizer_common/sanitizer_platform.h |  14 +-
 .../sanitizer_platform_interceptors.h         |  52 +-
 .../sanitizer_platform_limits_posix.cpp       |  68 ++-
 .../sanitizer_platform_limits_posix.h         |  94 +++-
 .../lib/sanitizer_common/sanitizer_posix.cpp  |   2 +-
 .../lib/sanitizer_common/sanitizer_posix.h    |   5 +
 .../sanitizer_posix_libcdep.cpp               |  29 +-
 .../lib/sanitizer_common/sanitizer_procmaps.h |   3 +-
 .../sanitizer_procmaps_aix.cpp                | 212 ++++++++
 .../sanitizer_procmaps_common.cpp             |   7 +-
 .../sanitizer_redefine_builtins.h             |   2 +-
 .../sanitizer_common/sanitizer_stacktrace.cpp |   7 +-
 .../sanitizer_common/sanitizer_symbolizer.cpp |   5 +-
 .../sanitizer_symbolizer_libcdep.cpp          |   9 +-
 .../sanitizer_symbolizer_posix_libcdep.cpp    |  32 +-
 .../sanitizer_symbolizer_win.cpp              |   2 +-
 .../sanitizer_common/sanitizer_unwind_aix.cpp |  66 +++
 .../lib/sanitizer_common/tests/CMakeLists.txt |   4 +
 .../tests/sanitizer_test_utils.h              |   2 +-
 compiler-rt/test/asan/CMakeLists.txt          |   2 +-
 .../Posix/asan-symbolize-bad-path.cpp         |   4 +
 .../Posix/asan-symbolize-sanity-test.cpp      |   8 +-
 .../plugin_wrong_frame_number_bug.cpp         |   4 +-
 .../test/asan/TestCases/Posix/asprintf.cpp    |   3 +
 .../test/asan/TestCases/Posix/closed-fds.cpp  |   2 +-
 .../asan/TestCases/Posix/coverage-fork.cpp    |   2 +
 .../Posix/coverage-module-unloaded.cpp        |   3 +
 .../asan/TestCases/Posix/coverage-reset.cpp   |   2 +
 .../test/asan/TestCases/Posix/coverage.cpp    |   3 +
 .../asan/TestCases/Posix/deep_call_stack.cpp  |   3 +-
 .../asan/TestCases/Posix/fake_stack_gc.cpp    |   3 +
 .../test/asan/TestCases/Posix/fgets_fputs.cpp |   6 +-
 .../asan/TestCases/Posix/fread_fwrite.cpp     |   4 +-
 .../Posix/interception-in-shared-lib-test.cpp |   2 +-
 .../Posix/invalid-pointer-pairs-threads.cpp   |  14 +-
 .../test/asan/TestCases/Posix/ioctl.cpp       |   2 +-
 .../TestCases/Posix/new_array_cookie_test.cpp |   2 +-
 .../TestCases/Posix/no_asan_gen_globals.c     |   5 +-
 .../asan/TestCases/Posix/shared-lib-test.cpp  |   4 +-
 .../asan/TestCases/Posix/stack-overflow.cpp   |   2 +
 .../TestCases/Posix/start-deactivated.cpp     |  26 +-
 .../Posix/unpoison-alternate-stack.cpp        |   3 +
 .../test/asan/TestCases/Posix/wait.cpp        |   4 +-
 .../test/asan/TestCases/Posix/wait3.cpp       |   4 +-
 .../test/asan/TestCases/Posix/wait4.cpp       |   4 +-
 .../test/asan/TestCases/Posix/waitid.cpp      |   4 +-
 .../test/asan/TestCases/calloc-overflow.cpp   |   2 +-
 .../test/asan/TestCases/coverage-disabled.cpp |   3 +
 .../test/asan/TestCases/debug_double_free.cpp |   2 +-
 .../test/asan/TestCases/debug_locate.cpp      |   4 +
 .../asan/TestCases/debug_ppc64_mapping.cpp    |   2 +-
 .../test/asan/TestCases/debug_report.cpp      |   2 +-
 .../test/asan/TestCases/double-free.cpp       |   4 +-
 .../test/asan/TestCases/frexp_interceptor.cpp |   3 +
 .../asan/TestCases/frexpf_interceptor.cpp     |   3 +
 .../asan/TestCases/frexpl_interceptor.cpp     |   4 +
 .../TestCases/global-location-nodebug.cpp     |   3 +-
 .../test/asan/TestCases/global-overflow.cpp   |   2 +-
 .../test/asan/TestCases/global-underflow.cpp  |   5 +
 .../test/asan/TestCases/heap-overflow.cpp     |   2 +-
 .../test/asan/TestCases/heavy_uar_test.cpp    |   2 +-
 .../asan/TestCases/initialization-bug.cpp     |   2 +-
 .../TestCases/intercept-rethrow-exception.cpp |   4 +
 .../test/asan/TestCases/invalid-free.cpp      |   9 +-
 .../invalid-pointer-pairs-compare-errors.cpp  |  36 +-
 .../invalid-pointer-pairs-subtract-errors.cpp |  12 +-
 .../asan/TestCases/invalid-pointer-pairs.cpp  |   6 +-
 .../test/asan/TestCases/large_func_test.cpp   |   8 +-
 .../asan/TestCases/malloc-size-too-big.cpp    |   2 +-
 .../asan/TestCases/malloc_context_size.cpp    |   8 +-
 .../test/asan/TestCases/memset_test.cpp       |  38 +-
 .../test/asan/TestCases/null_deref.cpp        |   2 +-
 .../test/asan/TestCases/print_summary.cpp     |   2 +-
 .../replaceable_new_delete_shared.cpp         |   3 +-
 .../test/asan/TestCases/set_shadow_test.c     |   4 +
 .../asan/TestCases/stack-buffer-overflow.cpp  |   2 +-
 .../test/asan/TestCases/strcasestr-1.c        |   3 +
 .../test/asan/TestCases/strcasestr-2.c        |   3 +
 .../test/asan/TestCases/strcasestr_strict.c   |   3 +
 .../test/asan/TestCases/strcat_strict.c       |   3 +
 compiler-rt/test/asan/TestCases/strcmp.c      |   3 +
 .../test/asan/TestCases/strcmp_strict.c       |   3 +
 .../test/asan/TestCases/strcpy-overlap.cpp    |   3 +
 .../test/asan/TestCases/strip_path_prefix.c   |   2 +-
 .../test/asan/TestCases/strncat-overlap.cpp   |   3 +
 .../test/asan/TestCases/strncat_strict.c      |   3 +
 .../test/asan/TestCases/strncmp_strict.c      |   3 +
 .../test/asan/TestCases/strncpy-overflow.cpp  |   3 +
 .../test/asan/TestCases/strncpy-overlap.cpp   |   3 +
 .../asan/TestCases/suppressions-library.cpp   |   6 +
 .../test/asan/TestCases/use-after-delete.cpp  |  12 +-
 .../asan/TestCases/use-after-free-right.cpp   |   6 +-
 .../test/asan/TestCases/use-after-free.cpp    |   6 +-
 .../TestCases/use-after-scope-dtor-order.cpp  |   2 +-
 .../asan/TestCases/use-after-scope-if.cpp     |   2 +-
 .../TestCases/use-after-scope-inlined.cpp     |   4 +-
 .../TestCases/use-after-scope-loop-bug.cpp    |   2 +-
 .../use-after-scope-loop-removed.cpp          |   2 +-
 .../asan/TestCases/use-after-scope-loop.cpp   |   2 +-
 .../asan/TestCases/use-after-scope-temp.cpp   |   2 +-
 .../asan/TestCases/use-after-scope-temp2.cpp  |   2 +-
 .../asan/TestCases/use-after-scope-types.cpp  |   2 +-
 .../test/asan/TestCases/use-after-scope.cpp   |   2 +-
 .../test/asan/TestCases/zero_page_pc.cpp      |   3 +
 compiler-rt/test/asan/lit.cfg.py              |   2 +-
 compiler-rt/test/lit.common.cfg.py            |  30 +-
 .../TestCases/Posix/arc4random.cpp            |   3 +-
 .../TestCases/Posix/create_thread_fail.cpp    |   3 +
 .../Posix/dedup_token_length_test.cpp         |   6 +-
 .../TestCases/Posix/devname.cpp               |   3 +-
 .../TestCases/Posix/devname_r.cpp             |   3 +-
 .../TestCases/Posix/fgetln.cpp                |   2 +-
 .../TestCases/Posix/fseek.cpp                 |   3 +-
 .../sanitizer_common/TestCases/Posix/fts.cpp  |   3 +-
 .../TestCases/Posix/funopen.cpp               |   3 +-
 .../TestCases/Posix/getcpuclockid.c           |   3 +-
 .../TestCases/Posix/getfsent.cpp              |   3 +-
 .../TestCases/Posix/getmntinfo.cpp            |   3 +-
 .../TestCases/Posix/getpass.cpp               |   3 +-
 .../TestCases/Posix/getpw_getgr.cpp           |   2 +-
 .../TestCases/Posix/huge_malloc.c             |   3 +
 .../TestCases/Posix/illegal_read_test.cpp     |   2 +-
 .../TestCases/Posix/illegal_write_test.cpp    |   2 +-
 .../TestCases/Posix/posix_spawn.c             |   3 +
 .../TestCases/Posix/setvbuf.cpp               |   3 +
 .../TestCases/Posix/signal.cpp                |   3 +
 .../TestCases/Posix/sl_add.cpp                |   3 +-
 .../TestCases/Posix/strlcat.cpp               |   3 +-
 .../TestCases/Posix/strlcpy.cpp               |   3 +-
 .../TestCases/Posix/strtonum.cpp              |   3 +-
 .../TestCases/Posix/sysctl.cpp                |   3 +-
 .../sanitizer_common/TestCases/Posix/vis.cpp  |   3 +-
 .../sanitizer_common/TestCases/Posix/wcsdup.c |   7 +
 .../TestCases/Posix/weak_hook_test.cpp        |   3 +
 .../TestCases/allocator_returns_null.cpp      |   3 +
 .../TestCases/hard_rss_limit_mb_test.cpp      |   3 +
 .../TestCases/max_allocation_size.cpp         |   3 +
 .../TestCases/print-stack-trace.cpp           |  10 +-
 ...anitizer_coverage_allowlist_ignorelist.cpp |   3 +
 .../sanitizer_coverage_control_flow.cpp       |   2 +
 .../sanitizer_coverage_inline8bit_counter.cpp |   2 +
 .../sanitizer_coverage_inline_bool_flag.cpp   |   2 +
 .../sanitizer_coverage_stack_depth.cpp        |   2 +
 .../sanitizer_coverage_trace_pc_guard-dso.cpp |   3 +
 .../sanitizer_coverage_trace_pc_guard.cpp     |   3 +
 .../sanitizer_common/TestCases/strcasestr.c   |   3 +
 .../TestCases/suffix-log-path_test.c          |   2 +-
 .../TestCases/symbolize_pc.cpp                |   6 +-
 .../TestCases/symbolize_pc_demangle.cpp       |   4 +-
 .../TestCases/symbolize_pc_inline.cpp         |   4 +-
 192 files changed, 2283 insertions(+), 297 deletions(-)
 create mode 100644 compiler-rt/lib/asan/asan.link_with_main_exec.txt
 create mode 100644 compiler-rt/lib/asan/asan_aix.cpp
 create mode 100644 compiler-rt/lib/asan/asan_cxx.link_with_main_exec.txt
 create mode 100644 compiler-rt/lib/asan/asan_mapping_aix64.h
 create mode 100644 compiler-rt/lib/interception/interception_aix.cpp
 create mode 100644 compiler-rt/lib/interception/interception_aix.h
 create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_aix.cpp
 create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_aix.h
 create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_procmaps_aix.cpp
 create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_unwind_aix.cpp

diff --git a/compiler-rt/cmake/Modules/AddCompilerRT.cmake b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
index c3e734f72392f..beccaa15bcca9 100644
--- a/compiler-rt/cmake/Modules/AddCompilerRT.cmake
+++ b/compiler-rt/cmake/Modules/AddCompilerRT.cmake
@@ -582,6 +582,23 @@ macro(add_compiler_rt_script name)
     DESTINATION ${COMPILER_RT_INSTALL_BINARY_DIR})
 endmacro(add_compiler_rt_script src name)
 
+macro(add_compiler_rt_cfg target_name file_name component)
+  set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}")
+  get_compiler_rt_output_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} output_dir)
+  set(dst_file "${output_dir}/${file_name}")
+  add_custom_command(OUTPUT ${dst_file}
+    DEPENDS ${src_file}
+    COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file}
+    COMMENT "Copying ${file_name}...")
+  add_custom_target(${target_name} DEPENDS ${dst_file})
+  install(FILES ${file_name}
+    DESTINATION ${COMPILER_RT_INSTALL_LIBRARY_DIR}
+    COMPONENT ${component})
+  add_dependencies(${component} ${target_name})
+
+  set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc")
+endmacro()
+
 # Builds custom version of libc++ and installs it in <prefix>.
 # Can be used to build sanitized versions of libc++ for running unit tests.
 # add_custom_libcxx(<name> <prefix>
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index 2683259e93e37..0816a05a7fbbd 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -28,11 +28,11 @@ if(WIN32)
   set(ARM32 ${ARM32} armv7)
 endif()
 
-set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64}
+set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC32} ${PPC64} ${RISCV64}
     ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9}
     ${HEXAGON} ${LOONGARCH64})
 set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
-    ${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
+    ${MIPS32} ${MIPS64} ${PPC32} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
     ${LOONGARCH64})
 set(ALL_ASAN_ABI_SUPPORTED_ARCH ${X86_64} ${ARM64} ${ARM64_32})
 set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${LOONGARCH64})
diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake
index d92bc0e71fa1a..953fa3983ecfc 100644
--- a/compiler-rt/cmake/base-config-ix.cmake
+++ b/compiler-rt/cmake/base-config-ix.cmake
@@ -14,7 +14,11 @@ include(CompilerRTDarwinUtils)
 check_include_file(unwind.h HAVE_UNWIND_H)
 
 # Used by sanitizer_common and tests.
-check_include_file(rpc/xdr.h HAVE_RPC_XDR_H)
+if (${CMAKE_SYSTEM_NAME} MATCHES AIX)
+  check_include_file(tirpc/rpc/xdr.h HAVE_RPC_XDR_H)
+else()
+  check_include_file(rpc/xdr.h HAVE_RPC_XDR_H)
+endif()
 if (NOT HAVE_RPC_XDR_H)
   set(HAVE_RPC_XDR_H 0)
 endif()
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index cf729c3adb1f5..075493feeadbd 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -141,6 +141,7 @@ check_cxx_compiler_flag("-Werror -Wgnu"                COMPILER_RT_HAS_WGNU_FLAG
 check_cxx_compiler_flag("-Werror -Wgnu-anonymous-struct" COMPILER_RT_HAS_WGNU_ANONYMOUS_STRUCT_FLAG)
 check_cxx_compiler_flag("-Werror -Wvariadic-macros"    COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG)
 check_cxx_compiler_flag("-Werror -Wunused-parameter"   COMPILER_RT_HAS_WUNUSED_PARAMETER_FLAG)
+check_cxx_compiler_flag("-Werror -Watomic-alignment" COMPILER_RT_HAS_WATOMIC_ALIGNMENT_FLAG)
 check_cxx_compiler_flag("-Werror -Wcovered-switch-default" COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG)
 check_cxx_compiler_flag("-Werror -Wsuggest-override"   COMPILER_RT_HAS_WSUGGEST_OVERRIDE_FLAG)
 check_cxx_compiler_flag("-Werror -Wthread-safety" COMPILER_RT_HAS_WTHREAD_SAFETY_FLAG)
@@ -760,7 +761,7 @@ set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING
 list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}")
 
 if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
-    (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS" OR
+    (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS|AIX" OR
     (OS_NAME MATCHES "Windows" AND NOT CYGWIN AND
         (NOT MINGW OR CMAKE_CXX_COMPILER_ID MATCHES "Clang"))))
   set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE)
diff --git a/compiler-rt/lib/asan/CMakeLists.txt b/compiler-rt/lib/asan/CMakeLists.txt
index e2f39f224df9c..6999180139562 100644
--- a/compiler-rt/lib/asan/CMakeLists.txt
+++ b/compiler-rt/lib/asan/CMakeLists.txt
@@ -1,6 +1,7 @@
 # Build for the AddressSanitizer runtime support library.
 
 set(ASAN_SOURCES
+  asan_aix.cpp
   asan_allocator.cpp
   asan_activation.cpp
   asan_debugging.cpp
@@ -281,6 +282,9 @@ else()
       PARENT_TARGET asan)
   endif()
 
+  # On AIX, we only need the static libraries.
+  if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+
   foreach(arch ${ASAN_SUPPORTED_ARCH})
     if (COMPILER_RT_HAS_VERSION_SCRIPT)
       if(WIN32)
@@ -382,10 +386,18 @@ else()
       endif()
     endif()
   endforeach()
+  endif()
 endif()
 
 add_compiler_rt_resource_file(asan_ignorelist asan_ignorelist.txt asan)
 
+# On AIX, we need to put asan.link_with_main_exec.txt and asan_cxx.link_with_main_exec.txt
+# to the build and install dir.
+if (${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+  add_compiler_rt_cfg(asan_symbols asan.link_with_main_exec.txt asan)
+  add_compiler_rt_cfg(asan_cxx_symbols asan_cxx.link_with_main_exec.txt asan)
+endif()
+
 add_subdirectory(scripts)
 
 if(COMPILER_RT_INCLUDE_TESTS)
diff --git a/compiler-rt/lib/asan/asan.link_with_main_exec.txt b/compiler-rt/lib/asan/asan.link_with_main_exec.txt
new file mode 100644
index 0000000000000..5efc48c262369
--- /dev/null
+++ b/compiler-rt/lib/asan/asan.link_with_main_exec.txt
@@ -0,0 +1,115 @@
+#! .
+__asan_report_load_n
+__asan_loadN
+__asan_report_load1
+__asan_load1
+__asan_report_load2
+__asan_load2
+__asan_report_load4
+__asan_load4
+__asan_report_load8
+__asan_load8
+__asan_report_load16
+__asan_load16
+__asan_report_store_n
+__asan_storeN
+__asan_report_store1
+__asan_store1
+__asan_report_store2
+__asan_store2
+__asan_report_store4
+__asan_store4
+__asan_report_store8
+__asan_store8
+__asan_report_store16
+__asan_store16
+__asan_report_exp_load_n
+__asan_exp_loadN
+__asan_report_exp_load1
+__asan_exp_load1
+__asan_report_exp_load2
+__asan_exp_load2
+__asan_report_exp_load4
+__asan_exp_load4
+__asan_report_exp_load8
+__asan_exp_load8
+__asan_report_exp_load16
+__asan_exp_load16
+__asan_report_exp_store_n
+__asan_exp_storeN
+__asan_report_exp_store1
+__asan_exp_store1
+__asan_report_exp_store2
+__asan_exp_store2
+__asan_report_exp_store4
+__asan_exp_store4
+__asan_report_exp_store8
+__asan_exp_store8
+__asan_report_exp_store16
+__asan_exp_store16
+__asan_memmove
+__asan_memcpy
+__asan_memset
+__asan_handle_no_return
+__sanitizer_ptr_cmp
+__sanitizer_ptr_sub
+__asan_before_dynamic_init
+__asan_after_dynamic_init
+__asan_register_globals
+__asan_unregister_globals
+__asan_register_image_globals
+__asan_unregister_image_globals
+__asan_register_elf_globals
+__asan_unregister_elf_globals
+__asan_init
+__asan_version_mismatch_check_v8
+__asan_stack_malloc_0
+__asan_stack_malloc_1
+__asan_stack_malloc_2
+__asan_stack_malloc_3
+__asan_stack_malloc_4
+__asan_stack_malloc_5
+__asan_stack_malloc_6
+__asan_stack_malloc_7
+__asan_stack_malloc_8
+__asan_stack_malloc_9
+__asan_stack_malloc_10
+__asan_stack_malloc_always_0
+__asan_stack_malloc_always_1
+__asan_stack_malloc_always_2
+__asan_stack_malloc_always_3
+__asan_stack_malloc_always_4
+__asan_stack_malloc_always_5
+__asan_stack_malloc_always_6
+__asan_stack_malloc_always_7
+__asan_stack_malloc_always_8
+__asan_stack_malloc_always_9
+__asan_stack_malloc_always_10
+__asan_stack_free_0
+__asan_stack_free_1
+__asan_stack_free_2
+__asan_stack_free_3
+__asan_stack_free_4
+__asan_stack_free_5
+__asan_stack_free_6
+__asan_stack_free_7
+__asan_stack_free_8
+__asan_stack_free_9
+__asan_stack_free_10
+__asan_set_shadow_00
+__asan_set_shadow_01
+__asan_set_shadow_02
+__asan_set_shadow_03
+__asan_set_shadow_04
+__asan_set_shadow_05
+__asan_set_shadow_06
+__asan_set_shadow_07
+__asan_set_shadow_f1
+__asan_set_shadow_f2
+__asan_set_shadow_f3
+__asan_set_shadow_f5
+__asan_set_shadow_f8
+__asan_poison_stack_memory
+__asan_unpoison_stack_memory
+__asan_option_detect_stack_use_after_return
+__asan_shadow_memory_dynamic_address
diff --git a/compiler-rt/lib/asan/asan_aix.cpp b/compiler-rt/lib/asan/asan_aix.cpp
new file mode 100644
index 0000000000000..d1a8a5ac8e59d
--- /dev/null
+++ b/compiler-rt/lib/asan/asan_aix.cpp
@@ -0,0 +1,44 @@
+//===-- asan_aix.cpp ------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// AIX-specific details.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_platform.h"
+
+#if SANITIZER_AIX
+#  include "asan_mapping.h"
+#  include "sanitizer_common/sanitizer_internal_defs.h"
+
+namespace __asan {
+
+void AsanCheckIncompatibleRT() {}
+
+void AsanCheckDynamicRTPrereqs() {}
+
+void InitializePlatformExceptionHandlers() {}
+
+void *AsanDoesNotSupportStaticLinkage() { return 0; }
+
+void InitializePlatformInterceptors() {}
+void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {}
+
+uptr FindDynamicShadowStart() {
+  UNREACHABLE("AIX does not use dynamic shadow offset!");
+  return 0;
+}
+
+void FlushUnneededASanShadowMemory(uptr p, uptr size) {
+  ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
+}
+
+}  // namespace __asan
+
+#endif  // SANITIZER_AIX
diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp
index 3a55c2af65653..fc826f6448325 100644
--- a/compiler-rt/lib/asan/asan_allocator.cpp
+++ b/compiler-rt/lib/asan/asan_allocator.cpp
@@ -770,11 +770,16 @@ struct Allocator {
       u8 chunk_state = atomic_load(&m->chunk_state, memory_order_acquire);
       if (chunk_state != CHUNK_ALLOCATED)
         ReportInvalidFree(old_ptr, chunk_state, stack);
-      CHECK_NE(REAL(memcpy), nullptr);
       uptr memcpy_size = Min(new_size, m->UsedSize());
       // If realloc() races with free(), we may start copying freed memory.
       // However, we will report racy double-free later anyway.
+#if !SANITIZER_AIX
+      CHECK_NE(REAL(memcpy), nullptr);
       REAL(memcpy)(new_ptr, old_ptr, memcpy_size);
+#else
+      // AIX does not intercept memcpy, we have to use internal_memcpy here.
+      internal_memcpy(new_ptr, old_ptr, memcpy_size);
+#endif
       Deallocate(old_ptr, 0, 0, stack, FROM_MALLOC);
     }
     return new_ptr;
@@ -797,8 +802,10 @@ struct Allocator {
   void ReportInvalidFree(void *ptr, u8 chunk_state, BufferedStackTrace *stack) {
     if (chunk_state == CHUNK_QUARANTINE)
       ReportDoubleFree((uptr)ptr, stack);
-    else
-      ReportFreeNotMalloced((uptr)ptr, stack);
+    else {
+      if (common_flags()->enable_unmalloced_free_check)
+        ReportFreeNotMalloced((uptr)ptr, stack);
+    }
   }
 
   void CommitBack(AsanThreadLocalMallocStorage *ms, BufferedStackTrace *stack) {
diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h
index db8dc3bebfc62..46cd7b118cd9a 100644
--- a/compiler-rt/lib/asan/asan_allocator.h
+++ b/compiler-rt/lib/asan/asan_allocator.h
@@ -197,7 +197,11 @@ const uptr kAllocatorSpace = ~(uptr)0;
 #    endif  // SANITIZER_APPLE
 
 #    if defined(__powerpc64__)
+#if SANITIZER_AIX
+const uptr kAllocatorSize  =  1ULL << 38;  // 256G.
+#else
 const uptr kAllocatorSize  =  0x20000000000ULL;  // 2T.
+#endif
 typedef DefaultSizeClassMap SizeClassMap;
 #    elif defined(__aarch64__) && SANITIZER_ANDROID
 // Android needs to support 39, 42 and 48 bit VMA.
diff --git a/compiler-rt/lib/asan/asan_cxx.link_with_main_exec.txt b/compiler-rt/lib/asan/asan_cxx.link_with_main_exec.txt
new file mode 100644
index 0000000000000..7387f8173e859
--- /dev/null
+++ b/compiler-rt/lib/asan/asan_cxx.link_with_main_exec.txt
@@ -0,0 +1,21 @@
+#! .
+_ZdaPv
+_ZdaPvRKSt9nothrow_t
+_ZdaPvSt11align_val_t
+_ZdaPvSt11align_val_tRKSt9nothrow_t
+_ZdaPvm
+_ZdaPvmSt11align_val_t
+_ZdlPv
+_ZdlPvRKSt9nothrow_t
+_ZdlPvSt11align_val_t
+_ZdlPvSt11align_val_tRKSt9nothrow_t
+_ZdlPvm
+_ZdlPvmSt11align_val_t
+_Znam
+_ZnamRKSt9nothrow_t
+_ZnamSt11align_val_t
+_ZnamSt11align_val_tRKSt9nothrow_t
+_Znwm
+_ZnwmRKSt9nothrow_t
+_ZnwmSt11align_val_t
+_ZnwmSt11align_val_tRKSt9nothrow_t
diff --git a/compiler-rt/lib/asan/asan_descriptions.cpp b/compiler-rt/lib/asan/asan_descriptions.cpp
index c9f3e4d682d95..6488d51b89a14 100644
--- a/compiler-rt/lib/asan/asan_descriptions.cpp
+++ b/compiler-rt/lib/asan/asan_descriptions.cpp
@@ -211,10 +211,10 @@ bool GetStackAddressInformation(uptr addr, uptr access_size,
   descr->frame_pc = access.frame_pc;
   descr->frame_descr = access.frame_descr;
 
-#if SANITIZER_PPC64V1
-  // On PowerPC64 ELFv1, the address of a function actually points to a
-  // three-doubleword data structure with the first field containing
-  // the address of the function's code.
+#if SANITIZER_PPC64V1 || SANITIZER_AIX
+  // On PowerPC64 ELFv1 or AIX, the address of a function actually points to a
+  // three-doubleword (or three-word for 32-bit AIX) data structure with the
+  // first field containing the address of the function's code.
   descr->frame_pc = *reinterpret_cast<uptr *>(descr->frame_pc);
 #endif
   descr->frame_pc += 16;
@@ -444,6 +444,15 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
     data.kind = kAddressKindShadow;
     return;
   }
+
+  // Check global first. On AIX, some global data defined in shared libraries
+  // are put to the STACK region for unknown reasons. Check global first can
+  // workaround this issue.
+  if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
+    data.kind = kAddressKindGlobal;
+    return;
+  }
+
   if (GetHeapAddressInformation(addr, access_size, &data.heap)) {
     data.kind = kAddressKindHeap;
     return;
@@ -461,10 +470,6 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
     return;
   }
 
-  if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
-    data.kind = kAddressKindGlobal;
-    return;
-  }
   data.kind = kAddressKindWild;
   data.wild.addr = addr;
   data.wild.access_size = access_size;
diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp
index 247ea1b92f1f4..d55ebedafb086 100644
--- a/compiler-rt/lib/asan/asan_interceptors.cpp
+++ b/compiler-rt/lib/asan/asan_interceptors.cpp
@@ -56,6 +56,7 @@ namespace __asan {
 #  define ASAN_READ_STRING(ctx, s, n) \
     ASAN_READ_STRING_OF_LEN((ctx), (s), internal_strlen(s), (n))
 
+#if SANITIZER_INTERCEPT_STRCAT || SANITIZER_INTERCEPT_STRCPY
 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
 #if SANITIZER_INTERCEPT_STRNLEN
   if (REAL(strnlen)) {
@@ -64,6 +65,7 @@ static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
 #endif
   return internal_strnlen(s, maxlen);
 }
+#endif
 
 void SetThreadName(const char *name) {
   AsanThread *t = GetCurrentThread();
@@ -275,7 +277,12 @@ INTERCEPTOR(int, pthread_create, void *thread, void *attr,
 #    endif
     asanThreadArgRetval().Create(detached, {start_routine, arg}, [&]() -> uptr {
       result = REAL(pthread_create)(thread, attr, asan_thread_start, t);
+// AIX pthread_t is unsigned int.
+#if SANITIZER_AIX
+      return result ? 0 : *(unsigned int *)(thread);
+#else
       return result ? 0 : *(uptr *)(thread);
+#endif
     });
   }
   if (result != 0) {
@@ -432,10 +439,12 @@ INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
 #define siglongjmp __siglongjmp14
 #endif
 
+#if ASAN_INTERCEPT_LONGJMP
 INTERCEPTOR(void, longjmp, void *env, int val) {
   __asan_handle_no_return();
   REAL(longjmp)(env, val);
 }
+#endif
 
 #if ASAN_INTERCEPT__LONGJMP
 INTERCEPTOR(void, _longjmp, void *env, int val) {
@@ -508,6 +517,7 @@ DEFINE_REAL(char*, index, const char *string, int c)
 
 // For both strcat() and strncat() we need to check the validity of |to|
 // argument irrespective of the |from| length.
+#if SANITIZER_INTERCEPT_STRCAT
   INTERCEPTOR(char *, strcat, char *to, const char *from) {
     void *ctx;
     ASAN_INTERCEPTOR_ENTER(ctx, strcat);
@@ -547,7 +557,9 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, usize size) {
   }
   return REAL(strncat)(to, from, size);
 }
+#endif
 
+#if SANITIZER_INTERCEPT_STRCPY
 INTERCEPTOR(char *, strcpy, char *to, const char *from) {
   void *ctx;
   ASAN_INTERCEPTOR_ENTER(ctx, strcpy);
@@ -569,6 +581,7 @@ INTERCEPTOR(char *, strcpy, char *to, const char *from) {
   }
   return REAL(strcpy)(to, from);
 }
+#endif
 
 // Windows doesn't always define the strdup identifier,
 // and when it does it's a macro defined to either _strdup
@@ -596,7 +609,13 @@ INTERCEPTOR(char*, strdup, const char *s) {
   GET_STACK_TRACE_MALLOC;
   void *new_mem = asan_malloc(length + 1, &stack);
   if (new_mem) {
+#  if SANITIZER_AIX
+    // memcpy is a static function defined in libc.a on AIX. It can not be
+    // intercepted, so REAL(memcpy) is null on AIX. Use internal_memcpy instead.
+    internal_memcpy(new_mem, s, length + 1);
+#  else
     REAL(memcpy)(new_mem, s, length + 1);
+#  endif
   }
   return reinterpret_cast<char*>(new_mem);
 }
@@ -614,12 +633,17 @@ INTERCEPTOR(char*, __strdup, const char *s) {
   GET_STACK_TRACE_MALLOC;
   void *new_mem = asan_malloc(length + 1, &stack);
   if (new_mem) {
+#if SANITIZER_AIX
+    internal_memcpy(new_mem, s, length + 1);
+#else
     REAL(memcpy)(new_mem, s, length + 1);
+#endif
   }
   return reinterpret_cast<char*>(new_mem);
 }
 #endif // ASAN_INTERCEPT___STRDUP
 
+#if SANITIZER_INTERCEPT_STRCPY
 INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) {
   void *ctx;
   ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
@@ -632,6 +656,7 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) {
   }
   return REAL(strncpy)(to, from, size);
 }
+#endif
 
 template <typename Fn>
 static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr,
@@ -743,6 +768,14 @@ static void AtCxaAtexit(void *unused) {
 }
 #endif
 
+#if ASAN_INTERCEPT_EXIT
+INTERCEPTOR(void, exit, int status) {
+  AsanInitFromRtl();
+  StopInitOrderChecking();
+  REAL(exit)(status);
+}
+#endif
+
 #if ASAN_INTERCEPT___CXA_ATEXIT
 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
             void *dso_handle) {
@@ -804,10 +837,14 @@ void InitializeAsanInterceptors() {
   InitializeSignalInterceptors();
 
   // Intercept str* functions.
+#if SANITIZER_INTERCEPT_STRCAT
   ASAN_INTERCEPT_FUNC(strcat);
-  ASAN_INTERCEPT_FUNC(strcpy);
   ASAN_INTERCEPT_FUNC(strncat);
+#endif
+#if SANITIZER_INTERCEPT_STRCPY
+  ASAN_INTERCEPT_FUNC(strcpy);
   ASAN_INTERCEPT_FUNC(strncpy);
+#endif
   ASAN_INTERCEPT_FUNC(strdup);
 #  if ASAN_INTERCEPT___STRDUP
   ASAN_INTERCEPT_FUNC(__strdup);
@@ -827,7 +864,9 @@ void InitializeAsanInterceptors() {
 #  endif
 
   // Intecept jump-related functions.
+#if ASAN_INTERCEPT_LONGJMP
   ASAN_INTERCEPT_FUNC(longjmp);
+#endif
 
 #  if ASAN_INTERCEPT_SWAPCONTEXT
   ASAN_INTERCEPT_FUNC(swapcontext);
@@ -894,6 +933,10 @@ void InitializeAsanInterceptors() {
   ASAN_INTERCEPT_FUNC(atexit);
 #endif
 
+#if ASAN_INTERCEPT_EXIT
+  ASAN_INTERCEPT_FUNC(exit);
+#endif
+
 #if ASAN_INTERCEPT_PTHREAD_ATFORK
   ASAN_INTERCEPT_FUNC(pthread_atfork);
 #endif
diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h
index 3e2386eaf8092..2ca6bd45b6604 100644
--- a/compiler-rt/lib/asan/asan_interceptors.h
+++ b/compiler-rt/lib/asan/asan_interceptors.h
@@ -31,10 +31,20 @@ void InitializePlatformInterceptors();
 // really defined to replace libc functions.
 #if !SANITIZER_FUCHSIA
 
+#if !SANITIZER_AIX
+# define ASAN_INTERCEPT_LONGJMP 1
+#else
+# define ASAN_INTERCEPT_LONGJMP 0
+#endif
+
 // Use macro to describe if specific function should be
 // intercepted on a given platform.
 #if !SANITIZER_WINDOWS
+#if !SANITIZER_AIX
 # define ASAN_INTERCEPT__LONGJMP 1
+#else
+# define ASAN_INTERCEPT__LONGJMP 0
+#endif
 # define ASAN_INTERCEPT_INDEX 1
 # define ASAN_INTERCEPT_PTHREAD_CREATE 1
 #else
@@ -56,7 +66,7 @@ void InitializePlatformInterceptors();
 # define ASAN_INTERCEPT_SWAPCONTEXT 0
 #endif
 
-#if !SANITIZER_WINDOWS
+#if !SANITIZER_WINDOWS && !SANITIZER_AIX
 # define ASAN_INTERCEPT_SIGLONGJMP 1
 #else
 # define ASAN_INTERCEPT_SIGLONGJMP 0
@@ -84,12 +94,18 @@ void InitializePlatformInterceptors();
 # define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0
 #endif
 
-#if !SANITIZER_WINDOWS
+#if !SANITIZER_WINDOWS && !SANITIZER_AIX
 # define ASAN_INTERCEPT___CXA_ATEXIT 1
 #else
 # define ASAN_INTERCEPT___CXA_ATEXIT 0
 #endif
 
+#if SANITIZER_AIX
+# define ASAN_INTERCEPT_EXIT 1
+#else
+# define ASAN_INTERCEPT_EXIT 0
+#endif
+
 #if SANITIZER_NETBSD
 # define ASAN_INTERCEPT_ATEXIT 1
 #else
@@ -110,6 +126,14 @@ void InitializePlatformInterceptors();
 # define ASAN_INTERCEPT_TRYJOIN 0
 #endif
 
+#if SANITIZER_AIX
+#define SANITIZER_INTERCEPT_STRCAT 0
+#define SANITIZER_INTERCEPT_STRCPY 0
+#else
+#define SANITIZER_INTERCEPT_STRCAT 1
+#define SANITIZER_INTERCEPT_STRCPY 1
+#endif
+
 #if SANITIZER_LINUX &&                                                \
     (defined(__arm__) || defined(__aarch64__) || defined(__i386__) || \
      defined(__x86_64__) || SANITIZER_RISCV64 || SANITIZER_LOONGARCH64)
diff --git a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp
index bdf328f892063..170d91e47e4cc 100644
--- a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp
+++ b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp
@@ -25,6 +25,7 @@ using namespace __asan;
 // memcpy is called during __asan_init() from the internals of printf(...).
 // We do not treat memcpy with to==from as a bug.
 // See http://llvm.org/bugs/show_bug.cgi?id=11763.
+// AIX does not intercept memcpy, so we have to use internal_memcpy.
 #define ASAN_MEMCPY_IMPL(ctx, to, from, size)                 \
   do {                                                        \
     if (LIKELY(replace_intrin_cached)) {                      \
@@ -36,7 +37,8 @@ using namespace __asan;
     } else if (UNLIKELY(!AsanInited())) {                     \
       return internal_memcpy(to, from, size);                 \
     }                                                         \
-    return REAL(memcpy)(to, from, size);                      \
+    return SANITIZER_AIX ? internal_memcpy(to, from, size) :  \
+      REAL(memcpy)(to, from, size);                           \
   } while (0)
 
 // memset is called inside Printf.
diff --git a/compiler-rt/lib/asan/asan_malloc_linux.cpp b/compiler-rt/lib/asan/asan_malloc_linux.cpp
index 3d6b03fefab70..5646a718d3ea0 100644
--- a/compiler-rt/lib/asan/asan_malloc_linux.cpp
+++ b/compiler-rt/lib/asan/asan_malloc_linux.cpp
@@ -14,8 +14,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "sanitizer_common/sanitizer_platform.h"
+// FIXME: rename this file, this is not just for Linux now, see FUCHSIA and AIX.
 #if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \
-    SANITIZER_NETBSD || SANITIZER_SOLARIS
+    SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_AIX
 
 #  include "asan_allocator.h"
 #  include "asan_interceptors.h"
@@ -61,6 +62,24 @@ INTERCEPTOR(void, cfree, void *ptr) {
 }
 #endif // SANITIZER_INTERCEPT_CFREE
 
+#if SANITIZER_AIX
+INTERCEPTOR(void*, vec_malloc, uptr size) {
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Allocate(size);
+  AsanInitFromRtl();
+  GET_STACK_TRACE_MALLOC;
+  return asan_malloc(size, &stack);
+}
+
+INTERCEPTOR(void*, vec_calloc, uptr nmemb, uptr size) {
+  if (DlsymAlloc::Use())
+    return DlsymAlloc::Callocate(nmemb, size);
+  AsanInitFromRtl();
+  GET_STACK_TRACE_MALLOC;
+  return asan_calloc(nmemb, size, &stack);
+}
+#endif
+
 INTERCEPTOR(void*, malloc, uptr size) {
   if (DlsymAlloc::Use())
     return DlsymAlloc::Allocate(size);
diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h
index 91fe60db6329a..ecd196e2a021e 100644
--- a/compiler-rt/lib/asan/asan_mapping.h
+++ b/compiler-rt/lib/asan/asan_mapping.h
@@ -178,6 +178,8 @@
 #    define ASAN_SHADOW_OFFSET_CONST 0x30000000
 #  elif SANITIZER_IOS
 #    define ASAN_SHADOW_OFFSET_DYNAMIC
+#  elif SANITIZER_AIX
+#    define ASAN_SHADOW_OFFSET_CONST 0x40000000
 #  else
 #    define ASAN_SHADOW_OFFSET_CONST 0x20000000
 #  endif
@@ -193,7 +195,11 @@
 #  elif defined(__aarch64__)
 #    define ASAN_SHADOW_OFFSET_CONST 0x0000001000000000
 #  elif defined(__powerpc64__)
-#    define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
+#    if SANITIZER_AIX
+#      define ASAN_SHADOW_OFFSET_CONST 0x0a01000000000000
+#    else
+#      define ASAN_SHADOW_OFFSET_CONST 0x0000100000000000
+#    endif
 #  elif defined(__s390x__)
 #    define ASAN_SHADOW_OFFSET_CONST 0x0010000000000000
 #  elif SANITIZER_FREEBSD
@@ -272,6 +278,8 @@ extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;  // Initialized in __asan_init.
 
 #  if defined(__sparc__) && SANITIZER_WORDSIZE == 64
 #    include "asan_mapping_sparc64.h"
+#  elif SANITIZER_WORDSIZE == 64 && SANITIZER_AIX
+#    include "asan_mapping_aix64.h"
 #  else
 #    define MEM_TO_SHADOW(mem) \
       (((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET))
diff --git a/compiler-rt/lib/asan/asan_mapping_aix64.h b/compiler-rt/lib/asan/asan_mapping_aix64.h
new file mode 100644
index 0000000000000..38b97482ec1f4
--- /dev/null
+++ b/compiler-rt/lib/asan/asan_mapping_aix64.h
@@ -0,0 +1,184 @@
+//===-- asan_mapping_aix64.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// AIX64-specific definitions for ASan memory mapping.
+//===----------------------------------------------------------------------===//
+#ifndef ASAN_MAPPING_AIX64_H
+#define ASAN_MAPPING_AIX64_H
+
+// https://www.ibm.com/docs/en/aix/7.3?topic=concepts-system-memory-allocation-using-malloc-subsystem
+//
+// For 64-bit on AIX,
+// - Data, heap, bss region is from 0x0000 0001 0000 0000 to
+//   0x07ff ffff ffff ffff (1ULL << 59).
+// - Shared library regions is from:
+//      0x0900 0000 0000 0000 to 0x09ff ffff ffff ffff
+//   or 0x0800 0000 0000 0000 to 0x08ff ffff ffff ffff ((1ULL << 52) * 2)
+// - mmap region is from 0x0a00 0000 0000 0000 to 0x0aff ffff ffff ffff
+//   (1ULL << 52).
+// - Initial stack region is from 0x0f00 0000 0000 0000 to
+//   0x0fff ffff ffff ffff (1ULL << 56).
+//
+// All above ranges are too big. And after verifying on AIX,(these datas are
+// from experiments on AIX72, AIX OS may change this layout in future)
+// - the biggest heap size is 1ULL << 47.
+// - the biggest global variable size is 1ULL << 29. (Which may be put in shared
+//   library data regions because global variables may be compiled to shared
+//   libraries.)
+//     the related address range for shared library data regions is:
+//          0x0900 1000 0000 0000 to 0x0900 1001 0000 0000
+//       or 0x0800 1000 0000 0000 to 0x0800 1001 0000 0000 (when above range is
+//          used by system libraries.)
+// - the biggest mmap size is 1ULL << 46.
+// - the biggest stack size is 1ULL << 32.
+//
+// We don't need so big heap and mmap, calling mmap for shadow memory for such
+// big heap and mmap is quite slow on AIX, so to balance runtime and examinable
+// memory size, we use 1ULL << 39(512GB) as size for each region except mmap
+// region. For mmap region, aix system mmap function may return a big range
+// address, we allocate 1ULL << 41(2TB).
+//
+// So the reasonable user space region size is:
+// - Data, heap, bss is from 0x0 to 0x0000 007f ffff ffff
+// - Shared library data is from:
+//        0x0900 1000 0000 0000 to 0x0900 107f ffff ffff
+//     or 0x0800 1000 0000 0000 to 0x0800 107f ffff ffff
+// - mmap is from 0x0a00 0000 0000 0000 to 0x0a00 01ff ffff ffff
+// - Stack is from 0x0fff ff80 0000 0000 to 0x0fff ffff ffff ffff
+//
+// AIX64 set ASAN_SHADOW_OFFSET_CONST at 0x0a01000000000000 because mmap
+// memory starts at 0x0a00000000000000 and shadow memory should be allocated
+// there. And we keep 0x0a00000000000000 to 0x0a01000000000000 For user mmap
+// usage.
+
+// NOTE: Users are not expected to use `mmap` specifying fixed address which is
+// inside the shadow memory ranges.
+
+// Default AIX64 mapping:
+// || `[0x0fffff8000000000, 0x0fffffffffffffff]` || HighMem    ||
+// || `[0x0a80fff000000000, 0x0a80ffffffffffff]` || HighShadow ||
+// || `[0x0a41000000000000, 0x0a41003fffffffff]` || MidShadow  ||
+// || `[0x0a21020000000000, 0x0a21020fffffffff]` || Mid2Shadow ||
+// || `[0x0a01020000000000, 0x0a01020fffffffff]` || Mid3Shadow ||
+// || `[0x0a01000000000000, 0x0a01000fffffffff]` || LowShadow  ||
+// || `[0x0a00000000000000, 0x0a0001ffffffffff]` || MidMem     ||
+// || `[0x0900100000000000, 0x0900107fffffffff]` || Mid2Mem    ||
+// || `[0x0800100000000000, 0x0800107fffffffff]` || Mid3Mem    ||
+// || `[0x0000000000000000, 0x0000007fffffffff]` || LowMem     ||
+
+#define VMA_BITS 58
+#define HIGH_BITS (64 - VMA_BITS)
+
+#define MEM_TO_SHADOW(mem)                                       \
+  ((((mem) << HIGH_BITS) >> (HIGH_BITS + (ASAN_SHADOW_SCALE))) + \
+   ASAN_SHADOW_OFFSET)
+
+#define SHADOW_TO_MEM(ptr) (__asan::ShadowToMemAIX64(ptr))
+
+#define kLowMemBeg 0ULL
+#define kLowMemEnd 0x0000007fffffffffULL
+
+#define kLowShadowBeg ASAN_SHADOW_OFFSET
+#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
+
+#define kHighMemBeg 0x0fffff8000000000ULL
+
+#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
+#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
+
+#define kMidMemBeg 0x0a00000000000000ULL
+#define kMidMemEnd 0x0a0001ffffffffffULL
+
+#define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
+#define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
+
+#define kMid2MemBeg 0x0900100000000000ULL
+#define kMid2MemEnd 0x0900107fffffffffULL
+
+#define kMid2ShadowBeg MEM_TO_SHADOW(kMid2MemBeg)
+#define kMid2ShadowEnd MEM_TO_SHADOW(kMid2MemEnd)
+
+#define kMid3MemBeg 0x0800100000000000ULL
+#define kMid3MemEnd 0x0800107fffffffffULL
+
+#define kMid3ShadowBeg MEM_TO_SHADOW(kMid3MemBeg)
+#define kMid3ShadowEnd MEM_TO_SHADOW(kMid3MemEnd)
+
+// AIX does not care about the gaps.
+#define kZeroBaseShadowStart 0
+#define kZeroBaseMaxShadowStart 0
+
+#define kShadowGapBeg 0
+#define kShadowGapEnd 0
+
+#define kShadowGap2Beg 0
+#define kShadowGap2End 0
+
+#define kShadowGap3Beg 0
+#define kShadowGap3End 0
+
+#define kShadowGap4Beg 0
+#define kShadowGap4End 0
+
+namespace __asan {
+
+static inline bool AddrIsInLowMem(uptr a) {
+  PROFILE_ASAN_MAPPING();
+  return a <= kLowMemEnd;
+}
+
+static inline bool AddrIsInLowShadow(uptr a) {
+  PROFILE_ASAN_MAPPING();
+  return a >= kLowShadowBeg && a <= kLowShadowEnd;
+}
+
+static inline bool AddrIsInMidMem(uptr a) {
+  PROFILE_ASAN_MAPPING();
+  return (a >= kMidMemBeg && a <= kMidMemEnd) ||
+         (a >= kMid2MemBeg && a <= kMid2MemEnd) ||
+         (a >= kMid3MemBeg && a <= kMid3MemEnd);
+}
+
+static inline bool AddrIsInMidShadow(uptr a) {
+  PROFILE_ASAN_MAPPING();
+  return (a >= kMidShadowBeg && a <= kMidShadowEnd) ||
+         (a >= kMid2ShadowBeg && a <= kMid2ShadowEnd) ||
+         (a >= kMid3ShadowBeg && a <= kMid3ShadowEnd);
+}
+
+static inline bool AddrIsInHighMem(uptr a) {
+  PROFILE_ASAN_MAPPING();
+  return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
+}
+
+static inline bool AddrIsInHighShadow(uptr a) {
+  PROFILE_ASAN_MAPPING();
+  return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
+}
+
+static inline bool AddrIsInShadowGap(uptr a) { return false; }
+
+static inline constexpr uptr ShadowToMemAIX64(uptr p) {
+  PROFILE_ASAN_MAPPING();
+  p -= ASAN_SHADOW_OFFSET;
+  p <<= ASAN_SHADOW_SCALE;
+  if (p >= 0x3ffff8000000000ULL) {
+    // HighMem
+    p |= (0x03ULL << VMA_BITS);
+  } else if (p >= 0x100000000000ULL) {
+    // MidShadow/Mid2Shadow/Mid2Shadow
+    p |= (0x02ULL << VMA_BITS);
+  }
+  return p;
+}
+
+}  // namespace __asan
+
+#endif  // ASAN_MAPPING_AIX64_H
diff --git a/compiler-rt/lib/asan/asan_poisoning.h b/compiler-rt/lib/asan/asan_poisoning.h
index 600bd011f304c..85482158dda9f 100644
--- a/compiler-rt/lib/asan/asan_poisoning.h
+++ b/compiler-rt/lib/asan/asan_poisoning.h
@@ -50,7 +50,9 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
   // for mapping shadow and zeroing out pages doesn't "just work", so we should
   // probably provide higher-level interface for these operations.
   // For now, just memset on Windows.
-  if (value || SANITIZER_WINDOWS == 1 ||
+  // On aix, calling ReserveShadowMemoryRange() is not allowed to remap the
+  // memory, so just memset the memory.
+  if (value || SANITIZER_WINDOWS == 1 || SANITIZER_AIX == 1 ||
       shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
     REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
   } else {
diff --git a/compiler-rt/lib/asan/asan_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp
index 39685696a0d0d..624b2743e80cf 100644
--- a/compiler-rt/lib/asan/asan_posix.cpp
+++ b/compiler-rt/lib/asan/asan_posix.cpp
@@ -14,7 +14,11 @@
 #include "sanitizer_common/sanitizer_platform.h"
 #if SANITIZER_POSIX
 
+// tid_t is also defined in AIX header /usr/include/sys/types.h which is
+// included by system pthread.h
+#  define tid_t tid_t_temp
 #  include <pthread.h>
+#  undef tid_t
 #  include <signal.h>
 #  include <stdlib.h>
 #  include <sys/resource.h>
@@ -173,7 +177,7 @@ static void AfterFork(bool fork_child) {
 }
 
 void InstallAtForkHandler() {
-#  if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE || \
+#  if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE || SANITIZER_AIX || \
       (SANITIZER_LINUX && SANITIZER_SPARC)
   // While other Linux targets use clone in internal_fork which doesn't
   // trigger pthread_atfork handlers, Linux/sparc64 uses __fork, causing a
diff --git a/compiler-rt/lib/asan/asan_rtl.cpp b/compiler-rt/lib/asan/asan_rtl.cpp
index 19c6c210b564c..92d8de36c82c6 100644
--- a/compiler-rt/lib/asan/asan_rtl.cpp
+++ b/compiler-rt/lib/asan/asan_rtl.cpp
@@ -55,13 +55,24 @@ static void AsanDie() {
   WaitForDebugger(flags()->sleep_before_dying, "before dying");
 
   if (flags()->unmap_shadow_on_exit) {
+#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
+    UnmapOrDie((void *)kHighShadowBeg, kHighShadowEnd - kHighShadowBeg);
+    UnmapOrDie((void *)kMidShadowBeg, kMidShadowEnd - kMidShadowBeg);
+
+    UnmapOrDie((void *)kMid2ShadowBeg, kMid2ShadowEnd - kMid2ShadowBeg);
+    UnmapOrDie((void *)kMid3ShadowBeg, kMid3ShadowEnd - kMid3ShadowBeg);
+
+    UnmapOrDie((void *)kLowShadowBeg, kLowShadowEnd - kLowShadowBeg);
+#else
     if (kMidMemBeg) {
-      UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
-      UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
+      UnmapOrDie((void *)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
+      UnmapOrDie((void *)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
     } else {
       if (kHighShadowEnd)
-        UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
+        UnmapOrDie((void *)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
+
     }
+#endif
   }
 }
 
@@ -85,7 +96,11 @@ bool AsanInited() {
 bool replace_intrin_cached;
 
 #if !ASAN_FIXED_MAPPING
+#if !(SANITIZER_AIX && __powerpc64__)
 uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
+#else
+uptr kHighMemEnd;
+#endif
 #endif
 
 // -------------------------- Misc ---------------- {{{1
@@ -341,17 +356,29 @@ void PrintAddressSpaceLayout() {
            (void*)kHighShadowBeg, (void*)kHighShadowEnd);
   }
   if (kMidMemBeg) {
+  // AIX shadowgap is always set to 0 for 64-bit.
+#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
     Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
            (void*)kShadowGap3Beg, (void*)kShadowGap3End);
+#endif
     Printf("|| `[%p, %p]` || MidMem     ||\n",
            (void*)kMidMemBeg, (void*)kMidMemEnd);
+#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
     Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
            (void*)kShadowGap2Beg, (void*)kShadowGap2End);
+#endif
     Printf("|| `[%p, %p]` || MidShadow  ||\n",
            (void*)kMidShadowBeg, (void*)kMidShadowEnd);
   }
+#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
+  Printf("|| `[%p, %p]` || Mid2Shadow  ||\n",
+         (void*)kMid2ShadowBeg, (void*)kMid2ShadowEnd);
+  Printf("|| `[%p, %p]` || Mid3Shadow  ||\n",
+         (void*)kMid3ShadowBeg, (void*)kMid3ShadowEnd);
+#else
   Printf("|| `[%p, %p]` || ShadowGap  ||\n",
          (void*)kShadowGapBeg, (void*)kShadowGapEnd);
+#endif
   if (kLowShadowBeg) {
     Printf("|| `[%p, %p]` || LowShadow  ||\n",
            (void*)kLowShadowBeg, (void*)kLowShadowEnd);
@@ -371,6 +398,15 @@ void PrintAddressSpaceLayout() {
            (void*)MEM_TO_SHADOW(kMidShadowBeg),
            (void*)MEM_TO_SHADOW(kMidShadowEnd));
   }
+// On AIX, for 64-bit, there are totally 3 mid memory regions.
+#if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
+    Printf(" %p %p",
+           (void*)MEM_TO_SHADOW(kMid2ShadowBeg),
+           (void*)MEM_TO_SHADOW(kMid2ShadowEnd));
+    Printf(" %p %p",
+           (void*)MEM_TO_SHADOW(kMid3ShadowBeg),
+           (void*)MEM_TO_SHADOW(kMid3ShadowEnd));
+#endif
   Printf("\n");
   Printf("redzone=%zu\n", (uptr)flags()->redzone);
   Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone);
@@ -386,7 +422,10 @@ void PrintAddressSpaceLayout() {
   CHECK(ASAN_SHADOW_SCALE >= 3 && ASAN_SHADOW_SCALE <= 7);
   if (kMidMemBeg)
     CHECK(kMidShadowBeg > kLowShadowEnd &&
+// On AIX 64-bit, we have a highly customized memory layout.
+#if !SANITIZER_AIX || SANITIZER_WORDSIZE != 64
           kMidMemBeg > kMidShadowEnd &&
+#endif
           kHighShadowBeg > kMidMemEnd);
 }
 
diff --git a/compiler-rt/lib/asan/asan_shadow_setup.cpp b/compiler-rt/lib/asan/asan_shadow_setup.cpp
index fc6de39622b51..c8416a2b0b7c7 100644
--- a/compiler-rt/lib/asan/asan_shadow_setup.cpp
+++ b/compiler-rt/lib/asan/asan_shadow_setup.cpp
@@ -91,9 +91,26 @@ void InitializeShadowMemory() {
       ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
     // mmap the high shadow.
     ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
-    // protect the gap.
-    ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
-    CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
+
+#  if SANITIZER_AIX == 1 && SANITIZER_WORDSIZE == 64
+    // Fox 64-bit AIX, there is a very customized memory layout, we don't have
+    // the ability to protect all the shadow gaps. But we need to reserve
+    // shadow memory for middle memory.
+    if (kMidShadowBeg)
+      ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, "mid shadow");
+
+    if (kMid2ShadowBeg)
+      ReserveShadowMemoryRange(kMid2ShadowBeg, kMid2ShadowEnd, "mid2 shadow");
+
+    if (kMid3ShadowBeg)
+      ReserveShadowMemoryRange(kMid3ShadowBeg, kMid3ShadowEnd, "mid3 shadow");
+#  else
+    if (kShadowGapBeg) {
+      // protect the gap.
+      ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
+      CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
+    }
+#  endif
   } else if (kMidMemBeg &&
              MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
              MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) {
diff --git a/compiler-rt/lib/asan/scripts/asan_symbolize.py b/compiler-rt/lib/asan/scripts/asan_symbolize.py
index 058a1614b55e6..8016d15e1cd64 100755
--- a/compiler-rt/lib/asan/scripts/asan_symbolize.py
+++ b/compiler-rt/lib/asan/scripts/asan_symbolize.py
@@ -59,6 +59,7 @@ def is_valid_arch(s):
         "armv7s",
         "armv7k",
         "arm64",
+        "powerpc"
         "powerpc64",
         "powerpc64le",
         "s390x",
@@ -449,7 +450,7 @@ def __init__(self, plugin_proxy=None, dsym_hint_producer=None):
             # E.g. in Chrome several binaries may share a single .dSYM.
             self.dsym_hint_producer = dsym_hint_producer
             self.system = os.uname()[0]
-            if self.system not in ["Linux", "Darwin", "FreeBSD", "NetBSD", "SunOS"]:
+            if self.system not in ["Linux", "Darwin", "FreeBSD", "NetBSD", "SunOS", "AIX"]:
                 raise Exception("Unknown system")
             self.llvm_symbolizers = {}
             self.last_llvm_symbolizer = None
diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt
index 00dcbf6534e28..4e556280d3e6e 100644
--- a/compiler-rt/lib/asan/tests/CMakeLists.txt
+++ b/compiler-rt/lib/asan/tests/CMakeLists.txt
@@ -80,6 +80,11 @@ if(NOT MSVC)
   list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS --driver-mode=g++)
 endif()
 
+# unittest will test asan sources which may require atomic library.
+if (${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+  list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -latomic)
+endif()
+
 # x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
 if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
   list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS "-lc++")
@@ -239,7 +244,8 @@ function(add_asan_tests arch test_runtime)
     LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS} ${TARGET_LINK_FLAGS})
 endfunction()
 
-if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
+# AIX can not run unittest because of shared library interception issue.
+if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "AIX")
   set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH})
   if(APPLE)
     darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH)
diff --git a/compiler-rt/lib/interception/CMakeLists.txt b/compiler-rt/lib/interception/CMakeLists.txt
index fe7fa27fbc78b..57c8c8ba20141 100644
--- a/compiler-rt/lib/interception/CMakeLists.txt
+++ b/compiler-rt/lib/interception/CMakeLists.txt
@@ -1,6 +1,7 @@
 # Build for the runtime interception helper library.
 
 set(INTERCEPTION_SOURCES
+  interception_aix.cpp
   interception_linux.cpp
   interception_mac.cpp
   interception_win.cpp
@@ -9,6 +10,7 @@ set(INTERCEPTION_SOURCES
 
 set(INTERCEPTION_HEADERS
   interception.h
+  interception_aix.h
   interception_linux.h
   interception_mac.h
   interception_win.h
diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h
index 3cb6b446638e0..3a20cfb04dcd6 100644
--- a/compiler-rt/lib/interception/interception.h
+++ b/compiler-rt/lib/interception/interception.h
@@ -19,7 +19,7 @@
 
 #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE &&    \
     !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
-    !SANITIZER_SOLARIS
+    !SANITIZER_SOLARIS && !SANITIZER_AIX
 #  error "Interception doesn't work on this operating system."
 #endif
 
@@ -168,6 +168,16 @@ const interpose_substitution substitution_##func_name[]             \
     extern "C" ret_type func(__VA_ARGS__);
 # define DECLARE_WRAPPER_WINAPI(ret_type, func, ...)  \
     extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
+#elif SANITIZER_AIX
+#  define WRAP(x) __interceptor_##x
+#  define TRAMPOLINE(x) WRAP(x)
+// # define WRAPPER_NAME(x) "__interceptor_" #x
+#  define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
+// AIX's linker will not select the weak symbol, so don't use weak for the
+// interceptors.
+#  define DECLARE_WRAPPER(ret_type, func, ...) \
+    extern "C" ret_type func(__VA_ARGS__)      \
+        __attribute__((alias("__interceptor_" #func), visibility("default")));
 #elif !SANITIZER_FUCHSIA  // LINUX, FREEBSD, NETBSD, SOLARIS
 # define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
 # if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
@@ -367,7 +377,12 @@ inline void DoesNotSupportStaticLinking() {}
 
 #define INCLUDED_FROM_INTERCEPTION_LIB
 
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
+#if SANITIZER_AIX
+# include "interception_aix.h"
+# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_AIX(func)
+# define INTERCEPT_FUNCTION_VER(func, symver) INTERCEPT_FUNCTION_AIX(func)
+
+#elif SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
     SANITIZER_SOLARIS
 
 # include "interception_linux.h"
diff --git a/compiler-rt/lib/interception/interception_aix.cpp b/compiler-rt/lib/interception/interception_aix.cpp
new file mode 100644
index 0000000000000..953bbad96eb47
--- /dev/null
+++ b/compiler-rt/lib/interception/interception_aix.cpp
@@ -0,0 +1,45 @@
+//===-- interception_aix.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// AIX-specific interception methods.
+//===----------------------------------------------------------------------===//
+
+#include "interception.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+#if SANITIZER_AIX
+
+#  include <dlfcn.h>  // for dlsym()
+
+namespace __interception {
+
+static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
+  // AIX dlsym can only defect the functions that are exported, so
+  // on AIX, we can not intercept some basic functions like memcpy.
+  // FIXME: if we are going to ship dynamic asan library, we may need to search
+  // all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed.
+  void *addr = dlsym(RTLD_NEXT, name);
+
+  // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
+  // We don't want to intercept the wrapper and have it point to itself.
+  if ((uptr)addr == wrapper_addr)
+    addr = nullptr;
+  return addr;
+}
+
+bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
+                       uptr wrapper) {
+  void *addr = GetFuncAddr(name, wrapper);
+  *ptr_to_real = (uptr)addr;
+  return addr && (func == wrapper);
+}
+
+}  // namespace __interception
+#endif  // SANITIZER_AIX
diff --git a/compiler-rt/lib/interception/interception_aix.h b/compiler-rt/lib/interception/interception_aix.h
new file mode 100644
index 0000000000000..08d17caeb6a8d
--- /dev/null
+++ b/compiler-rt/lib/interception/interception_aix.h
@@ -0,0 +1,36 @@
+//===-- interception_aix.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// AIX-specific interception methods.
+//===----------------------------------------------------------------------===//
+
+#if SANITIZER_AIX
+
+#  if !defined(INCLUDED_FROM_INTERCEPTION_LIB)
+#    error \
+        "interception_aix.h should be included from interception library only"
+#  endif
+
+#  ifndef INTERCEPTION_AIX_H
+#    define INTERCEPTION_AIX_H
+
+namespace __interception {
+bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
+                       uptr wrapper);
+}  // namespace __interception
+
+#    define INTERCEPT_FUNCTION_AIX(func)                \
+      ::__interception::InterceptFunction(              \
+          #func, (::__interception::uptr *)&REAL(func), \
+          (::__interception::uptr) & (func),            \
+          (::__interception::uptr)&WRAP(func))
+
+#  endif  // INTERCEPTION_AIX_H
+#endif    // SANITIZER_AIX
diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
index 09391e4f5f370..3652ddbd28333 100644
--- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt
+++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt
@@ -2,6 +2,7 @@
 # These components are shared between AddressSanitizer and ThreadSanitizer.
 
 set(SANITIZER_SOURCES_NOTERMINATION
+  sanitizer_aix.cpp
   sanitizer_allocator.cpp
   sanitizer_common.cpp
   sanitizer_deadlock_detector1.cpp
@@ -25,6 +26,7 @@ set(SANITIZER_SOURCES_NOTERMINATION
   sanitizer_platform_limits_solaris.cpp
   sanitizer_posix.cpp
   sanitizer_printf.cpp
+  sanitizer_procmaps_aix.cpp
   sanitizer_procmaps_common.cpp
   sanitizer_procmaps_bsd.cpp
   sanitizer_procmaps_fuchsia.cpp
@@ -95,6 +97,7 @@ set(SANITIZER_SYMBOLIZER_SOURCES
   sanitizer_symbolizer_report_fuchsia.cpp
   sanitizer_symbolizer_win.cpp
   sanitizer_thread_history.cpp
+  sanitizer_unwind_aix.cpp
   sanitizer_unwind_linux_libcdep.cpp
   sanitizer_unwind_fuchsia.cpp
   sanitizer_unwind_win.cpp
@@ -107,6 +110,7 @@ set(SANITIZER_IMPL_HEADERS
   sancov_flags.h
   sancov_flags.inc
   sanitizer_addrhashmap.h
+  sanitizer_aix.h
   sanitizer_allocator.h
   sanitizer_allocator_checks.h
   sanitizer_allocator_combined.h
@@ -239,6 +243,11 @@ append_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=570
 append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors
                SANITIZER_CFLAGS)
 
+# Suppress -Watomic-alignment warnings by not treating them as errors
+if (CMAKE_SYSTEM_NAME MATCHES "AIX")
+  list(APPEND SANITIZER_CFLAGS "-Wno-error=atomic-alignment")
+endif()
+
 if(APPLE)
   set(OS_OPTION OS ${SANITIZER_COMMON_SUPPORTED_OS})
 endif()
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_aix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_aix.cpp
new file mode 100644
index 0000000000000..fac3d7b10829f
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_aix.cpp
@@ -0,0 +1,499 @@
+//===-- sanitizer_aix.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between various sanitizers' runtime libraries and
+// implements AIX-specific functions.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+
+#if SANITIZER_AIX
+#  include <dlfcn.h>
+#  include <errno.h>
+#  include <fcntl.h>
+#  include <pthread.h>
+#  include <sched.h>
+#  include <signal.h>
+#  include <stdio.h>
+#  include <stdlib.h>
+#  include <string.h>
+#  include <sys/errno.h>
+#  include <sys/mman.h>
+#  include <sys/procfs.h>
+#  include <sys/stat.h>
+#  include <sys/thread.h>
+#  include <sys/time.h>
+#  include <sys/types.h>
+#  include <sys/ucontext.h>
+#  include <unistd.h>
+
+#  include "interception/interception.h"
+#  include "sanitizer_aix.h"
+#  include "sanitizer_common.h"
+#  include "sanitizer_file.h"
+#  include "sanitizer_libc.h"
+#  include "sanitizer_procmaps.h"
+
+extern char **p_xargv;
+
+namespace __sanitizer {
+
+#  include "sanitizer_syscall_generic.inc"
+
+static void *GetFuncAddr(const char *name) {
+  // FIXME: if we are going to ship dynamic asan library, we may need to search
+  // all the loaded modules with RTLD_DEFAULT if RTLD_NEXT failed.
+  void *addr = dlsym(RTLD_NEXT, name);
+  return addr;
+}
+
+// Internal implementation for the libc functions are also calling to the same
+// name function in libc. However because the same name function to libc may be
+// intercepted, and in the interceptor function, it may call REAL(func). But the
+// REAL(func) may be not assigned at this time, because internal_func may be
+// called before interceptor init functions are called. So we need to call to
+// libc function via function pointer.
+
+#  define _REAL(func, ...) real##_##func(__VA_ARGS__)
+
+#  define DEFINE__REAL(ret_type, func, ...)                       \
+    static ret_type (*real_##func)(__VA_ARGS__) = NULL;           \
+    if (!real_##func) {                                           \
+      real_##func = (ret_type(*)(__VA_ARGS__))GetFuncAddr(#func); \
+    }                                                             \
+    CHECK(real_##func);
+
+uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
+                   u64 offset) {
+  DEFINE__REAL(uptr, mmap, void *addr, uptr length, int prot, int flags, int fd,
+               u64 offset);
+  return _REAL(mmap, addr, length, prot, flags, fd, offset);
+}
+
+uptr internal_munmap(void *addr, uptr length) {
+  DEFINE__REAL(uptr, munmap, void *addr, uptr length);
+  return _REAL(munmap, addr, length);
+}
+
+int internal_mprotect(void *addr, uptr length, int prot) {
+  DEFINE__REAL(int, mprotect, void *addr, uptr length, int prot);
+  return _REAL(mprotect, addr, length, prot);
+}
+
+int internal_madvise(uptr addr, uptr length, int advice) {
+  char *raddr = reinterpret_cast<char *>(addr);
+  DEFINE__REAL(int, madvise, char *raddr, uptr length, int advice)
+  return _REAL(madvise, raddr, length, advice);
+}
+
+uptr internal_close(fd_t fd) {
+  DEFINE__REAL(uptr, close, fd_t fd);
+  return _REAL(close, fd);
+}
+
+uptr internal_open(const char *filename, int flags) {
+  DEFINE__REAL(uptr, open, const char *filename, int flags);
+  return _REAL(open, filename, flags);
+}
+
+uptr internal_open(const char *filename, int flags, u32 mode) {
+  DEFINE__REAL(uptr, open, const char *filename, int flags, u32 mode);
+  return _REAL(open, filename, flags, mode);
+}
+
+__sanitizer_FILE *internal_popen(const char *command, const char *type) {
+  DEFINE__REAL(__sanitizer_FILE *, popen, const char *command,
+               const char *type);
+  return _REAL(popen, command, type);
+}
+
+int internal_pclose(__sanitizer_FILE *file) {
+  FILE *rfile = reinterpret_cast<FILE *>(file);
+  DEFINE__REAL(int, pclose, FILE *file);
+  return _REAL(pclose, rfile);
+}
+
+uptr internal_read(fd_t fd, void *buf, uptr count) {
+  DEFINE__REAL(uptr, read, fd_t fd, void *buf, uptr count);
+  return _REAL(read, fd, buf, count);
+}
+
+uptr internal_write(fd_t fd, const void *buf, uptr count) {
+  DEFINE__REAL(uptr, write, fd_t fd, const void *buf, uptr count);
+  return _REAL(write, fd, buf, count);
+}
+
+uptr internal_stat(const char *path, void *buf) {
+  DEFINE__REAL(uptr, stat, const char *path, void *buf);
+  return _REAL(stat, path, buf);
+}
+
+uptr internal_lstat(const char *path, void *buf) {
+  DEFINE__REAL(uptr, lstat, const char *path, void *buf);
+  return _REAL(lstat, path, buf);
+}
+
+uptr internal_fstat(fd_t fd, void *buf) {
+  DEFINE__REAL(uptr, fstat, fd_t fd, void *buf);
+  return _REAL(fstat, fd, buf);
+}
+
+uptr internal_filesize(fd_t fd) {
+  struct stat st;
+  if (internal_fstat(fd, &st))
+    return -1;
+  return (uptr)st.st_size;
+}
+
+uptr internal_dup(int oldfd) {
+  DEFINE__REAL(uptr, dup, int oldfd);
+  return _REAL(dup, oldfd);
+}
+
+uptr internal_dup2(int oldfd, int newfd) {
+  DEFINE__REAL(uptr, dup2, int oldfd, int newfd);
+  return _REAL(dup2, oldfd, newfd);
+}
+
+uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
+  DEFINE__REAL(uptr, readlink, const char *path, char *buf, uptr bufsize);
+  return _REAL(readlink, path, buf, bufsize);
+}
+
+uptr internal_unlink(const char *path) {
+  DEFINE__REAL(uptr, unlink, const char *path);
+  return _REAL(unlink, path);
+}
+
+uptr internal_sched_yield() {
+  DEFINE__REAL(uptr, sched_yield);
+  return _REAL(sched_yield);
+}
+
+void FutexWait(atomic_uint32_t *p, u32 cmp) { internal_sched_yield(); }
+
+void FutexWake(atomic_uint32_t *p, u32 count) {}
+
+void internal__exit(int exitcode) {
+  DEFINE__REAL(void, _exit, int exitcode);
+  _REAL(_exit, exitcode);
+  Die();  // Unreachable.
+}
+
+void internal_usleep(u64 useconds) {
+  DEFINE__REAL(void, usleep, u64 useconds);
+  _REAL(usleep, useconds);
+}
+
+uptr internal_getpid() {
+  DEFINE__REAL(uptr, getpid);
+  return _REAL(getpid);
+}
+
+int internal_dlinfo(void *handle, int request, void *p) { return 0; }
+
+int internal_sigaction(int signum, const void *act, void *oldact) {
+  DEFINE__REAL(int, sigaction, int signum, const void *act, void *oldact);
+  return _REAL(sigaction, signum, act, oldact);
+}
+
+void internal_sigfillset(__sanitizer_sigset_t *set) {
+  sigset_t *rset = reinterpret_cast<sigset_t *>(set);
+  DEFINE__REAL(void, sigfillset, sigset_t *rset);
+  _REAL(sigfillset, rset);
+}
+
+uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
+                          __sanitizer_sigset_t *oldset) {
+  sigset_t *rset = reinterpret_cast<sigset_t *>(set);
+  sigset_t *roldset = reinterpret_cast<sigset_t *>(oldset);
+  DEFINE__REAL(uptr, sigprocmask, int how, sigset_t *rset, sigset_t *roldset);
+  return _REAL(sigprocmask, how, rset, roldset);
+}
+
+char *internal_getcwd(char *buf, uptr size) {
+  DEFINE__REAL(char *, getcwd, char *buf, uptr size);
+  return _REAL(getcwd, buf, size);
+}
+
+int internal_fork() {
+  DEFINE__REAL(int, fork);
+  return _REAL(fork);
+}
+
+uptr internal_execve(const char *filename, char *const argv[],
+                     char *const envp[]) {
+  DEFINE__REAL(uptr, execve, const char *filename, char *const argv[],
+               char *const envp[]);
+  return _REAL(execve, filename, argv, envp);
+}
+
+uptr internal_waitpid(int pid, int *status, int options) {
+  DEFINE__REAL(uptr, waitpid, int pid, int *status, int options);
+  return _REAL(waitpid, pid, status, options);
+}
+
+int internal_pthread_join(pthread_t thread, void **status) {
+  DEFINE__REAL(int, pthread_join, pthread_t thread, void **status);
+  return _REAL(pthread_join, thread, status);
+}
+
+int internal_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+                            void *(*start_routine)(void *), void *arg) {
+  DEFINE__REAL(int, pthread_create, pthread_t *thread,
+               const pthread_attr_t *attr, void *(*start_routine)(void *),
+               void *arg);
+  return _REAL(pthread_create, thread, attr, start_routine, arg);
+}
+
+void *internal_start_thread(void *(*func)(void *arg), void *arg) {
+  // Start the thread with signals blocked, otherwise it can steal user signals.
+  __sanitizer_sigset_t set, old;
+  internal_sigfillset(&set);
+  internal_sigprocmask(SIG_SETMASK, &set, &old);
+  pthread_t th;
+  internal_pthread_create(&th, 0, func, arg);
+  internal_sigprocmask(SIG_SETMASK, &old, 0);
+  // pthread_t is unsinged int on AIX
+  return reinterpret_cast<void *>(th);
+}
+
+void internal_join_thread(void *th) {
+  internal_pthread_join((pthread_t)(reinterpret_cast<uptr>(th)), nullptr);
+}
+
+uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
+  clock_t rclk_id = reinterpret_cast<clock_t>(clk_id);
+  struct timespec *rtp = reinterpret_cast<struct timespec *>(tp);
+  DEFINE__REAL(uptr, clock_gettime, clock_t rclk_id, struct timespec * rtp);
+  return _REAL(clock_gettime, rclk_id, rtp);
+}
+
+void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
+                                uptr *stack_bottom) {
+  CHECK(stack_top);
+  CHECK(stack_bottom);
+  if (at_initialization) {
+    // This is the main thread. Libpthread may not be initialized yet.
+    struct rlimit rl;
+    CHECK_EQ(getrlimit(RLIMIT_STACK, &rl), 0);
+
+    // Find the mapping that contains a stack variable.
+    MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
+    if (proc_maps.Error()) {
+      *stack_top = *stack_bottom = 0;
+      return;
+    }
+    MemoryMappedSegment segment;
+    uptr prev_end = 0;
+    while (proc_maps.Next(&segment)) {
+      if ((uptr)&rl < segment.end)
+        break;
+      prev_end = segment.end;
+    }
+
+    CHECK((uptr)&rl >= segment.start && (uptr)&rl < segment.end);
+
+    // Get stacksize from rlimit, but clip it so that it does not overlap
+    // with other mappings.
+    uptr stacksize = rl.rlim_cur;
+    if (stacksize > segment.end - prev_end)
+      stacksize = segment.end - prev_end;
+    // When running with unlimited stack size, we still want to set some limit.
+    // The unlimited stack size is caused by 'ulimit -s unlimited'.
+    // Also, for some reason, GNU make spawns subprocesses with unlimited stack.
+    if (stacksize > kMaxThreadStackSize)
+      stacksize = kMaxThreadStackSize;
+    *stack_top = segment.end;
+    *stack_bottom = segment.end - stacksize;
+    return;
+  }
+  uptr stacksize = 0;
+  void *stackaddr = nullptr;
+  pthread_attr_t attr;
+  pthread_attr_init(&attr);
+  CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0);
+  internal_pthread_attr_getstack(&attr, &stackaddr, &stacksize);
+  pthread_attr_destroy(&attr);
+
+  *stack_top = (uptr)stackaddr;
+  *stack_bottom = (uptr)stackaddr - stacksize;
+}
+
+void GetThreadStackAndTls(bool main, uptr *stk_begin, uptr *stk_end,
+                          uptr *tls_begin, uptr *tls_end) {
+  // FIXME: handle TLS related flag
+  *tls_begin = 0;
+  *tls_end = 0;
+
+  uptr stack_top, stack_bottom;
+  GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom);
+  *stk_begin = stack_bottom;
+  *stk_end = stack_top;
+}
+
+const char *GetEnv(const char *name) { return getenv(name); }
+
+tid_t GetTid() { return thread_self(); }
+
+uptr ReadBinaryName(char *buf, uptr buf_len) {
+  struct stat statData;
+  struct psinfo psinfoData;
+
+  char FilePsinfo[100] = {};
+  internal_snprintf(FilePsinfo, 100, "/proc/%d/psinfo", internal_getpid());
+  CHECK_EQ(internal_stat(FilePsinfo, &statData), 0);
+
+  const int fd = internal_open(FilePsinfo, O_RDONLY);
+  ssize_t readNum = internal_read(fd, &psinfoData, sizeof(psinfoData));
+  CHECK_GE(readNum, 0);
+
+  internal_close(fd);
+  char *binary_name = (reinterpret_cast<char ***>(psinfoData.pr_argv))[0][0];
+
+  // This is an absulate path.
+  if (binary_name[0] == '/')
+    return internal_snprintf(buf, buf_len, "%s", binary_name);
+
+  // This is a relative path to the binary, starts with ./ or ../
+  if (binary_name[0] == '.') {
+    char *path = nullptr;
+    if ((path = internal_getcwd(buf, buf_len)) != nullptr)
+      return internal_snprintf(buf + internal_strlen(path),
+                               buf_len - internal_strlen(path), "/%s",
+                               binary_name) +
+             internal_strlen(path);
+  }
+
+  // This is running a raw binary in the dir where it is from.
+  char *path = nullptr;
+  if ((path = internal_getcwd(buf, buf_len)) != nullptr) {
+    char fullName[kMaxPathLength] = {};
+    internal_snprintf(fullName, kMaxPathLength, "%s/%s", path, binary_name);
+    if (FileExists(fullName))
+      return internal_snprintf(buf + internal_strlen(path),
+                               buf_len - internal_strlen(path), "/%s",
+                               binary_name) +
+             internal_strlen(path);
+  }
+
+  // Find the binary in the env PATH.
+  if ((path = FindPathToBinaryOrLibrary(binary_name)) != nullptr)
+    return internal_snprintf(buf, buf_len, "%s", path);
+
+  return 0;
+}
+
+// https://www.ibm.com/docs/en/aix/7.3?topic=concepts-system-memory-allocation-using-malloc-subsystem
+uptr GetMaxVirtualAddress() {
+#  if SANITIZER_WORDSIZE == 64
+  return (1ULL << 60) - 1;
+#  else
+  return 0xffffffff;
+#  endif
+}
+
+uptr GetMaxUserVirtualAddress() { return GetMaxVirtualAddress(); }
+
+uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
+  return ReadBinaryName(buf, buf_len);
+}
+
+void InitializePlatformCommonFlags(CommonFlags *cf) {}
+
+void InitializePlatformEarly() {
+  // Do nothing.
+}
+
+uptr GetPageSize() { return getpagesize(); }
+
+void CheckASLR() {
+  // Do nothing
+}
+
+HandleSignalMode GetHandleSignalMode(int signum) {
+  switch (signum) {
+    case SIGABRT:
+      return common_flags()->handle_abort;
+    case SIGILL:
+      return common_flags()->handle_sigill;
+    case SIGTRAP:
+      return common_flags()->handle_sigtrap;
+    case SIGFPE:
+      return common_flags()->handle_sigfpe;
+    case SIGSEGV:
+      return common_flags()->handle_segv;
+    case SIGBUS:
+      return common_flags()->handle_sigbus;
+  }
+  return kHandleSignalNo;
+}
+
+void InitTlsSize() {}
+
+bool FileExists(const char *filename) {
+  struct stat st;
+  if (internal_stat(filename, &st))
+    return false;
+  // Sanity check: filename is a regular file.
+  return S_ISREG(st.st_mode);
+}
+
+bool DirExists(const char *path) {
+  struct stat st;
+  if (internal_stat(path, &st))
+    return false;
+  return S_ISDIR(st.st_mode);
+}
+
+uptr GetTlsSize() {
+  // FIXME: implement this interface.
+  return 0;
+}
+
+SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
+  return SignalContext::Unknown;
+}
+
+bool SignalContext::IsTrueFaultingAddress() const { return true; }
+
+void SignalContext::InitPcSpBp() {
+  ucontext_t *ucontext = (ucontext_t *)context;
+  pc = ucontext->uc_mcontext.jmp_context.iar;
+  sp = ucontext->uc_mcontext.jmp_context.gpr[1];
+  // The powerpc{,64} ABIs do not specify r31 as the frame pointer, but compiler
+  // always uses r31 when we need a frame pointer.
+  bp = ucontext->uc_mcontext.jmp_context.gpr[31];
+}
+
+void SignalContext::DumpAllRegisters(void *context) {}
+
+char **GetEnviron() { return nullptr; }
+
+char **GetArgv() { return p_xargv; }
+
+void ListOfModules::init() {
+  clearOrInit();
+  MemoryMappingLayout memory_mapping(false);
+  memory_mapping.DumpListOfModules(&modules_);
+}
+
+void ListOfModules::fallbackInit() { clear(); }
+
+u64 MonotonicNanoTime() {
+  timespec ts;
+  internal_clock_gettime(CLOCK_MONOTONIC, &ts);
+  return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec;
+}
+
+// FIXME implement on this platform.
+void GetMemoryProfile(fill_profile_f cb, uptr *stats) {}
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_AIX
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_aix.h b/compiler-rt/lib/sanitizer_common/sanitizer_aix.h
new file mode 100644
index 0000000000000..5883d1f2e16de
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_aix.h
@@ -0,0 +1,47 @@
+//===-- sanitizer_aix.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is shared between various sanitizers' runtime libraries and
+// provides definitions for AIX-specific functions.
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_AIX_H
+#define SANITIZER_AIX_H
+
+#include "sanitizer_platform.h"
+
+#if SANITIZER_AIX
+#include "sanitizer_common.h"
+#  include "sanitizer_posix.h"
+
+namespace __sanitizer {
+
+#if SANITIZER_WORDSIZE == 32
+static const uptr InstructionStart = 0x10000000;
+#else
+static const uptr InstructionStart = 0x100000000;
+#endif
+
+struct ProcSelfMapsBuff {
+  char *data;
+  uptr mmaped_size;
+  uptr len;
+};
+
+struct MemoryMappingLayoutData {
+  ProcSelfMapsBuff proc_self_maps;
+  const char *current;
+};
+
+void ReadProcMaps(ProcSelfMapsBuff *proc_maps);
+
+char *internal_getcwd(char *buf, uptr size);
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_AIX
+#endif  // SANITIZER_AIX_H
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h
index 62523c7ae187c..e5b912d70e61e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_internal.h
@@ -23,7 +23,12 @@ namespace __sanitizer {
 typedef CompactSizeClassMap InternalSizeClassMap;
 
 struct AP32 {
+// For AIX 64-bit, the mmap begin is at address 0x0a00000000000000ULL.
+#if SANITIZER_AIX && SANITIZER_WORDSIZE == 64
+  static const uptr kSpaceBeg = 0x0a00000000000000ULL;
+#else
   static const uptr kSpaceBeg = 0;
+#endif
   static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
   static const uptr kMetadataSize = 0;
   typedef InternalSizeClassMap SizeClassMap;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h
index 602b197c42ae3..0faf9b3c151a4 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_allocator_primary32.h
@@ -288,6 +288,7 @@ class SizeClassAllocator32 {
   uptr ComputeRegionId(uptr mem) const {
     if (SANITIZER_SIGN_EXTENDED_ADDRESSES)
       mem &= (kSpaceSize - 1);
+    mem -= kSpaceBeg;
     const uptr res = mem >> kRegionSizeLog;
     CHECK_LT(res, kNumPossibleRegions);
     return res;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp
index 6cd69a53093e7..3b5286bcf9be9 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp
@@ -275,6 +275,12 @@ const char *GetProcessName() {
   return process_name_cache_str;
 }
 
+const char *GetBinaryName() {
+  if (binary_name_cache_str[0] == '\0')
+    ReadBinaryName(binary_name_cache_str, sizeof(binary_name_cache_str));
+  return binary_name_cache_str;
+}
+
 static uptr ReadProcessName(/*out*/ char *buf, uptr buf_len) {
   ReadLongProcessName(buf, buf_len);
   char *s = const_cast<char *>(StripModuleName(buf));
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index d9e7ded593feb..466790d335ac0 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -290,6 +290,7 @@ uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len);
 uptr ReadBinaryDir(/*out*/ char *buf, uptr buf_len);
 uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len);
 const char *GetProcessName();
+const char *GetBinaryName();
 void UpdateProcessName();
 void CacheBinaryName();
 void DisableCoreDumperIfNecessary();
@@ -835,7 +836,8 @@ class LoadedModule {
         max_address_(0),
         arch_(kModuleArchUnknown),
         uuid_size_(0),
-        instrumented_(false) {
+        instrumented_(false),
+        instr_start_(0) {
     internal_memset(uuid_, 0, kModuleUUIDSize);
     ranges_.clear();
   }
@@ -855,6 +857,8 @@ class LoadedModule {
   const u8 *uuid() const { return uuid_; }
   uptr uuid_size() const { return uuid_size_; }
   bool instrumented() const { return instrumented_; }
+  uptr get_instr_start() const { return instr_start_; }
+  void set_instr_start(uptr start) { instr_start_ = start; }
 
   struct AddressRange {
     AddressRange *next;
@@ -885,6 +889,7 @@ class LoadedModule {
   uptr uuid_size_;
   u8 uuid_[kModuleUUIDSize];
   bool instrumented_;
+  uptr instr_start_;
   IntrusiveList<AddressRange> ranges_;
 };
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 24a8a2d4dc55b..a71981282f615 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -480,7 +480,7 @@ INTERCEPTOR(char*, textdomain, const char *domainname) {
 #define INIT_TEXTDOMAIN
 #endif
 
-#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP
+#if SANITIZER_INTERCEPT_MEMCMP
 static inline int CharCmpX(unsigned char c1, unsigned char c2) {
   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
 }
@@ -953,7 +953,7 @@ INTERCEPTOR(double, frexp, double x, int *exp) {
 #define INIT_FREXP
 #endif  // SANITIZER_INTERCEPT_FREXP
 
-#if SANITIZER_INTERCEPT_FREXPF_FREXPL
+#if SANITIZER_INTERCEPT_FREXPF
 INTERCEPTOR(float, frexpf, float x, int *exp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
@@ -963,6 +963,12 @@ INTERCEPTOR(float, frexpf, float x, int *exp) {
   return res;
 }
 
+#define INIT_FREXPF COMMON_INTERCEPT_FUNCTION(frexpf);
+#else
+#define INIT_FREXPF
+#endif
+
+#if SANITIZER_INTERCEPT_FREXPL
 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
@@ -972,12 +978,10 @@ INTERCEPTOR(long double, frexpl, long double x, int *exp) {
   return res;
 }
 
-#define INIT_FREXPF_FREXPL           \
-  COMMON_INTERCEPT_FUNCTION(frexpf); \
-  COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
+#define INIT_FREXPL COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
 #else
-#define INIT_FREXPF_FREXPL
-#endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
+#define INIT_FREXPL
+#endif
 
 #if SI_POSIX
 static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
@@ -1346,7 +1350,8 @@ INTERCEPTOR(unsigned long, time, unsigned long *t) {
 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
-#if !SANITIZER_SOLARIS
+// AIX tm struct does not have tm_zone field.
+#if !SANITIZER_SOLARIS && !SANITIZER_AIX
   if (tm->tm_zone) {
     // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
     // can point to shared memory and tsan would report a data race.
@@ -1731,8 +1736,10 @@ INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
 #endif
 
+#if SANITIZER_INTERCEPT_VASPRINTF
 INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
 VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
+#endif
 
 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
 INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
@@ -1783,8 +1790,10 @@ INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
 FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)
 #endif
 
+#if SANITIZER_INTERCEPT_ASPRINTF
 INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
 FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
+#endif
 
 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
 INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
@@ -1807,17 +1816,29 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
 #endif  // SANITIZER_INTERCEPT_PRINTF
 
 #if SANITIZER_INTERCEPT_PRINTF
+#if SANITIZER_AIX
+#define INIT_PRINTF                     \
+  COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
+  COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
+  COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
+  COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
+  COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
+  COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
+  COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
+  COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
+#else
 #define INIT_PRINTF                     \
   COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
   COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
   COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
-  COMMON_INTERCEPT_FUNCTION_LDBL(asprintf);  \
   COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
   COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
   COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
   COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
+  COMMON_INTERCEPT_FUNCTION_LDBL(asprintf);  \
   COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
   COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
+#endif
 #else
 #define INIT_PRINTF
 #endif
@@ -3901,7 +3922,10 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
   if (res != ((SIZE_T)-1)) {
     CHECK_LE(res, sizeof(local_dest));
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
-    REAL(memcpy)(dest, local_dest, res);
+    if (!SANITIZER_AIX)
+      REAL(memcpy)(dest, local_dest, res);
+    else
+      internal_memcpy(dest, local_dest, res);
   }
   return res;
 }
@@ -3923,7 +3947,10 @@ INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
   if (res != -1) {
     CHECK_LE(res, sizeof(local_dest));
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
-    REAL(memcpy)(dest, local_dest, res);
+    if (!SANITIZER_AIX)
+      REAL(memcpy)(dest, local_dest, res);
+    else
+      internal_memcpy(dest, local_dest, res);
   }
   return res;
 }
@@ -10329,7 +10356,8 @@ static void InitializeCommonInterceptors() {
   INIT_PRINTF_L;
   INIT_ISOC99_PRINTF;
   INIT_FREXP;
-  INIT_FREXPF_FREXPL;
+  INIT_FREXPF;
+  INIT_FREXPL;
   INIT_GETPWNAM_AND_FRIENDS;
   INIT_GETPWNAM_R_AND_FRIENDS;
   INIT_GETPWENT;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
index 49ec4097c900b..5b23039954a43 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
@@ -73,7 +73,9 @@ static void ioctl_table_fill() {
   _(TIOCNXCL, NONE, 0);
   _(TIOCOUTQ, WRITE, sizeof(int));
   _(TIOCPKT, READ, sizeof(int));
+#if !SANITIZER_AIX
   _(TIOCSCTTY, NONE, 0);
+#endif
   _(TIOCSETD, READ, sizeof(int));
   _(TIOCSPGRP, READ, pid_t_sz);
   _(TIOCSTI, READ, sizeof(char));
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
index 1565a494140f6..e542a6c7b438a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc
@@ -36,6 +36,8 @@
 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
 #elif SANITIZER_WINDOWS64
 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
+#elif SANITIZER_AIX
+#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
 #else
 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
 #endif  // SANITIZER_APPLE
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
index f275e81ff0416..a770c8cf656b3 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_libcdep.cpp
@@ -169,7 +169,12 @@ void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name,
                      : !MmapFixedNoReserve(beg, size, name)) {
     Report(
         "ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
-        "Perhaps you're using ulimit -v or ulimit -d\n",
+        "Perhaps you're using ulimit -v "
+#if SANITIZER_AIX && SANITIZER_WORDSIZE == 32
+        "or using large address-space model for 32-bit XCOFF by using ldedit "
+        "or setting LDR_CNTRL=MAXDATA or compiling the binary with -bmaxdata "
+#endif
+        "\n",
         size);
     Die();
   }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h
index 46c85364cef56..cb31f02fcd88f 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h
@@ -29,6 +29,8 @@
 #  define __errno_location ___errno
 #elif SANITIZER_WINDOWS
 #  define __errno_location _errno
+#elif SANITIZER_AIX
+#  define __errno_location _Errno
 #endif
 
 extern "C" int *__errno_location();
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
index 96af270f9d8b5..6684e54c1d510 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
@@ -203,12 +203,12 @@ bool ReadFileToVector(const char *file_name,
 
 static const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':';
 
-char *FindPathToBinary(const char *name) {
+char *FindPathToBinaryOrLibrary(const char *name, const char *env_string) {
   if (FileExists(name)) {
     return internal_strdup(name);
   }
 
-  const char *path = GetEnv("PATH");
+  const char *path = GetEnv(env_string);
   if (!path)
     return nullptr;
   uptr name_len = internal_strlen(name);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.h b/compiler-rt/lib/sanitizer_common/sanitizer_file.h
index bef2c842d9f24..000f437d126e5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.h
@@ -79,7 +79,8 @@ bool SupportsColoredOutput(fd_t fd);
 const char *GetPwd();
 bool FileExists(const char *filename);
 bool DirExists(const char *path);
-char *FindPathToBinary(const char *name);
+char *FindPathToBinaryOrLibrary(const char *name,
+                                const char *env_string = "PATH");
 bool IsPathSeparator(const char c);
 bool IsAbsolutePath(const char *path);
 // Returns true on success, false on failure.
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
index c1e3530618c20..a6c760b2387fb 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_flags.inc
@@ -269,6 +269,9 @@ COMMON_FLAG(bool, detect_write_exec, false,
 COMMON_FLAG(bool, test_only_emulate_no_memorymap, false,
             "TEST ONLY fail to read memory mappings to emulate sanitized "
             "\"init\"")
+COMMON_FLAG(bool, enable_unmalloced_free_check, !SANITIZER_AIX,
+            "if true, FreeNotMalloced error will be reported. Only disable "
+            "this error detecting on AIX by default for now.")
 // With static linking, dladdr((void*)pthread_join) or similar will return the
 // path to the main program. This flag will replace dlopen(<main program,...>
 // with dlopen(NULL,...), which is the correct way to get a handle to the main
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
index 57966403c92a9..214d2865892df 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -14,7 +14,7 @@
 
 #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
     !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) &&     \
-    !(defined(__sun__) && defined(__svr4__))
+    !(defined(__sun__) && defined(__svr4__)) && !defined(_AIX)
 #  error "This operating system is not supported"
 #endif
 
@@ -31,6 +31,12 @@
 #  define SANITIZER_LINUX 0
 #endif
 
+#if defined(_AIX)
+#  define SANITIZER_AIX 1
+#else
+#  define SANITIZER_AIX 0
+#endif
+
 #if defined(__GLIBC__)
 #  define SANITIZER_GLIBC 1
 #else
@@ -138,7 +144,7 @@
 
 #define SANITIZER_POSIX                                     \
   (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \
-   SANITIZER_NETBSD || SANITIZER_SOLARIS)
+   SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_AIX)
 
 #if __LP64__ || defined(_WIN64)
 #  define SANITIZER_WORDSIZE 64
@@ -392,7 +398,9 @@
 // (ie. same as double) to 128-bit long double.  On those, glibc symbols
 // involving long doubles come in two versions, and we need to pass the
 // correct one to dlvsym when intercepting them.
-#if SANITIZER_LINUX && (SANITIZER_S390 || SANITIZER_PPC32 || SANITIZER_PPC64V1)
+#if SANITIZER_LINUX &&                                        \
+    (SANITIZER_S390 || (SANITIZER_PPC32 && !SANITIZER_AIX) || \
+     SANITIZER_PPC64V1)
 #  define SANITIZER_NLDBL_VERSION "GLIBC_2.4"
 #endif
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index febd233bb1e3c..43a37037c971d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -139,6 +139,12 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SI_SOLARIS 0
 #endif
 
+#if SANITIZER_AIX
+#define SI_NOT_AIX 0
+#else
+#define SI_NOT_AIX 1
+#endif
+
 #if SANITIZER_SOLARIS32
 #define SI_SOLARIS32 1
 #else
@@ -159,20 +165,20 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 
 #define SANITIZER_INTERCEPT_STRLEN SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRNLEN (SI_NOT_MAC && SI_NOT_FUCHSIA)
-#define SANITIZER_INTERCEPT_STRCMP SI_NOT_FUCHSIA
+#define SANITIZER_INTERCEPT_STRCMP (SI_NOT_FUCHSIA && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_STRSTR SI_NOT_FUCHSIA
-#define SANITIZER_INTERCEPT_STRCASESTR SI_POSIX
+#define SANITIZER_INTERCEPT_STRCASESTR (SI_POSIX && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_STRTOK SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRCHR SI_NOT_FUCHSIA
-#define SANITIZER_INTERCEPT_STRCHRNUL SI_POSIX_NOT_MAC
+#define SANITIZER_INTERCEPT_STRCHRNUL (SI_POSIX_NOT_MAC && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_STRRCHR SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRSPN SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_STRPBRK SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_STRCASECMP SI_POSIX
 #define SANITIZER_INTERCEPT_MEMSET 1
-#define SANITIZER_INTERCEPT_MEMMOVE 1
-#define SANITIZER_INTERCEPT_MEMCPY 1
+#define SANITIZER_INTERCEPT_MEMMOVE SI_NOT_AIX
+#define SANITIZER_INTERCEPT_MEMCPY SI_NOT_AIX
 #define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA
 #define SANITIZER_INTERCEPT_BCMP \
   SANITIZER_INTERCEPT_MEMCMP &&  \
@@ -231,6 +237,8 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_ISOC99_SCANF SI_GLIBC
 
 #ifndef SANITIZER_INTERCEPT_PRINTF
+#define SANITIZER_INTERCEPT_ASPRINTF SI_NOT_AIX
+#define SANITIZER_INTERCEPT_VASPRINTF SI_NOT_AIX
 #define SANITIZER_INTERCEPT_PRINTF SI_POSIX
 #define SANITIZER_INTERCEPT_PRINTF_L (SI_FREEBSD || SI_NETBSD)
 #define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_GLIBC
@@ -239,8 +247,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT___PRINTF_CHK \
   (SANITIZER_INTERCEPT_PRINTF && SI_GLIBC)
 
-#define SANITIZER_INTERCEPT_FREXP SI_NOT_FUCHSIA
-#define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_POSIX
+// AIX libc does not export FREXP and FREXP.
+#define SANITIZER_INTERCEPT_FREXP (SI_NOT_FUCHSIA && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_FREXPF (SI_POSIX && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_FREXPL SI_POSIX
 
 #define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX
 #define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \
@@ -289,7 +299,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_ACCEPT4 \
   (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_FREEBSD)
 #define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD
-#define SANITIZER_INTERCEPT_MODF SI_POSIX
+#define SANITIZER_INTERCEPT_MODF (SI_POSIX && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_RECVMSG SI_POSIX
 #define SANITIZER_INTERCEPT_SENDMSG SI_POSIX
 #define SANITIZER_INTERCEPT_RECVMMSG SI_LINUX
@@ -324,8 +334,9 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT___WCSXFRM_L SI_LINUX
 #define SANITIZER_INTERCEPT_WCSNRTOMBS \
   (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
-#define SANITIZER_INTERCEPT_WCRTOMB \
-  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_WCRTOMB                                           \
+  (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS || \
+   !SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_WCTOMB \
   (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS
@@ -365,7 +376,8 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
 #define SANITIZER_INTERCEPT_STATFS \
   (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
-#define SANITIZER_INTERCEPT_STATFS64 SI_GLIBC && SANITIZER_HAS_STATFS64
+#define SANITIZER_INTERCEPT_STATFS64 \
+  ((SI_GLIBC || !SI_NOT_AIX) && SANITIZER_HAS_STATFS64)
 #define SANITIZER_INTERCEPT_STATVFS \
   (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID)
 #define SANITIZER_INTERCEPT_STATVFS64 SI_GLIBC
@@ -414,10 +426,10 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX
 #define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX
 #define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS
-#define SANITIZER_INTERCEPT_REMQUO SI_POSIX
-#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD)
-#define SANITIZER_INTERCEPT_LGAMMA SI_POSIX
-#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD)
+#define SANITIZER_INTERCEPT_REMQUO (SI_POSIX && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_LGAMMA (SI_POSIX && SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD && SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS)
 #define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
 #define SANITIZER_INTERCEPT_DRAND48_R SI_GLIBC
@@ -502,9 +514,11 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SI_STAT_LINUX (SI_LINUX && __GLIBC_PREREQ(2, 33))
 #define SANITIZER_INTERCEPT_STAT                                        \
   (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS ||     \
-   SI_STAT_LINUX)
-#define SANITIZER_INTERCEPT_STAT64 SI_STAT_LINUX && SANITIZER_HAS_STAT64
-#define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX)
+   SI_STAT_LINUX || !SI_NOT_AIX)
+#define SANITIZER_INTERCEPT_STAT64 \
+  ((SI_STAT_LINUX || !SI_NOT_AIX) && SANITIZER_HAS_STAT64)
+#define SANITIZER_INTERCEPT_LSTAT \
+  (SI_NETBSD || SI_FREEBSD || SI_STAT_LINUX || !SI_NOT_AIX)
 #define SANITIZER_INTERCEPT___XSTAT \
   ((!SANITIZER_INTERCEPT_STAT && SI_POSIX) || SI_STAT_LINUX)
 #define SANITIZER_INTERCEPT___XSTAT64 SI_GLIBC
@@ -572,7 +586,7 @@ SANITIZER_WEAK_IMPORT void *aligned_alloc(__sanitizer::usize __alignment,
 #define SANITIZER_INTERCEPT_PROTOENT_R SI_GLIBC
 #define SANITIZER_INTERCEPT_NETENT (SI_LINUX || SI_NETBSD || SI_FREEBSD)
 #define SANITIZER_INTERCEPT_SETVBUF \
-  (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC)
+  (SI_NETBSD || SI_FREEBSD || SI_LINUX || SI_MAC || !SI_NOT_AIX)
 #define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC)
 #define SANITIZER_INTERCEPT_MI_VECTOR_HASH SI_NETBSD
 #define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
index a5311d266b0c4..09a2fce1d856e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -24,7 +24,7 @@
 // Must go after undef _FILE_OFFSET_BITS.
 #include "sanitizer_platform.h"
 
-#if SANITIZER_LINUX || SANITIZER_APPLE
+#if SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_AIX
 // Must go after undef _FILE_OFFSET_BITS.
 #include "sanitizer_glibc_version.h"
 
@@ -61,7 +61,9 @@
 #endif
 
 #if !SANITIZER_ANDROID
+#if !SANITIZER_AIX
 #include <sys/mount.h>
+#endif
 #include <sys/timeb.h>
 #include <utmpx.h>
 #endif
@@ -110,7 +112,11 @@ typedef struct user_fpregs elf_fpregset_t;
 #endif
 
 #if !SANITIZER_ANDROID
+#if !SANITIZER_AIX
 #include <ifaddrs.h>
+#else
+#include <netinet/in.h>
+#endif
 #include <sys/ucontext.h>
 #include <wordexp.h>
 #endif
@@ -173,6 +179,17 @@ typedef struct user_fpregs elf_fpregset_t;
 #include <sys/sockio.h>
 #endif
 
+#if SANITIZER_AIX
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <stropts.h>
+#include <sys/statfs.h>
+#include <netinet/ip_mroute.h>
+#if HAVE_RPC_XDR_H
+#include <tirpc/rpc/xdr.h>
+#endif
+#endif
+
 // Include these after system headers to avoid name clashes and ambiguities.
 #  include "sanitizer_common.h"
 #  include "sanitizer_internal_defs.h"
@@ -551,12 +568,39 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
 
   const unsigned IOCTL_NOT_PRESENT = 0;
 
+  // On AIX, some variables are unsigned long types.
+#if SANITIZER_AIX
+  uptr IOCTL_FIOASYNC = FIOASYNC;
+  uptr IOCTL_FIONBIO = FIONBIO;
+  uptr IOCTL_FIOSETOWN = FIOSETOWN;
+  uptr IOCTL_SIOCSPGRP = SIOCSPGRP;
+  uptr IOCTL_TIOCCONS = TIOCCONS;
+  uptr IOCTL_TIOCMBIC = TIOCMBIC;
+  uptr IOCTL_TIOCMBIS = TIOCMBIS;
+  uptr IOCTL_TIOCMSET = TIOCMSET;
+  uptr IOCTL_TIOCPKT = TIOCPKT;
+  uptr IOCTL_TIOCSETD = TIOCSETD;
+  uptr IOCTL_TIOCSPGRP = TIOCSPGRP;
+  uptr IOCTL_TIOCSTI = TIOCSTI;
+  uptr IOCTL_TIOCSWINSZ = TIOCSWINSZ;
+#else
   unsigned IOCTL_FIOASYNC = FIOASYNC;
+  unsigned IOCTL_FIONBIO = FIONBIO;
+  unsigned IOCTL_FIOSETOWN = FIOSETOWN;
+  unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;
+  unsigned IOCTL_TIOCCONS = TIOCCONS;
+  unsigned IOCTL_TIOCMBIC = TIOCMBIC;
+  unsigned IOCTL_TIOCMBIS = TIOCMBIS;
+  unsigned IOCTL_TIOCMSET = TIOCMSET;
+  unsigned IOCTL_TIOCPKT = TIOCPKT;
+  unsigned IOCTL_TIOCSETD = TIOCSETD;
+  unsigned IOCTL_TIOCSPGRP = TIOCSPGRP;
+  unsigned IOCTL_TIOCSTI = TIOCSTI;
+  unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ;
+#endif
   unsigned IOCTL_FIOCLEX = FIOCLEX;
   unsigned IOCTL_FIOGETOWN = FIOGETOWN;
-  unsigned IOCTL_FIONBIO = FIONBIO;
   unsigned IOCTL_FIONCLEX = FIONCLEX;
-  unsigned IOCTL_FIOSETOWN = FIOSETOWN;
   unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI;
   unsigned IOCTL_SIOCATMARK = SIOCATMARK;
   unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI;
@@ -576,25 +620,17 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
   unsigned IOCTL_SIOCSIFMETRIC = SIOCSIFMETRIC;
   unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU;
   unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK;
-  unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;
-  unsigned IOCTL_TIOCCONS = TIOCCONS;
   unsigned IOCTL_TIOCEXCL = TIOCEXCL;
   unsigned IOCTL_TIOCGETD = TIOCGETD;
   unsigned IOCTL_TIOCGPGRP = TIOCGPGRP;
   unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ;
-  unsigned IOCTL_TIOCMBIC = TIOCMBIC;
-  unsigned IOCTL_TIOCMBIS = TIOCMBIS;
   unsigned IOCTL_TIOCMGET = TIOCMGET;
-  unsigned IOCTL_TIOCMSET = TIOCMSET;
   unsigned IOCTL_TIOCNOTTY = TIOCNOTTY;
   unsigned IOCTL_TIOCNXCL = TIOCNXCL;
   unsigned IOCTL_TIOCOUTQ = TIOCOUTQ;
-  unsigned IOCTL_TIOCPKT = TIOCPKT;
+#if !SANITIZER_AIX
   unsigned IOCTL_TIOCSCTTY = TIOCSCTTY;
-  unsigned IOCTL_TIOCSETD = TIOCSETD;
-  unsigned IOCTL_TIOCSPGRP = TIOCSPGRP;
-  unsigned IOCTL_TIOCSTI = TIOCSTI;
-  unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ;
+#endif
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
   unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT;
   unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT;
@@ -1103,6 +1139,8 @@ COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent));
 CHECK_SIZE_AND_OFFSET(dirent, d_ino);
 #if SANITIZER_APPLE
 CHECK_SIZE_AND_OFFSET(dirent, d_seekoff);
+#elif SANITIZER_AIX
+CHECK_SIZE_AND_OFFSET(dirent, d_offset);
 #elif SANITIZER_FREEBSD
 // There is no 'd_off' field on FreeBSD.
 #else
@@ -1191,8 +1229,10 @@ CHECK_SIZE_AND_OFFSET(tm, tm_year);
 CHECK_SIZE_AND_OFFSET(tm, tm_wday);
 CHECK_SIZE_AND_OFFSET(tm, tm_yday);
 CHECK_SIZE_AND_OFFSET(tm, tm_isdst);
+#if !SANITIZER_AIX
 CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff);
 CHECK_SIZE_AND_OFFSET(tm, tm_zone);
+#endif
 
 #if SANITIZER_LINUX
 CHECK_TYPE_SIZE(mntent);
@@ -1242,7 +1282,7 @@ CHECK_TYPE_SIZE(clock_t);
 CHECK_TYPE_SIZE(clockid_t);
 #endif
 
-#if !SANITIZER_ANDROID
+#if !SANITIZER_ANDROID && !SANITIZER_AIX
 CHECK_TYPE_SIZE(ifaddrs);
 CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next);
 CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 1a7d9e64048eb..4f5022a75d3cc 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -14,7 +14,7 @@
 #ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H
 #define SANITIZER_PLATFORM_LIMITS_POSIX_H
 
-#if SANITIZER_LINUX || SANITIZER_APPLE
+#if SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_AIX
 
 #include "sanitizer_internal_defs.h"
 #include "sanitizer_platform.h"
@@ -29,7 +29,7 @@
 #define SANITIZER_HAS_STAT64 0
 #define SANITIZER_HAS_STATFS64 0
 #endif
-#elif SANITIZER_GLIBC || SANITIZER_ANDROID
+#elif SANITIZER_GLIBC || SANITIZER_ANDROID || SANITIZER_AIX
 #define SANITIZER_HAS_STAT64 1
 #define SANITIZER_HAS_STATFS64 1
 #endif
@@ -319,7 +319,7 @@ struct __sanitizer_iovec {
   usize iov_len;
 };
 
-#if !SANITIZER_ANDROID
+#if !SANITIZER_ANDROID && !SANITIZER_AIX
 struct __sanitizer_ifaddrs {
   struct __sanitizer_ifaddrs *ifa_next;
   char *ifa_name;
@@ -341,7 +341,7 @@ typedef unsigned long __sanitizer_pthread_key_t;
 typedef unsigned __sanitizer_pthread_key_t;
 #endif
 
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
+#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_AIX
 
 struct __sanitizer_XDR {
   int x_op;
@@ -433,8 +433,10 @@ struct __sanitizer_tm {
   int tm_wday;
   int tm_yday;
   int tm_isdst;
+#if !SANITIZER_AIX
   long int tm_gmtoff;
   const char *tm_zone;
+#endif
 };
 
 #if SANITIZER_LINUX
@@ -478,11 +480,19 @@ struct __sanitizer_msghdr {
   struct __sanitizer_iovec *msg_iov;
   uptr msg_iovlen;
   void *msg_control;
+#if !SANITIZER_AIX
   uptr msg_controllen;
+#else
+  unsigned msg_controllen;
+#endif
   int msg_flags;
 };
 struct __sanitizer_cmsghdr {
+#if !SANITIZER_AIX
   uptr cmsg_len;
+#else
+  unsigned cmsg_len;
+#endif
   int cmsg_level;
   int cmsg_type;
 };
@@ -512,8 +522,13 @@ struct __sanitizer_dirent {
 };
 #  else
 struct __sanitizer_dirent {
+#if SANITIZER_AIX
+  uptr d_offset;
+  uptr d_ino;
+#else
   uptr d_ino;
   uptr d_off;
+#endif
   unsigned short d_reclen;
   // more fields that we don't care about
 };
@@ -529,7 +544,10 @@ struct __sanitizer_dirent64 {
 extern unsigned struct_sock_fprog_sz;
 #endif
 
-#if defined(__x86_64__) && !defined(_LP64)
+#if SANITIZER_AIX
+typedef int __sanitizer_clock_t;
+typedef int __sanitizer_clockid_t;
+#elif defined(__x86_64__) && !defined(_LP64)
 typedef long long __sanitizer_clock_t;
 #else
 typedef long __sanitizer_clock_t;
@@ -589,6 +607,14 @@ struct __sanitizer_sigset_t {
   // The size is determined by looking at sizeof of real sigset_t on linux.
   uptr val[128 / sizeof(uptr)];
 };
+#elif SANITIZER_AIX
+struct __sanitizer_sigset_t {
+#if SANITIZER_WORDSIZE == 64
+  uptr val[4];
+#else
+  uptr val[2];
+#endif
+};
 #endif
 
 struct __sanitizer_siginfo_pad {
@@ -779,8 +805,12 @@ struct __sanitizer_addrinfo {
   int ai_family;
   int ai_socktype;
   int ai_protocol;
-#if SANITIZER_ANDROID || SANITIZER_APPLE
+#if SANITIZER_ANDROID || SANITIZER_APPLE || SANITIZER_AIX
+#if SANITIZER_AIX // AIX ai_addrlen type is size_t
+  uptr ai_addrlen;
+#else
   unsigned ai_addrlen;
+#endif
   char *ai_canonname;
   void *ai_addr;
 #else // LINUX
@@ -789,6 +819,9 @@ struct __sanitizer_addrinfo {
   char *ai_canonname;
 #endif
   struct __sanitizer_addrinfo *ai_next;
+#if SANITIZER_AIX
+  int ai_eflags;
+#endif
 };
 
 struct __sanitizer_hostent {
@@ -805,7 +838,7 @@ struct __sanitizer_pollfd {
   short revents;
 };
 
-#if SANITIZER_ANDROID || SANITIZER_APPLE
+#if SANITIZER_ANDROID || SANITIZER_APPLE || SANITIZER_AIX
 typedef unsigned __sanitizer_nfds_t;
 #else
 typedef unsigned long __sanitizer_nfds_t;
@@ -843,6 +876,10 @@ struct __sanitizer_wordexp_t {
   uptr we_wordc;
   char **we_wordv;
   uptr we_offs;
+#if SANITIZER_AIX
+  int we_sflags;
+  uptr we_soffs;
+#endif
 };
 
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
@@ -1102,12 +1139,39 @@ extern unsigned fpos_t_sz;
 // when it can not be determined without including any system headers.
 extern const unsigned IOCTL_NOT_PRESENT;
 
+#if SANITIZER_AIX
+extern uptr IOCTL_FIOASYNC;
+extern uptr IOCTL_FIONBIO;
+extern uptr IOCTL_FIOSETOWN;
+extern uptr IOCTL_SIOCSPGRP;
+extern uptr IOCTL_TIOCCONS;
+extern uptr IOCTL_TIOCMBIC;
+extern uptr IOCTL_TIOCMBIS;
+extern uptr IOCTL_TIOCMSET;
+extern uptr IOCTL_TIOCPKT;
+extern uptr IOCTL_TIOCSETD;
+extern uptr IOCTL_TIOCSPGRP;
+extern uptr IOCTL_TIOCSTI;
+extern uptr IOCTL_TIOCSWINSZ;
+#else
 extern unsigned IOCTL_FIOASYNC;
+extern unsigned IOCTL_FIONBIO;
+extern unsigned IOCTL_FIOSETOWN;
+extern unsigned IOCTL_SIOCSPGRP;
+extern unsigned IOCTL_TIOCCONS;
+extern unsigned IOCTL_TIOCMBIC;
+extern unsigned IOCTL_TIOCMBIS;
+extern unsigned IOCTL_TIOCMSET;
+extern unsigned IOCTL_TIOCPKT;
+extern unsigned IOCTL_TIOCSETD;
+extern unsigned IOCTL_TIOCSPGRP;
+extern unsigned IOCTL_TIOCSTI;
+extern unsigned IOCTL_TIOCSWINSZ;
+#endif
+
 extern unsigned IOCTL_FIOCLEX;
 extern unsigned IOCTL_FIOGETOWN;
-extern unsigned IOCTL_FIONBIO;
 extern unsigned IOCTL_FIONCLEX;
-extern unsigned IOCTL_FIOSETOWN;
 extern unsigned IOCTL_SIOCADDMULTI;
 extern unsigned IOCTL_SIOCATMARK;
 extern unsigned IOCTL_SIOCDELMULTI;
@@ -1127,25 +1191,17 @@ extern unsigned IOCTL_SIOCSIFFLAGS;
 extern unsigned IOCTL_SIOCSIFMETRIC;
 extern unsigned IOCTL_SIOCSIFMTU;
 extern unsigned IOCTL_SIOCSIFNETMASK;
-extern unsigned IOCTL_SIOCSPGRP;
-extern unsigned IOCTL_TIOCCONS;
 extern unsigned IOCTL_TIOCEXCL;
 extern unsigned IOCTL_TIOCGETD;
 extern unsigned IOCTL_TIOCGPGRP;
 extern unsigned IOCTL_TIOCGWINSZ;
-extern unsigned IOCTL_TIOCMBIC;
-extern unsigned IOCTL_TIOCMBIS;
 extern unsigned IOCTL_TIOCMGET;
-extern unsigned IOCTL_TIOCMSET;
 extern unsigned IOCTL_TIOCNOTTY;
 extern unsigned IOCTL_TIOCNXCL;
 extern unsigned IOCTL_TIOCOUTQ;
-extern unsigned IOCTL_TIOCPKT;
+#if !SANITIZER_AIX
 extern unsigned IOCTL_TIOCSCTTY;
-extern unsigned IOCTL_TIOCSETD;
-extern unsigned IOCTL_TIOCSPGRP;
-extern unsigned IOCTL_TIOCSTI;
-extern unsigned IOCTL_TIOCSWINSZ;
+#endif
 #if SANITIZER_LINUX && !SANITIZER_ANDROID
 extern unsigned IOCTL_SIOCGETSGCNT;
 extern unsigned IOCTL_SIOCGETVIFCNT;
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
index 69af6465a62c2..44c40036babb2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp
@@ -27,7 +27,7 @@
 #include <signal.h>
 #include <sys/mman.h>
 
-#if SANITIZER_FREEBSD
+#if SANITIZER_FREEBSD || SANITIZER_AIX
 // The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before
 // that, it was never implemented.  So just define it to zero.
 #undef  MAP_NORESERVE
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
index b5491c540dc08..da9cd92357145 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix.h
@@ -33,6 +33,11 @@ uptr internal_close_range(fd_t lowfd, fd_t highfd, int flags);
 #  endif
 uptr internal_close(fd_t fd);
 
+#if SANITIZER_AIX
+__sanitizer_FILE* internal_popen(const char *command, const char *type);
+int internal_pclose(__sanitizer_FILE* file);
+#endif
+
 uptr internal_read(fd_t fd, void *buf, uptr count);
 uptr internal_write(fd_t fd, const void *buf, uptr count);
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index b1eb2009cf157..307d8c969a338 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -36,7 +36,7 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-#if SANITIZER_FREEBSD
+#if SANITIZER_FREEBSD || SANITIZER_AIX
 // The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before
 // that, it was never implemented.  So just define it to zero.
 #undef MAP_NORESERVE
@@ -416,8 +416,19 @@ bool MmapFixedSuperNoReserve(uptr fixed_addr, uptr size, const char *name) {
 }
 
 uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
+  // AIX can not mmap on a mmaped memory, so init it as read/write so we won't
+  // mmap on this memory again.
+#  if SANITIZER_AIX
+  if (fixed_addr) {
+    MmapFixed(fixed_addr, size, MAP_PRIVATE | MAP_FIXED | MAP_ANON, name);
+    base_ = (void *)fixed_addr;
+  } else
+    base_ = (void *)internal_mmap(nullptr, size, PROT_READ | PROT_WRITE,
+                                  MAP_PRIVATE | MAP_ANON, -1, 0);
+#  else
   base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size, name)
                      : MmapNoAccess(size);
+#  endif
   size_ = size;
   name_ = name;
   (void)os_handle_;  // unsupported
@@ -427,13 +438,21 @@ uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
 // Uses fixed_addr for now.
 // Will use offset instead once we've implemented this function for real.
 uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size, const char *name) {
+#if SANITIZER_AIX
+  return fixed_addr;
+#else
   return reinterpret_cast<uptr>(
       MmapFixedOrDieOnFatalError(fixed_addr, size, name));
+#endif
 }
 
 uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size,
                                     const char *name) {
+#if SANITIZER_AIX
+  return fixed_addr;
+#else
   return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size, name));
+#endif
 }
 
 void ReservedAddressRange::Unmap(uptr addr, uptr size) {
@@ -465,11 +484,15 @@ real_pthread_attr_getstack(void *attr, void **addr, size_t *size);
 } // extern "C"
 
 int internal_pthread_attr_getstack(void *attr, void **addr, uptr *size) {
-#if !SANITIZER_GO && !SANITIZER_APPLE
+// AIX requires definition for weak symbols. real_pthread_attr_getstack defined
+// in asan library which is not linked while compile with -fsanitize=undefined.
+// So don't use use real_pthread_attr_getstack on AIX either in this sanitizer
+// common file.
+#  if !SANITIZER_GO && !SANITIZER_APPLE && !SANITIZER_AIX
   if (&real_pthread_attr_getstack)
     return real_pthread_attr_getstack((pthread_attr_t *)attr, addr,
                                       (size_t *)size);
-#endif
+#  endif
   return pthread_attr_getstack((pthread_attr_t *)attr, addr, (size_t *)size);
 }
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h
index bf3c2c28e32e3..8e5162f40a55b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h
@@ -17,7 +17,7 @@
 
 #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
     SANITIZER_APPLE || SANITIZER_SOLARIS ||  \
-    SANITIZER_FUCHSIA
+    SANITIZER_FUCHSIA || SANITIZER_AIX
 
 #include "sanitizer_common.h"
 #include "sanitizer_internal_defs.h"
@@ -25,6 +25,7 @@
 #include "sanitizer_linux.h"
 #include "sanitizer_mac.h"
 #include "sanitizer_mutex.h"
+#include "sanitizer_aix.h"
 
 namespace __sanitizer {
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_aix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_aix.cpp
new file mode 100644
index 0000000000000..852aba2f169b8
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_aix.cpp
@@ -0,0 +1,212 @@
+//===-- sanitizer_procmaps_aix.cpp ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Information about the process mappings (AIX-specific parts).
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+
+#if SANITIZER_AIX
+#  include <stdio.h>
+
+#  include "sanitizer_common.h"
+#  include "sanitizer_procmaps.h"
+#  include "sanitizer_file.h"
+
+namespace __sanitizer {
+
+static bool IsOneOf(char c, char c1, char c2) { return c == c1 || c == c2; }
+
+void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
+  uptr pid = internal_getpid();
+
+  // The mapping in /proc/id/map is not ordered by address, this will hit some
+  // issue when checking stack base and size. Howevern AIX procmap can generate
+  // sorted ranges.
+  char Command[100] = {};
+
+  internal_snprintf(Command, 100, "procmap -qX %d", pid);
+  // Open pipe to file
+  __sanitizer_FILE *pipe = internal_popen(Command, "r");
+
+  if (!pipe) {
+    proc_maps->data = nullptr;
+    proc_maps->mmaped_size = 0;
+    proc_maps->len = 0;
+    return;
+  }
+
+  char buffer[512] = {};
+
+  InternalScopedString Data;
+  while (fgets(buffer, 512, reinterpret_cast<FILE *>(pipe)) != nullptr)
+    Data.Append(buffer);
+
+  size_t MmapedSize = Data.length() * 4 / 3;
+  void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()");
+  internal_memcpy(VmMap, Data.data(), Data.length());
+
+  proc_maps->data = (char *)VmMap;
+  proc_maps->mmaped_size = MmapedSize;
+  proc_maps->len = Data.length();
+
+  internal_pclose(pipe);
+}
+
+bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
+  if (Error())
+    return false;  // simulate empty maps
+  char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
+  if (data_.current >= last)
+    return false;
+  char *next_line =
+      (char *)internal_memchr(data_.current, '\n', last - data_.current);
+
+  // Skip the first header line and the second kernel line
+  // pid : binary name
+  if (data_.current == data_.proc_self_maps.data) {
+    data_.current = next_line + 1;
+    next_line =
+        (char *)internal_memchr(next_line + 1, '\n', last - data_.current);
+
+    data_.current = next_line + 1;
+    next_line =
+        (char *)internal_memchr(next_line + 1, '\n', last - data_.current);
+  }
+
+  if (next_line == 0)
+    next_line = last;
+
+  // Skip the last line:
+  // Total   533562K
+  if (!IsHex(*data_.current))
+    return false;
+
+  // Example: 10000000  10161fd9  1415K r-x   s  MAINTEXT  151ed82  a.out
+  segment->start = ParseHex(&data_.current);
+  while (data_.current < next_line && *data_.current == ' ') data_.current++;
+
+  segment->end = ParseHex(&data_.current);
+  while (data_.current < next_line && *data_.current == ' ') data_.current++;
+
+  // Ignore the size, we can get accurate size from end and start
+  while (IsDecimal(*data_.current)) data_.current++;
+  CHECK_EQ(*data_.current++, 'K');
+
+  while (data_.current < next_line && *data_.current == ' ') data_.current++;
+  segment->protection = 0;
+
+  if (*data_.current++ == 'r')
+    segment->protection |= kProtectionRead;
+  CHECK(IsOneOf(*data_.current, '-', 'w'));
+  if (*data_.current++ == 'w')
+    segment->protection |= kProtectionWrite;
+  CHECK(IsOneOf(*data_.current, '-', 'x'));
+  if (*data_.current++ == 'x')
+    segment->protection |= kProtectionExecute;
+
+  // Ignore the PSIZE(s/m/L/H)
+  while (data_.current < next_line && *data_.current == ' ') data_.current++;
+  data_.current += 4;
+
+  // Get the region TYPE
+  while (data_.current < next_line && *data_.current == ' ') data_.current++;
+  char Type[16] = {};
+  uptr len = 0;
+  while (*data_.current != ' ') Type[len++] = *data_.current++;
+  Type[len] = 0;
+
+  if (!internal_strcmp(Type, "SLIBTEXT") || !internal_strcmp(Type, "PLIBDATA"))
+    segment->protection |= kProtectionShared;
+
+  // Ignore the VSID
+  while (data_.current < next_line && *data_.current == ' ') data_.current++;
+  ParseHex(&data_.current);
+
+  while (data_.current < next_line && *data_.current == ' ') data_.current++;
+
+  if (segment->filename && data_.current != next_line) {
+    if (!internal_strcmp(Type, "MAINDATA") ||
+        !internal_strcmp(Type, "MAINTEXT")) {
+      // AIX procmap does not print full name for the binary, however when using
+      // llvm-symbolizer, it requires the binary must be with full name.
+      const char *BinaryName = GetBinaryName();
+      uptr len =
+          Min((uptr)(internal_strlen(BinaryName)), segment->filename_size - 1);
+      internal_strncpy(segment->filename, BinaryName, len);
+      segment->filename[len] = 0;
+    } else {
+      // AIX library may exist as xxx.a[yyy.o], to find the path to xxx.a,
+      // the [yyy.o] part needs to be removed.
+      char *NameEnd = (char *)internal_memchr(data_.current, '[',
+                                              next_line - data_.current);
+      if (!NameEnd)
+        NameEnd = next_line - 1;
+
+      uptr len = Min((uptr)(NameEnd - data_.current),
+                     segment->filename_size - 1);
+      internal_strncpy(segment->filename, data_.current, len);
+      segment->filename[len] = 0;
+
+      // AIX procmap does not print full name for user's library , however when
+      // use llvm-symbolizer, it requires the library must be with full name.
+      if ((!internal_strcmp(Type, "SLIBTEXT") ||
+           !internal_strcmp(Type, "PLIBDATA")) &&
+          segment->filename[0] != '/') {
+        // First check if the library is in the directory where the binary is
+        // executed. On AIX, there is no need to put library in same dir with
+        // the binary to path search envs.
+        char *path = nullptr;
+        char buf[kMaxPathLength];
+        unsigned buf_len = kMaxPathLength;
+        bool found = false;
+        if ((path = internal_getcwd(buf, buf_len)) != nullptr) {
+          // if the path is too long, don't do other search either.
+          if (internal_strlen(path) > segment->filename_size - 1)
+            found = true;
+          else {
+            internal_snprintf(
+                buf + internal_strlen(path),
+                segment->filename_size - 1 - internal_strlen(path), "/%s",
+                segment->filename);
+            if (FileExists(buf)) {
+              uptr len =
+                  Min((uptr)(internal_strlen(buf)), segment->filename_size - 1);
+              internal_strncpy(segment->filename, buf, len);
+              segment->filename[len] = 0;
+              found = true;
+            }
+          }
+        }
+        if (!found) {
+          const char *LibName =
+              FindPathToBinaryOrLibrary(segment->filename, "LIBPATH");
+          CHECK(LibName);
+          uptr len =
+              Min((uptr)(internal_strlen(LibName)), segment->filename_size - 1);
+          internal_strncpy(segment->filename, LibName, len);
+          segment->filename[len] = 0;
+	  found = true;
+        }
+        CHECK(found);
+      }
+    }
+  } else if (segment->filename) {
+    segment->filename[0] = 0;
+  }
+
+  segment->offset = 0;
+
+  data_.current = next_line + 1;
+
+  return true;
+}
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_AIX
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp
index 7214a2b9ea468..4089420c8f63e 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp
@@ -12,7 +12,7 @@
 #include "sanitizer_platform.h"
 
 #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||                \
-    SANITIZER_SOLARIS
+    SANITIZER_SOLARIS || SANITIZER_AIX
 
 #include "sanitizer_common.h"
 #include "sanitizer_placement_new.h"
@@ -140,6 +140,11 @@ void MemoryMappingLayout::DumpListOfModules(
     uptr base_address = (i ? segment.start : 0) - segment.offset;
     LoadedModule cur_module;
     cur_module.set(cur_name, base_address);
+#if SANITIZER_AIX
+    // Instructions in AIX shared libraries don't start 0x0.
+    if (segment.IsShared() && segment.IsExecutable())
+      cur_module.set_instr_start(InstructionStart);
+#endif
     segment.AddAddressRanges(&cur_module);
     modules->push_back(cur_module);
   }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h b/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h
index 41e0613d6fc13..bda0f04687693 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_redefine_builtins.h
@@ -15,7 +15,7 @@
 #    define SANITIZER_REDEFINE_BUILTINS_H
 
 // The asm hack only works with GCC and Clang.
-#    if !defined(_WIN32)
+#    if !defined(_WIN32) && !defined(_AIX)
 
 asm(R"(
     .set memcpy, __sanitizer_internal_memcpy
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp
index d24fae98213aa..824fa3ead5b81 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.cpp
@@ -111,13 +111,14 @@ void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
          IsAligned((uptr)frame, sizeof(*frame)) &&
          size < max_depth) {
 #ifdef __powerpc__
-    // PowerPC ABIs specify that the return address is saved at offset
-    // 16 of the *caller's* stack frame.  Thus we must dereference the
-    // back chain to find the caller frame before extracting it.
     uhwptr *caller_frame = (uhwptr*)frame[0];
     if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) ||
         !IsAligned((uptr)caller_frame, sizeof(uhwptr)))
       break;
+    // PowerPC ABIs(64-bit LE, 64-bit AIX, 32-bit AIX) specify that the return
+    // address is saved at offsettwo ptr size(16 for 64-bit, 8 for 32-bit) of
+    // the *caller's* stack frame.  Thus we must dereference the back chain to
+    // find the caller frame before extracting it.
     uhwptr pc1 = caller_frame[2];
 #elif defined(__s390__)
     uhwptr pc1 = frame[14];
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp
index 519f768f89694..3370feb7f17c6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp
@@ -46,7 +46,10 @@ void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset,
 
 void AddressInfo::FillModuleInfo(const LoadedModule &mod) {
   module = internal_strdup(mod.full_name());
-  module_offset = address - mod.base_address();
+  // On some platforms, like on AIX, the first instructions does not start from
+  // 0x0, we need to addd the start back to get correct instruction offset in
+  // the objects.
+  module_offset = address - mod.base_address() + mod.get_instr_start();
   module_arch = mod.arch();
   if (mod.uuid_size())
     internal_memcpy(uuid, mod.uuid(), mod.uuid_size());
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
index 74458028ae8f5..9695f9a408ce2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
@@ -179,7 +179,13 @@ bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address,
   if (!module)
     return false;
   *module_name = module->full_name();
+  // On AIX, the address for the data in the object is the same with the runtime one.
+  // So, we don't need to sub the base address.
+#if SANITIZER_AIX
+  *module_offset = address;
+#else
   *module_offset = address - module->base_address();
+#endif
   *module_arch = module->arch();
   return true;
 }
@@ -274,6 +280,8 @@ class LLVMSymbolizerProcess final : public SymbolizerProcess {
     const char* const kSymbolizerArch = "--default-arch=arm64";
 #elif defined(__arm__)
     const char* const kSymbolizerArch = "--default-arch=arm";
+#elif defined(__powerpc__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+    const char* const kSymbolizerArch = "--default-arch=powerpc";
 #elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
     const char* const kSymbolizerArch = "--default-arch=powerpc64";
 #elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
@@ -468,7 +476,6 @@ const char *LLVMSymbolizer::FormatAndSendCommand(const char *command_prefix,
     Report("WARNING: Command buffer too small");
     return nullptr;
   }
-
   return symbolizer_process_->SendCommand(buffer_);
 }
 
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
index 0ddc24802d216..f5858860c5aa5 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
@@ -38,9 +38,35 @@
 // because we do not require a C++ ABI library to be linked to a program
 // using sanitizers; if it's not present, we'll just use the mangled name.
 namespace __cxxabiv1 {
+// `weak` attribute without definition on AIX will cause linking time undefined
+// symbol error, we use dlopen/dlsym here to find related symbol.
+#  if SANITIZER_AIX
+typedef char *__cxa_demangle_t(const char *mangled, char *buffer,
+                               size_t *length, int *status);
+
+char *__cxa_demangle(const char *mangled, char *buffer, size_t *length,
+                     int *status) {
+  // Use NULL as the module name, so if the libc++abi module is linked into the
+  // main executable, we are able to find the __cxa_demangle symbol and this
+  // impelemtation will not force libc++abi to be loaded to the executable.
+  void *Handler = dlopen(0, RTLD_NOW);
+  if (!Handler) {
+    return nullptr;
+  }
+
+  auto FooPtr =
+      reinterpret_cast<__cxa_demangle_t *>(dlsym(Handler, "__cxa_demangle"));
+  if (!FooPtr) {
+    return nullptr;
+  }
+
+  return FooPtr(mangled, buffer, length, status);
+}
+#  else
   extern "C" SANITIZER_WEAK_ATTRIBUTE
   char *__cxa_demangle(const char *mangled, char *buffer,
                                   size_t *length, int *status);
+#  endif
 }
 
 namespace __sanitizer {
@@ -445,17 +471,17 @@ static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) {
   // Otherwise symbolizer program is unknown, let's search $PATH
   CHECK(path == nullptr);
 #if SANITIZER_APPLE
-  if (const char *found_path = FindPathToBinary("atos")) {
+  if (const char *found_path = FindPathToBinaryOrLibrary("atos")) {
     VReport(2, "Using atos found at: %s\n", found_path);
     return new(*allocator) AtosSymbolizer(found_path, allocator);
   }
 #endif  // SANITIZER_APPLE
-  if (const char *found_path = FindPathToBinary("llvm-symbolizer")) {
+  if (const char *found_path = FindPathToBinaryOrLibrary("llvm-symbolizer")) {
     VReport(2, "Using llvm-symbolizer found at: %s\n", found_path);
     return new(*allocator) LLVMSymbolizer(found_path, allocator);
   }
   if (common_flags()->allow_addr2line) {
-    if (const char *found_path = FindPathToBinary("addr2line")) {
+    if (const char *found_path = FindPathToBinaryOrLibrary("addr2line")) {
       VReport(2, "Using addr2line found at: %s\n", found_path);
       return new(*allocator) Addr2LinePool(found_path, allocator);
     }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp
index 1ff8b8f1bab48..531632c65fa6b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_win.cpp
@@ -289,7 +289,7 @@ static void ChooseSymbolizerTools(IntrusiveList<SymbolizerTool> *list,
   }
 
   const char *path =
-      user_path ? user_path : FindPathToBinary("llvm-symbolizer.exe");
+      user_path ? user_path : FindPathToBinaryOrLibrary("llvm-symbolizer.exe");
   if (path) {
     if (user_path && user_path[0] == '\0') {
       VReport(2, "External symbolizer is explicitly disabled.\n");
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_aix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_aix.cpp
new file mode 100644
index 0000000000000..45b4b1f3d5c9d
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_aix.cpp
@@ -0,0 +1,66 @@
+//===-- sanitizer_unwind_aix.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the unwind.h-based (aka "slow") stack unwinding routines
+// available to the tools on AIX.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+
+#if SANITIZER_AIX
+#  include <unwind.h>
+
+#  include "sanitizer_common.h"
+#  include "sanitizer_stacktrace.h"
+
+namespace __sanitizer {
+
+struct UnwindTraceArg {
+  BufferedStackTrace *stack;
+  u32 max_depth;
+};
+
+_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
+  UnwindTraceArg *arg = (UnwindTraceArg *)param;
+  CHECK_LT(arg->stack->size, arg->max_depth);
+  uptr pc = _Unwind_GetIP(ctx);
+  // On AIX 32-bit and 64-bit, address smaller than 0x0fffffff is for kernel.
+  if (pc <= 0x0fffffff)
+    return _URC_NORMAL_STOP;
+  arg->stack->trace_buffer[arg->stack->size++] = pc;
+  if (arg->stack->size == arg->max_depth)
+    return _URC_NORMAL_STOP;
+  return _URC_NO_REASON;
+}
+
+void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
+  CHECK_GE(max_depth, 2);
+  size = 0;
+  UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
+  _Unwind_Backtrace(Unwind_Trace, &arg);
+  // We need to pop a few frames so that pc is on top.
+  uptr to_pop = LocatePcInTrace(pc);
+  // trace_buffer[0] belongs to the current function so we always pop it,
+  // unless there is only 1 frame in the stack trace (1 frame is always better
+  // than 0!).
+  // 1-frame stacks don't normally happen, but this depends on the actual
+  // unwinder implementation (libgcc, libunwind, etc) which is outside of our
+  // control.
+  if (to_pop == 0 && size > 1)
+    to_pop = 1;
+
+  PopStackFrames(to_pop);
+  trace_buffer[0] = pc;
+}
+
+void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
+  UnwindSlow(pc, max_depth);
+}
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_AIX
diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt
index fef8bb772e0e0..231a95c21d8fb 100644
--- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt
+++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt
@@ -100,6 +100,10 @@ if(NOT MSVC)
   list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON --driver-mode=g++)
 endif()
 
+if(${CMAKE_SYSTEM_NAME} MATCHES "AIX")
+  list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -latomic)
+endif()
+
 if(ANDROID)
   list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -pie)
 endif()
diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h b/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h
index 5fd94a0281391..245164caa8a8f 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_test_utils.h
@@ -101,7 +101,7 @@ static inline uint32_t my_rand() {
 #endif
 
 #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__ANDROID__) && \
-    !defined(__NetBSD__) && !defined(_WIN32)
+    !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX)
 # define SANITIZER_TEST_HAS_MEMALIGN 1
 #else
 # define SANITIZER_TEST_HAS_MEMALIGN 0
diff --git a/compiler-rt/test/asan/CMakeLists.txt b/compiler-rt/test/asan/CMakeLists.txt
index 414a6cc9496ed..9a8283f68d07e 100644
--- a/compiler-rt/test/asan/CMakeLists.txt
+++ b/compiler-rt/test/asan/CMakeLists.txt
@@ -16,7 +16,7 @@ endif()
 macro(get_bits_for_arch arch bits)
   if (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|arm64|mips64|mips64el|s390x|sparcv9|riscv64|loongarch64")
     set(${bits} 64)
-  elseif (${arch} MATCHES "i386|arm|mips|mipsel|sparc")
+  elseif (${arch} MATCHES "i386|arm|mips|mipsel|sparc|powerpc")
     set(${bits} 32)
   else()
     message(FATAL_ERROR "Unknown target architecture: ${arch}")
diff --git a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-bad-path.cpp b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-bad-path.cpp
index c53a932a2e9ed..51a7887e16ff6 100644
--- a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-bad-path.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-bad-path.cpp
@@ -11,6 +11,10 @@
 // CHECK-BAD-ADDR: #0 0xabcdabcd
 // CHECK-BAD-ADDR-EMPTY:
 
+// AIX does not have a system symbolizer which will return result like expected.
+// llvm-symbolizer will not generate expected result either, an error will be emitted indicating "No such file or directory".
+// UNSUPPORTED: target={{.*aix.*}}
+
 int main() {
   return 0;
 }
diff --git a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp
index 5d3e7a767e45a..07a3b268846b3 100644
--- a/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cpp
@@ -38,11 +38,11 @@ int main(int argc, char *argv[]) {
   inc2(array, -1);  // BOOM
   // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow
   // CHECK: READ of size 4 at 0x{{.*}}
-  // CHECK: #0 {{.*}} in inc2 {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE+21]]
-  // CHECK: #1 {{.*}} in main {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE-4]]
+  // CHECK: #0 {{.*}} in {{inc2|.inc2}} {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE+21]]
+  // CHECK: #1 {{.*}} in {{main|.main}} {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE-4]]
   // CHECK: allocated by thread T{{.*}} here:
-  // CHECK: #{{.*}} in {{(wrap_|_?__interceptor_)?}}malloc
-  // CHECK: #{{.*}} in main {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE-9]]
+  // CHECK: #{{.*}} in {{(wrap_|_?__interceptor_)?}}{{malloc|.vec_malloc}}
+  // CHECK: #{{.*}} in {{main|.main}} {{.*}}asan-symbolize-sanity-test.cpp:[[@LINE-9]]
   return 0;
 }
 #else  // SHARED_LIBS
diff --git a/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp b/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp
index c3383d6082b44..a41477f92dc4a 100644
--- a/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/asan_symbolize_script/plugin_wrong_frame_number_bug.cpp
@@ -46,5 +46,5 @@ int main(int argc, char** argv) {
 // CHECK: AddressSanitizer: heap-use-after-free
 // CHECK-NEXT: WRITE of size
 // CHECK-NEXT: #0 0x{{[0-9a-fA-F]+}}
-// CHECK-NEXT: #1 0x{{[0-9a-fA-F]+}} in do_access
-// CHECK-NEXT: #2 0x{{[0-9a-fA-F]+}} in main
+// CHECK-NEXT: #1 0x{{[0-9a-fA-F]+}} in {{do_access|.do_access}}
+// CHECK-NEXT: #2 0x{{[0-9a-fA-F]+}} in {{main|.main}}
diff --git a/compiler-rt/test/asan/TestCases/Posix/asprintf.cpp b/compiler-rt/test/asan/TestCases/Posix/asprintf.cpp
index 6946e5013d2cb..c83112423f3ed 100644
--- a/compiler-rt/test/asan/TestCases/Posix/asprintf.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/asprintf.cpp
@@ -1,6 +1,9 @@
 // RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
 
+// AIX libc does not define asprintf.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #ifndef _GNU_SOURCE
 #define _GNU_SOURCE
 #endif
diff --git a/compiler-rt/test/asan/TestCases/Posix/closed-fds.cpp b/compiler-rt/test/asan/TestCases/Posix/closed-fds.cpp
index c18653bc29ef0..230ca078ec093 100644
--- a/compiler-rt/test/asan/TestCases/Posix/closed-fds.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/closed-fds.cpp
@@ -30,6 +30,6 @@ int main(int argc, char **argv) {
   // CHECK-FILE: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
   // CHECK-FILE:   {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
   // CHECK-FILE: {{WRITE of size 1 at 0x.* thread T0}}
-  // CHECK-FILE: {{    #0 0x.* in main .*closed-fds.cpp:}}[[@LINE-4]]
+  // CHECK-FILE: {{    #0 0x.* in (main|.main) .*closed-fds.cpp:}}[[@LINE-4]]
   return 0;
 }
diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage-fork.cpp b/compiler-rt/test/asan/TestCases/Posix/coverage-fork.cpp
index a8768479de2f6..9f2507defcf2b 100644
--- a/compiler-rt/test/asan/TestCases/Posix/coverage-fork.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/coverage-fork.cpp
@@ -6,6 +6,8 @@
 // UNSUPPORTED: android
 // UNSUPPORTED: iossim
 //
+// UNSUPPORTED: target={{.*aix.*}}
+
 // Ideally a forked-subprocess should only report it's own coverage,
 // not parent's one. But trace-pc-guard currently does nothing special for fork,
 // and thus this test is relaxed.
diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage-module-unloaded.cpp b/compiler-rt/test/asan/TestCases/Posix/coverage-module-unloaded.cpp
index d301bb5c7838d..8250752290172 100644
--- a/compiler-rt/test/asan/TestCases/Posix/coverage-module-unloaded.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/coverage-module-unloaded.cpp
@@ -11,6 +11,9 @@
 // XFAIL: android
 // UNSUPPORTED: ios
 
+// FIXME: support -fsanitize-coverage on AIX
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <dlfcn.h>
 #include <stdint.h>
diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage-reset.cpp b/compiler-rt/test/asan/TestCases/Posix/coverage-reset.cpp
index e89181cc6c376..6781d8e59db18 100644
--- a/compiler-rt/test/asan/TestCases/Posix/coverage-reset.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/coverage-reset.cpp
@@ -5,6 +5,8 @@
 //
 // UNSUPPORTED: ios
 
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <stdio.h>
 
 #include <sanitizer/coverage_interface.h>
diff --git a/compiler-rt/test/asan/TestCases/Posix/coverage.cpp b/compiler-rt/test/asan/TestCases/Posix/coverage.cpp
index 12a88402eb5aa..25f1a0fa98495 100644
--- a/compiler-rt/test/asan/TestCases/Posix/coverage.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/coverage.cpp
@@ -20,6 +20,9 @@
 // XFAIL: android
 // UNSUPPORTED: ios
 
+// FIXME: support -fsanitize-coverage on AIX.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/Posix/deep_call_stack.cpp b/compiler-rt/test/asan/TestCases/Posix/deep_call_stack.cpp
index 37aa7b11a231a..ffea7a7d86b78 100644
--- a/compiler-rt/test/asan/TestCases/Posix/deep_call_stack.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/deep_call_stack.cpp
@@ -1,7 +1,8 @@
 // Check that UAR mode can handle very deep recusrion.
+// On AIX, we need a large stack size to contain all the 15000 frames and its callees.
 // REQUIRES: shell
 // RUN: %clangxx_asan -O2 %s -o %t
-// RUN: ulimit -s 4096
+// RUN: ulimit -s 8192
 // RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s
 
 // Also check that use_sigaltstack+verbosity doesn't crash.
diff --git a/compiler-rt/test/asan/TestCases/Posix/fake_stack_gc.cpp b/compiler-rt/test/asan/TestCases/Posix/fake_stack_gc.cpp
index 36fdf81120b59..d28b7d9abe94e 100644
--- a/compiler-rt/test/asan/TestCases/Posix/fake_stack_gc.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/fake_stack_gc.cpp
@@ -7,6 +7,9 @@
 // (https://github.com/llvm/llvm-project/issues/64942).
 // UNSUPPORTED: iossim
 
+// FIXME: investigate this failure on AIX.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <algorithm>
 #include <assert.h>
 #include <csignal>
diff --git a/compiler-rt/test/asan/TestCases/Posix/fgets_fputs.cpp b/compiler-rt/test/asan/TestCases/Posix/fgets_fputs.cpp
index 34c952f2e02ef..30c06fee171ba 100644
--- a/compiler-rt/test/asan/TestCases/Posix/fgets_fputs.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/fgets_fputs.cpp
@@ -47,8 +47,8 @@ int main(int argc, char *argv[]) {
 }
 
 // CHECK-FGETS: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
-// CHECK-FGETS: #{{.*}} in {{(wrap_|__interceptor_)?}}fgets
+// CHECK-FGETS: #{{.*}} in {{(wrap_|__interceptor_)?}}{{fgets|.fgets}}
 // CHECK-FPUTS: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
-// CHECK-FPUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}fputs
+// CHECK-FPUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}{{fputs|.fputs}}
 // CHECK-PUTS: {{.*ERROR: AddressSanitizer: heap-use-after-free}}
-// CHECK-PUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}puts
+// CHECK-PUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}{{puts|.puts}}
diff --git a/compiler-rt/test/asan/TestCases/Posix/fread_fwrite.cpp b/compiler-rt/test/asan/TestCases/Posix/fread_fwrite.cpp
index c0629260418a3..f6cc8dc60c3f7 100644
--- a/compiler-rt/test/asan/TestCases/Posix/fread_fwrite.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/fread_fwrite.cpp
@@ -29,6 +29,6 @@ int main(int argc, char *argv[]) {
 }
 
 // CHECK-FREAD: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
-// CHECK-FREAD: #{{.*}} in {{(wrap_|__interceptor_)?}}fread
+// CHECK-FREAD: #{{.*}} in {{(wrap_|__interceptor_)?}}{{fread|.fread}}
 // CHECK-FWRITE: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
-// CHECK-FWRITE: #{{.*}} in {{(wrap_|__interceptor_)?}}fwrite
+// CHECK-FWRITE: #{{.*}} in {{(wrap_|__interceptor_)?}}{{fwrite|.fwrite}}
diff --git a/compiler-rt/test/asan/TestCases/Posix/interception-in-shared-lib-test.cpp b/compiler-rt/test/asan/TestCases/Posix/interception-in-shared-lib-test.cpp
index b592edb9f3df0..67010cd6948f4 100644
--- a/compiler-rt/test/asan/TestCases/Posix/interception-in-shared-lib-test.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/interception-in-shared-lib-test.cpp
@@ -21,7 +21,7 @@ int main(int argc, char *argv[]) {
   my_memset(buf, 11);
   // CHECK: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}}
   // CHECK: {{WRITE of size 11 at 0x.* thread T0}}
-  // CHECK: {{0x.* in my_memset .*interception-in-shared-lib-test.cpp:}}[[@LINE-10]]
+  // CHECK: {{0x.* in (my_memset|.my_memset) .*interception-in-shared-lib-test.cpp:}}[[@LINE-10]]
   return 0;
 }
 #endif
diff --git a/compiler-rt/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cpp b/compiler-rt/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cpp
index d32dae9c01e87..3498c7c2a14fd 100644
--- a/compiler-rt/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cpp
@@ -1,6 +1,14 @@
+// On AIX, for 32 bit, the stack of main thread contains all other thread's stack.
+// So we should be able to check invalid pointer based on the main thread stack, because
+// all the stack address are in main thread's stack.
+// However this is not true for 64 bit, for 64 bit, main thread stack does not overlap with
+// other thread stack. This is same with other targets.
+// See GetStackVariableShadowStart() for details.
+
 // RUN: %clangxx_asan -O0 %s -pthread -o %t -mllvm -asan-detect-invalid-pointer-pair
 
-// RUN: %env_asan_opts=detect_invalid_pointer_pairs=2 %run %t a 2>&1 | FileCheck %s -check-prefix=OK -allow-empty
+// RUN: %if target={{.*aix.*}} && asan-32-bits %{ %env_asan_opts=detect_invalid_pointer_pairs=2 not %run %t a 2>&1 | FileCheck %s -check-prefix=AIX %} %else \
+// RUN:   %{ %env_asan_opts=detect_invalid_pointer_pairs=2 %run %t a 2>&1 | FileCheck %s -check-prefix=OK -allow-empty %}
 // RUN: %env_asan_opts=detect_invalid_pointer_pairs=2 not %run %t b 2>&1 | FileCheck %s -check-prefix=B
 
 // pthread barriers are not available on OS X
@@ -38,13 +46,15 @@ int main(int argc, char **argv) {
 
   if (t == 'a') {
     // OK-NOT: not handled yet
+    // AIX: ERROR: AddressSanitizer: invalid-pointer-pair
+    // AIX: #{{[0-9]+ .*}} in .main {{.*}}invalid-pointer-pairs-threads.cpp:[[@LINE+1]]
     unsigned r = pointers[0] - pointers[1];
   } else {
     char local;
     char *parent_pointer = &local;
 
     // B: ERROR: AddressSanitizer: invalid-pointer-pair
-    // B: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-threads.cpp:[[@LINE+1]]
+    // B: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-threads.cpp:[[@LINE+1]]
     unsigned r = parent_pointer - pointers[0];
   }
 
diff --git a/compiler-rt/test/asan/TestCases/Posix/ioctl.cpp b/compiler-rt/test/asan/TestCases/Posix/ioctl.cpp
index 01e9843619b7f..d10e711214829 100644
--- a/compiler-rt/test/asan/TestCases/Posix/ioctl.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/ioctl.cpp
@@ -21,7 +21,7 @@ int main(int argc, char **argv) {
   int res = ioctl(fd, FIONBIO, &nonblock + 1);
   // CHECK: AddressSanitizer: stack-buffer-overflow
   // CHECK: READ of size 4 at
-  // CHECK: {{#.* in main .*ioctl.cpp:}}[[@LINE-3]]
+  // CHECK: {{#.* in (main|.main) .*ioctl.cpp:}}[[@LINE-3]]
   assert(res == 0);
   close(fd);
   return 0;
diff --git a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp
index edbdb4016d86e..614569b00f28a 100644
--- a/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/new_array_cookie_test.cpp
@@ -20,7 +20,7 @@ int main(int argc, char **argv) {
   C *buffer = new C[argc];
   buffer[-2].x = 10;
 // CHECK: AddressSanitizer: heap-buffer-overflow
-// CHECK: in main {{.*}}new_array_cookie_test.cpp:[[@LINE-2]]
+// CHECK: in {{main|.main}} {{.*}}new_array_cookie_test.cpp:[[@LINE-2]]
 // CHECK: is located 0 bytes inside of 12-byte region
 // NO_COOKIE: ZZZZZZZZ
   delete [] buffer;
diff --git a/compiler-rt/test/asan/TestCases/Posix/no_asan_gen_globals.c b/compiler-rt/test/asan/TestCases/Posix/no_asan_gen_globals.c
index 994f827974be9..136f150c94c7f 100644
--- a/compiler-rt/test/asan/TestCases/Posix/no_asan_gen_globals.c
+++ b/compiler-rt/test/asan/TestCases/Posix/no_asan_gen_globals.c
@@ -3,7 +3,10 @@
 // Make sure ___asan_gen_* strings do not end up in the symbol table.
 
 // RUN: %clang_asan %s -o %t.exe
-// RUN: nm %t.exe | FileCheck %s
+// RUN: nm %if target={{.*aix.*}} %{ -X32_64 %} %t.exe | FileCheck %s
+
+// UNSUPPORTED: target={{.*aix.*}}
+
 
 int x, y, z;
 int main() { return 0; }
diff --git a/compiler-rt/test/asan/TestCases/Posix/shared-lib-test.cpp b/compiler-rt/test/asan/TestCases/Posix/shared-lib-test.cpp
index 6f0a9f74a1978..b68d20bbb0a02 100644
--- a/compiler-rt/test/asan/TestCases/Posix/shared-lib-test.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/shared-lib-test.cpp
@@ -30,11 +30,11 @@ int main(int argc, char *argv[]) {
   if (!inc) return 1;
   printf("ok\n");
   inc(1);
-  inc(-1);  // BOOM
+  inc(11);  // BOOM, 11 is more robust than -1 as -1 requires the GLOB and pad are stored adjacent.
   // CHECK: {{.*ERROR: AddressSanitizer: global-buffer-overflow}}
   // CHECK: {{READ of size 4 at 0x.* thread T0}}
   // CHECK: {{    #0 0x.*}}
-  // CHECK: {{    #1 0x.* in main .*shared-lib-test.cpp:}}[[@LINE-4]]
+  // CHECK: {{    #1 0x.* in (main|.main) .*shared-lib-test.cpp:}}[[@LINE-4]]
   return 0;
 }
 #else  // SHARED_LIB
diff --git a/compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp b/compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp
index 3d95a4ba273db..0a54c75ca2a1c 100644
--- a/compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp
@@ -21,6 +21,8 @@
 
 // UNSUPPORTED: ios
 
+// XFAIL: target={{powerpc-.*aix.*}}
+
 #include <assert.h>
 #include <stdlib.h>
 #include <pthread.h>
diff --git a/compiler-rt/test/asan/TestCases/Posix/start-deactivated.cpp b/compiler-rt/test/asan/TestCases/Posix/start-deactivated.cpp
index 4ddfd423167d3..f9bdb5cc85178 100644
--- a/compiler-rt/test/asan/TestCases/Posix/start-deactivated.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/start-deactivated.cpp
@@ -4,6 +4,10 @@
 // Fails with debug checks: https://bugs.llvm.org/show_bug.cgi?id=46862
 // XFAIL: !compiler-rt-optimized
 
+// For this case, do_another_bad_thing(which calls malloc) is compiled to a shared library,
+// and intercepting symbols in a shared library is still unsupported.
+// UNSUPPORTED: target={{.*aix.*}}
+
 // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -std=c++11 -fPIC -shared -o %t-so.so
 // RUN: %clangxx -O0 %s -std=c++11 -c -o %t.o
 // RUN: %clangxx_asan -O0 %t.o %libdl -o %t
@@ -83,27 +87,27 @@ int main(int argc, char *argv[]) {
   // After this line ASan is activated and starts detecting errors.
   void *fn = dlsym(dso, "do_another_bad_thing");
   if (!fn) {
-    fprintf(stderr, "dlsym failed: %s\n", dlerror());
-    return 1;
+	  fprintf(stderr, "dlsym failed: %s\n", dlerror());
+	  return 1;
   }
 
   // After activation: redzones.
   for (int i = 1; i < HoneyPotSize; ++i) {
-    honeyPot[i] = (char *)malloc(HoneyPotBlockSize);
-    test_malloc_shadow(honeyPot[i], HoneyPotBlockSize, true);
+	  honeyPot[i] = (char *)malloc(HoneyPotBlockSize);
+	  test_malloc_shadow(honeyPot[i], HoneyPotBlockSize, true);
   }
   {
-    char *p = (char *)malloc(HoneyPotBlockSize);
-    test_malloc_shadow(p, HoneyPotBlockSize, true);
-    free(p);
+	  char *p = (char *)malloc(HoneyPotBlockSize);
+	  test_malloc_shadow(p, HoneyPotBlockSize, true);
+	  free(p);
   }
   for (int i = 1; i < HoneyPotSize; ++i)
-    free(honeyPot[i]);
+	  free(honeyPot[i]);
 
   // Pre-existing allocations got redzones, too.
   for (size_t sz = 1; sz < nPtrs; ++sz) {
-    test_malloc_shadow(ptrs[sz], sz, true);
-    free(ptrs[sz]);
+	  test_malloc_shadow(ptrs[sz], sz, true);
+	  free(ptrs[sz]);
   }
 
   // Test that ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 has effect.
@@ -116,7 +120,7 @@ int main(int argc, char *argv[]) {
   // CHECK: READ of size 1
   // CHECK: {{#0 .* in do_another_bad_thing}}
   // CHECK: is located 5 bytes after 100-byte region
-  // CHECK: in do_another_bad_thing
+  // CHECK: in {{do_another_bad_thing|.do_another_bad_thing}}
 
   return 0;
 }
diff --git a/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp b/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp
index 8e7d5082d0b5d..eb66a3631a953 100644
--- a/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/unpoison-alternate-stack.cpp
@@ -6,6 +6,9 @@
 // RUN: %clangxx_asan -fexceptions -O0 %s -o %t -pthread
 // RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t
 
+// This will hang on AIX
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <algorithm>
 #include <cassert>
 #include <cerrno>
diff --git a/compiler-rt/test/asan/TestCases/Posix/wait.cpp b/compiler-rt/test/asan/TestCases/Posix/wait.cpp
index 7ca1c57a2edd9..5438249df65bc 100644
--- a/compiler-rt/test/asan/TestCases/Posix/wait.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/wait.cpp
@@ -24,9 +24,9 @@ int main(int argc, char **argv) {
     // CHECK: stack-buffer-overflow
     // CHECK: {{WRITE of size .* at 0x.* thread T0}}
     // CHECK: {{in .*wait}}
-    // CHECK: {{in main .*wait.cpp:}}
+    // CHECK: {{in (main|.main) .*wait.cpp:}}
     // CHECK: is located in stack of thread T0 at offset
-    // CHECK: {{in main}}
+    // CHECK: {{in (main|.main)}}
     return res == -1 ? 1 : 0;
   }
   // child
diff --git a/compiler-rt/test/asan/TestCases/Posix/wait3.cpp b/compiler-rt/test/asan/TestCases/Posix/wait3.cpp
index 7fb4d65122592..77e89921cec4e 100644
--- a/compiler-rt/test/asan/TestCases/Posix/wait3.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/wait3.cpp
@@ -26,9 +26,9 @@ int main(int argc, char **argv) {
     // CHECK: stack-buffer-overflow
     // CHECK: {{WRITE of size .* at 0x.* thread T0}}
     // CHECK: {{in .*wait}}
-    // CHECK: {{in main .*wait3.cpp:}}
+    // CHECK: {{in (main|.main) .*wait3.cpp:}}
     // CHECK: is located in stack of thread T0 at offset
-    // CHECK: {{in main}}
+    // CHECK: {{in (main|.main)}}
     return res == -1 ? 1 : 0;
   }
   // child
diff --git a/compiler-rt/test/asan/TestCases/Posix/wait4.cpp b/compiler-rt/test/asan/TestCases/Posix/wait4.cpp
index 1e574d99fe00c..a91c9e88c8959 100644
--- a/compiler-rt/test/asan/TestCases/Posix/wait4.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/wait4.cpp
@@ -34,9 +34,9 @@ int main(int argc, char **argv) {
     // CHECK: stack-buffer-overflow
     // CHECK: {{WRITE of size .* at 0x.* thread T0}}
     // CHECK: {{in .*wait}}
-    // CHECK: {{in main .*wait4.cpp:}}
+    // CHECK: {{in (main|.main) .*wait4.cpp:}}
     // CHECK: is located in stack of thread T0 at offset
-    // CHECK: {{in main}}
+    // CHECK: {{in (main|.main)}}
     return res == -1 ? 1 : 0;
   }
   // child
diff --git a/compiler-rt/test/asan/TestCases/Posix/waitid.cpp b/compiler-rt/test/asan/TestCases/Posix/waitid.cpp
index 96b91f94765c3..0e1a068907dd8 100644
--- a/compiler-rt/test/asan/TestCases/Posix/waitid.cpp
+++ b/compiler-rt/test/asan/TestCases/Posix/waitid.cpp
@@ -20,9 +20,9 @@ int main(int argc, char **argv) {
     // CHECK: stack-buffer-overflow
     // CHECK: {{WRITE of size .* at 0x.* thread T0}}
     // CHECK: {{in .*waitid}}
-    // CHECK: {{in main .*waitid.cpp:}}
+    // CHECK: {{in (main|.main) .*waitid.cpp:}}
     // CHECK: is located in stack of thread T0 at offset
-    // CHECK: {{in main}}
+    // CHECK: {{in (main|.main)}}
     return res != -1;
   }
   // child
diff --git a/compiler-rt/test/asan/TestCases/calloc-overflow.cpp b/compiler-rt/test/asan/TestCases/calloc-overflow.cpp
index b930b65cd8c3b..ceebdd3faa0bf 100644
--- a/compiler-rt/test/asan/TestCases/calloc-overflow.cpp
+++ b/compiler-rt/test/asan/TestCases/calloc-overflow.cpp
@@ -11,7 +11,7 @@ int main() {
   void *p = calloc(-1, 1000);
   // CHECK: {{ERROR: AddressSanitizer: calloc parameters overflow: count \* size \(.* \* 1000\) cannot be represented in type size_t}}
   // CHECK: {{#0 0x.* in .*calloc}}
-  // CHECK: {{#[1-3] 0x.* in main .*calloc-overflow.cpp:}}[[@LINE-3]]
+  // CHECK: {{#[1-3] 0x.* in (main|.main) .*calloc-overflow.cpp:}}[[@LINE-3]]
   // CHECK: SUMMARY: AddressSanitizer: calloc-overflow
 
   printf("calloc returned: %zu\n", (size_t)p);
diff --git a/compiler-rt/test/asan/TestCases/coverage-disabled.cpp b/compiler-rt/test/asan/TestCases/coverage-disabled.cpp
index 2a283b4652121..b8f4d7e3b3514 100644
--- a/compiler-rt/test/asan/TestCases/coverage-disabled.cpp
+++ b/compiler-rt/test/asan/TestCases/coverage-disabled.cpp
@@ -10,6 +10,9 @@
 //
 // UNSUPPORTED: android
 
+// FIXME: support -fsanitize-coverage on AIX
+// UNSUPPORTED: target={{.*aix.*}}
+
 int main(int argc, char **argv) {
   return 0;
 }
diff --git a/compiler-rt/test/asan/TestCases/debug_double_free.cpp b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
index c1cc383b3c1e3..e4afaf0cf1821 100644
--- a/compiler-rt/test/asan/TestCases/debug_double_free.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_double_free.cpp
@@ -13,7 +13,7 @@
 #  define PTR_FMT "0x%08x"
 # endif
 // Solaris libc omits the leading 0x.
-#elif defined(__sun__) && defined(__svr4__)
+#elif (defined(__sun__) && defined(__svr4__)) || defined(_AIX)
 # define PTR_FMT "0x%p"
 #else
 # define PTR_FMT "%p"
diff --git a/compiler-rt/test/asan/TestCases/debug_locate.cpp b/compiler-rt/test/asan/TestCases/debug_locate.cpp
index 93d1af8b83916..e4769a3bec1df 100644
--- a/compiler-rt/test/asan/TestCases/debug_locate.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_locate.cpp
@@ -61,6 +61,9 @@ int main() {
   assert(region_address == heap_ptr);
   assert(10 == region_size);
 
+// AIX 64-bit has a highly customized memory layout, it has no shadow gap and
+// 3 mid memory regions.
+#if !defined(__LP64__) || !defined(_AIX)
   size_t shadow_scale;
   size_t shadow_offset;
   __asan_get_shadow_mapping(&shadow_scale, &shadow_offset);
@@ -73,6 +76,7 @@ int main() {
   uintptr_t shadow_gap = (shadow_ptr >> shadow_scale) + shadow_offset;
   type = __asan_locate_address((void *)shadow_gap, NULL, 0, NULL, NULL);
   assert(0 == strcmp(type, "shadow gap"));
+#endif
 
   free(heap_ptr);
 
diff --git a/compiler-rt/test/asan/TestCases/debug_ppc64_mapping.cpp b/compiler-rt/test/asan/TestCases/debug_ppc64_mapping.cpp
index a67804023c0cd..813c85a4b8ae9 100644
--- a/compiler-rt/test/asan/TestCases/debug_ppc64_mapping.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_ppc64_mapping.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_asan -O0 %s -o %t
 // RUN: %env_asan_opts=verbosity=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64-V0
 // RUN: %env_asan_opts=verbosity=2 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64
-// REQUIRES: powerpc64-target-arch
+// REQUIRES: powerpc64-linux-
 
 #include <stdio.h>
 
diff --git a/compiler-rt/test/asan/TestCases/debug_report.cpp b/compiler-rt/test/asan/TestCases/debug_report.cpp
index 0dbb9f2fb9988..80cd9624523dd 100644
--- a/compiler-rt/test/asan/TestCases/debug_report.cpp
+++ b/compiler-rt/test/asan/TestCases/debug_report.cpp
@@ -28,7 +28,7 @@ int main() {
 #  define PTR_FMT "0x%08x"
 # endif
 // Solaris libc omits the leading 0x.
-#elif defined(__sun__) && defined(__svr4__)
+#elif (defined(__sun__) && defined(__svr4__)) || defined(_AIX)
 # define PTR_FMT "0x%p"
 #else
 # define PTR_FMT "%p"
diff --git a/compiler-rt/test/asan/TestCases/double-free.cpp b/compiler-rt/test/asan/TestCases/double-free.cpp
index 7b61df0715afa..9fbeb0ad3cd3b 100644
--- a/compiler-rt/test/asan/TestCases/double-free.cpp
+++ b/compiler-rt/test/asan/TestCases/double-free.cpp
@@ -19,10 +19,10 @@ int main(int argc, char **argv) {
   free(x + argc - 1);  // BOOM
   // CHECK: AddressSanitizer: attempting double-free{{.*}}in thread T0
   // CHECK: #0 0x{{.*}} in {{.*}}free
-  // CHECK: #{{[1-3]}} 0x{{.*}} in main {{.*}}double-free.cpp:[[@LINE-3]]
+  // CHECK: #{{[1-3]}} 0x{{.*}} in {{main|.main}} {{.*}}double-free.cpp:[[@LINE-3]]
   // CHECK: freed by thread T0 here:
   // MALLOC-CTX: #0 0x{{.*}} in {{.*}}free
-  // MALLOC-CTX: #{{[1-3]}} 0x{{.*}} in main {{.*}}double-free.cpp:[[@LINE-7]]
+  // MALLOC-CTX: #{{[1-3]}} 0x{{.*}} in {{main|.main}} {{.*}}double-free.cpp:[[@LINE-7]]
   // CHECK: allocated by thread T0 here:
   // MALLOC-CTX: double-free.cpp:[[@LINE-12]]
   // CHECK-RECOVER: AddressSanitizer: attempting double-free{{.*}}in thread T0
diff --git a/compiler-rt/test/asan/TestCases/frexp_interceptor.cpp b/compiler-rt/test/asan/TestCases/frexp_interceptor.cpp
index d75ba992b650b..5e21b392667c4 100644
--- a/compiler-rt/test/asan/TestCases/frexp_interceptor.cpp
+++ b/compiler-rt/test/asan/TestCases/frexp_interceptor.cpp
@@ -2,6 +2,9 @@
 
 // Test the frexp() interceptor.
 
+// AIX does not intercept frexp
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp b/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp
index 91da09a6880cf..18fb71b9a89a8 100644
--- a/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp
+++ b/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp
@@ -2,6 +2,9 @@
 
 // Test the frexpf() interceptor.
 
+// AIX can not intercept frexpf because libc does not export this symbol.
+// UNSUPPORTED: aix
+
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp b/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp
index 721eecc6f82a3..2df5e431024cc 100644
--- a/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp
+++ b/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp
@@ -6,6 +6,10 @@
 // interceptor seems to not work.
 // XFAIL: target={{.*-windows-gnu}}
 
+// clang will expand frexpl to a function(with mangle name) that calls frexp.
+// On AIX, frexp can not be intercepted.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp b/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp
index 07c8e63f439da..641854c13f494 100644
--- a/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp
+++ b/compiler-rt/test/asan/TestCases/global-location-nodebug.cpp
@@ -10,7 +10,8 @@
 
 /// Solaris ld -S has different semantics, so enforce -fuse-ld= for
 /// configurations that default to GNU ld.
-// XFAIL: target={{.*solaris.*}}
+/// AIX ld -S has different semnatics.
+// XFAIL: target={{.*solaris.*|.*aix.*}}
 
 // CHECK: AddressSanitizer: global-buffer-overflow
 // CLASS_STATIC-NO-G: 0x{{.*}} is located 4 bytes after global variable '{{.*}}C::array{{.*}}' defined in '{{.*}}global-location.cpp' {{.*}} of size 40
diff --git a/compiler-rt/test/asan/TestCases/global-overflow.cpp b/compiler-rt/test/asan/TestCases/global-overflow.cpp
index ed276ca44aa26..ffc311b614f7c 100644
--- a/compiler-rt/test/asan/TestCases/global-overflow.cpp
+++ b/compiler-rt/test/asan/TestCases/global-overflow.cpp
@@ -16,7 +16,7 @@ int main(int argc, char **argv) {
   memset(ZZZ, 0, 10);
   int res = YYY[argc * 10];  // BOOOM
   // CHECK: {{READ of size 1 at 0x.* thread T0}}
-  // CHECK: {{    #0 0x.* in main .*global-overflow.cpp:}}[[@LINE-2]]
+  // CHECK: {{    #0 0x.* in (main|.main) .*global-overflow.cpp:}}[[@LINE-2]]
   // CHECK: {{0x.* is located 0 bytes after global variable}}
   // CHECK:   {{.*YYY.* of size 10}}
   res += XXX[argc] + ZZZ[argc];
diff --git a/compiler-rt/test/asan/TestCases/global-underflow.cpp b/compiler-rt/test/asan/TestCases/global-underflow.cpp
index 32b4ce82f9b04..cde8b59fbe565 100644
--- a/compiler-rt/test/asan/TestCases/global-underflow.cpp
+++ b/compiler-rt/test/asan/TestCases/global-underflow.cpp
@@ -3,6 +3,11 @@
 // RUN: %clangxx_asan -O2 %s %p/Helpers/underflow.cpp -o %t && not %run %t 2>&1 | FileCheck %s
 // RUN: %clangxx_asan -O3 %s %p/Helpers/underflow.cpp -o %t && not %run %t 2>&1 | FileCheck %s
 
+// aix puts XXX and YYY at very different addresses. For example YYY is 0x20004340, XXX is 0x20000c20
+// This address allocation does not match the assumption in https://reviews.llvm.org/D38056.
+// It was awared that this case may be not reliable on other OS.
+// UNSUPPORTED: target={{.*aix.*}}
+
 int XXX[2] = {2, 3};
 extern int YYY[];
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/heap-overflow.cpp b/compiler-rt/test/asan/TestCases/heap-overflow.cpp
index f5bdcd5386373..102f5eafcb16e 100644
--- a/compiler-rt/test/asan/TestCases/heap-overflow.cpp
+++ b/compiler-rt/test/asan/TestCases/heap-overflow.cpp
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
   memset(x, 0, 10);
   int res = x[argc * 10];  // BOOOM
   // CHECK: {{READ of size 1 at 0x.* thread T0}}
-  // CHECK: {{    #0 0x.* in main .*heap-overflow.cpp:}}[[@LINE-2]]
+  // CHECK: {{    #0 0x.* in (main|.main) .*heap-overflow.cpp:}}[[@LINE-2]]
   // CHECK: {{0x.* is located 0 bytes after 10-byte region}}
   // CHECK: {{allocated by thread T0 here:}}
 
diff --git a/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp b/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp
index 661867260d260..d14d70ca05704 100644
--- a/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp
+++ b/compiler-rt/test/asan/TestCases/heavy_uar_test.cpp
@@ -72,7 +72,7 @@ int main(int argc, char **argv) {
   stale_stack[100]++;
   // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address
   // CHECK: is located in stack of thread T0 at offset {{116|132}} in frame
-  // CHECK:  in LeakStack{{.*}}heavy_uar_test.cpp:
+  // CHECK:  in {{(LeakStack|.LeakStack).*}}heavy_uar_test.cpp:
   // CHECK: [{{16|32}}, {{1040|1056}}) 'x'
   return 0;
 }
diff --git a/compiler-rt/test/asan/TestCases/initialization-bug.cpp b/compiler-rt/test/asan/TestCases/initialization-bug.cpp
index 2775f6ce356dd..666fb887bc445 100644
--- a/compiler-rt/test/asan/TestCases/initialization-bug.cpp
+++ b/compiler-rt/test/asan/TestCases/initialization-bug.cpp
@@ -33,7 +33,7 @@ int __attribute__((noinline)) initX() {
   // CHECK: {{READ of size .* at 0x.* thread T0}}
   // CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}}
   // CHECK: registered at:
-  // CHECK: 0x{{.*}} in __asan_register_globals
+  // CHECK: 0x{{.*}} in {{__asan_register_globals|.__asan_register_globals}}
 }
 
 // This initializer begins our initialization order problems.
diff --git a/compiler-rt/test/asan/TestCases/intercept-rethrow-exception.cpp b/compiler-rt/test/asan/TestCases/intercept-rethrow-exception.cpp
index bf51eed41fddf..19e1eebfe6a77 100644
--- a/compiler-rt/test/asan/TestCases/intercept-rethrow-exception.cpp
+++ b/compiler-rt/test/asan/TestCases/intercept-rethrow-exception.cpp
@@ -15,6 +15,10 @@
 // https://reviews.llvm.org/D111703 made compiler incompatible with released NDK.
 // UNSUPPORTED: android && arm-target-arch
 
+// make_exception_ptr on AIX will call __cxa_throw, and __cxa_throw will call malloc
+// and memset, these function call will change shadow memory unexpectly.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <exception>
 #include <sanitizer/asan_interface.h>
diff --git a/compiler-rt/test/asan/TestCases/invalid-free.cpp b/compiler-rt/test/asan/TestCases/invalid-free.cpp
index f550dc14a5a68..09228dc8ab69e 100644
--- a/compiler-rt/test/asan/TestCases/invalid-free.cpp
+++ b/compiler-rt/test/asan/TestCases/invalid-free.cpp
@@ -1,9 +1,12 @@
 // RUN: %clangxx_asan -O0 %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX
+// RUN: %if target={{.*aix.*}} %{ %env_asan_opts=enable_unmalloced_free_check=1 %} not %run %t 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX
 
 // Also works if no malloc context is available.
-// RUN: %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
-// RUN: %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %if target={{.*aix.*}} %{ %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=0:enable_unmalloced_free_check=1 %} %else \
+// RUN:   %{ %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=0 %} not %run %t 2>&1 | FileCheck %s
+// RUN: %if target={{.*aix.*}} %{ %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=1:enable_unmalloced_free_check=1 %} %else \
+// RUN:  %{ %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=1 %} not %run %t 2>&1 | FileCheck %s
 // REQUIRES: stable-runtime
 
 #include <stdlib.h>
diff --git a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cpp b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cpp
index 7b1479e2d05bd..a924bdada2e9e 100644
--- a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cpp
+++ b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cpp
@@ -23,82 +23,82 @@ int main() {
   char *heap2 = (char *)malloc(42);
 
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(heap1, heap2);
   free(heap1);
   free(heap2);
 
   heap1 = (char *)malloc(1024);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(heap1, heap1 + 1025);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(heap1 + 1024, heap1 + 1025);
   free(heap1);
 
   heap1 = (char *)malloc(4096);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(heap1, heap1 + 4097);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(heap1, 0);
 
   // Global variables.
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(&global1[0], &global2[10]);
 
   char *p = &small_global[0];
   foo(p, p); // OK
   foo(p, p + 7); // OK
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p, p + 8);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p - 1, p);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p, p - 1);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p - 1, p + 8);
 
   p = &large_global[0];
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p - 1, p);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p, p - 1);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p, &global1[0]);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p, &small_global[0]);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(p, 0);
 
   // Stack variables.
   char stack1, stack2;
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(&stack1, &stack2);
 
   // Mixtures.
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(heap1, &stack1);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
   foo(heap1, &global1[0]);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
   foo(&stack1, &global1[0]);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-compare-errors.cpp:[[@LINE+1]]
   foo(&stack1, 0);
 
   free(heap1);
diff --git a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cpp b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cpp
index 535833d05c89a..d8157f86e2f45 100644
--- a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cpp
+++ b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cpp
@@ -17,29 +17,29 @@ int main() {
   char *heap2 = (char *)malloc(42);
 
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
   foo(heap1, heap2);
 
   // Global variables.
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
   foo(&global1[0], &global2[10]);
 
   // Stack variables.
   char stack1, stack2;
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
   foo(&stack1, &stack2);
 
   // Mixtures.
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
   foo(heap1, &stack1);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
   foo(heap1, &global1[0]);
   // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair
-  // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
+  // CHECK: #{{[0-9]+ .*}} in {{main|.main}} {{.*}}invalid-pointer-pairs-subtract-errors.cpp:[[@LINE+1]]
   foo(&stack1, &global1[0]);
 
   free(heap1);
diff --git a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs.cpp b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs.cpp
index accd9b7704d51..cb2fecbb8a512 100644
--- a/compiler-rt/test/asan/TestCases/invalid-pointer-pairs.cpp
+++ b/compiler-rt/test/asan/TestCases/invalid-pointer-pairs.cpp
@@ -13,10 +13,10 @@ int f(char c, char *p, char *q) {
   // [[PTR1:0x[0-9a-f]+]] [[PTR2:0x[0-9a-f]+]]
   switch (c) {
   case 'g':
-    // CMP: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]]
+    // CMP: #{{[0-9]+ .*}} in {{f|.f}}({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]]
     return p > q;
   case 's':
-    // SUB: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]]
+    // SUB: #{{[0-9]+ .*}} in {{f|.f}}({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+1]]
     return p - q;
   case 'k': {
     // OK-NOT: ERROR
@@ -26,7 +26,7 @@ int f(char c, char *p, char *q) {
   case 'f': {
     char *p3 = p + 20;
     free(p);
-    // FREE: #{{[0-9]+ .*}} in f({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+2]]
+    // FREE: #{{[0-9]+ .*}} in {{f|.f}}({{char, *char *\*, *char *\*}}) {{.*}}invalid-pointer-pairs.cpp:[[@LINE+2]]
     // FREE: freed by thread
     return p < p3;
   }
diff --git a/compiler-rt/test/asan/TestCases/large_func_test.cpp b/compiler-rt/test/asan/TestCases/large_func_test.cpp
index c64fc7d3c7aa7..e7572029022b9 100644
--- a/compiler-rt/test/asan/TestCases/large_func_test.cpp
+++ b/compiler-rt/test/asan/TestCases/large_func_test.cpp
@@ -32,6 +32,7 @@ static void LargeFunction(int *x, int zero) {
   // CHECK-Windows:{{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-5]]
   // CHECK-FreeBSD:{{#0 0x.* in LargeFunction.*large_func_test.cpp:}}[[@LINE-6]]
   // CHECK-Darwin: {{#0 0x.* in .*LargeFunction.*large_func_test.cpp}}:[[@LINE-7]]
+  // CHECK-AIX:    {{#0 0x.* in .*LargeFunction.*large_func_test.cpp}}:[[@LINE-8]]
 
   x[10]++;
   x[11]++;
@@ -48,7 +49,7 @@ static void LargeFunction(int *x, int zero) {
 int main(int argc, char **argv) {
   int *x = new int[100];
   LargeFunction(x, argc - 1);
-  // CHECK: {{    #1 0x.* in main .*large_func_test.cpp:}}[[@LINE-1]]
+  // CHECK: {{    #1 0x.* in (main|.main) .*large_func_test.cpp:}}[[@LINE-1]]
   // CHECK: {{0x.* is located 12 bytes after 400-byte region}}
   // CHECK: {{allocated by thread T0 here:}}
   // CHECK-Linux:  {{    #0 0x.* in operator new}}
@@ -56,7 +57,10 @@ int main(int argc, char **argv) {
   // CHECK-Windows:{{    #0 0x.* in operator new}}
   // CHECK-FreeBSD:{{    #0 0x.* in operator new}}
   // CHECK-Darwin: {{    #0 0x.* in .*_Zna}}
-  // CHECK-NEXT:   {{    #1 0x.* in main .*large_func_test.cpp:}}[[@LINE-10]]
+  // AIX currently have some issue while symbolizing operator new.
+  // FIXME: fix this symbolizer issue on aix.
+  // CHECK-AIX:    {{    #0 0x.* }}
+  // CHECK-NEXT:   {{    #1 0x.* in (main|.main) .*large_func_test.cpp:}}[[@LINE-13]]
   int y = x[argc];
   delete[] x;
   return y;
diff --git a/compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp b/compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp
index 771640a4ac08d..e3d0d57920242 100644
--- a/compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp
+++ b/compiler-rt/test/asan/TestCases/malloc-size-too-big.cpp
@@ -18,7 +18,7 @@ int main() {
   void *p = malloc(kMaxAllowedMallocSizePlusOne);
   // CHECK: {{ERROR: AddressSanitizer: requested allocation size .* \(.* after adjustments for alignment, red zones etc\.\) exceeds maximum supported size}}
   // CHECK: {{#0 0x.* in .*malloc}}
-  // CHECK: {{#[1-3] 0x.* in main .*malloc-size-too-big.cpp:}}[[@LINE-3]]
+  // CHECK: {{#[1-3] 0x.* in (main|.main) .*malloc-size-too-big.cpp:}}[[@LINE-3]]
   // CHECK: SUMMARY: AddressSanitizer: allocation-size-too-big
 
   printf("malloc returned: %zu\n", (size_t)p);
diff --git a/compiler-rt/test/asan/TestCases/malloc_context_size.cpp b/compiler-rt/test/asan/TestCases/malloc_context_size.cpp
index e75bc48793ad1..a249df54b8cb5 100644
--- a/compiler-rt/test/asan/TestCases/malloc_context_size.cpp
+++ b/compiler-rt/test/asan/TestCases/malloc_context_size.cpp
@@ -11,17 +11,19 @@ int main() {
   return x[0];
 
   // CHECK: freed by thread T{{.*}} here:
-  // CHECK-NEXT: #0 0x{{.*}} in {{operator delete( )?\[\]|_ZdaPv}}
+  // FIXME: aix currently can not symbolize operator delete inside asan library.
+  // CHECK-NEXT: #0 0x{{.*}} {{(in operator delete( )?\[\]|wrap__ZdaPv|.*)}}
   // CHECK-NOT: #1 0x{{.*}}
 
   // CHECK: previously allocated by thread T{{.*}} here:
-  // CHECK-NEXT: #0 0x{{.*}} in {{operator new( )?\[\]|_Znam}}
+  // FIXME: aix currently can not symbolize operator delete inside asan library.
+  // CHECK-NEXT: #0 0x{{.*}} {{(in operator new( )?\[\]|wrap__Znam|.*)}}
   // CHECK-NOT: #1 0x{{.*}}
 
   // CHECK: SUMMARY: AddressSanitizer: heap-use-after-free
 
   // TWO: previously allocated by thread T{{.*}} here:
   // TWO-NEXT: #0 0x{{.*}}
-  // TWO-NEXT: #1 0x{{.*}} in main {{.*}}malloc_context_size.cpp
+  // TWO-NEXT: #1 0x{{.*}} in {{main|.main}} {{.*}}malloc_context_size.cpp
   // TWO: SUMMARY: AddressSanitizer: heap-use-after-free
 }
diff --git a/compiler-rt/test/asan/TestCases/memset_test.cpp b/compiler-rt/test/asan/TestCases/memset_test.cpp
index 0530c8483d72f..7c3a3064e76f3 100644
--- a/compiler-rt/test/asan/TestCases/memset_test.cpp
+++ b/compiler-rt/test/asan/TestCases/memset_test.cpp
@@ -9,26 +9,28 @@
 // RUN: %clangxx_asan -O3 -DTEST_MEMSET %s -o %t && not %run %t 2>&1 | \
 // RUN:     FileCheck %s --check-prefix=CHECK-MEMSET
 
-// RUN: %clangxx_asan -O0 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY
-// RUN: %clangxx_asan -O1 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY
-// RUN: %clangxx_asan -O2 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY
-// RUN: %clangxx_asan -O3 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY
+// AIX can not intercept memcpy
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O0 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY %}
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O1 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY %}
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O2 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY %}
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O3 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY %}
 
-// RUN: %clangxx_asan -O0 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMMOVE
-// RUN: %clangxx_asan -O1 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMMOVE
-// RUN: %clangxx_asan -O2 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMMOVE
-// RUN: %clangxx_asan -O3 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMMOVE
+// AIX can not intercept memmove
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O0 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMMOVE %}
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O1 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMMOVE %}
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O2 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMMOVE %}
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O3 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMMOVE %}
 
-// RUN: %clangxx_asan -O2 -DTEST_MEMCPY_SIZE_OVERFLOW %s -o %t && not %run %t 2>&1 | \
-// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY_SIZE_OVERFLOW
+// RUN: %if !target={{.*aix.*}} %{ %clangxx_asan -O2 -DTEST_MEMCPY_SIZE_OVERFLOW %s -o %t && not %run %t 2>&1 | \
+// RUN:     FileCheck %s --check-prefix=CHECK-MEMCPY_SIZE_OVERFLOW %}
 
 #include <assert.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/null_deref.cpp b/compiler-rt/test/asan/TestCases/null_deref.cpp
index a8947a4378032..8859c9be770c5 100644
--- a/compiler-rt/test/asan/TestCases/null_deref.cpp
+++ b/compiler-rt/test/asan/TestCases/null_deref.cpp
@@ -19,6 +19,6 @@ void NullDeref(int *ptr) {
 }
 int main() {
   NullDeref((int*)0);
-  // CHECK: {{    #1 0x.* in main.*null_deref.cpp}}
+  // CHECK: {{    #1 0x.* in (main|.main).*null_deref.cpp}}
   // CHECK: AddressSanitizer can not provide additional info.
 }
diff --git a/compiler-rt/test/asan/TestCases/print_summary.cpp b/compiler-rt/test/asan/TestCases/print_summary.cpp
index f3f7697056eab..ec407855304b8 100644
--- a/compiler-rt/test/asan/TestCases/print_summary.cpp
+++ b/compiler-rt/test/asan/TestCases/print_summary.cpp
@@ -8,7 +8,7 @@ int main() {
   delete[] x;
   return x[0];
   // SOURCE: ERROR: AddressSanitizer: heap-use-after-free
-  // SOURCE: SUMMARY: AddressSanitizer: heap-use-after-free {{.*}}print_summary.cpp:[[@LINE-2]]{{.*}} main
+  // SOURCE: SUMMARY: AddressSanitizer: heap-use-after-free {{.*}}print_summary.cpp:[[@LINE-2]]{{.*}} {{main|.main}}
   // MODULE: ERROR: AddressSanitizer: heap-use-after-free
   // MODULE: SUMMARY: AddressSanitizer: heap-use-after-free ({{.*}}+0x{{.*}})
   // MISSING: ERROR: AddressSanitizer: heap-use-after-free
diff --git a/compiler-rt/test/asan/TestCases/replaceable_new_delete_shared.cpp b/compiler-rt/test/asan/TestCases/replaceable_new_delete_shared.cpp
index 6a78ebb3489b9..5302c3d71a108 100644
--- a/compiler-rt/test/asan/TestCases/replaceable_new_delete_shared.cpp
+++ b/compiler-rt/test/asan/TestCases/replaceable_new_delete_shared.cpp
@@ -3,7 +3,8 @@
 // FIXME: Weak symbols aren't supported on Windows, although some code in
 // compiler-rt already exists to solve this problem. We should probably define
 // the new/delete interceptors as "weak" using those workarounds as well.
-// UNSUPPORTED: target={{.*windows.*}}
+// AIX does not support shared sanitizer libraries.
+// UNSUPPORTED: target={{.*(windows|aix).*}}
 
 // RUN: %clangxx %s -o %t -fsanitize=address -shared-libsan && not %run %t 2>&1 | FileCheck %s
 
diff --git a/compiler-rt/test/asan/TestCases/set_shadow_test.c b/compiler-rt/test/asan/TestCases/set_shadow_test.c
index f1c96502eba7e..39368ae3d3188 100644
--- a/compiler-rt/test/asan/TestCases/set_shadow_test.c
+++ b/compiler-rt/test/asan/TestCases/set_shadow_test.c
@@ -32,7 +32,11 @@ void f(long arg) {
   size_t shadow_offset;
   size_t shadow_scale;
   __asan_get_shadow_mapping(&shadow_scale, &shadow_offset);
+#if !defined(__LP64__) || !defined(_AIX)
   size_t addr = (((size_t)a) >> shadow_scale) + shadow_offset;
+#else
+  size_t addr = (((size_t)a << 6) >> (6 + shadow_scale)) + shadow_offset;
+#endif
 
   switch (arg) {
   // X00-NOT: AddressSanitizer
diff --git a/compiler-rt/test/asan/TestCases/stack-buffer-overflow.cpp b/compiler-rt/test/asan/TestCases/stack-buffer-overflow.cpp
index 07cf39433b458..341003750b674 100644
--- a/compiler-rt/test/asan/TestCases/stack-buffer-overflow.cpp
+++ b/compiler-rt/test/asan/TestCases/stack-buffer-overflow.cpp
@@ -9,7 +9,7 @@ int main(int argc, char **argv) {
   memset(x, 0, 10);
   int res = x[argc * 10];  // BOOOM
   // CHECK: {{READ of size 1 at 0x.* thread T0}}
-  // CHECK: {{    #0 0x.* in main .*stack-buffer-overflow.cpp:}}[[@LINE-2]]
+  // CHECK: {{    #0 0x.* in (main|.main) .*stack-buffer-overflow.cpp:}}[[@LINE-2]]
   // CHECK: {{Address 0x.* is located in stack of thread T0 at offset}}
   // CHECK-NEXT: in{{.*}}main{{.*}}stack-buffer-overflow.cpp
   return res;
diff --git a/compiler-rt/test/asan/TestCases/strcasestr-1.c b/compiler-rt/test/asan/TestCases/strcasestr-1.c
index 9fa4a2b31b97f..832178378ab30 100644
--- a/compiler-rt/test/asan/TestCases/strcasestr-1.c
+++ b/compiler-rt/test/asan/TestCases/strcasestr-1.c
@@ -8,6 +8,9 @@
 // There's no interceptor for strcasestr on Windows
 // XFAIL: target={{.*windows-(msvc.*|gnu)}}
 
+// AIX does not define strcasestr
+// UNSUPPORTED: target={{.*aix.*}}
+
 #define _GNU_SOURCE
 #include <assert.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/strcasestr-2.c b/compiler-rt/test/asan/TestCases/strcasestr-2.c
index 920d11e275c6a..2f530cda44484 100644
--- a/compiler-rt/test/asan/TestCases/strcasestr-2.c
+++ b/compiler-rt/test/asan/TestCases/strcasestr-2.c
@@ -8,6 +8,9 @@
 // There's no interceptor for strcasestr on Windows
 // XFAIL: target={{.*windows-(msvc.*|gnu)}}
 
+// AIX does not define strcasestr.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #define _GNU_SOURCE
 #include <assert.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/strcasestr_strict.c b/compiler-rt/test/asan/TestCases/strcasestr_strict.c
index 16efae72ada4e..268e63860242d 100644
--- a/compiler-rt/test/asan/TestCases/strcasestr_strict.c
+++ b/compiler-rt/test/asan/TestCases/strcasestr_strict.c
@@ -6,6 +6,9 @@
 // There's no interceptor for strcasestr on Windows
 // XFAIL: target={{.*windows-(msvc.*|gnu)}}
 
+// AIX does not define strcasestr.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #define _GNU_SOURCE
 #include <assert.h>
 #include <stdlib.h>
diff --git a/compiler-rt/test/asan/TestCases/strcat_strict.c b/compiler-rt/test/asan/TestCases/strcat_strict.c
index 6e9bd8eb08602..55324624f3238 100644
--- a/compiler-rt/test/asan/TestCases/strcat_strict.c
+++ b/compiler-rt/test/asan/TestCases/strcat_strict.c
@@ -7,6 +7,9 @@
 // RUN: %env_asan_opts=strict_string_checks=false not  %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2
 // RUN: %env_asan_opts=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2
 
+// AIX does not intercept strcat.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/strcmp.c b/compiler-rt/test/asan/TestCases/strcmp.c
index 417bd491ebe02..eba27d2cfa77b 100644
--- a/compiler-rt/test/asan/TestCases/strcmp.c
+++ b/compiler-rt/test/asan/TestCases/strcmp.c
@@ -3,6 +3,9 @@
 // RUN: %env_asan_opts=intercept_strcmp=true not %run %t 2>&1 | FileCheck %s
 // RUN:                                      not %run %t 2>&1 | FileCheck %s
 
+// AIX does not intercept strcmp.
+//UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/strcmp_strict.c b/compiler-rt/test/asan/TestCases/strcmp_strict.c
index e168923749ce2..654cccd4dc5ac 100644
--- a/compiler-rt/test/asan/TestCases/strcmp_strict.c
+++ b/compiler-rt/test/asan/TestCases/strcmp_strict.c
@@ -3,6 +3,9 @@
 // RUN: %env_asan_opts=strict_string_checks=false %run %t 2>&1
 // RUN: %env_asan_opts=strict_string_checks=true not %run %t 2>&1 | FileCheck %s
 
+// AIX does not intercept strcmp.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp b/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp
index efd2e6b7521ef..31fe1fe469799 100644
--- a/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp
+++ b/compiler-rt/test/asan/TestCases/strcpy-overlap.cpp
@@ -28,6 +28,9 @@
 
 // UNSUPPORTED: android
 
+// AIX does not intercept strcpy
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <string.h>
 
 
diff --git a/compiler-rt/test/asan/TestCases/strip_path_prefix.c b/compiler-rt/test/asan/TestCases/strip_path_prefix.c
index e77f1d5ddaf42..0534bb1d09167 100644
--- a/compiler-rt/test/asan/TestCases/strip_path_prefix.c
+++ b/compiler-rt/test/asan/TestCases/strip_path_prefix.c
@@ -8,5 +8,5 @@ int main() {
   return x[5];
   // Check that paths in error report don't start with slash.
   // CHECK: heap-use-after-free
-  // CHECK: #0 0x{{.*}} in main {{.*}}strip_path_prefix.c:[[@LINE-3]]
+  // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}strip_path_prefix.c:[[@LINE-3]]
 }
diff --git a/compiler-rt/test/asan/TestCases/strncat-overlap.cpp b/compiler-rt/test/asan/TestCases/strncat-overlap.cpp
index 3e3f7ee2723f5..ff04127ecd9c6 100644
--- a/compiler-rt/test/asan/TestCases/strncat-overlap.cpp
+++ b/compiler-rt/test/asan/TestCases/strncat-overlap.cpp
@@ -28,6 +28,9 @@
 
 // UNSUPPORTED: android
 
+// AIX does not intercept strncat.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <string.h>
 
 
diff --git a/compiler-rt/test/asan/TestCases/strncat_strict.c b/compiler-rt/test/asan/TestCases/strncat_strict.c
index 2b44b565a5e4f..2f61af491536e 100644
--- a/compiler-rt/test/asan/TestCases/strncat_strict.c
+++ b/compiler-rt/test/asan/TestCases/strncat_strict.c
@@ -7,6 +7,9 @@
 // RUN: %env_asan_opts=strict_string_checks=false not  %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2
 // RUN: %env_asan_opts=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2
 
+// aix does not intercept strncat.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/strncmp_strict.c b/compiler-rt/test/asan/TestCases/strncmp_strict.c
index e06d1475b96f5..35bda6f7df020 100644
--- a/compiler-rt/test/asan/TestCases/strncmp_strict.c
+++ b/compiler-rt/test/asan/TestCases/strncmp_strict.c
@@ -14,6 +14,9 @@
 // RUN: %env_asan_opts=strict_string_checks=false %run %t i 2>&1
 // RUN: %env_asan_opts=strict_string_checks=true not %run %t i 2>&1 | FileCheck %s
 
+// AIX does not intercept strncmp.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <stdlib.h>
 #include <stdio.h>
diff --git a/compiler-rt/test/asan/TestCases/strncpy-overflow.cpp b/compiler-rt/test/asan/TestCases/strncpy-overflow.cpp
index ff84052a94987..12d6bca00f556 100644
--- a/compiler-rt/test/asan/TestCases/strncpy-overflow.cpp
+++ b/compiler-rt/test/asan/TestCases/strncpy-overflow.cpp
@@ -6,6 +6,9 @@
 // REQUIRES: compiler-rt-optimized
 // REQUIRES: stable-runtime
 
+// AIX does not intercept strncpy.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <string.h>
 #include <stdlib.h>
 
diff --git a/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp b/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp
index 860fc5d304e0e..85fd1a9b41e72 100644
--- a/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp
+++ b/compiler-rt/test/asan/TestCases/strncpy-overlap.cpp
@@ -28,6 +28,9 @@
 
 // UNSUPPORTED: android
 
+// AIX does not intercept strncpy.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <string.h>
 
 
diff --git a/compiler-rt/test/asan/TestCases/suppressions-library.cpp b/compiler-rt/test/asan/TestCases/suppressions-library.cpp
index 5427122eaa92f..78a1235c83c5b 100644
--- a/compiler-rt/test/asan/TestCases/suppressions-library.cpp
+++ b/compiler-rt/test/asan/TestCases/suppressions-library.cpp
@@ -12,6 +12,12 @@
 // FIXME: Upload suppressions to device.
 // XFAIL: android
 
+// For this case, crash_function(which calls malloc/free) is compiled to a shared library,
+// However intercepting symbols in a shared library is still unsupported.
+
+// UNSUPPORTED: target={{.*aix.*}}
+
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/compiler-rt/test/asan/TestCases/use-after-delete.cpp b/compiler-rt/test/asan/TestCases/use-after-delete.cpp
index 4d0c055368bb0..ee8146cff99dc 100644
--- a/compiler-rt/test/asan/TestCases/use-after-delete.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-delete.cpp
@@ -4,6 +4,9 @@
 // RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK
 // REQUIRES: stable-runtime
 
+// AIX currently have some issue while symbolizing operator new/delete.
+// FIXME: fix this symbolizer issue on aix.
+
 #include <stdlib.h>
 int main() {
   char * volatile x = new char[10];
@@ -12,7 +15,7 @@ int main() {
   // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
   // CHECK:   {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
   // CHECK: {{READ of size 1 at 0x.* thread T0}}
-  // CHECK: {{    #0 0x.* in main .*use-after-delete.cpp:}}[[@LINE-4]]
+  // CHECK: {{    #0 0x.* in (main|.main) .*use-after-delete.cpp:}}[[@LINE-4]]
   // CHECK: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}}
 
   // CHECK: {{freed by thread T0 here:}}
@@ -21,7 +24,8 @@ int main() {
   // CHECK-Windows:{{    #0 0x.* in operator delete\[\]}}
   // CHECK-FreeBSD:{{    #0 0x.* in operator delete\[\]}}
   // CHECK-Darwin: {{    #0 0x.* in .*_Zda}}
-  // CHECK-NEXT:   {{    #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-14]]
+  // CHECK-AIX:    {{    #0 0x.*}}
+  // CHECK-NEXT:   {{    #1 0x.* in (main|.main) .*use-after-delete.cpp:}}[[@LINE-15]]
 
   // CHECK: {{previously allocated by thread T0 here:}}
   // CHECK-Linux:  {{    #0 0x.* in operator new\[\]}}
@@ -29,8 +33,8 @@ int main() {
   // CHECK-Windows:{{    #0 0x.* in operator new\[\]}}
   // CHECK-FreeBSD:{{    #0 0x.* in operator new\[\]}}
   // CHECK-Darwin: {{    #0 0x.* in .*_Zna}}
-  // CHECK-NEXT:   {{    #1 0x.* in main .*use-after-delete.cpp:}}[[@LINE-23]]
-
+  // CHECK-AIX:    {{    #0 0x.*}}
+  // CHECK-NEXT:   {{    #1 0x.* in (main|.main) .*use-after-delete.cpp:}}[[@LINE-25]]
 
   // CHECK: Shadow byte legend (one shadow byte represents {{[0-9]+}} application bytes):
   // CHECK: Global redzone:
diff --git a/compiler-rt/test/asan/TestCases/use-after-free-right.cpp b/compiler-rt/test/asan/TestCases/use-after-free-right.cpp
index 11011e4b4fb1a..90e8c61d740e1 100644
--- a/compiler-rt/test/asan/TestCases/use-after-free-right.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-free-right.cpp
@@ -15,13 +15,13 @@ int main() {
   // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
   // CHECK:   {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
   // CHECK: {{WRITE of size 1 at 0x.* thread T0}}
-  // CHECK: {{    #0 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-4]]
+  // CHECK: {{    #0 0x.* in (main|.main) .*use-after-free-right.cpp:}}[[@LINE-4]]
   // CHECK: {{0x.* is located 0 bytes inside of 1-byte region .0x.*,0x.*}}
   // CHECK: {{freed by thread T0 here:}}
   // CHECK: {{    #0 0x.* in .*free}}
-  // CHECK: {{    #[1-3] 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-9]]
+  // CHECK: {{    #[1-3] 0x.* in (main|.main) .*use-after-free-right.cpp:}}[[@LINE-9]]
 
   // CHECK: {{previously allocated by thread T0 here:}}
   // CHECK: {{    #0 0x.* in .*malloc}}
-  // CHECK: {{    #[1-3] 0x.* in main .*use-after-free-right.cpp:}}[[@LINE-14]]
+  // CHECK: {{    #[1-3] 0x.* in (main|.main) .*use-after-free-right.cpp:}}[[@LINE-14]]
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-free.cpp b/compiler-rt/test/asan/TestCases/use-after-free.cpp
index f19c461960d36..7d02d97a6678c 100644
--- a/compiler-rt/test/asan/TestCases/use-after-free.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-free.cpp
@@ -12,15 +12,15 @@ int main() {
   // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
   // CHECK:   {{0x.* at pc 0x.* bp 0x.* sp 0x.*}}
   // CHECK: {{READ of size 1 at 0x.* thread T0}}
-  // CHECK: {{    #0 0x.* in main .*use-after-free.cpp:}}[[@LINE-4]]
+  // CHECK: {{    #0 0x.* in (main|.main) .*use-after-free.cpp:}}[[@LINE-4]]
   // CHECK: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}}
   // CHECK: {{freed by thread T0 here:}}
   // CHECK: {{    #0 0x.* in .*free}}
-  // CHECK: {{    #[1-3] 0x.* in main .*use-after-free.cpp:}}[[@LINE-9]]
+  // CHECK: {{    #[1-3] 0x.* in (main|.main) .*use-after-free.cpp:}}[[@LINE-9]]
 
   // CHECK: {{previously allocated by thread T0 here:}}
   // CHECK: {{    #0 0x.* in .*malloc}}
-  // CHECK: {{    #[1-3] 0x.* in main .*use-after-free.cpp:}}[[@LINE-14]]
+  // CHECK: {{    #[1-3] 0x.* in (main|.main) .*use-after-free.cpp:}}[[@LINE-14]]
   // CHECK: Shadow byte legend (one shadow byte represents {{[0-9]+}} application bytes):
   // CHECK: Global redzone:
   // CHECK: ASan internal:
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-dtor-order.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-dtor-order.cpp
index 42f62c72397ec..916b6d52f7085 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-dtor-order.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-dtor-order.cpp
@@ -7,7 +7,7 @@ struct IntHolder {
   __attribute__((noinline)) ~IntHolder() {
     printf("Value: %d\n", *val_);  // BOOM
     // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-    // CHECK:  #0 0x{{.*}} in IntHolder::~IntHolder{{.*}}.cpp:[[@LINE-2]]
+    // CHECK:  #0 0x{{.*}} in {{(IntHolder::~IntHolder|.IntHolder::~IntHolder).*}}.cpp:[[@LINE-2]]
   }
   void set(int *val) { val_ = val; }
   int *get() { return val_; }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-if.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-if.cpp
index 4c6cf34eaa9fd..d94bc03754078 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-if.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-if.cpp
@@ -10,5 +10,5 @@ int main() {
   }
   return *p;  // BOOM
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-  // CHECK:  #0 0x{{.*}} in main {{.*}}.cpp:[[@LINE-2]]
+  // CHECK:  #0 0x{{.*}} in {{main|.main}} {{.*}}.cpp:[[@LINE-2]]
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-inlined.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-inlined.cpp
index 1014ff919b9ef..3492125264de4 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-inlined.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-inlined.cpp
@@ -18,10 +18,10 @@ int main(int argc, char *argv[]) {
   return arr[argc - 1];  // BOOM
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
   // CHECK: READ of size 4 at 0x{{.*}} thread T0
-  // CHECK:   #0 0x{{.*}} in main
+  // CHECK:   #0 0x{{.*}} in {{main|.main}}
   // CHECK:      {{.*}}use-after-scope-inlined.cpp:[[@LINE-4]]
   // CHECK: Address 0x{{.*}} is located in stack of thread T0 at offset [[OFFSET:[^ ]*]] in frame
-  // CHECK:      {{.*}} in main
+  // CHECK:      {{.*}} in {{main|.main}}
   // CHECK:   This frame has
   // CHECK:     {{\[}}[[OFFSET]], {{.*}}) 'x.i' (line [[@LINE-15]])
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-loop-bug.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-loop-bug.cpp
index 286b6441a5698..8b5dbfdd18f0e 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-loop-bug.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-loop-bug.cpp
@@ -10,7 +10,7 @@ int main() {
   }
   return *p;  // BOOM
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-  // CHECK:  #0 0x{{.*}} in main {{.*}}use-after-scope-loop-bug.cpp:[[@LINE-2]]
+  // CHECK:  #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope-loop-bug.cpp:[[@LINE-2]]
   // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame
   // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x'
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-loop-removed.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-loop-removed.cpp
index 8a8a7b60deb6b..9f9372f053bec 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-loop-removed.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-loop-removed.cpp
@@ -11,7 +11,7 @@ int main() {
   }
   return *p;  // BOOM
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-  // CHECK:  #0 0x{{.*}} in main {{.*}}use-after-scope-loop-removed.cpp:[[@LINE-2]]
+  // CHECK:  #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope-loop-removed.cpp:[[@LINE-2]]
   // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame
   // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x'
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-loop.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-loop.cpp
index 3e199056930cb..e1a739bdcc33b 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-loop.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-loop.cpp
@@ -9,5 +9,5 @@ int main() {
   }
   return **p;  // BOOM
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-  // CHECK: #0 0x{{.*}} in main {{.*}}.cpp:[[@LINE-2]]
+  // CHECK: #0 0x{{.*}} in {{main|.main}} {{.*}}.cpp:[[@LINE-2]]
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-temp.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-temp.cpp
index 29680f37bfa53..07aa98b5b6063 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-temp.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-temp.cpp
@@ -14,6 +14,6 @@ int main(int argc, char *argv[]) {
   save({argc});
   int x = saved->val;  // BOOM
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-  // CHECK:  #0 0x{{.*}} in main {{.*}}use-after-scope-temp.cpp:[[@LINE-2]]
+  // CHECK:  #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope-temp.cpp:[[@LINE-2]]
   return x;
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-temp2.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-temp2.cpp
index b98d6f12911a7..45ffd24ba4e30 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-temp2.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-temp2.cpp
@@ -13,6 +13,6 @@ int main(int argc, char *argv[]) {
   saved = &IntHolder().Self();
   int x = saved->val;  // BOOM
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-  // CHECK:  #0 0x{{.*}} in main {{.*}}use-after-scope-temp2.cpp:[[@LINE-2]]
+  // CHECK:  #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope-temp2.cpp:[[@LINE-2]]
   return x;
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp b/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp
index 5751a0a09bb4e..90ce1f45a8080 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope-types.cpp
@@ -41,7 +41,7 @@ template <class T> __attribute__((noinline)) void test() {
 
   ptr.Access();
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-  // CHECK:  #{{[0-9]+}} 0x{{.*}} in {{(void )?test.*\((void)?\) .*}}use-after-scope-types.cpp
+  // CHECK:  #{{[0-9]+}} 0x{{.*}} in {{(void |.void )?test.*\((void)?\) .*}}use-after-scope-types.cpp
   // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame
   // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x'
 }
diff --git a/compiler-rt/test/asan/TestCases/use-after-scope.cpp b/compiler-rt/test/asan/TestCases/use-after-scope.cpp
index eb61679d2b2aa..746788823e333 100644
--- a/compiler-rt/test/asan/TestCases/use-after-scope.cpp
+++ b/compiler-rt/test/asan/TestCases/use-after-scope.cpp
@@ -9,7 +9,7 @@ int main() {
   }
   *p = 5;  // BOOM
   // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
-  // CHECK:  #0 0x{{.*}} in main {{.*}}use-after-scope.cpp:[[@LINE-2]]
+  // CHECK:  #0 0x{{.*}} in {{main|.main}} {{.*}}use-after-scope.cpp:[[@LINE-2]]
   // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame
   // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x'
   return 0;
diff --git a/compiler-rt/test/asan/TestCases/zero_page_pc.cpp b/compiler-rt/test/asan/TestCases/zero_page_pc.cpp
index a7d00ce9b6988..71339f4ddb46f 100644
--- a/compiler-rt/test/asan/TestCases/zero_page_pc.cpp
+++ b/compiler-rt/test/asan/TestCases/zero_page_pc.cpp
@@ -5,6 +5,9 @@
 #  include <ptrauth.h>
 #endif
 
++// AIX reports illegal instruction error instead of SEGV while accesses address 0x4.
++// UNSUPPORTED: aix
+
 typedef void void_f();
 int main() {
   void_f *func = (void_f *)0x4;
diff --git a/compiler-rt/test/asan/lit.cfg.py b/compiler-rt/test/asan/lit.cfg.py
index c57f5ca0fa652..4103d80a57fdd 100644
--- a/compiler-rt/test/asan/lit.cfg.py
+++ b/compiler-rt/test/asan/lit.cfg.py
@@ -40,7 +40,7 @@ def get_required_attr(config, attr_name):
 # Setup source root.
 config.test_source_root = os.path.dirname(__file__)
 
-if config.host_os not in ["FreeBSD", "NetBSD"]:
+if config.host_os not in ["FreeBSD", "NetBSD", "AIX"]:
     libdl_flag = "-ldl"
 else:
     libdl_flag = ""
diff --git a/compiler-rt/test/lit.common.cfg.py b/compiler-rt/test/lit.common.cfg.py
index c6f27748ccb76..ab190a1ffb523 100644
--- a/compiler-rt/test/lit.common.cfg.py
+++ b/compiler-rt/test/lit.common.cfg.py
@@ -880,17 +880,35 @@ def is_windows_lto_supported():
             )
         )
         config.substitutions.append(("%ld_flags_rpath_so" + postfix, ""))
+    elif config.host_os == "AIX":
+         config.substitutions.append(
+             (
+                 "%ld_flags_rpath_exe" + postfix,
+                 "-L%T -l%xdynamiclib_namespec" + postfix,
+             )
+         )
+         config.substitutions.append(("%ld_flags_rpath_so" + postfix, ""))
 
     # Must be defined after the substitutions that use %dynamiclib.
     config.substitutions.append(
         ("%dynamiclib" + postfix, "%T/%xdynamiclib_filename" + postfix)
     )
-    config.substitutions.append(
-        (
-            "%xdynamiclib_filename" + postfix,
-            "lib%xdynamiclib_namespec{}.so".format(postfix),
-        )
-    )
+
+    if config.host_os == "AIX":
+         config.substitutions.append(
+             (
+                 "%xdynamiclib_filename" + postfix,
+                 "lib%xdynamiclib_namespec{}.a".format(postfix)
+             )
+         )
+    else:
+         config.substitutions.append(
+             (
+                 "%xdynamiclib_filename" + postfix,
+                 "lib%xdynamiclib_namespec{}.so".format(postfix),
+             )
+         )
+
     config.substitutions.append(("%xdynamiclib_namespec", "%basename_t.dynamic"))
 
 config.default_sanitizer_opts = []
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/arc4random.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/arc4random.cpp
index 5e95cbc331424..138c3b497d8ee 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/arc4random.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/arc4random.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: target={{.*(linux|solaris).*}}
+// aix does not define arc4random().
+// UNSUPPORTED: target={{.*(linux|solaris|aix).*}}
 
 #include <cstdlib>
 #include <ctime>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/create_thread_fail.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/create_thread_fail.cpp
index 8ed9b4ccf16c2..afb412368ec85 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/create_thread_fail.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/create_thread_fail.cpp
@@ -4,6 +4,9 @@
 // pthread_create with lsan i386 does not fail here.
 // UNSUPPORTED: i386-linux && lsan
 
+// pthread_create on AIX does not fail here.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <cassert>
 #include <pthread.h>
 #include <stdlib.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp
index deedbba76cdeb..d375a92a4c6a8 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cpp
@@ -33,6 +33,6 @@ int main(int argc, char **argv) {
 }
 
 // CHECK0-NOT: DEDUP_TOKEN:
-// CHECK1: DEDUP_TOKEN: void Xyz::Abc<int, int>()
-// CHECK2: DEDUP_TOKEN: void Xyz::Abc<int, int>()--bar
-// CHECK3: DEDUP_TOKEN: void Xyz::Abc<int, int>()--bar--FOO()
+// CHECK1: DEDUP_TOKEN: {{void|.void}} Xyz::Abc<int, int>()
+// CHECK2: DEDUP_TOKEN: {{void|.void}} Xyz::Abc<int, int>()--{{bar|.bar}}
+// CHECK3: DEDUP_TOKEN: {{void|.void}} Xyz::Abc<int, int>()--{{bar|.bar}}--{{FOO|.FOO}}()
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/devname.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/devname.cpp
index 8a34de5e31061..aaa461fe2aea0 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/devname.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/devname.cpp
@@ -1,5 +1,6 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
-// UNSUPPORTED: target={{.*(linux|solaris).*}}
+// AIX does not define devname_r()
+// UNSUPPORTED: target={{.*(linux|solaris|aix).*}}
 
 #include <assert.h>
 #include <stdio.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/devname_r.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/devname_r.cpp
index 5f0968e2be55b..017dbdcae3fe0 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/devname_r.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/devname_r.cpp
@@ -1,5 +1,6 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
-// UNSUPPORTED: target={{.*(linux|solaris).*}}
+// AIX does not define devname_r.
+// UNSUPPORTED: target={{.*(linux|solaris|aix).*}}
 
 #include <sys/cdefs.h>
 #include <sys/stat.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fgetln.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fgetln.cpp
index 68b4ad5b887d1..59996e7d17e44 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fgetln.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fgetln.cpp
@@ -1,6 +1,6 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t
 // fgetln is BSD-only.
-// UNSUPPORTED: target={{.*(linux|solaris).*}}
+// UNSUPPORTED: target={{.*(linux|solaris|aix).*}}
 
 #include <assert.h>
 #include <stdio.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fseek.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fseek.cpp
index 5de879d2392e2..ee8feced542a6 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fseek.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fseek.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}}
+// on AIX, fail even without -fsanitize=address
+// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}}
 
 #include <assert.h>
 #include <inttypes.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fts.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fts.cpp
index 795bc11a39e60..fbbca187ebb70 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fts.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fts.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}}
+// Header fts.h is not available on AIX.
+// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}}
 
 #include <sys/param.h>
 #include <sys/types.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/funopen.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/funopen.cpp
index 052cc19dff286..2523317af529b 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/funopen.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/funopen.cpp
@@ -11,7 +11,8 @@
 // CHECK-NEXT: READ CALLED; len={{[0-9]*}}
 // CHECK-NEXT: READ: test
 //
-// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}}
+// AIX does not define strlcpy.
+// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}}
 
 #include <assert.h>
 #include <stdio.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c
index e382cb5f714ed..6b422f6c6bdd4 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c
@@ -1,6 +1,7 @@
 // RUN: %clang -pthread %s -Wl,-as-needed -o %t && %run %t
 //
-// UNSUPPORTED: darwin, target={{.*solaris.*}}
+// as-needed is not a supported linker option on AIX.
+// UNSUPPORTED: darwin, target={{.*(solaris|aix).*}}
 
 #include <time.h>
 #include <unistd.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getfsent.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/getfsent.cpp
index 8df8b5726148b..6ab3170097f7e 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getfsent.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getfsent.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}}
+// The usage of getfsspec() on aix is not right in this file.
+// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}}
 
 #include <assert.h>
 #include <errno.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getmntinfo.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/getmntinfo.cpp
index 25d6310df2fb1..4a33288b11402 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getmntinfo.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getmntinfo.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: target={{.*(linux|solaris).*}}
+// AIX does not have header sys/mount.h.
+// UNSUPPORTED: target={{.*(linux|solaris|aix).*}}
 
 #include <sys/types.h>
 
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getpass.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/getpass.cpp
index 2711cfb112959..f0a3d183f2eea 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getpass.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getpass.cpp
@@ -7,7 +7,8 @@
 // XFAIL: android && asan
 
 // No libutil.
-// UNSUPPORTED: target={{.*solaris.*}}
+// AIX does not have util.h
+// UNSUPPORTED: target={{.*(solaris|aix).*}}
 
 #include <assert.h>
 #include <stdio.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cpp
index 848774a8909bd..7d614e748e597 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getpw_getgr.cpp
@@ -81,7 +81,7 @@ int main(int argc, const char *argv[]) {
   setgrent();
   test<group>(&getgrent);
 
-#if !defined(__APPLE__) && !(defined(__sun__) && defined(__svr4__))
+#if !defined(__APPLE__) && !(defined(__sun__) && defined(__svr4__)) && !defined(_AIX)
   setpwent();
   test_r<passwd>(&getpwent_r);
   setgrent();
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/huge_malloc.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/huge_malloc.c
index 16ebeda5315e0..883ea6261bb41 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/huge_malloc.c
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/huge_malloc.c
@@ -15,6 +15,9 @@
 // FIXME: Something wrong with MADV_FREE or MAP_NORESERVE there.
 // UNSUPPORTED: target={{.*solaris.*}}
 
+// Large calloc causes AIX kill all bash processes.
+// UNSUPPORTED: target={{.*aix.*}}
+
 void *p;
 
 int main(int argc, char **argv) {
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_read_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_read_test.cpp
index 45d3f256378fc..3c770064b2646 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_read_test.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_read_test.cpp
@@ -4,7 +4,7 @@
 // RUN: %clangxx -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
 
 // REQUIRES: stable-runtime
-// XFAIL: target={{(powerpc64|s390x).*}}
+// XFAIL: target={{(powerpc|powerpc64|s390x).*}}
 
 volatile int *null = 0;
 volatile int a;
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_write_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_write_test.cpp
index 9b94b8d0237ce..5995f0760601b 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_write_test.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/illegal_write_test.cpp
@@ -4,7 +4,7 @@
 // RUN: %clangxx -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
 
 // REQUIRES: stable-runtime
-// XFAIL: target={{(powerpc64|s390x).*}}
+// XFAIL: target={{(powerpc|powerpc64|s390x).*}}
 
 volatile int *null = 0;
 
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/posix_spawn.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/posix_spawn.c
index ea58b92af6097..838dc89a86b88 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/posix_spawn.c
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/posix_spawn.c
@@ -3,6 +3,9 @@
 // Older versions of Android do not have certain posix_spawn* functions.
 // UNSUPPORTED: android
 
+// AIX reports EINVAL for the posix_spawnp() even without asan.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <spawn.h>
 #include <stdio.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/setvbuf.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/setvbuf.cpp
index b7bcdf15499d2..20db3166032a1 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/setvbuf.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/setvbuf.cpp
@@ -2,6 +2,9 @@
 
 // UNSUPPORTED: target={{.*solaris.*}}
 
+// AIX can get "setvbuf" printed but after `FileCheck` can not find it after "2>&1 |"
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <stdio.h>
 
 void print_something() {
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp
index e96717f3b267c..26f5f366e06dc 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/signal.cpp
@@ -1,5 +1,8 @@
 // RUN: %clangxx -std=c++11 -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 
+// line 73 signal(SIGRTMAX + 1, &signal_handler) will not fail on AIX, SIGRTMAX + 1 is a valid signal.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <climits>
 #include <errno.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/sl_add.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/sl_add.cpp
index 6c14add8c4078..dc6e04bb81986 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/sl_add.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/sl_add.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}}
+// AIX does not have stringlist.h.
+// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}}
 
 #include <assert.h>
 #include <errno.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcat.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcat.cpp
index b026f12f35fca..4ed823bc4c053 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcat.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcat.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t
 
-// UNSUPPORTED: target={{.*linux.*}}
+// AIX does not define strlcat.
+// UNSUPPORTED: target={{.*(linux|aix).*}}
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcpy.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcpy.cpp
index d7a5d1d3a51e9..a3ad20d897335 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcpy.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/strlcpy.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t
 
-// UNSUPPORTED: target={{.*linux.*}}
+// AIX does not define strlcpy.
+// UNSUPPORTED: target={{.*(linux|aix).*}}
 
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/strtonum.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/strtonum.cpp
index a4f013096c596..0052d8103f464 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/strtonum.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/strtonum.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: darwin, target={{.*(linux|solaris).*}}
+// AIX does not define strtonum
+// UNSUPPORTED: darwin, target={{.*(linux|solaris|aix).*}}
 
 #define _OPENBSD_SOURCE
 
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/sysctl.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/sysctl.cpp
index 38c34259bbae0..0f4e94dd9f562 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/sysctl.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/sysctl.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: linux, target={{.*solaris.*}}
+// AIX does not have sys/sysctl.h
+// UNSUPPORTED: linux, target={{.*(solaris|aix).*}}
 
 #include <sys/param.h>
 #include <sys/types.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/vis.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/vis.cpp
index 0d31082f92b25..96b9e4270fcbf 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/vis.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/vis.cpp
@@ -1,6 +1,7 @@
 // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
 //
-// UNSUPPORTED: target={{.*(linux|solaris).*}}, darwin
+// AIX does not have err.h
+// UNSUPPORTED: target={{.*(linux|solaris|aix).*}}, darwin
 
 #include <ctype.h>
 #include <err.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/wcsdup.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/wcsdup.c
index e26aad855621c..36b7a574775a1 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/wcsdup.c
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/wcsdup.c
@@ -1,5 +1,12 @@
 // RUN: %clang %s -o %t && %run %t 2>&1
 
+// wcsdup internally calls malloc defined in libc library, however
+// aix sanitizers can not intercept functions used in shared libraries,
+// so the malloc is not intercepted and this case get error for the free:
+// AddressSanitizer: attempting free on address which was not malloc()-ed:
+//
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <stdlib.h>
 #include <wchar.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/weak_hook_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/weak_hook_test.cpp
index e95de739fe784..21fd18090c7dd 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/weak_hook_test.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/weak_hook_test.cpp
@@ -7,6 +7,9 @@
 // FIXME: Implement.
 // XFAIL: hwasan
 
+// AIX does not define strcasestr.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <assert.h>
 #include <string.h>
 #if defined(_GNU_SOURCE)
diff --git a/compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp b/compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp
index ca6f637b9a3f5..0be4099e2a2c0 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/allocator_returns_null.cpp
@@ -38,6 +38,9 @@
 // TODO(alekseyshl): win32 is disabled due to failing errno tests, fix it there.
 // UNSUPPORTED: ubsan, target={{.*windows-msvc.*}}
 
+// The llvm-symbolizer on AIX can not symbolize the pc to asan's source.
+// XFAIL: target={{.*aix.*}}
+
 #include <assert.h>
 #include <errno.h>
 #include <stdio.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp b/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp
index 4eb2247b1d38f..343c1edbfb181 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cpp
@@ -17,6 +17,9 @@
 // THUMB starts background thead only for Asan.
 // XFAIL: target=thumb{{.*}} && !asan
 
+// AIX does not use background thread.
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp b/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp
index 2fde16fbed3d2..eb7ad6c68e644 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp
@@ -46,6 +46,9 @@
 // Symbolizer needs to allocated memory when reporting.
 // UNSUPPORTED: internal_symbolizer
 
+// The llvm-symbolizer on AIX can not symbolize the pc to asan's source.
+// XFAIL: target={{.*aix.*}}
+
 #include <assert.h>
 #include <errno.h>
 #include <limits>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp b/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp
index 9d7d03d81b531..c35a5cb59e129 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/print-stack-trace.cpp
@@ -19,15 +19,15 @@ int main() {
   FooBarBaz();
   return 0;
 }
-// CHECK: {{    #0 0x.* in __sanitizer_print_stack_trace}}
-// CHECK: {{    #1 0x.* in FooBarBaz(\(\))? .*}}print-stack-trace.cpp:[[@LINE-8]]
-// CHECK: {{    #2 0x.* in main.*}}print-stack-trace.cpp:[[@LINE-5]]
+// CHECK: {{    #0 0x.* in (__sanitizer_print_stack_trace|.__sanitizer_print_stack_trace)}}
+// CHECK: {{    #1 0x.* in (FooBarBaz|.FooBarBaz)(\(\))? .*}}print-stack-trace.cpp:[[@LINE-8]]
+// CHECK: {{    #2 0x.* in (main|.main).*}}print-stack-trace.cpp:[[@LINE-5]]
 
 // CUSTOM: frame1_lineno[[@LINE-11]]
 // CUSTOM: frame2_lineno[[@LINE-8]]
 
-// NOINLINE: #0 0x{{.*}} in __sanitizer_print_stack_trace
-// NOINLINE: #1 0x{{.*}} in main{{.*}}print-stack-trace.cpp:[[@LINE-15]]
+// NOINLINE: #0 0x{{.*}} in {{__sanitizer_print_stack_trace|.__sanitizer_print_stack_trace}}
+// NOINLINE: #1 0x{{.*}} in {{main|.main}}{{.*}}print-stack-trace.cpp:[[@LINE-15]]
 
 // NOSYMBOLIZE: frame:0 address:{{0x.*}}
 // NOSYMBOLIZE: frame:1 address:{{0x.*}}
diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_allowlist_ignorelist.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_allowlist_ignorelist.cpp
index 6fdd23b84432f..72590ad3d6343 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_allowlist_ignorelist.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_allowlist_ignorelist.cpp
@@ -7,6 +7,9 @@
 // XFAIL: ubsan,tsan
 // XFAIL: android && asan
 
+// FIXME: support -fsanitize-coverage on AIX
+// UNSUPPORTED: target={{.*aix.*}}
+
 // RUN: rm -rf %t_workdir
 // RUN: mkdir -p %t_workdir
 // RUN: cd %t_workdir
diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp
index 5223af07f18ae..7cda2275cfbd7 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_control_flow.cpp
@@ -6,6 +6,8 @@
 // RUN: %clangxx -O0 -std=c++11 -fsanitize-coverage=control-flow %s -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 
+// XFAIL: target={{.*aix.*}}
+
 #include <cstdint>
 #include <cstdio>
 #if __has_feature(ptrauth_calls)
diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline8bit_counter.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline8bit_counter.cpp
index 68eca85eb4d42..4579a8a8ee646 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline8bit_counter.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline8bit_counter.cpp
@@ -6,6 +6,8 @@
 // RUN: %clangxx -O0 %s -fsanitize-coverage=inline-8bit-counters,pc-table -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 
+// XFAIL: target={{.*aix.*}}
+
 #include <stdio.h>
 #include <stdint.h>
 #include <assert.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp
index d62ffe613b5b0..94b4cd3e93094 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_inline_bool_flag.cpp
@@ -6,6 +6,8 @@
 // RUN: %clangxx -O0 %s -fsanitize-coverage=inline-bool-flag,pc-table -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 
+// XFAIL: target={{.*aix.*}}
+
 #include <assert.h>
 #include <stdint.h>
 #include <stdio.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_stack_depth.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_stack_depth.cpp
index 29a63c0a92f32..889125421db6b 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_stack_depth.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_stack_depth.cpp
@@ -6,6 +6,8 @@
 // RUN:     %s -o %t
 // RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not Assertion{{.*}}failed
 
+// UNSUPPORTED: target={{.*aix.*}}
+
 #include <cstdint>
 #include <cstdio>
 #include <cassert>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard-dso.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard-dso.cpp
index f6ccbb6981352..8986dc1adca4c 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard-dso.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard-dso.cpp
@@ -6,6 +6,9 @@
 // XFAIL: tsan,darwin
 // XFAIL: android && asan
 
+// FIXME: support -fsanitize-coverage on AIX
+// UNSUPPORTED: target={{.*aix.*}}
+
 // RUN: rm -rf %t_workdir
 // RUN: mkdir -p %t_workdir
 // RUN: cd %t_workdir
diff --git a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard.cpp b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard.cpp
index 84c28e82f04ac..94508a939340a 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/sanitizer_coverage_trace_pc_guard.cpp
@@ -7,6 +7,9 @@
 // XFAIL: tsan
 // XFAIL: android && asan
 
+// FIXME: support -fsanitize-coverage on AIX
+// UNSUPPORTED: target={{.*aix.*}}
+
 // RUN: rm -rf %t_workdir
 // RUN: mkdir -p %t_workdir
 // RUN: cd %t_workdir
diff --git a/compiler-rt/test/sanitizer_common/TestCases/strcasestr.c b/compiler-rt/test/sanitizer_common/TestCases/strcasestr.c
index 8831977569b84..f3280a87dde93 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/strcasestr.c
+++ b/compiler-rt/test/sanitizer_common/TestCases/strcasestr.c
@@ -3,6 +3,9 @@
 // There's no interceptor for strcasestr on Windows
 // XFAIL: target={{.*windows-msvc.*}}
 
+// AIX does not define strcasestr
+// UNSUPPORTED: target={{.*aix.*}}
+
 #define _GNU_SOURCE
 #include <assert.h>
 #include <string.h>
diff --git a/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c b/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c
index 8e131054c2d4d..2bf5782db623c 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c
+++ b/compiler-rt/test/sanitizer_common/TestCases/suffix-log-path_test.c
@@ -19,4 +19,4 @@ int main(int argc, char **argv) {
   __sanitizer_print_stack_trace();
   return 0;
 }
-// CHECK: #{{.*}} main
+// CHECK: #{{.*}} {{main|.main}}
diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp
index f495e2cefdd74..0bcb4115385c9 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc.cpp
@@ -72,12 +72,12 @@ int main() {
   // CHECK: PARTIAL '0x{{.*}}'
   SymbolizeSmallBuffer();
 
-  // CHECK: FIRST_FORMAT 0x{{.*}} in main symbolize_pc.cpp:[[@LINE+2]]
-  // CHECK: SECOND_FORMAT FUNC:main LINE:[[@LINE+1]] FILE:symbolize_pc.cpp
+  // CHECK: FIRST_FORMAT 0x{{.*}} in {{main|.main}} symbolize_pc.cpp:[[@LINE+2]]
+  // CHECK: SECOND_FORMAT FUNC:{{main|.main}} LINE:[[@LINE+1]] FILE:symbolize_pc.cpp
   SymbolizeCaller();
 
   struct s s;
-  // CHECK: SRET: FUNC:main LINE:[[@LINE+1]] FILE:symbolize_pc.cpp
+  // CHECK: SRET: FUNC:{{main|.main}} LINE:[[@LINE+1]] FILE:symbolize_pc.cpp
   s = SymbolizeSRet();
 
   // CHECK: GLOBAL: GLOBAL_VAR_ABC
diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp
index 6e035c16a3045..4133aacf9dc0a 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_demangle.cpp
@@ -22,8 +22,8 @@ struct Symbolizer {
   __attribute__((noinline)) ~Symbolizer() { Symbolize(); }
 };
 
-// NODEMANGLE: in _ZN10SymbolizerD2Ev
-// CHECK: in Symbolizer::~Symbolizer
+// NODEMANGLE: in {{_ZN10SymbolizerD2Ev|._ZN10SymbolizerD2Ev}}
+// CHECK: in {{Symbolizer::~Symbolizer|.Symbolizer::~Symbolizer}}
 int main() {
   Symbolizer();
   return 0;
diff --git a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp
index e95ef324db652..5baf695f1f99b 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/symbolize_pc_inline.cpp
@@ -18,7 +18,7 @@ __attribute__((noinline)) static void Symbolize() {
     printf("%s\n", p);
 }
 
-// NOINLINE: {{0x[0-9a-f]+}} in main symbolize_pc_inline.cpp:[[@LINE+2]]
+// NOINLINE: {{0x[0-9a-f]+}} in {{main|.main}} symbolize_pc_inline.cpp:[[@LINE+2]]
 // CHECK: [[ADDR:0x[0-9a-f]+]] in C2 symbolize_pc_inline.cpp:[[@LINE+1]]
 static inline void C2() { Symbolize(); }
 
@@ -28,5 +28,5 @@ static inline void C3() { C2(); }
 // CHECK: [[ADDR]] in C4 symbolize_pc_inline.cpp:[[@LINE+1]]
 static inline void C4() { C3(); }
 
-// CHECK: [[ADDR]] in main symbolize_pc_inline.cpp:[[@LINE+1]]
+// CHECK: [[ADDR]] in {{main|.main}} symbolize_pc_inline.cpp:[[@LINE+1]]
 int main() { C4(); }



More information about the llvm-commits mailing list