Propagating prior merge from 'llvm.org/release_50'.
diff --git a/README.txt b/README.txt
index fc88432..2d64f00 100644
--- a/README.txt
+++ b/README.txt
@@ -8,4 +8,3 @@
 terms of the license agreement found in LICENSE.txt.
 
 ================================
-
diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c
index d038bb9..553baad 100644
--- a/lib/profile/InstrProfilingFile.c
+++ b/lib/profile/InstrProfilingFile.c
@@ -14,6 +14,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <signal.h>
 #ifdef _MSC_VER
 /* For _alloca. */
 #include <malloc.h>
@@ -59,6 +60,7 @@
 }
 
 #define MAX_PID_SIZE 16
+#define MAX_SIGNAL_HANDLERS 16
 /* Data structure holding the result of parsed filename pattern. */
 typedef struct lprofFilename {
   /* File name string possibly with %p or %h specifiers. */
@@ -79,11 +81,13 @@
    * 2 profile data files. %1m is equivalent to %m. Also %m specifier
    * can only appear once at the end of the name pattern. */
   unsigned MergePoolSize;
+  char ExitOnSignals[MAX_SIGNAL_HANDLERS];
+  unsigned NumExitSignals;
   ProfileNameSpecifier PNS;
 } lprofFilename;
 
-COMPILER_RT_WEAK lprofFilename lprofCurFilename = {0, 0, 0, {0}, {0},
-                                                   0, 0, 0, PNS_unknown};
+COMPILER_RT_WEAK lprofFilename lprofCurFilename = {
+    0, 0, 0, {0}, {0}, 0, 0, 0, {0}, 0, PNS_unknown};
 
 int getpid(void);
 static int getCurFilenameLength();
@@ -278,6 +282,19 @@
   fclose(File);
 }
 
+static void exitSignalHandler(int sig) {
+  (void)sig;
+  exit(0);
+}
+
+static void installExitSignalHandlers(void) {
+  unsigned I;
+  for (I = 0; I < lprofCurFilename.NumExitSignals; ++I) {
+    lprofInstallSignalHandler(lprofCurFilename.ExitOnSignals[I],
+                              exitSignalHandler);
+  }
+}
+
 static const char *DefaultProfileName = "default.profraw";
 static void resetFilenameToDefault(void) {
   if (lprofCurFilename.FilenamePat && lprofCurFilename.OwnsFilenamePat) {
@@ -288,14 +305,25 @@
   lprofCurFilename.PNS = PNS_default;
 }
 
+static int isDigit(char C) { return C >= '0' && C <= '9'; }
+
+static int isNonZeroDigit(char C) { return C >= '1' && C <= '9'; }
+
 static int containsMergeSpecifier(const char *FilenamePat, int I) {
   return (FilenamePat[I] == 'm' ||
-          (FilenamePat[I] >= '1' && FilenamePat[I] <= '9' &&
+          (isNonZeroDigit(FilenamePat[I]) &&
            /* If FilenamePat[I] is not '\0', the next byte is guaranteed
             * to be in-bound as the string is null terminated. */
            FilenamePat[I + 1] == 'm'));
 }
 
+static int containsExitOnSignalSpecifier(const char *FilenamePat, int I) {
+  if (!isNonZeroDigit(FilenamePat[I]))
+    return 0;
+  return (FilenamePat[I + 1] == 'x') ||
+         (isDigit(FilenamePat[I + 1]) && FilenamePat[I + 2] == 'x');
+}
+
 /* Parses the pattern string \p FilenamePat and stores the result to
  * lprofcurFilename structure. */
 static int parseFilenamePattern(const char *FilenamePat,
@@ -304,6 +332,7 @@
   char *PidChars = &lprofCurFilename.PidChars[0];
   char *Hostname = &lprofCurFilename.Hostname[0];
   int MergingEnabled = 0;
+  char SignalNo;
 
   /* Clean up cached prefix.  */
   if (lprofCurFilename.ProfilePathPrefix)
@@ -353,6 +382,22 @@
           lprofCurFilename.MergePoolSize = FilenamePat[I] - '0';
           I++; /* advance to 'm' */
         }
+      } else if (containsExitOnSignalSpecifier(FilenamePat, I)) {
+        if (lprofCurFilename.NumExitSignals == MAX_SIGNAL_HANDLERS) {
+          PROF_WARN("%%x specifier has been specified too many times in %s.\n",
+                    FilenamePat);
+          return -1;
+        }
+        /* Grab the signal number. */
+        SignalNo = FilenamePat[I] - '0';
+        I++; /* advance to either another digit, or 'x' */
+        if (FilenamePat[I] != 'x') {
+          SignalNo = (SignalNo * 10) + (FilenamePat[I] - '0');
+          I++; /* advance to 'x' */
+        }
+        lprofCurFilename.ExitOnSignals[lprofCurFilename.NumExitSignals] =
+            SignalNo;
+        ++lprofCurFilename.NumExitSignals;
       }
     }
 
