aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-04-22 13:38:13 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-04-22 13:38:13 +0000
commit86321b98854d834e516cc65ddd09ef53e930fc4c (patch)
tree41cca4d40c59161100bc4ddad210a20a65b90d57
parent8a37c71e9d8855c91b9ef296ed389248f960bb52 (diff)
-rw-r--r--clang/lib/Format/Format.cpp10
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp9
-rw-r--r--compiler-rt/lib/asan/asan_interceptors.cpp47
-rw-r--r--compiler-rt/lib/asan/asan_internal.h2
-rw-r--r--compiler-rt/lib/asan/asan_linux.cpp158
-rw-r--r--libcxx/include/__config2
-rw-r--r--libunwind/src/UnwindRegistersRestore.S4
-rw-r--r--llvm/include/llvm/TargetParser/AArch64TargetParser.h2
-rw-r--r--llvm/lib/CodeGen/StackProtector.cpp21
-rw-r--r--llvm/lib/Support/raw_ostream.cpp7
-rw-r--r--llvm/lib/Transforms/Scalar/SROA.cpp6
11 files changed, 151 insertions, 117 deletions
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 0d3fde90ab38..a59d53009eaa 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -721,23 +721,23 @@ template <> struct MappingTraits<FormatStyle::TrailingCommentsAlignmentStyle> {
FormatStyle::TrailingCommentsAlignmentStyle &Value) {
IO.enumCase(Value, "Leave",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Leave, 1}));
+ {FormatStyle::TCAS_Leave, 0}));
IO.enumCase(Value, "Always",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Always, 1}));
+ {FormatStyle::TCAS_Always, 0}));
IO.enumCase(Value, "Never",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Never, 1}));
+ {FormatStyle::TCAS_Never, 0}));
// For backwards compatibility
IO.enumCase(Value, "true",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Always, 1}));
+ {FormatStyle::TCAS_Always, 0}));
IO.enumCase(Value, "false",
FormatStyle::TrailingCommentsAlignmentStyle(
- {FormatStyle::TCAS_Never, 1}));
+ {FormatStyle::TCAS_Never, 0}));
}
static void mapping(IO &IO,
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index ca651eaa9440..464594bf7488 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -399,8 +399,7 @@ private:
FormatToken *Next = CurrentToken->Next;
if (PrevPrev && PrevPrev->is(tok::identifier) &&
Prev->isOneOf(tok::star, tok::amp, tok::ampamp) &&
- CurrentToken->is(tok::identifier) &&
- !Next->isOneOf(tok::equal, tok::l_brace)) {
+ CurrentToken->is(tok::identifier) && Next->isNot(tok::equal)) {
Prev->setType(TT_BinaryOperator);
LookForDecls = false;
}
@@ -2399,12 +2398,6 @@ private:
return TT_PointerOrReference;
}
- // if (Class* obj { function() })
- if (PrevToken->Tok.isAnyIdentifier() && NextToken->Tok.isAnyIdentifier() &&
- NextToken->Next && NextToken->Next->is(tok::l_brace)) {
- return TT_PointerOrReference;
- }
-
if (PrevToken->endsSequence(tok::r_square, tok::l_square, tok::kw_delete))
return TT_UnaryOperator;
diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp
index 817008253fc0..776f512d08a0 100644
--- a/compiler-rt/lib/asan/asan_interceptors.cpp
+++ b/compiler-rt/lib/asan/asan_interceptors.cpp
@@ -257,12 +257,36 @@ static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
PoisonShadow(bottom, ssize, 0);
}
-INTERCEPTOR(int, getcontext, struct ucontext_t *ucp) {
- // API does not requires to have ucp clean, and sets only part of fields. We
- // use ucp->uc_stack to unpoison new stack. We prefer to have zeroes then
- // uninitialized bytes.
- ResetContextStack(ucp);
- return REAL(getcontext)(ucp);
+INTERCEPTOR(void, makecontext, struct ucontext_t *ucp, void (*func)(), int argc,
+ ...) {
+ va_list ap;
+ uptr args[64];
+ // We don't know a better way to forward ... into REAL function. We can
+ // increase args size if neccecary.
+ CHECK_LE(argc, ARRAY_SIZE(args));
+ internal_memset(args, 0, sizeof(args));
+ va_start(ap, argc);
+ for (int i = 0; i < argc; ++i) args[i] = va_arg(ap, uptr);
+ va_end(ap);
+
+# define ENUMERATE_ARRAY_4(start) \
+ args[start], args[start + 1], args[start + 2], args[start + 3]
+# define ENUMERATE_ARRAY_16(start) \
+ ENUMERATE_ARRAY_4(start), ENUMERATE_ARRAY_4(start + 4), \
+ ENUMERATE_ARRAY_4(start + 8), ENUMERATE_ARRAY_4(start + 12)
+# define ENUMERATE_ARRAY_64() \
+ ENUMERATE_ARRAY_16(0), ENUMERATE_ARRAY_16(16), ENUMERATE_ARRAY_16(32), \
+ ENUMERATE_ARRAY_16(48)
+
+ REAL(makecontext)
+ ((struct ucontext_t *)ucp, func, argc, ENUMERATE_ARRAY_64());
+
+# undef ENUMERATE_ARRAY_4
+# undef ENUMERATE_ARRAY_16
+# undef ENUMERATE_ARRAY_64
+
+ // Sign the stack so we can identify it for unpoisoning.
+ SignContextStack(ucp);
}
INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
@@ -279,9 +303,6 @@ INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
ReadContextStack(ucp, &stack, &ssize);
ClearShadowMemoryForContextStack(stack, ssize);
- // See getcontext interceptor.
- ResetContextStack(oucp);
-
# if __has_attribute(__indirect_return__) && \
(defined(__x86_64__) || defined(__i386__))
int (*real_swapcontext)(struct ucontext_t *, struct ucontext_t *)
@@ -658,11 +679,11 @@ void InitializeAsanInterceptors() {
// Intecept jump-related functions.
ASAN_INTERCEPT_FUNC(longjmp);
-#if ASAN_INTERCEPT_SWAPCONTEXT
- ASAN_INTERCEPT_FUNC(getcontext);
+# if ASAN_INTERCEPT_SWAPCONTEXT
ASAN_INTERCEPT_FUNC(swapcontext);
-#endif
-#if ASAN_INTERCEPT__LONGJMP
+ ASAN_INTERCEPT_FUNC(makecontext);
+# endif
+# if ASAN_INTERCEPT__LONGJMP
ASAN_INTERCEPT_FUNC(_longjmp);
#endif
#if ASAN_INTERCEPT___LONGJMP_CHK
diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h
index 959fdec26042..a5348e35b297 100644
--- a/compiler-rt/lib/asan/asan_internal.h
+++ b/compiler-rt/lib/asan/asan_internal.h
@@ -105,8 +105,8 @@ void AsanApplyToGlobals(globals_op_fptr op, const void *needle);
void AsanOnDeadlySignal(int, void *siginfo, void *context);
+void SignContextStack(void *context);
void ReadContextStack(void *context, uptr *stack, uptr *ssize);
-void ResetContextStack(void *context);
void StopInitOrderChecking();
// Wrapper for TLS/TSD.
diff --git a/compiler-rt/lib/asan/asan_linux.cpp b/compiler-rt/lib/asan/asan_linux.cpp
index 4c01ff9e2ae8..e19b4479aaf3 100644
--- a/compiler-rt/lib/asan/asan_linux.cpp
+++ b/compiler-rt/lib/asan/asan_linux.cpp
@@ -15,55 +15,56 @@
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
SANITIZER_SOLARIS
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_premap_shadow.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_freebsd.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_procmaps.h"
-
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/mman.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <unwind.h>
-
-#if SANITIZER_FREEBSD
-#include <sys/link_elf.h>
-#endif
-
-#if SANITIZER_SOLARIS
-#include <link.h>
-#endif
-
-#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS
-#include <ucontext.h>
-extern "C" void* _DYNAMIC;
-#elif SANITIZER_NETBSD
-#include <link_elf.h>
-#include <ucontext.h>
+# include <dlfcn.h>
+# include <fcntl.h>
+# include <limits.h>
+# include <pthread.h>
+# include <stdio.h>
+# include <sys/mman.h>
+# include <sys/resource.h>
+# include <sys/syscall.h>
+# include <sys/time.h>
+# include <sys/types.h>
+# include <unistd.h>
+# include <unwind.h>
+
+# include "asan_interceptors.h"
+# include "asan_internal.h"
+# include "asan_premap_shadow.h"
+# include "asan_thread.h"
+# include "sanitizer_common/sanitizer_flags.h"
+# include "sanitizer_common/sanitizer_freebsd.h"
+# include "sanitizer_common/sanitizer_hash.h"
+# include "sanitizer_common/sanitizer_libc.h"
+# include "sanitizer_common/sanitizer_procmaps.h"
+
+# if SANITIZER_FREEBSD
+# include <sys/link_elf.h>
+# endif
+
+# if SANITIZER_SOLARIS
+# include <link.h>
+# endif
+
+# if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS
+# include <ucontext.h>
+extern "C" void *_DYNAMIC;
+# elif SANITIZER_NETBSD
+# include <link_elf.h>
+# include <ucontext.h>
extern Elf_Dyn _DYNAMIC;
-#else
-#include <sys/ucontext.h>
-#include <link.h>
+# else
+# include <link.h>
+# include <sys/ucontext.h>
extern ElfW(Dyn) _DYNAMIC[];
-#endif
+# endif
// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in
// 32-bit mode.
-#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) && \
- __FreeBSD_version <= 902001 // v9.2
-#define ucontext_t xucontext_t
-#endif
+# if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) && \
+ __FreeBSD_version <= 902001 // v9.2
+# define ucontext_t xucontext_t
+# endif
typedef enum {
ASAN_RT_VERSION_UNDEFINED = 0,
@@ -74,21 +75,21 @@ typedef enum {
// FIXME: perhaps also store abi version here?
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE
-asan_rt_version_t __asan_rt_version;
+asan_rt_version_t __asan_rt_version;
}
namespace __asan {
void InitializePlatformInterceptors() {}
void InitializePlatformExceptionHandlers() {}
-bool IsSystemHeapAddress (uptr addr) { return false; }
+bool IsSystemHeapAddress(uptr addr) { return false; }
void *AsanDoesNotSupportStaticLinkage() {
// This will fail to link with -static.
return &_DYNAMIC;
}
-#if ASAN_PREMAP_SHADOW
+# if ASAN_PREMAP_SHADOW
uptr FindPremappedShadowStart(uptr shadow_size_bytes) {
uptr granularity = GetMmapGranularity();
uptr shadow_start = reinterpret_cast<uptr>(&__asan_shadow);
@@ -98,14 +99,14 @@ uptr FindPremappedShadowStart(uptr shadow_size_bytes) {
UnmapFromTo(shadow_start + shadow_size, shadow_start + premap_shadow_size);
return shadow_start;
}
-#endif
+# endif
uptr FindDynamicShadowStart() {
uptr shadow_size_bytes = MemToShadowSize(kHighMemEnd);
-#if ASAN_PREMAP_SHADOW
+# if ASAN_PREMAP_SHADOW
if (!PremapShadowFailed())
return FindPremappedShadowStart(shadow_size_bytes);
-#endif
+# endif
return MapDynamicShadow(shadow_size_bytes, ASAN_SHADOW_SCALE,
/*min_shadow_base_alignment*/ 0, kHighMemEnd);
@@ -121,11 +122,11 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) {
ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
}
-#if SANITIZER_ANDROID
+# if SANITIZER_ANDROID
// FIXME: should we do anything for Android?
void AsanCheckDynamicRTPrereqs() {}
void AsanCheckIncompatibleRT() {}
-#else
+# else
static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size,
void *data) {
VReport(2, "info->dlpi_name = %s\tinfo->dlpi_addr = %p\n", info->dlpi_name,
@@ -154,7 +155,7 @@ static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size,
static bool IsDynamicRTName(const char *libname) {
return internal_strstr(libname, "libclang_rt.asan") ||
- internal_strstr(libname, "libasan.so");
+ internal_strstr(libname, "libasan.so");
}
static void ReportIncompatibleRT() {
@@ -170,9 +171,10 @@ void AsanCheckDynamicRTPrereqs() {
const char *first_dso_name = nullptr;
dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name);
if (first_dso_name && first_dso_name[0] && !IsDynamicRTName(first_dso_name)) {
- Report("ASan runtime does not come first in initial library list; "
- "you should either link runtime to your application or "
- "manually preload it with LD_PRELOAD.\n");
+ Report(
+ "ASan runtime does not come first in initial library list; "
+ "you should either link runtime to your application or "
+ "manually preload it with LD_PRELOAD.\n");
Die();
}
}
@@ -190,13 +192,14 @@ void AsanCheckIncompatibleRT() {
// as early as possible, otherwise ASan interceptors could bind to
// the functions in dynamic ASan runtime instead of the functions in
// system libraries, causing crashes later in ASan initialization.
- MemoryMappingLayout proc_maps(/*cache_enabled*/true);
+ MemoryMappingLayout proc_maps(/*cache_enabled*/ true);
char filename[PATH_MAX];
MemoryMappedSegment segment(filename, sizeof(filename));
while (proc_maps.Next(&segment)) {
if (IsDynamicRTName(segment.filename)) {
- Report("Your application is linked against "
- "incompatible ASan runtimes.\n");
+ Report(
+ "Your application is linked against "
+ "incompatible ASan runtimes.\n");
Die();
}
}
@@ -206,25 +209,36 @@ void AsanCheckIncompatibleRT() {
}
}
}
-#endif // SANITIZER_ANDROID
+# endif // SANITIZER_ANDROID
# if ASAN_INTERCEPT_SWAPCONTEXT
-void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
- ucontext_t *ucp = (ucontext_t*)context;
- *stack = (uptr)ucp->uc_stack.ss_sp;
- *ssize = ucp->uc_stack.ss_size;
+constexpr u32 kAsanContextStackFlagsMagic = 0x51260eea;
+
+static int HashContextStack(const ucontext_t &ucp) {
+ MurMur2Hash64Builder hash(kAsanContextStackFlagsMagic);
+ hash.add(reinterpret_cast<uptr>(ucp.uc_stack.ss_sp));
+ hash.add(ucp.uc_stack.ss_size);
+ return static_cast<int>(hash.get());
}
-void ResetContextStack(void *context) {
- ucontext_t *ucp = (ucontext_t *)context;
- ucp->uc_stack.ss_sp = nullptr;
- ucp->uc_stack.ss_size = 0;
+void SignContextStack(void *context) {
+ ucontext_t *ucp = reinterpret_cast<ucontext_t *>(context);
+ ucp->uc_stack.ss_flags = HashContextStack(*ucp);
}
-# endif // ASAN_INTERCEPT_SWAPCONTEXT
-void *AsanDlSymNext(const char *sym) {
- return dlsym(RTLD_NEXT, sym);
+void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
+ const ucontext_t *ucp = reinterpret_cast<const ucontext_t *>(context);
+ if (HashContextStack(*ucp) == ucp->uc_stack.ss_flags) {
+ *stack = reinterpret_cast<uptr>(ucp->uc_stack.ss_sp);
+ *ssize = ucp->uc_stack.ss_size;
+ return;
+ }
+ *stack = 0;
+ *ssize = 0;
}
+# endif // ASAN_INTERCEPT_SWAPCONTEXT
+
+void *AsanDlSymNext(const char *sym) { return dlsym(RTLD_NEXT, sym); }
bool HandleDlopenInit() {
// Not supported on this platform.
@@ -233,7 +247,7 @@ bool HandleDlopenInit() {
return false;
}
-} // namespace __asan
+} // namespace __asan
#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
// SANITIZER_SOLARIS
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 581ada45b3f0..5e30a42174af 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -38,7 +38,7 @@
// _LIBCPP_VERSION represents the version of libc++, which matches the version of LLVM.
// Given a LLVM release LLVM XX.YY.ZZ (e.g. LLVM 16.0.1 == 16.00.01), _LIBCPP_VERSION is
// defined to XXYYZZ.
-# define _LIBCPP_VERSION 160001
+# define _LIBCPP_VERSION 160002
# define _LIBCPP_CONCAT_IMPL(_X, _Y) _X##_Y
# define _LIBCPP_CONCAT(_X, _Y) _LIBCPP_CONCAT_IMPL(_X, _Y)
diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S
index 543b19f7e72a..951189ea54dd 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -1221,8 +1221,8 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv)
ld.d $r\i, $a0, (8 * \i)
.endr
- ld.d $r4, $a0, (8 * 4) // restore $a0 last
- ld.d $r1, $a0, (8 * 32) // load new pc into $ra
+ ld.d $ra, $a0, (8 * 32) // load new pc into $ra
+ ld.d $a0, $a0, (8 * 4) // restore $a0 last
jr $ra
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 11fce886ffb8..1326968e34de 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -177,7 +177,7 @@ inline constexpr ExtensionInfo Extensions[] = {
{"brbe", AArch64::AEK_BRBE, "+brbe", "-brbe", FEAT_MAX, "", 0},
{"bti", AArch64::AEK_NONE, {}, {}, FEAT_BTI, "+bti", 510},
{"crc", AArch64::AEK_CRC, "+crc", "-crc", FEAT_CRC, "+crc", 110},
- {"crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", FEAT_MAX, "", 0},
+ {"crypto", AArch64::AEK_CRYPTO, "+crypto", "-crypto", FEAT_MAX, "+aes,+sha2", 0},
{"cssc", AArch64::AEK_CSSC, "+cssc", "-cssc", FEAT_MAX, "", 0},
{"d128", AArch64::AEK_D128, "+d128", "-d128", FEAT_MAX, "", 0},
{"dgh", AArch64::AEK_NONE, {}, {}, FEAT_DGH, "", 260},
diff --git a/llvm/lib/CodeGen/StackProtector.cpp b/llvm/lib/CodeGen/StackProtector.cpp
index 46685f7b8208..c5cf6ae6578b 100644
--- a/llvm/lib/CodeGen/StackProtector.cpp
+++ b/llvm/lib/CodeGen/StackProtector.cpp
@@ -455,18 +455,15 @@ bool StackProtector::InsertStackProtectors() {
if (&BB == FailBB)
continue;
Instruction *CheckLoc = dyn_cast<ReturnInst>(BB.getTerminator());
- if (!CheckLoc && !DisableCheckNoReturn) {
- for (auto &Inst : BB) {
- auto *CB = dyn_cast<CallBase>(&Inst);
- if (!CB)
- continue;
- if (!CB->doesNotReturn())
- continue;
- // Do stack check before non-return calls (e.g: __cxa_throw)
- CheckLoc = CB;
- break;
- }
- }
+ if (!CheckLoc && !DisableCheckNoReturn)
+ for (auto &Inst : BB)
+ if (auto *CB = dyn_cast<CallBase>(&Inst))
+ // Do stack check before noreturn calls that aren't nounwind (e.g:
+ // __cxa_throw).
+ if (CB->doesNotReturn() && !CB->doesNotThrow()) {
+ CheckLoc = CB;
+ break;
+ }
if (!CheckLoc)
continue;
diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp
index 7b9b8b2f53fb..fae4a4308fd7 100644
--- a/llvm/lib/Support/raw_ostream.cpp
+++ b/llvm/lib/Support/raw_ostream.cpp
@@ -84,8 +84,15 @@ raw_ostream::~raw_ostream() {
}
size_t raw_ostream::preferred_buffer_size() const {
+#ifdef _WIN32
+ // On Windows BUFSIZ is only 512 which results in more calls to write. This
+ // overhead can cause significant performance degradation. Therefore use a
+ // better default.
+ return (16 * 1024);
+#else
// BUFSIZ is intended to be a reasonable default.
return BUFSIZ;
+#endif
}
void raw_ostream::SetBuffered() {
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 8339981e1bdc..818d64725893 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -1581,15 +1581,17 @@ static void rewriteMemOpOfSelect(SelectInst &SI, T &I,
bool IsThen = SuccBB == HeadBI->getSuccessor(0);
int SuccIdx = IsThen ? 0 : 1;
auto *NewMemOpBB = SuccBB == Tail ? Head : SuccBB;
+ auto &CondMemOp = cast<T>(*I.clone());
if (NewMemOpBB != Head) {
NewMemOpBB->setName(Head->getName() + (IsThen ? ".then" : ".else"));
if (isa<LoadInst>(I))
++NumLoadsPredicated;
else
++NumStoresPredicated;
- } else
+ } else {
+ CondMemOp.dropUndefImplyingAttrsAndUnknownMetadata();
++NumLoadsSpeculated;
- auto &CondMemOp = cast<T>(*I.clone());
+ }
CondMemOp.insertBefore(NewMemOpBB->getTerminator());
Value *Ptr = SI.getOperand(1 + SuccIdx);
if (auto *PtrTy = Ptr->getType();