@@ -396,6 +441,7 @@
   }
 
   truncateCurrentFile();
+  installExitSignalHandlers();
 }
 
 /* Return buffer length that is required to store the current profile
@@ -404,11 +450,12 @@
 #define SIGLEN 24
 static int getCurFilenameLength() {
   int Len;
+  unsigned I;
   if (!lprofCurFilename.FilenamePat || !lprofCurFilename.FilenamePat[0])
     return 0;
 
   if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts ||
-        lprofCurFilename.MergePoolSize))
+        lprofCurFilename.MergePoolSize || lprofCurFilename.NumExitSignals))
     return strlen(lprofCurFilename.FilenamePat);
 
   Len = strlen(lprofCurFilename.FilenamePat) +
@@ -416,6 +463,11 @@
         lprofCurFilename.NumHosts * (strlen(lprofCurFilename.Hostname) - 2);
   if (lprofCurFilename.MergePoolSize)
     Len += SIGLEN;
+  for (I = 0; I < lprofCurFilename.NumExitSignals; ++I) {
+    Len -= 3; /* Drop the '%', signal number, and the 'x'. */
+    if (lprofCurFilename.ExitOnSignals[I] >= 10)
+      --Len; /* Drop the second digit of the signal number. */
+  }
   return Len;
 }
 
@@ -431,7 +483,7 @@
     return 0;
 
   if (!(lprofCurFilename.NumPids || lprofCurFilename.NumHosts ||
-        lprofCurFilename.MergePoolSize))
+        lprofCurFilename.MergePoolSize || lprofCurFilename.NumExitSignals))
     return lprofCurFilename.FilenamePat;
 
   PidLength = strlen(lprofCurFilename.PidChars);
@@ -457,6 +509,9 @@
         J += S;
         if (FilenamePat[I] != 'm')
           I++;
+      } else if (containsExitOnSignalSpecifier(FilenamePat, I)) {
+        while (FilenamePat[I] != 'x')
+          ++I;
       }
       /* Drop any unknown substitutions. */
     } else
diff --git a/lib/profile/InstrProfilingUtil.c b/lib/profile/InstrProfilingUtil.c
index fb68f30..b8c1269 100644
--- a/lib/profile/InstrProfilingUtil.c
+++ b/lib/profile/InstrProfilingUtil.c
@@ -26,6 +26,7 @@
 #include <sys/utsname.h>
 #endif
 
+#include <signal.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -225,6 +226,24 @@
   return Sep;
 }
 
+COMPILER_RT_VISIBILITY void lprofInstallSignalHandler(int sig,
+                                                      void (*handler)(int)) {
+#ifdef _WIN32
+  void (*err)(int) = signal(sig, handler);
+  if (err == SIG_ERR)
+    PROF_WARN("Unable to install an exit signal handler for %d (errno = %d).\n",
+              sig, errno);
+#else
+  struct sigaction sigact;
+  memset(&sigact, 0, sizeof(sigact));
+  sigact.sa_handler = handler;
+  int err = sigaction(sig, &sigact, NULL);
+  if (err)
+    PROF_WARN("Unable to install an exit signal handler for %d (errno = %d).\n",
+              sig, err);
+#endif
+}
+
 COMPILER_RT_VISIBILITY int lprofSuspendSigKill() {
 #if defined(__linux__)
   int PDeachSig = 0;
diff --git a/lib/profile/InstrProfilingUtil.h b/lib/profile/InstrProfilingUtil.h
index 9698599..61e3020 100644
--- a/lib/profile/InstrProfilingUtil.h
+++ b/lib/profile/InstrProfilingUtil.h
@@ -51,6 +51,8 @@
 unsigned lprofBoolCmpXchg(void **Ptr, void *OldV, void *NewV);
 void *lprofPtrFetchAdd(void **Mem, long ByteIncr);
 
+void lprofInstallSignalHandler(int sig, void(*handler)(int));
+
 /* Temporarily suspend SIGKILL. Return value of 1 means a restore is needed.
  * Other return values mean no restore is needed.
  */
diff --git a/lib/ubsan/ubsan_checks.inc b/lib/ubsan/ubsan_checks.inc
index 0a87e6e..73c6936 100644
--- a/lib/ubsan/ubsan_checks.inc
+++ b/lib/ubsan/ubsan_checks.inc
@@ -29,6 +29,7 @@
 UBSAN_CHECK(IntegerDivideByZero, "integer-divide-by-zero",
             "integer-divide-by-zero")
 UBSAN_CHECK(FloatDivideByZero, "float-divide-by-zero", "float-divide-by-zero")
+UBSAN_CHECK(InvalidBuiltin, "invalid-builtin-use", "invalid-builtin-use")
 UBSAN_CHECK(InvalidShiftBase, "invalid-shift-base", "shift-base")
 UBSAN_CHECK(InvalidShiftExponent, "invalid-shift-exponent", "shift-exponent")
 UBSAN_CHECK(OutOfBoundsIndex, "out-of-bounds-index", "bounds")
diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc
index 75a4490..06438a5 100644
--- a/lib/ubsan/ubsan_handlers.cc
+++ b/lib/ubsan/ubsan_handlers.cc
@@ -437,6 +437,30 @@
   Die();
 }
 
+static void handleInvalidBuiltin(InvalidBuiltinData *Data, ReportOptions Opts) {
+  SourceLocation Loc = Data->Loc.acquire();
+  ErrorType ET = ErrorType::InvalidBuiltin;
+
+  if (ignoreReport(Loc, Opts, ET))
+    return;
+
+  ScopedReport R(Opts, Loc, ET);
+
+  Diag(Loc, DL_Error,
+       "passing zero to %0, which is not a valid argument")
+    << ((Data->Kind == BCK_CTZPassedZero) ? "ctz()" : "clz()");
+}
+
+void __ubsan::__ubsan_handle_invalid_builtin(InvalidBuiltinData *Data) {
+  GET_REPORT_OPTIONS(true);
+  handleInvalidBuiltin(Data, Opts);
+}
+void __ubsan::__ubsan_handle_invalid_builtin_abort(InvalidBuiltinData *Data) {
+  GET_REPORT_OPTIONS(true);
+  handleInvalidBuiltin(Data, Opts);
+  Die();
+}
+
 static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
                                        ValueHandle Function,
                                        ReportOptions Opts) {
diff --git a/lib/ubsan/ubsan_handlers.h b/lib/ubsan/ubsan_handlers.h
index 796321b..5a9e902 100644
--- a/lib/ubsan/ubsan_handlers.h
+++ b/lib/ubsan/ubsan_handlers.h
@@ -122,6 +122,21 @@
 /// \brief Handle a load of an invalid value for the type.
 RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val)
 
+/// Known builtin check kinds.
+/// Keep in sync with the enum of the same name in CodeGenFunction.h
+enum BuiltinCheckKind : unsigned char {
+  BCK_CTZPassedZero,
+  BCK_CLZPassedZero,
+};
+
+struct InvalidBuiltinData {
+  SourceLocation Loc;
+  unsigned char Kind;
+};
+
+/// Handle a builtin called in an invalid way.
+RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data)
+
 struct FunctionTypeMismatchData {
   SourceLocation Loc;
   const TypeDescriptor &Type;
diff --git a/lib/ubsan/ubsan_interface.inc b/lib/ubsan/ubsan_interface.inc
index a69ca57..4c8f92e 100644
--- a/lib/ubsan/ubsan_interface.inc
+++ b/lib/ubsan/ubsan_interface.inc
@@ -19,6 +19,8 @@
 INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow_abort)
 INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch)
 INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort)
+INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin)
+INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin_abort)
 INTERFACE_FUNCTION(__ubsan_handle_load_invalid_value)
 INTERFACE_FUNCTION(__ubsan_handle_load_invalid_value_abort)
 INTERFACE_FUNCTION(__ubsan_handle_missing_return)
diff --git a/test/lit.common.cfg b/test/lit.common.cfg
index 6080edc..5f89000 100644
--- a/test/lit.common.cfg
+++ b/test/lit.common.cfg
@@ -87,6 +87,9 @@
 if re.match(r'^x86_64.*-linux', config.target_triple):
       config.available_features.add("x86_64-linux")
 
+if lit.util.isMacOSTriple(config.target_triple):
+   config.available_features.add('darwin')
+
 # Use ugly construction to explicitly prohibit "clang", "clang++" etc.
 # in RUN lines.
 config.substitutions.append(
diff --git a/test/profile/instrprof-exit-on-signal.c b/test/profile/instrprof-exit-on-signal.c
new file mode 100644
index 0000000..efe1013
--- /dev/null
+++ b/test/profile/instrprof-exit-on-signal.c
@@ -0,0 +1,26 @@
+// RUN: %clang_profgen -o %t %s
+//
+// Verify SIGTERM handling.
+// RUN: %run LLVM_PROFILE_FILE="%15x%t.profraw" %t 15
+// RUN: llvm-profdata show %t.profraw | FileCheck %s
+//
+// Verify SIGUSR1 handling.
+// RUN: %run LLVM_PROFILE_FILE="%30x%t.profraw" %t 30
+// RUN: llvm-profdata show %t.profraw | FileCheck %s
+
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+// CHECK: Total functions: 1
+int main(int argc, char **argv) {
+  (void)argc;
+
+  int sig = atoi(argv[1]);
+  kill(getpid(), sig);
+  
+  while (1) {
+    /* loop forever */
+  }
+  return 1;
+}
diff --git a/test/ubsan/TestCases/Misc/builtins.cpp b/test/ubsan/TestCases/Misc/builtins.cpp
new file mode 100644
index 0000000..18c68b5
--- /dev/null
+++ b/test/ubsan/TestCases/Misc/builtins.cpp
@@ -0,0 +1,35 @@
+// REQUIRES: arch=x86_64
+//
+// RUN: %clangxx -fsanitize=builtin -w %s -O3 -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+// RUN: %clangxx -fsanitize=builtin -fno-sanitize-recover=builtin -w %s -O3 -o %t.abort
+// RUN: not %run %t.abort 2>&1 | FileCheck %s --check-prefix=ABORT
+
+void check_ctz(int n) {
+  // ABORT: builtins.cpp:[[@LINE+2]]:17: runtime error: passing zero to ctz(), which is not a valid argument
+  // RECOVER: builtins.cpp:[[@LINE+1]]:17: runtime error: passing zero to ctz(), which is not a valid argument
+  __builtin_ctz(n);
+
+  // RECOVER: builtins.cpp:[[@LINE+1]]:18: runtime error: passing zero to ctz(), which is not a valid argument
+  __builtin_ctzl(n);
+
+  // RECOVER: builtins.cpp:[[@LINE+1]]:19: runtime error: passing zero to ctz(), which is not a valid argument
+  __builtin_ctzll(n);
+}
+
+void check_clz(int n) {
+  // RECOVER: builtins.cpp:[[@LINE+1]]:17: runtime error: passing zero to clz(), which is not a valid argument
+  __builtin_clz(n);
+
+  // RECOVER: builtins.cpp:[[@LINE+1]]:18: runtime error: passing zero to clz(), which is not a valid argument
+  __builtin_clzl(n);
+
+  // RECOVER: builtins.cpp:[[@LINE+1]]:19: runtime error: passing zero to clz(), which is not a valid argument
+  __builtin_clzll(n);
+}
+
+int main() {
+  check_ctz(0);
+  check_clz(0);
+  return 0;
+}
diff --git a/test/ubsan/TestCases/TypeCheck/PR33221.cpp b/test/ubsan/TestCases/TypeCheck/PR33221.cpp
index c691e5f..71da06c 100644
--- a/test/ubsan/TestCases/TypeCheck/PR33221.cpp
+++ b/test/ubsan/TestCases/TypeCheck/PR33221.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -frtti -fsanitize=vptr -g %s -O3 -o %t
+// RUN: %clangxx -frtti -fsanitize=null,vptr -g %s -O3 -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 
 // REQUIRES: cxxabi
diff --git a/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp b/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp
index 37ffe5b..898577d 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
+// RUN: %clangxx -frtti -fsanitize=vptr,null -fno-sanitize-recover=vptr,null -g %s -O3 -o %t
 // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-CORRUPTED-VTABLE --strict-whitespace
 
 // UNSUPPORTED: win32
diff --git a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
index 09deac1..f1fb111 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
+// RUN: %clangxx -frtti -fsanitize=null,vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t
 // RUN: not %run %t 2>&1 | FileCheck %s
 
 // REQUIRES: cxxabi
diff --git a/test/ubsan/TestCases/TypeCheck/vptr.cpp b/test/ubsan/TestCases/TypeCheck/vptr.cpp
index 53a79c9..183c7b7 100644
--- a/test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ b/test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false
+// RUN: %clangxx -frtti -fsanitize=null,vptr -fno-sanitize-recover=null,vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false
 // RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT
 // RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU
 // RUN: %run %t rS && %run %t rV && %run %t oV
@@ -9,7 +9,9 @@
 // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
 // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
 // RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
+// RUN: not %run %t nN 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMFUN --strict-whitespace
 
 // RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") > %t.supp
 // RUN: %env_ubsan_opts=suppressions='"%t.supp"' %run %t mS
@@ -99,6 +101,9 @@
   case 'V':
     p = reinterpret_cast<T*>(new U);
     break;
+  case 'N':
+    p = 0;
+    break;
   }
 
   access_p(p, argv[1][0]);
@@ -134,11 +139,11 @@
     // CHECK-Linux-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
     return p->b;
 
-    // CHECK-NULL-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
-    // CHECK-NULL-MEMBER-NEXT: [[PTR]]: note: object has invalid vptr
-    // CHECK-NULL-MEMBER-NEXT: {{^  ?.. .. .. ..  ?00 00 00 00  ?00 00 00 00  ?}}
-    // CHECK-NULL-MEMBER-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
-    // CHECK-NULL-MEMBER-NEXT: {{^              invalid vptr}}
+    // CHECK-INVALID-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T'
+    // CHECK-INVALID-MEMBER-NEXT: [[PTR]]: note: object has invalid vptr
+    // CHECK-INVALID-MEMBER-NEXT: {{^  ?.. .. .. ..  ?00 00 00 00  ?00 00 00 00  ?}}
+    // CHECK-INVALID-MEMBER-NEXT: {{^              \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}}
+    // CHECK-INVALID-MEMBER-NEXT: {{^              invalid vptr}}
     // CHECK-Linux-NULL-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE-7]]
 
   case 'f':
@@ -168,6 +173,10 @@
     // CHECK-Linux-DOWNCAST: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]]
     (void)static_cast<T*>(reinterpret_cast<S*>(p));
     return 0;
+
+  case 'n':
+    // CHECK-NULL-MEMFUN: vptr.cpp:[[@LINE+1]]:15: runtime error: member call on null pointer of type 'T'
+    return p->g();
   }
   return 0;
 }
diff --git a/test/ubsan/lit.common.cfg b/test/ubsan/lit.common.cfg
index e3a1367..b55fb5f 100644
--- a/test/ubsan/lit.common.cfg
+++ b/test/ubsan/lit.common.cfg
@@ -77,3 +77,5 @@
 # because the test hangs or fails on one configuration and not the other.
 if config.target_arch.startswith('arm') == False and config.target_arch != 'aarch64':
   config.available_features.add('stable-runtime')
+
+config.available_features.add('arch=' + config.target_arch)