LLVM 24.0.0git
MemorySanitizer.cpp
Go to the documentation of this file.
1//===- MemorySanitizer.cpp - detector of uninitialized reads --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// This file is a part of MemorySanitizer, a detector of uninitialized
11/// reads.
12///
13/// The algorithm of the tool is similar to Memcheck
14/// (https://static.usenix.org/event/usenix05/tech/general/full_papers/seward/seward_html/usenix2005.html)
15/// We associate a few shadow bits with every byte of the application memory,
16/// poison the shadow of the malloc-ed or alloca-ed memory, load the shadow,
17/// bits on every memory read, propagate the shadow bits through some of the
18/// arithmetic instruction (including MOV), store the shadow bits on every
19/// memory write, report a bug on some other instructions (e.g. JMP) if the
20/// associated shadow is poisoned.
21///
22/// But there are differences too. The first and the major one:
23/// compiler instrumentation instead of binary instrumentation. This
24/// gives us much better register allocation, possible compiler
25/// optimizations and a fast start-up. But this brings the major issue
26/// as well: msan needs to see all program events, including system
27/// calls and reads/writes in system libraries, so we either need to
28/// compile *everything* with msan or use a binary translation
29/// component (e.g. DynamoRIO) to instrument pre-built libraries.
30/// Another difference from Memcheck is that we use 8 shadow bits per
31/// byte of application memory and use a direct shadow mapping. This
32/// greatly simplifies the instrumentation code and avoids races on
33/// shadow updates (Memcheck is single-threaded so races are not a
34/// concern there. Memcheck uses 2 shadow bits per byte with a slow
35/// path storage that uses 8 bits per byte).
36///
37/// The default value of shadow is 0, which means "clean" (not poisoned).
38///
39/// Every module initializer should call __msan_init to ensure that the
40/// shadow memory is ready. On error, __msan_warning is called. Since
41/// parameters and return values may be passed via registers, we have a
42/// specialized thread-local shadow for return values
43/// (__msan_retval_tls) and parameters (__msan_param_tls).
44///
45/// Origin tracking.
46///
47/// MemorySanitizer can track origins (allocation points) of all uninitialized
48/// values. This behavior is controlled with a flag (msan-track-origins) and is
49/// disabled by default.
50///
51/// Origins are 4-byte values created and interpreted by the runtime library.
52/// They are stored in a second shadow mapping, one 4-byte value for 4 bytes
53/// of application memory. Propagation of origins is basically a bunch of
54/// "select" instructions that pick the origin of a dirty argument, if an
55/// instruction has one.
56///
57/// Every 4 aligned, consecutive bytes of application memory have one origin
58/// value associated with them. If these bytes contain uninitialized data
59/// coming from 2 different allocations, the last store wins. Because of this,
60/// MemorySanitizer reports can show unrelated origins, but this is unlikely in
61/// practice.
62///
63/// Origins are meaningless for fully initialized values, so MemorySanitizer
64/// avoids storing origin to memory when a fully initialized value is stored.
65/// This way it avoids needless overwriting origin of the 4-byte region on
66/// a short (i.e. 1 byte) clean store, and it is also good for performance.
67///
68/// Atomic handling.
69///
70/// Ideally, every atomic store of application value should update the
71/// corresponding shadow location in an atomic way. Unfortunately, atomic store
72/// of two disjoint locations can not be done without severe slowdown.
73///
74/// Therefore, we implement an approximation that may err on the safe side.
75/// In this implementation, every atomically accessed location in the program
76/// may only change from (partially) uninitialized to fully initialized, but
77/// not the other way around. We load the shadow _after_ the application load,
78/// and we store the shadow _before_ the app store. Also, we always store clean
79/// shadow (if the application store is atomic). This way, if the store-load
80/// pair constitutes a happens-before arc, shadow store and load are correctly
81/// ordered such that the load will get either the value that was stored, or
82/// some later value (which is always clean).
83///
84/// This does not work very well with Compare-And-Swap (CAS) and
85/// Read-Modify-Write (RMW) operations. To follow the above logic, CAS and RMW
86/// must store the new shadow before the app operation, and load the shadow
87/// after the app operation. Computers don't work this way. Current
88/// implementation ignores the load aspect of CAS/RMW, always returning a clean
89/// value. It implements the store part as a simple atomic store by storing a
90/// clean shadow.
91///
92/// Instrumenting inline assembly.
93///
94/// For inline assembly code LLVM has little idea about which memory locations
95/// become initialized depending on the arguments. It can be possible to figure
96/// out which arguments are meant to point to inputs and outputs, but the
97/// actual semantics can be only visible at runtime. In the Linux kernel it's
98/// also possible that the arguments only indicate the offset for a base taken
99/// from a segment register, so it's dangerous to treat any asm() arguments as
100/// pointers. We take a conservative approach generating calls to
101/// __msan_instrument_asm_store(ptr, size)
102/// , which defer the memory unpoisoning to the runtime library.
103/// The latter can perform more complex address checks to figure out whether
104/// it's safe to touch the shadow memory.
105/// Like with atomic operations, we call __msan_instrument_asm_store() before
106/// the assembly call, so that changes to the shadow memory will be seen by
107/// other threads together with main memory initialization.
108///
109/// KernelMemorySanitizer (KMSAN) implementation.
110///
111/// The major differences between KMSAN and MSan instrumentation are:
112/// - KMSAN always tracks the origins and implies msan-keep-going=true;
113/// - KMSAN allocates shadow and origin memory for each page separately, so
114/// there are no explicit accesses to shadow and origin in the
115/// instrumentation.
116/// Shadow and origin values for a particular X-byte memory location
117/// (X=1,2,4,8) are accessed through pointers obtained via the
118/// __msan_metadata_ptr_for_load_X(ptr)
119/// __msan_metadata_ptr_for_store_X(ptr)
120/// functions. The corresponding functions check that the X-byte accesses
121/// are possible and returns the pointers to shadow and origin memory.
122/// Arbitrary sized accesses are handled with:
123/// __msan_metadata_ptr_for_load_n(ptr, size)
124/// __msan_metadata_ptr_for_store_n(ptr, size);
125/// Note that the sanitizer code has to deal with how shadow/origin pairs
126/// returned by the these functions are represented in different ABIs. In
127/// the X86_64 ABI they are returned in RDX:RAX, in PowerPC64 they are
128/// returned in r3 and r4, and in the SystemZ ABI they are written to memory
129/// pointed to by a hidden parameter.
130/// - TLS variables are stored in a single per-task struct. A call to a
131/// function __msan_get_context_state() returning a pointer to that struct
132/// is inserted into every instrumented function before the entry block;
133/// - __msan_warning() takes a 32-bit origin parameter;
134/// - local variables are poisoned with __msan_poison_alloca() upon function
135/// entry and unpoisoned with __msan_unpoison_alloca() before leaving the
136/// function;
137/// - the pass doesn't declare any global variables or add global constructors
138/// to the translation unit.
139///
140/// Also, KMSAN currently ignores uninitialized memory passed into inline asm
141/// calls, making sure we're on the safe side wrt. possible false positives.
142///
143/// KernelMemorySanitizer only supports X86_64, SystemZ and PowerPC64 at the
144/// moment.
145///
146//
147// FIXME: This sanitizer does not yet handle scalable vectors
148//
149//===----------------------------------------------------------------------===//
150
153#include "llvm/ADT/APInt.h"
154#include "llvm/ADT/ArrayRef.h"
155#include "llvm/ADT/DenseMap.h"
157#include "llvm/ADT/SetVector.h"
158#include "llvm/ADT/SmallPtrSet.h"
159#include "llvm/ADT/SmallVector.h"
161#include "llvm/ADT/StringRef.h"
165#include "llvm/IR/Argument.h"
167#include "llvm/IR/Attributes.h"
168#include "llvm/IR/BasicBlock.h"
169#include "llvm/IR/CallingConv.h"
170#include "llvm/IR/Constant.h"
171#include "llvm/IR/Constants.h"
172#include "llvm/IR/DataLayout.h"
173#include "llvm/IR/DerivedTypes.h"
174#include "llvm/IR/Function.h"
175#include "llvm/IR/GlobalValue.h"
177#include "llvm/IR/IRBuilder.h"
178#include "llvm/IR/InlineAsm.h"
179#include "llvm/IR/InstVisitor.h"
180#include "llvm/IR/InstrTypes.h"
181#include "llvm/IR/Instruction.h"
182#include "llvm/IR/Instructions.h"
184#include "llvm/IR/Intrinsics.h"
185#include "llvm/IR/IntrinsicsAArch64.h"
186#include "llvm/IR/IntrinsicsX86.h"
187#include "llvm/IR/MDBuilder.h"
188#include "llvm/IR/Module.h"
189#include "llvm/IR/Type.h"
190#include "llvm/IR/Value.h"
191#include "llvm/IR/ValueMap.h"
194#include "llvm/Support/Casting.h"
195#include "llvm/Support/Debug.h"
205#include <algorithm>
206#include <cassert>
207#include <cstddef>
208#include <cstdint>
209#include <memory>
210#include <numeric>
211#include <string>
212#include <tuple>
213
214using namespace llvm;
215
216#define DEBUG_TYPE "msan"
217
218DEBUG_COUNTER(DebugInsertCheck, "msan-insert-check",
219 "Controls which checks to insert");
220
221DEBUG_COUNTER(DebugInstrumentInstruction, "msan-instrument-instruction",
222 "Controls which instruction to instrument");
223
224static const unsigned kOriginSize = 4;
227
228// These constants must be kept in sync with the ones in msan.h.
229// TODO: increase size to match SVE/SVE2/SME/SME2 limits
230static const unsigned kParamTLSSize = 800;
231static const unsigned kRetvalTLSSize = 800;
232
233// Accesses sizes are powers of two: 1, 2, 4, 8.
234static const size_t kNumberOfAccessSizes = 4;
235
236const char kMsanModuleCtorName[] = "msan.module_ctor";
237const char kMsanInitName[] = "__msan_init";
238
239namespace {
240
241// Memory map parameters used in application-to-shadow address calculation.
242// Offset = (Addr & ~AndMask) ^ XorMask
243// Shadow = ShadowBase + Offset
244// Origin = OriginBase + Offset
245struct MemoryMapParams {
246 uint64_t AndMask;
247 uint64_t XorMask;
248 uint64_t ShadowBase;
249 uint64_t OriginBase;
250};
251
252struct PlatformMemoryMapParams {
253 const MemoryMapParams *bits32;
254 const MemoryMapParams *bits64;
255};
256
257} // end anonymous namespace
258
259// i386 Linux
260static const MemoryMapParams Linux_I386_MemoryMapParams = {
261 0x000080000000, // AndMask
262 0, // XorMask (not used)
263 0, // ShadowBase (not used)
264 0x000040000000, // OriginBase
265};
266
267// x86_64 Linux
268static const MemoryMapParams Linux_X86_64_MemoryMapParams = {
269 0, // AndMask (not used)
270 0x500000000000, // XorMask
271 0, // ShadowBase (not used)
272 0x100000000000, // OriginBase
273};
274
275// mips32 Linux
276// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
277// after picking good constants
278
279// mips64 Linux
280static const MemoryMapParams Linux_MIPS64_MemoryMapParams = {
281 0, // AndMask (not used)
282 0x008000000000, // XorMask
283 0, // ShadowBase (not used)
284 0x002000000000, // OriginBase
285};
286
287// ppc32 Linux
288// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
289// after picking good constants
290
291// ppc64 Linux
292static const MemoryMapParams Linux_PowerPC64_MemoryMapParams = {
293 0xE00000000000, // AndMask
294 0x100000000000, // XorMask
295 0x080000000000, // ShadowBase
296 0x1C0000000000, // OriginBase
297};
298
299// s390x Linux
300static const MemoryMapParams Linux_S390X_MemoryMapParams = {
301 0xC00000000000, // AndMask
302 0, // XorMask (not used)
303 0x080000000000, // ShadowBase
304 0x1C0000000000, // OriginBase
305};
306
307// arm32 Linux
308// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
309// after picking good constants
310
311// aarch64 Linux
312static const MemoryMapParams Linux_AArch64_MemoryMapParams = {
313 0, // AndMask (not used)
314 0x0B00000000000, // XorMask
315 0, // ShadowBase (not used)
316 0x0200000000000, // OriginBase
317};
318
319// loongarch64 Linux
320static const MemoryMapParams Linux_LoongArch64_MemoryMapParams = {
321 0, // AndMask (not used)
322 0x500000000000, // XorMask
323 0, // ShadowBase (not used)
324 0x100000000000, // OriginBase
325};
326
327// hexagon Linux
328static const MemoryMapParams Linux_Hexagon_MemoryMapParams = {
329 0, // AndMask (not used)
330 0x20000000, // XorMask
331 0, // ShadowBase (not used)
332 0x50000000, // OriginBase
333};
334
335// riscv32 Linux
336// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
337// after picking good constants
338
339// aarch64 FreeBSD
340static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams = {
341 0x1800000000000, // AndMask
342 0x0400000000000, // XorMask
343 0x0200000000000, // ShadowBase
344 0x0700000000000, // OriginBase
345};
346
347// i386 FreeBSD
348static const MemoryMapParams FreeBSD_I386_MemoryMapParams = {
349 0x000180000000, // AndMask
350 0x000040000000, // XorMask
351 0x000020000000, // ShadowBase
352 0x000700000000, // OriginBase
353};
354
355// x86_64 FreeBSD
356static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams = {
357 0xc00000000000, // AndMask
358 0x200000000000, // XorMask
359 0x100000000000, // ShadowBase
360 0x380000000000, // OriginBase
361};
362
363// x86_64 NetBSD
364static const MemoryMapParams NetBSD_X86_64_MemoryMapParams = {
365 0, // AndMask
366 0x500000000000, // XorMask
367 0, // ShadowBase
368 0x100000000000, // OriginBase
369};
370
371static const PlatformMemoryMapParams Linux_X86_MemoryMapParams = {
374};
375
376static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams = {
377 nullptr,
379};
380
381static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams = {
382 nullptr,
384};
385
386static const PlatformMemoryMapParams Linux_S390_MemoryMapParams = {
387 nullptr,
389};
390
391static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams = {
392 nullptr,
394};
395
396static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams = {
397 nullptr,
399};
400
401static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P = {
403 nullptr,
404};
405
406static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams = {
407 nullptr,
409};
410
411static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams = {
414};
415
416static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams = {
417 nullptr,
419};
420
422
423namespace {
424
425/// Instrument functions of a module to detect uninitialized reads.
426///
427/// Instantiating MemorySanitizer inserts the msan runtime library API function
428/// declarations into the module if they don't exist already. Instantiating
429/// ensures the __msan_init function is in the list of global constructors for
430/// the module.
431class MemorySanitizer {
432public:
433 MemorySanitizer(const InstrumentationOptions &Opts, Module &M,
434 MemorySanitizerOptions Options)
435 : Opts(Opts), CompileKernel(Options.Kernel),
436 TrackOrigins(Options.TrackOrigins), Recover(Options.Recover),
437 EagerChecks(Options.EagerChecks) {
438 initializeModule(M);
439 }
440
441 // MSan cannot be moved or copied because of MapParams.
442 MemorySanitizer(MemorySanitizer &&) = delete;
443 MemorySanitizer &operator=(MemorySanitizer &&) = delete;
444 MemorySanitizer(const MemorySanitizer &) = delete;
445 MemorySanitizer &operator=(const MemorySanitizer &) = delete;
446
447 bool sanitizeFunction(Function &F, TargetLibraryInfo &TLI);
448
449private:
450 friend struct MemorySanitizerVisitor;
451 friend struct VarArgHelperBase;
452 friend struct VarArgAMD64Helper;
453 friend struct VarArgAArch64Helper;
454 friend struct VarArgPowerPC64Helper;
455 friend struct VarArgPowerPC32Helper;
456 friend struct VarArgSystemZHelper;
457 friend struct VarArgI386Helper;
458 friend struct VarArgGenericHelper;
459
460 void initializeModule(Module &M);
461 void initializeCallbacks(Module &M, const TargetLibraryInfo &TLI);
462 void createKernelApi(Module &M, const TargetLibraryInfo &TLI);
463 void createUserspaceApi(Module &M, const TargetLibraryInfo &TLI);
464
465 template <typename... ArgsTy>
466 FunctionCallee getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
467 ArgsTy... Args);
468
469 const InstrumentationOptions &Opts;
470 /// True if we're compiling the Linux kernel.
471 bool CompileKernel;
472 /// Track origins (allocation points) of uninitialized values.
473 int TrackOrigins;
474 bool Recover;
475 bool EagerChecks;
476
477 Triple TargetTriple;
478 LLVMContext *C;
479 Type *IntptrTy; ///< Integer type with the size of a ptr in default AS.
480 Type *OriginTy;
481 PointerType *PtrTy; ///< Integer type with the size of a ptr in default AS.
482
483 // XxxTLS variables represent the per-thread state in MSan and per-task state
484 // in KMSAN.
485 // For the userspace these point to thread-local globals. In the kernel land
486 // they point to the members of a per-task struct obtained via a call to
487 // __msan_get_context_state().
488
489 /// Thread-local shadow storage for function parameters.
490 Value *ParamTLS;
491
492 /// Thread-local origin storage for function parameters.
493 Value *ParamOriginTLS;
494
495 /// Thread-local shadow storage for function return value.
496 Value *RetvalTLS;
497
498 /// Thread-local origin storage for function return value.
499 Value *RetvalOriginTLS;
500
501 /// Thread-local shadow storage for in-register va_arg function.
502 Value *VAArgTLS;
503
504 /// Thread-local shadow storage for in-register va_arg function.
505 Value *VAArgOriginTLS;
506
507 /// Thread-local shadow storage for va_arg overflow area.
508 Value *VAArgOverflowSizeTLS;
509
510 /// Are the instrumentation callbacks set up?
511 bool CallbacksInitialized = false;
512
513 /// The run-time callback to print a warning.
514 FunctionCallee WarningFn;
515
516 // These arrays are indexed by log2(AccessSize).
517 FunctionCallee MaybeWarningFn[kNumberOfAccessSizes];
518 FunctionCallee MaybeWarningVarSizeFn;
519 FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes];
520
521 /// Run-time helper that generates a new origin value for a stack
522 /// allocation.
523 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
524 // No description version
525 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
526
527 /// Run-time helper that poisons stack on function entry.
528 FunctionCallee MsanPoisonStackFn;
529
530 /// Run-time helper that records a store (or any event) of an
531 /// uninitialized value and returns an updated origin id encoding this info.
532 FunctionCallee MsanChainOriginFn;
533
534 /// Run-time helper that paints an origin over a region.
535 FunctionCallee MsanSetOriginFn;
536
537 /// MSan runtime replacements for memmove, memcpy and memset.
538 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
539
540 /// KMSAN callback for task-local function argument shadow.
541 StructType *MsanContextStateTy;
542 FunctionCallee MsanGetContextStateFn;
543
544 /// Functions for poisoning/unpoisoning local variables
545 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
546
547 /// Pair of shadow/origin pointers.
548 Type *MsanMetadata;
549
550 /// Each of the MsanMetadataPtrXxx functions returns a MsanMetadata.
551 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
552 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
553 FunctionCallee MsanMetadataPtrForStore_1_8[4];
554 FunctionCallee MsanInstrumentAsmStoreFn;
555
556 /// Storage for return values of the MsanMetadataPtrXxx functions.
557 Value *MsanMetadataAlloca;
558
559 /// Helper to choose between different MsanMetadataPtrXxx().
560 FunctionCallee getKmsanShadowOriginAccessFn(bool isStore, int size);
561
562 /// Memory map parameters used in application-to-shadow calculation.
563 const MemoryMapParams *MapParams;
564
565 /// Custom memory map parameters used when -msan-shadow-base or
566 // -msan-origin-base is provided.
567 MemoryMapParams CustomMapParams;
568
569 MDNode *ColdCallWeights;
570
571 /// Branch weights for origin store.
572 MDNode *OriginStoreWeights;
573};
574
575void insertModuleCtor(const InstrumentationOptions &Opts, Module &M) {
578 /*InitArgTypes=*/{},
579 /*InitArgs=*/{},
580 // This callback is invoked when the functions are created the first
581 // time. Hook them into the global ctors list in that case:
582 [&](Function *Ctor, FunctionCallee) {
583 if (!Opts.msan_with_comdat) {
584 appendToGlobalCtors(M, Ctor, 0);
585 return;
586 }
587 Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
588 Ctor->setComdat(MsanCtorComdat);
589 appendToGlobalCtors(M, Ctor, 0, Ctor);
590 });
591}
592
593} // end anonymous namespace
594
596 : Kernel(K), TrackOrigins(TO), Recover(R), EagerChecks(EC) {}
597
598static MemorySanitizerOptions resolveOptions(const InstrumentationOptions &Opts,
600 O.Kernel = valueOr(Opts.msan_kernel, O.Kernel);
601 O.TrackOrigins =
602 Opts.msan_track_origins.value_or(O.Kernel ? 2 : O.TrackOrigins);
603 O.Recover = valueOr(Opts.msan_keep_going, O.Kernel || O.Recover);
604 O.EagerChecks = valueOr(Opts.msan_eager_checks, O.EagerChecks);
605 return O;
606}
607
610 // Return early if nosanitize_memory module flag is present for the module.
611 if (checkIfAlreadyInstrumented(M, "nosanitize_memory"))
612 return PreservedAnalyses::all();
613 const InstrumentationOptions &Opts = getInstrumentationOptions(M);
614 MemorySanitizerOptions MSanOpts = resolveOptions(Opts, Options);
615 bool Modified = false;
616 if (!MSanOpts.Kernel) {
617 insertModuleCtor(Opts, M);
618 Modified = true;
619 }
620
621 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
622 for (Function &F : M) {
623 if (F.empty())
624 continue;
625 MemorySanitizer Msan(Opts, *F.getParent(), MSanOpts);
626 Modified |=
627 Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
628 }
629
630 if (!Modified)
631 return PreservedAnalyses::all();
632
634 // GlobalsAA is considered stateless and does not get invalidated unless
635 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
636 // make changes that require GlobalsAA to be invalidated.
637 PA.abandon<GlobalsAA>();
638 return PA;
639}
640
642 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
643 static_cast<PassInfoMixin<MemorySanitizerPass> *>(this)->printPipeline(
644 OS, MapClassName2PassName);
645 OS << '<';
646 if (Options.Recover)
647 OS << "recover;";
648 if (Options.Kernel)
649 OS << "kernel;";
650 if (Options.EagerChecks)
651 OS << "eager-checks;";
652 OS << "track-origins=" << Options.TrackOrigins;
653 OS << '>';
654}
655
656/// Create a non-const global initialized with the given string.
657///
658/// Creates a writable global for Str so that we can pass it to the
659/// run-time lib. Runtime uses first 4 bytes of the string to store the
660/// frame ID, so the string needs to be mutable.
662 StringRef Str) {
663 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
664 return new GlobalVariable(M, StrConst->getType(), /*isConstant=*/true,
665 GlobalValue::PrivateLinkage, StrConst, "");
666}
667
668template <typename... ArgsTy>
670MemorySanitizer::getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
671 ArgsTy... Args) {
672 if (TargetTriple.getArch() == Triple::systemz) {
673 // SystemZ ABI: shadow/origin pair is returned via a hidden parameter.
674 return M.getOrInsertFunction(Name, Type::getVoidTy(*C), PtrTy,
675 std::forward<ArgsTy>(Args)...);
676 }
677
678 return M.getOrInsertFunction(Name, MsanMetadata,
679 std::forward<ArgsTy>(Args)...);
680}
681
682/// Create KMSAN API callbacks.
683void MemorySanitizer::createKernelApi(Module &M, const TargetLibraryInfo &TLI) {
684 IRBuilder<> IRB(M);
685
686 // These will be initialized in insertKmsanPrologue().
687 RetvalTLS = nullptr;
688 RetvalOriginTLS = nullptr;
689 ParamTLS = nullptr;
690 ParamOriginTLS = nullptr;
691 VAArgTLS = nullptr;
692 VAArgOriginTLS = nullptr;
693 VAArgOverflowSizeTLS = nullptr;
694
695 WarningFn = M.getOrInsertFunction("__msan_warning",
696 TLI.getAttrList(C, {0}, /*Signed=*/false),
697 IRB.getVoidTy(), IRB.getInt32Ty());
698
699 // Requests the per-task context state (kmsan_context_state*) from the
700 // runtime library.
701 MsanContextStateTy = StructType::get(
702 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
703 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8),
704 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
705 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), /* va_arg_origin */
706 IRB.getInt64Ty(), ArrayType::get(OriginTy, kParamTLSSize / 4), OriginTy,
707 OriginTy);
708 MsanGetContextStateFn =
709 M.getOrInsertFunction("__msan_get_context_state", PtrTy);
710
711 MsanMetadata = StructType::get(PtrTy, PtrTy);
712
713 for (int ind = 0, size = 1; ind < 4; ind++, size <<= 1) {
714 std::string name_load =
715 "__msan_metadata_ptr_for_load_" + std::to_string(size);
716 std::string name_store =
717 "__msan_metadata_ptr_for_store_" + std::to_string(size);
718 MsanMetadataPtrForLoad_1_8[ind] =
719 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
720 MsanMetadataPtrForStore_1_8[ind] =
721 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
722 }
723
724 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
725 M, "__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
726 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
727 M, "__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
728
729 // Functions for poisoning and unpoisoning memory.
730 MsanPoisonAllocaFn = M.getOrInsertFunction(
731 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
732 MsanUnpoisonAllocaFn = M.getOrInsertFunction(
733 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
734}
735
737 return M.getOrInsertGlobal(Name, Ty, [&] {
738 return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
739 nullptr, Name, nullptr,
741 });
742}
743
744/// Insert declarations for userspace-specific functions and globals.
745void MemorySanitizer::createUserspaceApi(Module &M,
746 const TargetLibraryInfo &TLI) {
747 IRBuilder<> IRB(M);
748
749 // Create the callback.
750 // FIXME: this function should have "Cold" calling conv,
751 // which is not yet implemented.
752 if (TrackOrigins) {
753 StringRef WarningFnName = Recover ? "__msan_warning_with_origin"
754 : "__msan_warning_with_origin_noreturn";
755 WarningFn = M.getOrInsertFunction(WarningFnName,
756 TLI.getAttrList(C, {0}, /*Signed=*/false),
757 IRB.getVoidTy(), IRB.getInt32Ty());
758 } else {
759 StringRef WarningFnName =
760 Recover ? "__msan_warning" : "__msan_warning_noreturn";
761 WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
762 }
763
764 // Create the global TLS variables.
765 RetvalTLS =
766 getOrInsertGlobal(M, "__msan_retval_tls",
767 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8));
768
769 RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy);
770
771 ParamTLS =
772 getOrInsertGlobal(M, "__msan_param_tls",
773 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
774
775 ParamOriginTLS =
776 getOrInsertGlobal(M, "__msan_param_origin_tls",
777 ArrayType::get(OriginTy, kParamTLSSize / 4));
778
779 VAArgTLS =
780 getOrInsertGlobal(M, "__msan_va_arg_tls",
781 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
782
783 VAArgOriginTLS =
784 getOrInsertGlobal(M, "__msan_va_arg_origin_tls",
785 ArrayType::get(OriginTy, kParamTLSSize / 4));
786
787 VAArgOverflowSizeTLS = getOrInsertGlobal(M, "__msan_va_arg_overflow_size_tls",
788 IRB.getIntPtrTy(M.getDataLayout()));
789
790 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
791 AccessSizeIndex++) {
792 unsigned AccessSize = 1 << AccessSizeIndex;
793 std::string FunctionName = "__msan_maybe_warning_" + itostr(AccessSize);
794 MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction(
795 FunctionName, TLI.getAttrList(C, {0, 1}, /*Signed=*/false),
796 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
797 MaybeWarningVarSizeFn = M.getOrInsertFunction(
798 "__msan_maybe_warning_N", TLI.getAttrList(C, {}, /*Signed=*/false),
799 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
800 FunctionName = "__msan_maybe_store_origin_" + itostr(AccessSize);
801 MaybeStoreOriginFn[AccessSizeIndex] = M.getOrInsertFunction(
802 FunctionName, TLI.getAttrList(C, {0, 2}, /*Signed=*/false),
803 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
804 IRB.getInt32Ty());
805 }
806
807 MsanSetAllocaOriginWithDescriptionFn =
808 M.getOrInsertFunction("__msan_set_alloca_origin_with_descr",
809 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
810 MsanSetAllocaOriginNoDescriptionFn =
811 M.getOrInsertFunction("__msan_set_alloca_origin_no_descr",
812 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
813 MsanPoisonStackFn = M.getOrInsertFunction("__msan_poison_stack",
814 IRB.getVoidTy(), PtrTy, IntptrTy);
815}
816
817/// Insert extern declaration of runtime-provided functions and globals.
818void MemorySanitizer::initializeCallbacks(Module &M,
819 const TargetLibraryInfo &TLI) {
820 // Only do this once.
821 if (CallbacksInitialized)
822 return;
823
824 IRBuilder<> IRB(M);
825 // Initialize callbacks that are common for kernel and userspace
826 // instrumentation.
827 MsanChainOriginFn = M.getOrInsertFunction(
828 "__msan_chain_origin",
829 TLI.getAttrList(C, {0}, /*Signed=*/false, /*Ret=*/true), IRB.getInt32Ty(),
830 IRB.getInt32Ty());
831 MsanSetOriginFn = M.getOrInsertFunction(
832 "__msan_set_origin", TLI.getAttrList(C, {2}, /*Signed=*/false),
833 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
834 MemmoveFn =
835 M.getOrInsertFunction("__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
836 MemcpyFn =
837 M.getOrInsertFunction("__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
838 MemsetFn = M.getOrInsertFunction("__msan_memset",
839 TLI.getAttrList(C, {1}, /*Signed=*/true),
840 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
841
842 MsanInstrumentAsmStoreFn = M.getOrInsertFunction(
843 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
844
845 if (CompileKernel) {
846 createKernelApi(M, TLI);
847 } else {
848 createUserspaceApi(M, TLI);
849 }
850 CallbacksInitialized = true;
851}
852
853FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore,
854 int size) {
855 FunctionCallee *Fns =
856 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
857 switch (size) {
858 case 1:
859 return Fns[0];
860 case 2:
861 return Fns[1];
862 case 4:
863 return Fns[2];
864 case 8:
865 return Fns[3];
866 default:
867 return nullptr;
868 }
869}
870
871/// Module-level initialization.
872///
873/// inserts a call to __msan_init to the module's constructor list.
874void MemorySanitizer::initializeModule(Module &M) {
875 auto &DL = M.getDataLayout();
876
877 TargetTriple = M.getTargetTriple();
878
879 bool ShadowPassed = Opts.msan_shadow_base.has_value();
880 bool OriginPassed = Opts.msan_origin_base.has_value();
881 // Check the overrides first
882 if (ShadowPassed || OriginPassed) {
883 CustomMapParams.AndMask = Opts.msan_and_mask;
884 CustomMapParams.XorMask = Opts.msan_xor_mask;
885 CustomMapParams.ShadowBase = Opts.msan_shadow_base.value_or(0);
886 CustomMapParams.OriginBase = Opts.msan_origin_base.value_or(0);
887 MapParams = &CustomMapParams;
888 } else {
889 switch (TargetTriple.getOS()) {
890 case Triple::FreeBSD:
891 switch (TargetTriple.getArch()) {
892 case Triple::aarch64:
893 MapParams = FreeBSD_ARM_MemoryMapParams.bits64;
894 break;
895 case Triple::x86_64:
896 MapParams = FreeBSD_X86_MemoryMapParams.bits64;
897 break;
898 case Triple::x86:
899 MapParams = FreeBSD_X86_MemoryMapParams.bits32;
900 break;
901 default:
902 report_fatal_error("unsupported architecture");
903 }
904 break;
905 case Triple::NetBSD:
906 switch (TargetTriple.getArch()) {
907 case Triple::x86_64:
908 MapParams = NetBSD_X86_MemoryMapParams.bits64;
909 break;
910 default:
911 report_fatal_error("unsupported architecture");
912 }
913 break;
914 case Triple::Linux:
915 switch (TargetTriple.getArch()) {
916 case Triple::x86_64:
917 MapParams = Linux_X86_MemoryMapParams.bits64;
918 break;
919 case Triple::x86:
920 MapParams = Linux_X86_MemoryMapParams.bits32;
921 break;
922 case Triple::mips64:
923 case Triple::mips64el:
924 MapParams = Linux_MIPS_MemoryMapParams.bits64;
925 break;
926 case Triple::ppc64:
927 case Triple::ppc64le:
928 MapParams = Linux_PowerPC_MemoryMapParams.bits64;
929 break;
930 case Triple::systemz:
931 MapParams = Linux_S390_MemoryMapParams.bits64;
932 break;
933 case Triple::aarch64:
935 MapParams = Linux_ARM_MemoryMapParams.bits64;
936 break;
938 MapParams = Linux_LoongArch_MemoryMapParams.bits64;
939 break;
940 case Triple::hexagon:
941 MapParams = Linux_Hexagon_MemoryMapParams_P.bits32;
942 break;
943 default:
944 report_fatal_error("unsupported architecture");
945 }
946 break;
947 default:
948 report_fatal_error("unsupported operating system");
949 }
950 }
951
952 C = &(M.getContext());
953 IRBuilder<> IRB(M);
954 IntptrTy = IRB.getIntPtrTy(DL);
955 OriginTy = IRB.getInt32Ty();
956 PtrTy = IRB.getPtrTy();
957
958 ColdCallWeights = MDBuilder(*C).createUnlikelyBranchWeights();
959 OriginStoreWeights = MDBuilder(*C).createUnlikelyBranchWeights();
960
961 if (!CompileKernel) {
962 if (TrackOrigins)
963 M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
964 return new GlobalVariable(
965 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
966 IRB.getInt32(TrackOrigins), "__msan_track_origins");
967 });
968
969 if (Recover)
970 M.getOrInsertGlobal("__msan_keep_going", IRB.getInt32Ty(), [&] {
971 return new GlobalVariable(M, IRB.getInt32Ty(), true,
972 GlobalValue::WeakODRLinkage,
973 IRB.getInt32(Recover), "__msan_keep_going");
974 });
975 }
976}
977
978namespace {
979
980/// A helper class that handles instrumentation of VarArg
981/// functions on a particular platform.
982///
983/// Implementations are expected to insert the instrumentation
984/// necessary to propagate argument shadow through VarArg function
985/// calls. Visit* methods are called during an InstVisitor pass over
986/// the function, and should avoid creating new basic blocks. A new
987/// instance of this class is created for each instrumented function.
988struct VarArgHelper {
989 virtual ~VarArgHelper() = default;
990
991 /// Visit a CallBase.
992 virtual void visitCallBase(CallBase &CB, IRBuilder<> &IRB) = 0;
993
994 /// Visit a va_start call.
995 virtual void visitVAStartInst(VAStartInst &I) = 0;
996
997 /// Visit a va_copy call.
998 virtual void visitVACopyInst(VACopyInst &I) = 0;
999
1000 /// Finalize function instrumentation.
1001 ///
1002 /// This method is called after visiting all interesting (see above)
1003 /// instructions in a function.
1004 virtual void finalizeInstrumentation() = 0;
1005};
1006
1007struct MemorySanitizerVisitor;
1008
1009} // end anonymous namespace
1010
1011static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
1012 MemorySanitizerVisitor &Visitor);
1013
1014static unsigned TypeSizeToSizeIndex(TypeSize TS) {
1015 if (TS.isScalable())
1016 // Scalable types unconditionally take slowpaths.
1017 return kNumberOfAccessSizes;
1018 unsigned TypeSizeFixed = TS.getFixedValue();
1019 if (TypeSizeFixed <= 8)
1020 return 0;
1021 return Log2_32_Ceil((TypeSizeFixed + 7) / 8);
1022}
1023
1024namespace {
1025
1026/// Helper class to attach debug information of the given instruction onto new
1027/// instructions inserted after.
1028class NextNodeIRBuilder : public IRBuilder<> {
1029public:
1030 explicit NextNodeIRBuilder(Instruction *IP) : IRBuilder<>(IP->getNextNode()) {
1031 SetCurrentDebugLocation(IP->getDebugLoc());
1032 }
1033};
1034
1035/// This class does all the work for a given function. Store and Load
1036/// instructions store and load corresponding shadow and origin
1037/// values. Most instructions propagate shadow from arguments to their
1038/// return values. Certain instructions (most importantly, BranchInst)
1039/// test their argument shadow and print reports (with a runtime call) if it's
1040/// non-zero.
1041struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1042 const InstrumentationOptions &Opts;
1043 Function &F;
1044 MemorySanitizer &MS;
1045 SmallVector<PHINode *, 16> ShadowPHINodes, OriginPHINodes;
1046 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1047 std::unique_ptr<VarArgHelper> VAHelper;
1048 const TargetLibraryInfo *TLI;
1049 Instruction *FnPrologueEnd;
1050 SmallVector<Instruction *, 16> Instructions;
1051
1052 // The following flags disable parts of MSan instrumentation based on
1053 // exclusion list contents and command-line options.
1054 bool InsertChecks;
1055 bool PropagateShadow;
1056 bool PoisonStack;
1057 bool PoisonUndef;
1058 bool PoisonUndefVectors;
1059
1060 struct ShadowOriginAndInsertPoint {
1061 Value *Shadow;
1062 Value *Origin;
1063 Instruction *OrigIns;
1064
1065 ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I)
1066 : Shadow(S), Origin(O), OrigIns(I) {}
1067 };
1069 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1070 SmallSetVector<AllocaInst *, 16> AllocaSet;
1073 int64_t SplittableBlocksCount = 0;
1074
1075 MemorySanitizerVisitor(Function &F, MemorySanitizer &MS,
1076 const TargetLibraryInfo &TLI)
1077 : Opts(MS.Opts), F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)),
1078 TLI(&TLI) {
1079 bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeMemory) &&
1080 !Opts.msan_disable_checks;
1081 InsertChecks = SanitizeFunction;
1082 PropagateShadow = SanitizeFunction;
1083 PoisonStack = SanitizeFunction && Opts.msan_poison_stack;
1084 PoisonUndef = SanitizeFunction && Opts.msan_poison_undef;
1085 PoisonUndefVectors = SanitizeFunction && Opts.msan_poison_undef_vectors;
1086
1087 // In the presence of unreachable blocks, we may see Phi nodes with
1088 // incoming nodes from such blocks. Since InstVisitor skips unreachable
1089 // blocks, such nodes will not have any shadow value associated with them.
1090 // It's easier to remove unreachable blocks than deal with missing shadow.
1092
1093 MS.initializeCallbacks(*F.getParent(), TLI);
1094 FnPrologueEnd =
1095 IRBuilder<>(F.getEntryBlock().getFirstNonPHIIt())
1096 .CreateIntrinsicWithoutFolding(Intrinsic::donothing, {});
1097
1098 if (MS.CompileKernel) {
1099 IRBuilder<> IRB(FnPrologueEnd);
1100 insertKmsanPrologue(IRB);
1101 }
1102
1103 LLVM_DEBUG(if (!InsertChecks) dbgs()
1104 << "MemorySanitizer is not inserting checks into '"
1105 << F.getName() << "'\n");
1106 }
1107
1108 bool instrumentWithCalls(Value *V) {
1109 // Constants likely will be eliminated by follow-up passes.
1110 if (isa<Constant>(V))
1111 return false;
1112 ++SplittableBlocksCount;
1113 return Opts.msan_instrumentation_with_call_threshold >= 0 &&
1114 SplittableBlocksCount >
1115 Opts.msan_instrumentation_with_call_threshold;
1116 }
1117
1118 bool isInPrologue(Instruction &I) {
1119 return I.getParent() == FnPrologueEnd->getParent() &&
1120 (&I == FnPrologueEnd || I.comesBefore(FnPrologueEnd));
1121 }
1122
1123 // Creates a new origin and records the stack trace. In general we can call
1124 // this function for any origin manipulation we like. However it will cost
1125 // runtime resources. So use this wisely only if it can provide additional
1126 // information helpful to a user.
1127 Value *updateOrigin(Value *V, IRBuilder<> &IRB) {
1128 if (MS.TrackOrigins <= 1)
1129 return V;
1130 return IRB.CreateCall(MS.MsanChainOriginFn, V);
1131 }
1132
1133 Value *originToIntptr(IRBuilder<> &IRB, Value *Origin) {
1134 const DataLayout &DL = F.getDataLayout();
1135 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1136 if (IntptrSize == kOriginSize)
1137 return Origin;
1138 assert(IntptrSize == kOriginSize * 2);
1139 Origin = IRB.CreateIntCast(Origin, MS.IntptrTy, /* isSigned */ false);
1140 return IRB.CreateOr(Origin, IRB.CreateShl(Origin, kOriginSize * 8));
1141 }
1142
1143 /// Fill memory range with the given origin value.
1144 void paintOrigin(IRBuilder<> &IRB, Value *Origin, Value *OriginPtr,
1145 TypeSize TS, Align Alignment) {
1146 const DataLayout &DL = F.getDataLayout();
1147 const Align IntptrAlignment = DL.getABITypeAlign(MS.IntptrTy);
1148 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1149 assert(IntptrAlignment >= kMinOriginAlignment);
1150 assert(IntptrSize >= kOriginSize);
1151
1152 // Note: The loop based formation works for fixed length vectors too,
1153 // however we prefer to unroll and specialize alignment below.
1154 if (TS.isScalable()) {
1155 Value *Size = IRB.CreateTypeSize(MS.IntptrTy, TS);
1156 Value *RoundUp =
1157 IRB.CreateAdd(Size, ConstantInt::get(MS.IntptrTy, kOriginSize - 1));
1158 Value *End =
1159 IRB.CreateUDiv(RoundUp, ConstantInt::get(MS.IntptrTy, kOriginSize));
1160 auto [InsertPt, Index] =
1162 IRB.SetInsertPoint(InsertPt);
1163
1164 Value *GEP = IRB.CreateGEP(MS.OriginTy, OriginPtr, Index);
1166 return;
1167 }
1168
1169 unsigned Size = TS.getFixedValue();
1170
1171 unsigned Ofs = 0;
1172 Align CurrentAlignment = Alignment;
1173 if (Alignment >= IntptrAlignment && IntptrSize > kOriginSize) {
1174 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1175 Value *IntptrOriginPtr = IRB.CreatePointerCast(OriginPtr, MS.PtrTy);
1176 for (unsigned i = 0; i < Size / IntptrSize; ++i) {
1177 Value *Ptr = i ? IRB.CreateConstGEP1_32(MS.IntptrTy, IntptrOriginPtr, i)
1178 : IntptrOriginPtr;
1179 IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
1180 Ofs += IntptrSize / kOriginSize;
1181 CurrentAlignment = IntptrAlignment;
1182 }
1183 }
1184
1185 for (unsigned i = Ofs; i < (Size + kOriginSize - 1) / kOriginSize; ++i) {
1186 Value *GEP =
1187 i ? IRB.CreateConstGEP1_32(MS.OriginTy, OriginPtr, i) : OriginPtr;
1188 IRB.CreateAlignedStore(Origin, GEP, CurrentAlignment);
1189 CurrentAlignment = kMinOriginAlignment;
1190 }
1191 }
1192
1193 void storeOrigin(IRBuilder<> &IRB, Value *Addr, Value *Shadow, Value *Origin,
1194 Value *OriginPtr, Align Alignment) {
1195 const DataLayout &DL = F.getDataLayout();
1196 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1197 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
1198 // ZExt cannot convert between vector and scalar
1199 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1200 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1201 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1202 // Origin is not needed: value is initialized or const shadow is
1203 // ignored.
1204 return;
1205 }
1206 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1207 // Copy origin as the value is definitely uninitialized.
1208 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1209 OriginAlignment);
1210 return;
1211 }
1212 // Fallback to runtime check, which still can be optimized out later.
1213 }
1214
1215 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1216 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1217 if (instrumentWithCalls(ConvertedShadow) &&
1218 SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
1219 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1220 Value *ConvertedShadow2 =
1221 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1222 CallBase *CB = IRB.CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1223 CB->addParamAttr(0, Attribute::ZExt);
1224 CB->addParamAttr(2, Attribute::ZExt);
1225 } else {
1226 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1228 Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
1229 IRBuilder<> IRBNew(CheckTerm);
1230 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1231 OriginAlignment);
1232 }
1233 }
1234
1235 void materializeStores() {
1236 for (StoreInst *SI : StoreList) {
1237 IRBuilder<> IRB(SI);
1238 Value *Val = SI->getValueOperand();
1239 Value *Addr = SI->getPointerOperand();
1240 Value *Shadow = SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1241 Value *ShadowPtr, *OriginPtr;
1242 Type *ShadowTy = Shadow->getType();
1243 const Align Alignment = SI->getAlign();
1244 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1245 std::tie(ShadowPtr, OriginPtr) =
1246 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ true);
1247
1248 [[maybe_unused]] StoreInst *NewSI =
1249 IRB.CreateAlignedStore(Shadow, ShadowPtr, Alignment);
1250 LLVM_DEBUG(dbgs() << " STORE: " << *NewSI << "\n");
1251
1252 if (SI->isAtomic())
1253 SI->setOrdering(addReleaseOrdering(SI->getOrdering()));
1254
1255 if (MS.TrackOrigins && !SI->isAtomic())
1256 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1257 OriginAlignment);
1258 }
1259 }
1260
1261 // Returns true if Debug Location corresponds to multiple warnings.
1262 bool shouldDisambiguateWarningLocation(const DebugLoc &DebugLoc) {
1263 if (MS.TrackOrigins < 2)
1264 return false;
1265
1266 if (LazyWarningDebugLocationCount.empty())
1267 for (const auto &I : InstrumentationList)
1268 ++LazyWarningDebugLocationCount[I.OrigIns->getDebugLoc()];
1269
1270 return LazyWarningDebugLocationCount[DebugLoc] >=
1271 Opts.msan_disambiguate_warning_threshold;
1272 }
1273
1274 /// Helper function to insert a warning at IRB's current insert point.
1275 void insertWarningFn(IRBuilder<> &IRB, Value *Origin) {
1276 if (!Origin)
1277 Origin = (Value *)IRB.getInt32(0);
1278 assert(Origin->getType()->isIntegerTy());
1279
1280 if (shouldDisambiguateWarningLocation(IRB.getCurrentDebugLocation())) {
1281 // Try to create additional origin with debug info of the last origin
1282 // instruction. It may provide additional information to the user.
1283 if (Instruction *OI = dyn_cast_or_null<Instruction>(Origin)) {
1284 assert(MS.TrackOrigins);
1285 auto NewDebugLoc = OI->getDebugLoc();
1286 // Origin update with missing or the same debug location provides no
1287 // additional value.
1288 if (NewDebugLoc && NewDebugLoc != IRB.getCurrentDebugLocation()) {
1289 // Insert update just before the check, so we call runtime only just
1290 // before the report.
1291 IRBuilder<> IRBOrigin(&*IRB.GetInsertPoint());
1292 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1293 Origin = updateOrigin(Origin, IRBOrigin);
1294 }
1295 }
1296 }
1297
1298 if (MS.CompileKernel || MS.TrackOrigins)
1299 IRB.CreateCall(MS.WarningFn, Origin)->setCannotMerge();
1300 else
1301 IRB.CreateCall(MS.WarningFn)->setCannotMerge();
1302 // FIXME: Insert UnreachableInst if !MS.Recover?
1303 // This may invalidate some of the following checks and needs to be done
1304 // at the very end.
1305 }
1306
1307 void materializeOneCheck(IRBuilder<> &IRB, Value *ConvertedShadow,
1308 Value *Origin) {
1309 const DataLayout &DL = F.getDataLayout();
1310 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1311 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1312 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1313 // ZExt cannot convert between vector and scalar
1314 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1315 Value *ConvertedShadow2 =
1316 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1317
1318 if (SizeIndex < kNumberOfAccessSizes) {
1319 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1320 CallBase *CB = IRB.CreateCall(
1321 Fn,
1322 {ConvertedShadow2,
1323 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1324 CB->addParamAttr(0, Attribute::ZExt);
1325 CB->addParamAttr(1, Attribute::ZExt);
1326 } else {
1327 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1328 Value *ShadowAlloca = IRB.CreateAlloca(ConvertedShadow2->getType(), 0u);
1329 IRB.CreateStore(ConvertedShadow2, ShadowAlloca);
1330 unsigned ShadowSize = DL.getTypeAllocSize(ConvertedShadow2->getType());
1331 CallBase *CB = IRB.CreateCall(
1332 Fn,
1333 {ShadowAlloca, ConstantInt::get(IRB.getInt64Ty(), ShadowSize),
1334 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1335 CB->addParamAttr(1, Attribute::ZExt);
1336 CB->addParamAttr(2, Attribute::ZExt);
1337 }
1338 } else {
1339 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1341 Cmp, &*IRB.GetInsertPoint(),
1342 /* Unreachable */ !MS.Recover, MS.ColdCallWeights);
1343
1344 IRB.SetInsertPoint(CheckTerm);
1345 insertWarningFn(IRB, Origin);
1346 LLVM_DEBUG(dbgs() << " CHECK: " << *Cmp << "\n");
1347 }
1348 }
1349
1350 void materializeInstructionChecks(
1351 ArrayRef<ShadowOriginAndInsertPoint> InstructionChecks) {
1352 const DataLayout &DL = F.getDataLayout();
1353 // Disable combining in some cases. TrackOrigins checks each shadow to pick
1354 // correct origin.
1355 bool Combine = !MS.TrackOrigins;
1356 Instruction *Instruction = InstructionChecks.front().OrigIns;
1357 Value *Shadow = nullptr;
1358 for (const auto &ShadowData : InstructionChecks) {
1359 assert(ShadowData.OrigIns == Instruction);
1360 IRBuilder<> IRB(Instruction);
1361
1362 Value *ConvertedShadow = ShadowData.Shadow;
1363
1364 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1365 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1366 // Skip, value is initialized or const shadow is ignored.
1367 continue;
1368 }
1369 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1370 // Report as the value is definitely uninitialized.
1371 insertWarningFn(IRB, ShadowData.Origin);
1372 if (!MS.Recover)
1373 return; // Always fail and stop here, not need to check the rest.
1374 // Skip entire instruction,
1375 continue;
1376 }
1377 // Fallback to runtime check, which still can be optimized out later.
1378 }
1379
1380 if (!Combine) {
1381 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1382 continue;
1383 }
1384
1385 if (!Shadow) {
1386 Shadow = ConvertedShadow;
1387 continue;
1388 }
1389
1390 Shadow = convertToBool(Shadow, IRB, "_mscmp");
1391 ConvertedShadow = convertToBool(ConvertedShadow, IRB, "_mscmp");
1392 Shadow = IRB.CreateOr(Shadow, ConvertedShadow, "_msor");
1393 }
1394
1395 if (Shadow) {
1396 assert(Combine);
1397 IRBuilder<> IRB(Instruction);
1398 materializeOneCheck(IRB, Shadow, nullptr);
1399 }
1400 }
1401
1402 static bool isAArch64SVCount(Type *Ty) {
1403 if (TargetExtType *TTy = dyn_cast<TargetExtType>(Ty))
1404 return TTy->getName() == "aarch64.svcount";
1405 return false;
1406 }
1407
1408 // This is intended to match the "AArch64 Predicate-as-Counter Type" (aka
1409 // 'target("aarch64.svcount")', but not e.g., <vscale x 4 x i32>.
1410 static bool isScalableNonVectorType(Type *Ty) {
1411 if (!isAArch64SVCount(Ty))
1412 LLVM_DEBUG(dbgs() << "isScalableNonVectorType: Unexpected type " << *Ty
1413 << "\n");
1414
1415 return Ty->isScalableTy() && !isa<VectorType>(Ty);
1416 }
1417
1418 void materializeChecks() {
1419#ifndef NDEBUG
1420 // For assert below.
1421 SmallPtrSet<Instruction *, 16> Done;
1422#endif
1423
1424 for (auto I = InstrumentationList.begin();
1425 I != InstrumentationList.end();) {
1426 auto OrigIns = I->OrigIns;
1427 // Checks are grouped by the original instruction. We call all
1428 // `insertShadowCheck` for an instruction at once.
1429 assert(Done.insert(OrigIns).second);
1430 auto J = std::find_if(I + 1, InstrumentationList.end(),
1431 [OrigIns](const ShadowOriginAndInsertPoint &R) {
1432 return OrigIns != R.OrigIns;
1433 });
1434 // Process all checks of instruction at once.
1435 materializeInstructionChecks(ArrayRef<ShadowOriginAndInsertPoint>(I, J));
1436 I = J;
1437 }
1438
1439 LLVM_DEBUG(dbgs() << "DONE:\n" << F);
1440 }
1441
1442 // Returns the last instruction in the new prologue
1443 void insertKmsanPrologue(IRBuilder<> &IRB) {
1444 Value *ContextState = IRB.CreateCall(MS.MsanGetContextStateFn, {});
1445 Constant *Zero = IRB.getInt32(0);
1446 MS.ParamTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1447 {Zero, IRB.getInt32(0)}, "param_shadow");
1448 MS.RetvalTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1449 {Zero, IRB.getInt32(1)}, "retval_shadow");
1450 MS.VAArgTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1451 {Zero, IRB.getInt32(2)}, "va_arg_shadow");
1452 MS.VAArgOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1453 {Zero, IRB.getInt32(3)}, "va_arg_origin");
1454 MS.VAArgOverflowSizeTLS =
1455 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1456 {Zero, IRB.getInt32(4)}, "va_arg_overflow_size");
1457 MS.ParamOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1458 {Zero, IRB.getInt32(5)}, "param_origin");
1459 MS.RetvalOriginTLS =
1460 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1461 {Zero, IRB.getInt32(6)}, "retval_origin");
1462 if (MS.TargetTriple.getArch() == Triple::systemz)
1463 MS.MsanMetadataAlloca = IRB.CreateAlloca(MS.MsanMetadata, 0u);
1464 }
1465
1466 /// Add MemorySanitizer instrumentation to a function.
1467 bool runOnFunction() {
1468 // Iterate all BBs in depth-first order and create shadow instructions
1469 // for all instructions (where applicable).
1470 // For PHI nodes we create dummy shadow PHIs which will be finalized later.
1471 for (BasicBlock *BB : depth_first(FnPrologueEnd->getParent()))
1472 visit(*BB);
1473
1474 // `visit` above only collects instructions. Process them after iterating
1475 // CFG to avoid requirement on CFG transformations.
1476 for (Instruction *I : Instructions)
1478
1479 // Finalize PHI nodes.
1480 for (PHINode *PN : ShadowPHINodes) {
1481 PHINode *PNS = cast<PHINode>(getShadow(PN));
1482 PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
1483 size_t NumValues = PN->getNumIncomingValues();
1484 for (size_t v = 0; v < NumValues; v++) {
1485 PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1486 if (PNO)
1487 PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1488 }
1489 }
1490
1491 VAHelper->finalizeInstrumentation();
1492
1493 // Poison llvm.lifetime.start intrinsics, if we haven't fallen back to
1494 // instrumenting only allocas.
1495 if (Opts.msan_handle_lifetime_intrinsics) {
1496 for (auto Item : LifetimeStartList) {
1497 instrumentAlloca(*Item.second, Item.first);
1498 AllocaSet.remove(Item.second);
1499 }
1500 }
1501 // Poison the allocas for which we didn't instrument the corresponding
1502 // lifetime intrinsics.
1503 for (AllocaInst *AI : AllocaSet)
1504 instrumentAlloca(*AI);
1505
1506 // Insert shadow value checks.
1507 materializeChecks();
1508
1509 // Delayed instrumentation of StoreInst.
1510 // This may not add new address checks.
1511 materializeStores();
1512
1513 return true;
1514 }
1515
1516 /// Compute the shadow type that corresponds to a given Value.
1517 Type *getShadowTy(Value *V) { return getShadowTy(V->getType()); }
1518
1519 /// Compute the shadow type that corresponds to a given Type.
1520 Type *getShadowTy(Type *OrigTy) {
1521 if (!OrigTy->isSized()) {
1522 return nullptr;
1523 }
1524 // For integer type, shadow is the same as the original type.
1525 // This may return weird-sized types like i1.
1526 if (IntegerType *IT = dyn_cast<IntegerType>(OrigTy))
1527 return IT;
1528 const DataLayout &DL = F.getDataLayout();
1529 if (VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
1530 uint32_t EltSize = DL.getTypeSizeInBits(VT->getElementType());
1531 return VectorType::get(IntegerType::get(*MS.C, EltSize),
1532 VT->getElementCount());
1533 }
1534 if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) {
1535 return ArrayType::get(getShadowTy(AT->getElementType()),
1536 AT->getNumElements());
1537 }
1538 if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
1540 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1541 Elements.push_back(getShadowTy(ST->getElementType(i)));
1542 StructType *Res = StructType::get(*MS.C, Elements, ST->isPacked());
1543 LLVM_DEBUG(dbgs() << "getShadowTy: " << *ST << " ===> " << *Res << "\n");
1544 return Res;
1545 }
1546 if (isScalableNonVectorType(OrigTy)) {
1547 LLVM_DEBUG(dbgs() << "getShadowTy: Scalable non-vector type: " << *OrigTy
1548 << "\n");
1549 return OrigTy;
1550 }
1551
1552 uint32_t TypeSize = DL.getTypeSizeInBits(OrigTy);
1553 return IntegerType::get(*MS.C, TypeSize);
1554 }
1555
1556 /// Extract combined shadow of struct elements as a bool
1557 Value *collapseStructShadow(StructType *Struct, Value *Shadow,
1558 IRBuilder<> &IRB) {
1559 Value *FalseVal = IRB.getIntN(/* width */ 1, /* value */ 0);
1560 Value *Aggregator = FalseVal;
1561
1562 for (unsigned Idx = 0; Idx < Struct->getNumElements(); Idx++) {
1563 // Combine by ORing together each element's bool shadow
1564 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1565 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1566
1567 if (Aggregator != FalseVal)
1568 Aggregator = IRB.CreateOr(Aggregator, ShadowBool);
1569 else
1570 Aggregator = ShadowBool;
1571 }
1572
1573 return Aggregator;
1574 }
1575
1576 // Extract combined shadow of array elements
1577 Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
1578 IRBuilder<> &IRB) {
1579 if (!Array->getNumElements())
1580 return IRB.getIntN(/* width */ 1, /* value */ 0);
1581
1582 Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
1583 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1584
1585 for (unsigned Idx = 1; Idx < Array->getNumElements(); Idx++) {
1586 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1587 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1588 Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
1589 }
1590 return Aggregator;
1591 }
1592
1593 /// Convert a shadow value to it's flattened variant. The resulting
1594 /// shadow may not necessarily have the same bit width as the input
1595 /// value, but it will always be comparable to zero.
1596 Value *convertShadowToScalar(Value *V, IRBuilder<> &IRB) {
1597 if (StructType *Struct = dyn_cast<StructType>(V->getType()))
1598 return collapseStructShadow(Struct, V, IRB);
1599 if (ArrayType *Array = dyn_cast<ArrayType>(V->getType()))
1600 return collapseArrayShadow(Array, V, IRB);
1601 if (isa<VectorType>(V->getType())) {
1602 if (isa<ScalableVectorType>(V->getType()))
1603 return convertShadowToScalar(IRB.CreateOrReduce(V), IRB);
1604 unsigned BitWidth =
1605 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1606 return IRB.CreateBitCast(V, IntegerType::get(*MS.C, BitWidth));
1607 }
1608 return V;
1609 }
1610
1611 // Convert a scalar value to an i1 by comparing with 0
1612 Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &name = "") {
1613 Type *VTy = V->getType();
1614 if (!VTy->isIntegerTy())
1615 return convertToBool(convertShadowToScalar(V, IRB), IRB, name);
1616 if (VTy->getIntegerBitWidth() == 1)
1617 // Just converting a bool to a bool, so do nothing.
1618 return V;
1619 return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), name);
1620 }
1621
1622 Type *ptrToIntPtrType(Type *PtrTy) const {
1623 if (VectorType *VectTy = dyn_cast<VectorType>(PtrTy)) {
1624 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1625 VectTy->getElementCount());
1626 }
1627 assert(PtrTy->isIntOrPtrTy());
1628 return MS.IntptrTy;
1629 }
1630
1631 Type *getPtrToShadowPtrType(Type *IntPtrTy, Type *ShadowTy) const {
1632 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1633 return VectorType::get(
1634 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1635 VectTy->getElementCount());
1636 }
1637 assert(IntPtrTy == MS.IntptrTy);
1638 return MS.PtrTy;
1639 }
1640
1641 Constant *constToIntPtr(Type *IntPtrTy, uint64_t C) const {
1642 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1644 VectTy->getElementCount(),
1645 constToIntPtr(VectTy->getElementType(), C));
1646 }
1647 assert(IntPtrTy == MS.IntptrTy);
1648 // TODO: Avoid implicit trunc?
1649 // See https://github.com/llvm/llvm-project/issues/112510.
1650 return ConstantInt::get(MS.IntptrTy, C, /*IsSigned=*/false,
1651 /*ImplicitTrunc=*/true);
1652 }
1653
1654 /// Returns the integer shadow offset that corresponds to a given
1655 /// application address, whereby:
1656 ///
1657 /// Offset = (Addr & ~AndMask) ^ XorMask
1658 /// Shadow = ShadowBase + Offset
1659 /// Origin = (OriginBase + Offset) & ~Alignment
1660 ///
1661 /// Note: for efficiency, many shadow mappings only require use the XorMask
1662 /// and OriginBase; the AndMask and ShadowBase are often zero.
1663 Value *getShadowPtrOffset(Value *Addr, IRBuilder<> &IRB) {
1664 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1665 Value *OffsetLong = IRB.CreatePointerCast(Addr, IntptrTy);
1666
1667 if (uint64_t AndMask = MS.MapParams->AndMask)
1668 OffsetLong = IRB.CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1669
1670 if (uint64_t XorMask = MS.MapParams->XorMask)
1671 OffsetLong = IRB.CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1672 return OffsetLong;
1673 }
1674
1675 /// Compute the shadow and origin addresses corresponding to a given
1676 /// application address.
1677 ///
1678 /// Shadow = ShadowBase + Offset
1679 /// Origin = (OriginBase + Offset) & ~3ULL
1680 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1681 /// a single pointee.
1682 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1683 std::pair<Value *, Value *>
1684 getShadowOriginPtrUserspace(Value *Addr, IRBuilder<> &IRB, Type *ShadowTy,
1685 MaybeAlign Alignment) {
1686 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1687 if (!VectTy) {
1688 assert(Addr->getType()->isPointerTy());
1689 } else {
1690 assert(VectTy->getElementType()->isPointerTy());
1691 }
1692 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1693 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1694 Value *ShadowLong = ShadowOffset;
1695 if (uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1696 ShadowLong =
1697 IRB.CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1698 }
1699 Value *ShadowPtr = IRB.CreateIntToPtr(
1700 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1701
1702 Value *OriginPtr = nullptr;
1703 if (MS.TrackOrigins) {
1704 Value *OriginLong = ShadowOffset;
1705 uint64_t OriginBase = MS.MapParams->OriginBase;
1706 if (OriginBase != 0)
1707 OriginLong =
1708 IRB.CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1709 if (!Alignment || *Alignment < kMinOriginAlignment) {
1711 OriginLong = IRB.CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1712 }
1713 OriginPtr = IRB.CreateIntToPtr(
1714 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1715 }
1716 return std::make_pair(ShadowPtr, OriginPtr);
1717 }
1718
1719 template <typename... ArgsTy>
1720 Value *createMetadataCall(IRBuilder<> &IRB, FunctionCallee Callee,
1721 ArgsTy... Args) {
1722 if (MS.TargetTriple.getArch() == Triple::systemz) {
1723 IRB.CreateCall(Callee,
1724 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1725 return IRB.CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1726 }
1727
1728 return IRB.CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1729 }
1730
1731 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(Value *Addr,
1732 IRBuilder<> &IRB,
1733 Type *ShadowTy,
1734 bool isStore) {
1735 Value *ShadowOriginPtrs;
1736 const DataLayout &DL = F.getDataLayout();
1737 TypeSize Size = DL.getTypeStoreSize(ShadowTy);
1738
1739 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size);
1740 Value *AddrCast = IRB.CreatePointerCast(Addr, MS.PtrTy);
1741 if (Getter) {
1742 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1743 } else {
1744 Value *SizeVal = ConstantInt::get(MS.IntptrTy, Size);
1745 ShadowOriginPtrs = createMetadataCall(
1746 IRB,
1747 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1748 AddrCast, SizeVal);
1749 }
1750 Value *ShadowPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 0);
1751 ShadowPtr = IRB.CreatePointerCast(ShadowPtr, MS.PtrTy);
1752 Value *OriginPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 1);
1753
1754 return std::make_pair(ShadowPtr, OriginPtr);
1755 }
1756
1757 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1758 /// a single pointee.
1759 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1760 std::pair<Value *, Value *> getShadowOriginPtrKernel(Value *Addr,
1761 IRBuilder<> &IRB,
1762 Type *ShadowTy,
1763 bool isStore) {
1764 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1765 if (!VectTy) {
1766 assert(Addr->getType()->isPointerTy());
1767 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy, isStore);
1768 }
1769
1770 // TODO: Support callbacs with vectors of addresses.
1771 unsigned NumElements = cast<FixedVectorType>(VectTy)->getNumElements();
1772 Value *ShadowPtrs = ConstantInt::getNullValue(
1773 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1774 Value *OriginPtrs = nullptr;
1775 if (MS.TrackOrigins)
1776 OriginPtrs = ConstantInt::getNullValue(
1777 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1778 for (unsigned i = 0; i < NumElements; ++i) {
1779 Value *OneAddr =
1780 IRB.CreateExtractElement(Addr, ConstantInt::get(IRB.getInt32Ty(), i));
1781 auto [ShadowPtr, OriginPtr] =
1782 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy, isStore);
1783
1784 ShadowPtrs = IRB.CreateInsertElement(
1785 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1786 if (MS.TrackOrigins)
1787 OriginPtrs = IRB.CreateInsertElement(
1788 OriginPtrs, OriginPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1789 }
1790 return {ShadowPtrs, OriginPtrs};
1791 }
1792
1793 std::pair<Value *, Value *> getShadowOriginPtr(Value *Addr, IRBuilder<> &IRB,
1794 Type *ShadowTy,
1795 MaybeAlign Alignment,
1796 bool isStore) {
1797 if (MS.CompileKernel)
1798 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy, isStore);
1799 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1800 }
1801
1802 /// Compute the shadow address for a given function argument.
1803 ///
1804 /// Shadow = ParamTLS+ArgOffset.
1805 Value *getShadowPtrForArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
1806 return IRB.CreatePtrAddWithUnsignedOffset(MS.ParamTLS, ArgOffset, "_msarg");
1807 }
1808
1809 /// Compute the origin address for a given function argument.
1810 Value *getOriginPtrForArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
1811 if (!MS.TrackOrigins)
1812 return nullptr;
1813 return IRB.CreatePtrAddWithUnsignedOffset(MS.ParamOriginTLS, ArgOffset,
1814 "_msarg_o");
1815 }
1816
1817 /// Compute the shadow address for a retval.
1818 Value *getShadowPtrForRetval(IRBuilder<> &IRB) {
1819 return IRB.CreatePointerCast(MS.RetvalTLS, IRB.getPtrTy(0), "_msret");
1820 }
1821
1822 /// Compute the origin address for a retval.
1823 Value *getOriginPtrForRetval() {
1824 // We keep a single origin for the entire retval. Might be too optimistic.
1825 return MS.RetvalOriginTLS;
1826 }
1827
1828 /// Set SV to be the shadow value for V.
1829 void setShadow(Value *V, Value *SV) {
1830 assert(!ShadowMap.count(V) && "Values may only have one shadow");
1831
1832 // getShadowTy(VoidType) == nullptr
1833 if (SV && !V->getType()->isVoidTy() && getShadowTy(V) != SV->getType()) {
1834 LLVM_DEBUG(dbgs() << "V: " << *V << "\n");
1835 LLVM_DEBUG(dbgs() << "SV: " << *SV << "\n");
1836 assert(getShadowTy(V) == SV->getType() &&
1837 "setShadow called with mismatching types");
1838 }
1839
1840 ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
1841 }
1842
1843 /// Set Origin to be the origin value for V.
1844 void setOrigin(Value *V, Value *Origin) {
1845 if (!MS.TrackOrigins)
1846 return;
1847 assert(!OriginMap.count(V) && "Values may only have one origin");
1848 LLVM_DEBUG(dbgs() << "ORIGIN: " << *V << " ==> " << *Origin << "\n");
1849 OriginMap[V] = Origin;
1850 }
1851
1852 Constant *getCleanShadow(Type *OrigTy) {
1853 Type *ShadowTy = getShadowTy(OrigTy);
1854 if (!ShadowTy)
1855 return nullptr;
1856 return Constant::getNullValue(ShadowTy);
1857 }
1858
1859 /// Create a clean shadow value for a given value.
1860 ///
1861 /// Clean shadow (all zeroes) means all bits of the value are defined
1862 /// (initialized).
1863 Constant *getCleanShadow(Value *V) { return getCleanShadow(V->getType()); }
1864
1865 /// Create a dirty shadow of a given shadow type.
1866 Constant *getPoisonedShadow(Type *ShadowTy) {
1867 assert(ShadowTy);
1868 if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
1869 return Constant::getAllOnesValue(ShadowTy);
1870 if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) {
1871 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
1872 getPoisonedShadow(AT->getElementType()));
1873 return ConstantArray::get(AT, Vals);
1874 }
1875 if (StructType *ST = dyn_cast<StructType>(ShadowTy)) {
1876 SmallVector<Constant *, 4> Vals;
1877 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1878 Vals.push_back(getPoisonedShadow(ST->getElementType(i)));
1879 return ConstantStruct::get(ST, Vals);
1880 }
1881 llvm_unreachable("Unexpected shadow type");
1882 }
1883
1884 /// Create a dirty shadow for a given value.
1885 Constant *getPoisonedShadow(Value *V) {
1886 Type *ShadowTy = getShadowTy(V);
1887 if (!ShadowTy)
1888 return nullptr;
1889 return getPoisonedShadow(ShadowTy);
1890 }
1891
1892 /// Create a clean (zero) origin.
1893 Value *getCleanOrigin() { return Constant::getNullValue(MS.OriginTy); }
1894
1895 /// Get the shadow value for a given Value.
1896 ///
1897 /// This function either returns the value set earlier with setShadow,
1898 /// or extracts if from ParamTLS (for function arguments).
1899 Value *getShadow(Value *V) {
1900 if (Instruction *I = dyn_cast<Instruction>(V)) {
1901 if (!PropagateShadow || I->getMetadata(LLVMContext::MD_nosanitize))
1902 return getCleanShadow(V);
1903 // For instructions the shadow is already stored in the map.
1904 Value *Shadow = ShadowMap[V];
1905 if (!Shadow) {
1906 LLVM_DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent()));
1907 assert(Shadow && "No shadow for a value");
1908 }
1909 return Shadow;
1910 }
1911 // Handle fully undefined values
1912 // (partially undefined constant vectors are handled later)
1913 if ([[maybe_unused]] UndefValue *U = dyn_cast<UndefValue>(V)) {
1914 Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
1915 : getCleanShadow(V);
1916 LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n");
1917 return AllOnes;
1918 }
1919 if (Argument *A = dyn_cast<Argument>(V)) {
1920 // For arguments we compute the shadow on demand and store it in the map.
1921 Value *&ShadowPtr = ShadowMap[V];
1922 if (ShadowPtr)
1923 return ShadowPtr;
1924 Function *F = A->getParent();
1925 IRBuilder<> EntryIRB(FnPrologueEnd);
1926 unsigned ArgOffset = 0;
1927 const DataLayout &DL = F->getDataLayout();
1928 for (auto &FArg : F->args()) {
1929 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
1930 LLVM_DEBUG(dbgs() << (FArg.getType()->isScalableTy()
1931 ? "vscale not fully supported\n"
1932 : "Arg is not sized\n"));
1933 if (A == &FArg) {
1934 ShadowPtr = getCleanShadow(V);
1935 setOrigin(A, getCleanOrigin());
1936 break;
1937 }
1938 continue;
1939 }
1940
1941 unsigned Size = FArg.hasByValAttr()
1942 ? DL.getTypeAllocSize(FArg.getParamByValType())
1943 : DL.getTypeAllocSize(FArg.getType());
1944
1945 if (A == &FArg) {
1946 bool Overflow = ArgOffset + Size > kParamTLSSize;
1947 if (FArg.hasByValAttr()) {
1948 // ByVal pointer itself has clean shadow. We copy the actual
1949 // argument shadow to the underlying memory.
1950 // Figure out maximal valid memcpy alignment.
1951 const Align ArgAlign = DL.getValueOrABITypeAlignment(
1952 FArg.getParamAlign(), FArg.getParamByValType());
1953 Value *CpShadowPtr, *CpOriginPtr;
1954 std::tie(CpShadowPtr, CpOriginPtr) =
1955 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
1956 /*isStore*/ true);
1957 if (!PropagateShadow || Overflow) {
1958 // ParamTLS overflow.
1959 EntryIRB.CreateMemSet(
1960 CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()),
1961 Size, ArgAlign);
1962 } else {
1963 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1964 const Align CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
1965 [[maybe_unused]] Value *Cpy = EntryIRB.CreateMemCpy(
1966 CpShadowPtr, CopyAlign, Base, CopyAlign, Size);
1967 LLVM_DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n");
1968
1969 if (MS.TrackOrigins) {
1970 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1971 // FIXME: OriginSize should be:
1972 // alignTo(V % kMinOriginAlignment + Size, kMinOriginAlignment)
1973 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
1974 EntryIRB.CreateMemCpy(
1975 CpOriginPtr,
1976 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginPtr,
1977 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
1978 OriginSize);
1979 }
1980 }
1981 }
1982
1983 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
1984 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
1985 ShadowPtr = getCleanShadow(V);
1986 setOrigin(A, getCleanOrigin());
1987 } else {
1988 // Shadow over TLS
1989 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1990 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg), Base,
1992 if (MS.TrackOrigins) {
1993 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1994 setOrigin(A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
1995 }
1996 }
1998 << " ARG: " << FArg << " ==> " << *ShadowPtr << "\n");
1999 break;
2000 }
2001
2002 ArgOffset += alignTo(Size, kShadowTLSAlignment);
2003 }
2004 assert(ShadowPtr && "Could not find shadow for an argument");
2005 return ShadowPtr;
2006 }
2007
2008 // Check for partially-undefined constant vectors
2009 // TODO: scalable vectors (this is hard because we do not have IRBuilder)
2010 if (isa<FixedVectorType>(V->getType()) && isa<Constant>(V) &&
2011 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2012 PoisonUndefVectors) {
2013 unsigned NumElems = cast<FixedVectorType>(V->getType())->getNumElements();
2014 SmallVector<Constant *, 32> ShadowVector(NumElems);
2015 for (unsigned i = 0; i != NumElems; ++i) {
2016 Constant *Elem = cast<Constant>(V)->getAggregateElement(i);
2017 ShadowVector[i] = isa<UndefValue>(Elem) ? getPoisonedShadow(Elem)
2018 : getCleanShadow(Elem);
2019 }
2020
2021 Value *ShadowConstant = ConstantVector::get(ShadowVector);
2022 LLVM_DEBUG(dbgs() << "Partial undef constant vector: " << *V << " ==> "
2023 << *ShadowConstant << "\n");
2024
2025 return ShadowConstant;
2026 }
2027
2028 // TODO: partially-undefined constant arrays, structures, and nested types
2029
2030 // For everything else the shadow is zero.
2031 return getCleanShadow(V);
2032 }
2033
2034 /// Get the shadow for i-th argument of the instruction I.
2035 Value *getShadow(Instruction *I, int i) {
2036 return getShadow(I->getOperand(i));
2037 }
2038
2039 /// Get the origin for a value.
2040 Value *getOrigin(Value *V) {
2041 if (!MS.TrackOrigins)
2042 return nullptr;
2043 if (!PropagateShadow || isa<Constant>(V) || isa<InlineAsm>(V))
2044 return getCleanOrigin();
2046 "Unexpected value type in getOrigin()");
2047 if (Instruction *I = dyn_cast<Instruction>(V)) {
2048 if (I->getMetadata(LLVMContext::MD_nosanitize))
2049 return getCleanOrigin();
2050 }
2051 Value *Origin = OriginMap[V];
2052 assert(Origin && "Missing origin");
2053 return Origin;
2054 }
2055
2056 /// Get the origin for i-th argument of the instruction I.
2057 Value *getOrigin(Instruction *I, int i) {
2058 return getOrigin(I->getOperand(i));
2059 }
2060
2061 /// Remember the place where a shadow check should be inserted.
2062 ///
2063 /// This location will be later instrumented with a check that will print a
2064 /// UMR warning in runtime if the shadow value is not 0.
2065 void insertCheckShadow(Value *Shadow, Value *Origin, Instruction *OrigIns) {
2066 assert(Shadow);
2067 if (!InsertChecks)
2068 return;
2069
2070 if (!DebugCounter::shouldExecute(DebugInsertCheck)) {
2071 LLVM_DEBUG(dbgs() << "Skipping check of " << *Shadow << " before "
2072 << *OrigIns << "\n");
2073 return;
2074 }
2075
2076 Type *ShadowTy = Shadow->getType();
2077 if (isScalableNonVectorType(ShadowTy)) {
2078 LLVM_DEBUG(dbgs() << "Skipping check of scalable non-vector " << *Shadow
2079 << " before " << *OrigIns << "\n");
2080 return;
2081 }
2082#ifndef NDEBUG
2083 assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
2084 isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
2085 "Can only insert checks for integer, vector, and aggregate shadow "
2086 "types");
2087#endif
2088 InstrumentationList.push_back(
2089 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2090 }
2091
2092 /// Get shadow for value, and remember the place where a shadow check should
2093 /// be inserted.
2094 ///
2095 /// This location will be later instrumented with a check that will print a
2096 /// UMR warning in runtime if the value is not fully defined.
2097 void insertCheckShadowOf(Value *Val, Instruction *OrigIns) {
2098 assert(Val);
2099 Value *Shadow, *Origin;
2100 if (Opts.msan_check_constant_shadow) {
2101 Shadow = getShadow(Val);
2102 if (!Shadow)
2103 return;
2104 Origin = getOrigin(Val);
2105 } else {
2106 Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
2107 if (!Shadow)
2108 return;
2109 Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
2110 }
2111 insertCheckShadow(Shadow, Origin, OrigIns);
2112 }
2113
2115 switch (a) {
2116 case AtomicOrdering::NotAtomic:
2117 return AtomicOrdering::NotAtomic;
2118 case AtomicOrdering::Unordered:
2119 case AtomicOrdering::Monotonic:
2120 case AtomicOrdering::Release:
2121 return AtomicOrdering::Release;
2122 case AtomicOrdering::Acquire:
2123 case AtomicOrdering::AcquireRelease:
2124 return AtomicOrdering::AcquireRelease;
2125 case AtomicOrdering::SequentiallyConsistent:
2126 return AtomicOrdering::SequentiallyConsistent;
2127 }
2128 llvm_unreachable("Unknown ordering");
2129 }
2130
2131 Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
2132 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2133 uint32_t OrderingTable[NumOrderings] = {};
2134
2135 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2136 OrderingTable[(int)AtomicOrderingCABI::release] =
2137 (int)AtomicOrderingCABI::release;
2138 OrderingTable[(int)AtomicOrderingCABI::consume] =
2139 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2140 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2141 (int)AtomicOrderingCABI::acq_rel;
2142 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2143 (int)AtomicOrderingCABI::seq_cst;
2144
2145 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2146 }
2147
2149 switch (a) {
2150 case AtomicOrdering::NotAtomic:
2151 return AtomicOrdering::NotAtomic;
2152 case AtomicOrdering::Unordered:
2153 case AtomicOrdering::Monotonic:
2154 case AtomicOrdering::Acquire:
2155 return AtomicOrdering::Acquire;
2156 case AtomicOrdering::Release:
2157 case AtomicOrdering::AcquireRelease:
2158 return AtomicOrdering::AcquireRelease;
2159 case AtomicOrdering::SequentiallyConsistent:
2160 return AtomicOrdering::SequentiallyConsistent;
2161 }
2162 llvm_unreachable("Unknown ordering");
2163 }
2164
2165 Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
2166 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2167 uint32_t OrderingTable[NumOrderings] = {};
2168
2169 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2170 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2171 OrderingTable[(int)AtomicOrderingCABI::consume] =
2172 (int)AtomicOrderingCABI::acquire;
2173 OrderingTable[(int)AtomicOrderingCABI::release] =
2174 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2175 (int)AtomicOrderingCABI::acq_rel;
2176 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2177 (int)AtomicOrderingCABI::seq_cst;
2178
2179 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2180 }
2181
2182 // ------------------- Visitors.
2183 using InstVisitor<MemorySanitizerVisitor>::visit;
2184 void visit(Instruction &I) {
2185 if (I.getMetadata(LLVMContext::MD_nosanitize))
2186 return;
2187 // Don't want to visit if we're in the prologue
2188 if (isInPrologue(I))
2189 return;
2190 if (!DebugCounter::shouldExecute(DebugInstrumentInstruction)) {
2191 LLVM_DEBUG(dbgs() << "Skipping instruction: " << I << "\n");
2192 // We still need to set the shadow and origin to clean values.
2193 setShadow(&I, getCleanShadow(&I));
2194 setOrigin(&I, getCleanOrigin());
2195 return;
2196 }
2197
2198 Instructions.push_back(&I);
2199 }
2200
2201 /// Instrument LoadInst
2202 ///
2203 /// Loads the corresponding shadow and (optionally) origin.
2204 /// Optionally, checks that the load address is fully defined.
2205 void visitLoadInst(LoadInst &I) {
2206 assert(I.getType()->isSized() && "Load type must have size");
2207 assert(!I.getMetadata(LLVMContext::MD_nosanitize));
2208 NextNodeIRBuilder IRB(&I);
2209 Type *ShadowTy = getShadowTy(&I);
2210 Value *Addr = I.getPointerOperand();
2211 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
2212 const Align Alignment = I.getAlign();
2213 if (PropagateShadow) {
2214 std::tie(ShadowPtr, OriginPtr) =
2215 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
2216 setShadow(&I,
2217 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2218 } else {
2219 setShadow(&I, getCleanShadow(&I));
2220 }
2221
2222 if (Opts.msan_check_access_address)
2223 insertCheckShadowOf(I.getPointerOperand(), &I);
2224
2225 if (I.isAtomic())
2226 I.setOrdering(addAcquireOrdering(I.getOrdering()));
2227
2228 if (MS.TrackOrigins) {
2229 if (PropagateShadow) {
2230 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
2231 setOrigin(
2232 &I, IRB.CreateAlignedLoad(MS.OriginTy, OriginPtr, OriginAlignment));
2233 } else {
2234 setOrigin(&I, getCleanOrigin());
2235 }
2236 }
2237 }
2238
2239 /// Instrument StoreInst
2240 ///
2241 /// Stores the corresponding shadow and (optionally) origin.
2242 /// Optionally, checks that the store address is fully defined.
2243 void visitStoreInst(StoreInst &I) {
2244 StoreList.push_back(&I);
2245 if (Opts.msan_check_access_address)
2246 insertCheckShadowOf(I.getPointerOperand(), &I);
2247 }
2248
2249 void handleCASOrRMW(Instruction &I) {
2251
2252 IRBuilder<> IRB(&I);
2253 Value *Addr = I.getOperand(0);
2254 Value *Val = I.getOperand(1);
2255 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val), Align(1),
2256 /*isStore*/ true)
2257 .first;
2258
2259 if (Opts.msan_check_access_address)
2260 insertCheckShadowOf(Addr, &I);
2261
2262 // Only test the conditional argument of cmpxchg instruction.
2263 // The other argument can potentially be uninitialized, but we can not
2264 // detect this situation reliably without possible false positives.
2266 insertCheckShadowOf(Val, &I);
2267
2268 IRB.CreateStore(getCleanShadow(Val), ShadowPtr);
2269
2270 setShadow(&I, getCleanShadow(&I));
2271 setOrigin(&I, getCleanOrigin());
2272 }
2273
2274 void visitAtomicRMWInst(AtomicRMWInst &I) {
2275 handleCASOrRMW(I);
2276 I.setOrdering(addReleaseOrdering(I.getOrdering()));
2277 }
2278
2279 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
2280 handleCASOrRMW(I);
2281 I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
2282 }
2283
2284 /// Generic handler to compute shadow for == and != comparisons.
2285 ///
2286 /// This function is used by handleEqualityComparison and visitSwitchInst.
2287 ///
2288 /// Sometimes the comparison result is known even if some of the bits of the
2289 /// arguments are not.
2290 Value *propagateEqualityComparison(IRBuilder<> &IRB, Value *A, Value *B,
2291 Value *Sa, Value *Sb) {
2292 assert(getShadowTy(A) == Sa->getType());
2293 assert(getShadowTy(B) == Sb->getType());
2294
2295 // Get rid of pointers and vectors of pointers.
2296 // For ints (and vectors of ints), types of A and Sa match,
2297 // and this is a no-op.
2298 A = IRB.CreatePointerCast(A, Sa->getType());
2299 B = IRB.CreatePointerCast(B, Sb->getType());
2300
2301 // A == B <==> (C = A^B) == 0
2302 // A != B <==> (C = A^B) != 0
2303 // Sc = Sa | Sb
2304 Value *C = IRB.CreateXor(A, B);
2305 Value *Sc = IRB.CreateOr(Sa, Sb);
2306 // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
2307 // Result is defined if one of the following is true
2308 // * there is a defined 1 bit in C
2309 // * C is fully defined
2310 // Si = !(C & ~Sc) && Sc
2312 Value *MinusOne = Constant::getAllOnesValue(Sc->getType());
2313 Value *LHS = IRB.CreateICmpNE(Sc, Zero);
2314 Value *RHS =
2315 IRB.CreateICmpEQ(IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero);
2316 Value *Si = IRB.CreateAnd(LHS, RHS);
2317 Si->setName("_msprop_icmp");
2318
2319 return Si;
2320 }
2321
2322 // Instrument:
2323 // switch i32 %Val, label %else [ i32 0, label %A
2324 // i32 1, label %B
2325 // i32 2, label %C ]
2326 //
2327 // Typically, the switch input value (%Val) is fully initialized.
2328 //
2329 // Sometimes the compiler may convert (icmp + br) into a switch statement.
2330 // MSan allows icmp eq/ne with partly initialized inputs to still result in a
2331 // fully initialized output, if there exists a bit that is initialized in
2332 // both inputs with a differing value. For compatibility, we support this in
2333 // the switch instrumentation as well. Note that this edge case only applies
2334 // if the switch input value does not match *any* of the cases (matching any
2335 // of the cases requires an exact, fully initialized match).
2336 //
2337 // ShadowCases = 0
2338 // | propagateEqualityComparison(Val, 0)
2339 // | propagateEqualityComparison(Val, 1)
2340 // | propagateEqualityComparison(Val, 2))
2341 void visitSwitchInst(SwitchInst &SI) {
2342 IRBuilder<> IRB(&SI);
2343
2344 Value *Val = SI.getCondition();
2345 Value *ShadowVal = getShadow(Val);
2346 // TODO: add fast path - if the condition is fully initialized, we know
2347 // there is no UUM, without needing to consider the case values below.
2348
2349 // Some code (e.g., AMDGPUGenMCCodeEmitter.inc) has tens of thousands of
2350 // cases. This results in an extremely long chained expression for MSan's
2351 // switch instrumentation, which can cause the JumpThreadingPass to have a
2352 // stack overflow or excessive runtime. We limit the number of cases
2353 // considered, with the tradeoff of niche false negatives.
2354 // TODO: figure out a better solution.
2355 int casesToConsider = Opts.msan_switch_precision;
2356
2357 Value *ShadowCases = nullptr;
2358 for (auto Case : SI.cases()) {
2359 if (casesToConsider <= 0)
2360 break;
2361
2362 Value *Comparator = Case.getCaseValue();
2363 // TODO: some simplification is possible when comparing multiple cases
2364 // simultaneously.
2365 Value *ComparisonShadow = propagateEqualityComparison(
2366 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2367
2368 if (ShadowCases)
2369 ShadowCases = IRB.CreateOr(ShadowCases, ComparisonShadow);
2370 else
2371 ShadowCases = ComparisonShadow;
2372
2373 casesToConsider--;
2374 }
2375
2376 if (ShadowCases)
2377 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2378 }
2379
2380 // Vector manipulation.
2381 void visitExtractElementInst(ExtractElementInst &I) {
2382 insertCheckShadowOf(I.getOperand(1), &I);
2383 IRBuilder<> IRB(&I);
2384 setShadow(&I, IRB.CreateExtractElement(getShadow(&I, 0), I.getOperand(1),
2385 "_msprop"));
2386 setOrigin(&I, getOrigin(&I, 0));
2387 }
2388
2389 void visitInsertElementInst(InsertElementInst &I) {
2390 insertCheckShadowOf(I.getOperand(2), &I);
2391 IRBuilder<> IRB(&I);
2392 auto *Shadow0 = getShadow(&I, 0);
2393 auto *Shadow1 = getShadow(&I, 1);
2394 setShadow(&I, IRB.CreateInsertElement(Shadow0, Shadow1, I.getOperand(2),
2395 "_msprop"));
2396 setOriginForNaryOp(I);
2397 }
2398
2399 void visitShuffleVectorInst(ShuffleVectorInst &I) {
2400 IRBuilder<> IRB(&I);
2401 auto *Shadow0 = getShadow(&I, 0);
2402 auto *Shadow1 = getShadow(&I, 1);
2403 setShadow(&I, IRB.CreateShuffleVector(Shadow0, Shadow1, I.getShuffleMask(),
2404 "_msprop"));
2405 setOriginForNaryOp(I);
2406 }
2407
2408 // Casts.
2409 void visitSExtInst(SExtInst &I) {
2410 IRBuilder<> IRB(&I);
2411 setShadow(&I, IRB.CreateSExt(getShadow(&I, 0), I.getType(), "_msprop"));
2412 setOrigin(&I, getOrigin(&I, 0));
2413 }
2414
2415 void visitZExtInst(ZExtInst &I) {
2416 IRBuilder<> IRB(&I);
2417 setShadow(&I, IRB.CreateZExt(getShadow(&I, 0), I.getType(), "_msprop"));
2418 setOrigin(&I, getOrigin(&I, 0));
2419 }
2420
2421 void visitTruncInst(TruncInst &I) {
2422 IRBuilder<> IRB(&I);
2423 setShadow(&I, IRB.CreateTrunc(getShadow(&I, 0), I.getType(), "_msprop"));
2424 setOrigin(&I, getOrigin(&I, 0));
2425 }
2426
2427 void visitBitCastInst(BitCastInst &I) {
2428 // Special case: if this is the bitcast (there is exactly 1 allowed) between
2429 // a musttail call and a ret, don't instrument. New instructions are not
2430 // allowed after a musttail call.
2431 if (auto *CI = dyn_cast<CallInst>(I.getOperand(0)))
2432 if (CI->isMustTailCall())
2433 return;
2434 IRBuilder<> IRB(&I);
2435 setShadow(&I, IRB.CreateBitCast(getShadow(&I, 0), getShadowTy(&I)));
2436 setOrigin(&I, getOrigin(&I, 0));
2437 }
2438
2439 void visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
2440 IRBuilder<> IRB(&I);
2441 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2442 "_msprop_addrspacecast"));
2443 setOrigin(&I, getOrigin(&I, 0));
2444 }
2445
2446 void visitPtrToIntInst(PtrToIntInst &I) {
2447 IRBuilder<> IRB(&I);
2448 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2449 "_msprop_ptrtoint"));
2450 setOrigin(&I, getOrigin(&I, 0));
2451 }
2452
2453 void visitPtrToAddrInst(PtrToAddrInst &I) {
2454 IRBuilder<> IRB(&I);
2455 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2456 "_msprop_ptrtoaddr"));
2457 setOrigin(&I, getOrigin(&I, 0));
2458 }
2459
2460 void visitIntToPtrInst(IntToPtrInst &I) {
2461 IRBuilder<> IRB(&I);
2462 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2463 "_msprop_inttoptr"));
2464 setOrigin(&I, getOrigin(&I, 0));
2465 }
2466
2467 /// Handle LLVM and NEON vector convert intrinsics.
2468 ///
2469 /// e.g., <4 x i32> @llvm.aarch64.neon.fcvtpu.v4i32.v4f32(<4 x float>)
2470 /// i32 @llvm.aarch64.neon.fcvtms.i32.f64 (double)
2471 /// <2 x i32> @fptoui (<2 x float>)
2472 /// i64 @llvm.fptosi.sat.i64.f64(double)
2473 ///
2474 /// Note that the size of input/output elements can differ e.g.,
2475 /// double @sitofp(i32)
2476 /// but the number of elements must be the same.
2477 ///
2478 /// For conversions to or from fixed-point, there is a trailing argument to
2479 /// indicate the fixed-point precision:
2480 /// - <4 x float> llvm.aarch64.neon.vcvtfxs2fp.v4f32.v4i32(<4 x i32>, i32)
2481 /// - <4 x i32> llvm.aarch64.neon.vcvtfp2fxu.v4i32.v4f32(<4 x float>, i32)
2482 ///
2483 /// For x86 SSE vector convert intrinsics, see
2484 /// handleSSEVectorConvertIntrinsic().
2485 void handleGenericVectorConvertIntrinsic(Instruction &I, bool FixedPoint) {
2486 [[maybe_unused]] unsigned NumArgs = I.getNumOperands();
2487 if (auto *CI = dyn_cast<CallInst>(&I))
2488 NumArgs = CI->arg_size();
2489
2490 if (FixedPoint) {
2491 assert(NumArgs == 2);
2492 Value *Precision = I.getOperand(1);
2493 insertCheckShadowOf(Precision, &I);
2494 } else {
2495 assert(NumArgs == 1);
2496 }
2497
2498 IRBuilder<> IRB(&I);
2499 Value *S0 = getShadow(&I, 0);
2500
2501 /// For scalars:
2502 /// Since they are converting from floating-point to integer, or between
2503 /// different width floating-point values, the output is:
2504 /// - fully uninitialized if *any* bit of the input is uninitialized
2505 /// - fully ininitialized if all bits of the input are ininitialized
2506 /// We apply the same principle on a per-field basis for vectors.
2507 Value *OutShadow = IRB.CreateSExt(IRB.CreateICmpNE(S0, getCleanShadow(S0)),
2508 getShadowTy(&I));
2509 setShadow(&I, OutShadow);
2510 setOriginForNaryOp(I);
2511 }
2512
2513 void visitFPToSIInst(CastInst &I) {
2514 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2515 }
2516 void visitFPToUIInst(CastInst &I) {
2517 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2518 }
2519 void visitSIToFPInst(CastInst &I) {
2520 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2521 }
2522 void visitUIToFPInst(CastInst &I) {
2523 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2524 }
2525
2526 void visitFPExtInst(CastInst &I) {
2527 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2528 }
2529 void visitFPTruncInst(CastInst &I) {
2530 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2531 }
2532
2533 /// Generic handler to compute shadow for bitwise AND.
2534 ///
2535 /// This is used by 'visitAnd' but also as a primitive for other handlers.
2536 ///
2537 /// This code is precise: it implements the rule that "And" of an initialized
2538 /// zero bit always results in an initialized value:
2539 // 1&1 => 1; 0&1 => 0; p&1 => p;
2540 // 1&0 => 0; 0&0 => 0; p&0 => 0;
2541 // 1&p => p; 0&p => 0; p&p => p;
2542 //
2543 // S = (S1 & S2) | (V1 & S2) | (S1 & V2)
2544 Value *handleBitwiseAnd(IRBuilder<> &IRB, Value *V1, Value *V2, Value *S1,
2545 Value *S2) {
2546 // "The two arguments to the ‘and’ instruction must be integer or vector
2547 // of integer values. Both arguments must have identical types."
2548 //
2549 // We enforce this condition for all callers to handleBitwiseAnd(); callers
2550 // with non-integer types should call CreateAppToShadowCast() themselves.
2551 assert(V1->getType()->isIntOrIntVectorTy());
2552 assert(V1->getType() == V2->getType());
2553
2554 // Conveniently, getShadowTy() of Int/IntVector returns the original type.
2555 assert(V1->getType() == S1->getType());
2556 assert(V2->getType() == S2->getType());
2557
2558 Value *S1S2 = IRB.CreateAnd(S1, S2);
2559 Value *V1S2 = IRB.CreateAnd(V1, S2);
2560 Value *S1V2 = IRB.CreateAnd(S1, V2);
2561
2562 return IRB.CreateOr({S1S2, V1S2, S1V2});
2563 }
2564
2565 /// Handler for bitwise AND operator.
2566 void visitAnd(BinaryOperator &I) {
2567 IRBuilder<> IRB(&I);
2568 Value *V1 = I.getOperand(0);
2569 Value *V2 = I.getOperand(1);
2570 Value *S1 = getShadow(&I, 0);
2571 Value *S2 = getShadow(&I, 1);
2572
2573 Value *OutShadow = handleBitwiseAnd(IRB, V1, V2, S1, S2);
2574
2575 setShadow(&I, OutShadow);
2576 setOriginForNaryOp(I);
2577 }
2578
2579 void visitOr(BinaryOperator &I) {
2580 IRBuilder<> IRB(&I);
2581 // "Or" of 1 and a poisoned value results in unpoisoned value:
2582 // 1|1 => 1; 0|1 => 1; p|1 => 1;
2583 // 1|0 => 1; 0|0 => 0; p|0 => p;
2584 // 1|p => 1; 0|p => p; p|p => p;
2585 //
2586 // S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2)
2587 //
2588 // If the "disjoint OR" property is violated, the result is poison, and
2589 // hence the entire shadow is uninitialized:
2590 // S = S | SignExt(V1 & V2 != 0)
2591 Value *S1 = getShadow(&I, 0);
2592 Value *S2 = getShadow(&I, 1);
2593 Value *V1 = I.getOperand(0);
2594 Value *V2 = I.getOperand(1);
2595
2596 // "The two arguments to the ‘or’ instruction must be integer or vector
2597 // of integer values. Both arguments must have identical types."
2598 assert(V1->getType()->isIntOrIntVectorTy());
2599 assert(V1->getType() == V2->getType());
2600
2601 // Conveniently, getShadowTy() of Int/IntVector returns the original type.
2602 assert(V1->getType() == S1->getType());
2603 assert(V2->getType() == S2->getType());
2604
2605 Value *NotV1 = IRB.CreateNot(V1);
2606 Value *NotV2 = IRB.CreateNot(V2);
2607
2608 Value *S1S2 = IRB.CreateAnd(S1, S2);
2609 Value *S2NotV1 = IRB.CreateAnd(NotV1, S2);
2610 Value *S1NotV2 = IRB.CreateAnd(S1, NotV2);
2611
2612 Value *S = IRB.CreateOr({S1S2, S2NotV1, S1NotV2});
2613
2614 if (Opts.msan_precise_disjoint_or &&
2615 cast<PossiblyDisjointInst>(&I)->isDisjoint()) {
2616 Value *V1V2 = IRB.CreateAnd(V1, V2);
2617 Value *DisjointOrShadow = IRB.CreateSExt(
2618 IRB.CreateICmpNE(V1V2, getCleanShadow(V1V2)), V1V2->getType());
2619 S = IRB.CreateOr(S, DisjointOrShadow, "_ms_disjoint");
2620 }
2621
2622 setShadow(&I, S);
2623 setOriginForNaryOp(I);
2624 }
2625
2626 /// Default propagation of shadow and/or origin.
2627 ///
2628 /// This class implements the general case of shadow propagation, used in all
2629 /// cases where we don't know and/or don't care about what the operation
2630 /// actually does. It converts all input shadow values to a common type
2631 /// (extending or truncating as necessary), and bitwise OR's them.
2632 ///
2633 /// This is much cheaper than inserting checks (i.e. requiring inputs to be
2634 /// fully initialized), and less prone to false positives.
2635 ///
2636 /// This class also implements the general case of origin propagation. For a
2637 /// Nary operation, result origin is set to the origin of an argument that is
2638 /// not entirely initialized. If there is more than one such arguments, the
2639 /// rightmost of them is picked. It does not matter which one is picked if all
2640 /// arguments are initialized.
2641 template <bool CombineShadow> class Combiner {
2642 Value *Shadow = nullptr;
2643 Value *Origin = nullptr;
2644 IRBuilder<> &IRB;
2645 MemorySanitizerVisitor *MSV;
2646
2647 public:
2648 Combiner(MemorySanitizerVisitor *MSV, IRBuilder<> &IRB)
2649 : IRB(IRB), MSV(MSV) {}
2650
2651 /// Add a pair of shadow and origin values to the mix.
2652 Combiner &Add(Value *OpShadow, Value *OpOrigin) {
2653 if (CombineShadow) {
2654 assert(OpShadow);
2655 if (!Shadow)
2656 Shadow = OpShadow;
2657 else {
2658 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2659 Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop");
2660 }
2661 }
2662
2663 if (MSV->MS.TrackOrigins) {
2664 assert(OpOrigin);
2665 if (!Origin) {
2666 Origin = OpOrigin;
2667 } else {
2668 Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
2669 // No point in adding something that might result in 0 origin value.
2670 if (!ConstOrigin || !ConstOrigin->isNullValue()) {
2671 Value *Cond = MSV->convertToBool(OpShadow, IRB);
2672 Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
2673 }
2674 }
2675 }
2676 return *this;
2677 }
2678
2679 /// Add an application value to the mix.
2680 Combiner &Add(Value *V) {
2681 Value *OpShadow = MSV->getShadow(V);
2682 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : nullptr;
2683 return Add(OpShadow, OpOrigin);
2684 }
2685
2686 /// Set the current combined values as the given instruction's shadow
2687 /// and origin.
2688 void Done(Instruction *I) {
2689 if (CombineShadow) {
2690 assert(Shadow);
2691 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
2692 MSV->setShadow(I, Shadow);
2693 }
2694 if (MSV->MS.TrackOrigins) {
2695 assert(Origin);
2696 MSV->setOrigin(I, Origin);
2697 }
2698 }
2699
2700 /// Store the current combined value at the specified origin
2701 /// location.
2702 void DoneAndStoreOrigin(TypeSize TS, Value *OriginPtr) {
2703 if (MSV->MS.TrackOrigins) {
2704 assert(Origin);
2705 MSV->paintOrigin(IRB, Origin, OriginPtr, TS, kMinOriginAlignment);
2706 }
2707 }
2708 };
2709
2710 using ShadowAndOriginCombiner = Combiner<true>;
2711 using OriginCombiner = Combiner<false>;
2712
2713 /// Propagate origin for arbitrary operation.
2714 void setOriginForNaryOp(Instruction &I) {
2715 if (!MS.TrackOrigins)
2716 return;
2717 IRBuilder<> IRB(&I);
2718 OriginCombiner OC(this, IRB);
2719 for (Use &Op : I.operands())
2720 OC.Add(Op.get());
2721 OC.Done(&I);
2722 }
2723
2724 size_t VectorOrPrimitiveTypeSizeInBits(Type *Ty) {
2725 assert(!(Ty->isVectorTy() && Ty->getScalarType()->isPointerTy()) &&
2726 "Vector of pointers is not a valid shadow type");
2727 return Ty->isVectorTy() ? cast<FixedVectorType>(Ty)->getNumElements() *
2729 : Ty->getPrimitiveSizeInBits();
2730 }
2731
2732 /// Cast between two shadow types, extending or truncating as
2733 /// necessary.
2734 Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
2735 bool Signed = false) {
2736 Type *srcTy = V->getType();
2737 if (srcTy == dstTy)
2738 return V;
2739 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2740 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2741 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2742 return IRB.CreateICmpNE(V, getCleanShadow(V));
2743
2744 if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
2745 return IRB.CreateIntCast(V, dstTy, Signed);
2746 if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
2747 cast<VectorType>(dstTy)->getElementCount() ==
2748 cast<VectorType>(srcTy)->getElementCount())
2749 return IRB.CreateIntCast(V, dstTy, Signed);
2750 Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
2751 Value *V2 =
2752 IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
2753 return IRB.CreateBitCast(V2, dstTy);
2754 // TODO: handle struct types.
2755 }
2756
2757 /// Cast an application value to the type of its own shadow.
2758 Value *CreateAppToShadowCast(IRBuilder<> &IRB, Value *V) {
2759 Type *ShadowTy = getShadowTy(V);
2760 if (V->getType() == ShadowTy)
2761 return V;
2762 if (V->getType()->isPtrOrPtrVectorTy())
2763 return IRB.CreatePtrToInt(V, ShadowTy);
2764 else
2765 return IRB.CreateBitCast(V, ShadowTy);
2766 }
2767
2768 /// Propagate shadow for arbitrary operation.
2769 void handleShadowOr(Instruction &I) {
2770 IRBuilder<> IRB(&I);
2771 ShadowAndOriginCombiner SC(this, IRB);
2772 for (Use &Op : I.operands())
2773 SC.Add(Op.get());
2774 SC.Done(&I);
2775 }
2776
2777 // Perform a bitwise OR on the horizontal pairs (or other specified grouping)
2778 // of elements.
2779 //
2780 // For example, suppose we have:
2781 // VectorA: <a0, a1, a2, a3, a4, a5>
2782 // VectorB: <b0, b1, b2, b3, b4, b5>
2783 // ReductionFactor: 3
2784 // Shards: 1
2785 // The output would be:
2786 // <a0|a1|a2, a3|a4|a5, b0|b1|b2, b3|b4|b5>
2787 //
2788 // If we have:
2789 // VectorA: <a0, a1, a2, a3, a4, a5, a6, a7>
2790 // VectorB: <b0, b1, b2, b3, b4, b5, b6, b7>
2791 // ReductionFactor: 2
2792 // Shards: 2
2793 // then a and be each have 2 "shards", resulting in the output being
2794 // interleaved:
2795 // <a0|a1, a2|a3, b0|b1, b2|b3, a4|a5, a6|a7, b4|b5, b6|b7>
2796 //
2797 // This is convenient for instrumenting horizontal add/sub.
2798 // For bitwise OR on "vertical" pairs, see maybeHandleSimpleNomemIntrinsic().
2799 Value *horizontalReduce(IntrinsicInst &I, unsigned ReductionFactor,
2800 unsigned Shards, Value *VectorA, Value *VectorB) {
2801 assert(isa<FixedVectorType>(VectorA->getType()));
2802 unsigned NumElems =
2803 cast<FixedVectorType>(VectorA->getType())->getNumElements();
2804
2805 [[maybe_unused]] unsigned TotalNumElems = NumElems;
2806 if (VectorB) {
2807 assert(VectorA->getType() == VectorB->getType());
2808 TotalNumElems *= 2;
2809 }
2810
2811 assert(NumElems % (ReductionFactor * Shards) == 0);
2812
2813 Value *Or = nullptr;
2814
2815 IRBuilder<> IRB(&I);
2816 for (unsigned i = 0; i < ReductionFactor; i++) {
2817 SmallVector<int, 16> Mask;
2818
2819 for (unsigned j = 0; j < Shards; j++) {
2820 unsigned Offset = NumElems / Shards * j;
2821
2822 for (unsigned X = 0; X < NumElems / Shards; X += ReductionFactor)
2823 Mask.push_back(Offset + X + i);
2824
2825 if (VectorB) {
2826 for (unsigned X = 0; X < NumElems / Shards; X += ReductionFactor)
2827 Mask.push_back(NumElems + Offset + X + i);
2828 }
2829 }
2830
2831 Value *Masked;
2832 if (VectorB)
2833 Masked = IRB.CreateShuffleVector(VectorA, VectorB, Mask);
2834 else
2835 Masked = IRB.CreateShuffleVector(VectorA, Mask);
2836
2837 if (Or)
2838 Or = IRB.CreateOr(Or, Masked);
2839 else
2840 Or = Masked;
2841 }
2842
2843 return Or;
2844 }
2845
2846 /// Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
2847 /// fields.
2848 ///
2849 /// e.g., <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16>)
2850 /// <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8>, <16 x i8>)
2851 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &I, unsigned Shards) {
2852 assert(I.arg_size() == 1 || I.arg_size() == 2);
2853
2854 assert(I.getType()->isVectorTy());
2855 assert(I.getArgOperand(0)->getType()->isVectorTy());
2856
2857 [[maybe_unused]] FixedVectorType *ParamType =
2858 cast<FixedVectorType>(I.getArgOperand(0)->getType());
2859 assert((I.arg_size() != 2) ||
2860 (ParamType == cast<FixedVectorType>(I.getArgOperand(1)->getType())));
2861 [[maybe_unused]] FixedVectorType *ReturnType =
2862 cast<FixedVectorType>(I.getType());
2863 assert(ParamType->getNumElements() * I.arg_size() ==
2864 2 * ReturnType->getNumElements());
2865
2866 IRBuilder<> IRB(&I);
2867
2868 // Horizontal OR of shadow
2869 Value *FirstArgShadow = getShadow(&I, 0);
2870 Value *SecondArgShadow = nullptr;
2871 if (I.arg_size() == 2)
2872 SecondArgShadow = getShadow(&I, 1);
2873
2874 Value *OrShadow = horizontalReduce(I, /*ReductionFactor=*/2, Shards,
2875 FirstArgShadow, SecondArgShadow);
2876
2877 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
2878
2879 setShadow(&I, OrShadow);
2880 setOriginForNaryOp(I);
2881 }
2882
2883 /// Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
2884 /// fields, with the parameters reinterpreted to have elements of a specified
2885 /// width. For example:
2886 /// @llvm.x86.ssse3.phadd.w(<1 x i64> [[VAR1]], <1 x i64> [[VAR2]])
2887 /// conceptually operates on
2888 /// (<4 x i16> [[VAR1]], <4 x i16> [[VAR2]])
2889 /// and can be handled with ReinterpretElemWidth == 16.
2890 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &I, unsigned Shards,
2891 int ReinterpretElemWidth) {
2892 assert(I.arg_size() == 1 || I.arg_size() == 2);
2893
2894 assert(I.getType()->isVectorTy());
2895 assert(I.getArgOperand(0)->getType()->isVectorTy());
2896
2897 FixedVectorType *ParamType =
2898 cast<FixedVectorType>(I.getArgOperand(0)->getType());
2899 assert((I.arg_size() != 2) ||
2900 (ParamType == cast<FixedVectorType>(I.getArgOperand(1)->getType())));
2901
2902 [[maybe_unused]] FixedVectorType *ReturnType =
2903 cast<FixedVectorType>(I.getType());
2904 assert(ParamType->getNumElements() * I.arg_size() ==
2905 2 * ReturnType->getNumElements());
2906
2907 IRBuilder<> IRB(&I);
2908
2909 FixedVectorType *ReinterpretShadowTy = nullptr;
2910 assert(isAligned(Align(ReinterpretElemWidth),
2911 ParamType->getPrimitiveSizeInBits()));
2912 ReinterpretShadowTy = FixedVectorType::get(
2913 IRB.getIntNTy(ReinterpretElemWidth),
2914 ParamType->getPrimitiveSizeInBits() / ReinterpretElemWidth);
2915
2916 // Horizontal OR of shadow
2917 Value *FirstArgShadow = getShadow(&I, 0);
2918 FirstArgShadow = IRB.CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
2919
2920 // If we had two parameters each with an odd number of elements, the total
2921 // number of elements is even, but we have never seen this in extant
2922 // instruction sets, so we enforce that each parameter must have an even
2923 // number of elements.
2925 Align(2),
2926 cast<FixedVectorType>(FirstArgShadow->getType())->getNumElements()));
2927
2928 Value *SecondArgShadow = nullptr;
2929 if (I.arg_size() == 2) {
2930 SecondArgShadow = getShadow(&I, 1);
2931 SecondArgShadow = IRB.CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2932 }
2933
2934 Value *OrShadow = horizontalReduce(I, /*ReductionFactor=*/2, Shards,
2935 FirstArgShadow, SecondArgShadow);
2936
2937 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
2938
2939 setShadow(&I, OrShadow);
2940 setOriginForNaryOp(I);
2941 }
2942
2943 void visitFNeg(UnaryOperator &I) { handleShadowOr(I); }
2944
2945 // Handle multiplication by constant.
2946 //
2947 // Handle a special case of multiplication by constant that may have one or
2948 // more zeros in the lower bits. This makes corresponding number of lower bits
2949 // of the result zero as well. We model it by shifting the other operand
2950 // shadow left by the required number of bits. Effectively, we transform
2951 // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B).
2952 // We use multiplication by 2**N instead of shift to cover the case of
2953 // multiplication by 0, which may occur in some elements of a vector operand.
2954 void handleMulByConstant(BinaryOperator &I, Constant *ConstArg,
2955 Value *OtherArg) {
2956 Constant *ShadowMul;
2957 Type *Ty = ConstArg->getType();
2958 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
2959 unsigned NumElements = cast<FixedVectorType>(VTy)->getNumElements();
2960 Type *EltTy = VTy->getElementType();
2962 for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
2963 if (ConstantInt *Elt =
2965 const APInt &V = Elt->getValue();
2966 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
2967 Elements.push_back(ConstantInt::get(EltTy, V2));
2968 } else {
2969 Elements.push_back(ConstantInt::get(EltTy, 1));
2970 }
2971 }
2972 ShadowMul = ConstantVector::get(Elements);
2973 } else {
2974 if (ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg)) {
2975 const APInt &V = Elt->getValue();
2976 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
2977 ShadowMul = ConstantInt::get(Ty, V2);
2978 } else {
2979 ShadowMul = ConstantInt::get(Ty, 1);
2980 }
2981 }
2982
2983 IRBuilder<> IRB(&I);
2984 setShadow(&I,
2985 IRB.CreateMul(getShadow(OtherArg), ShadowMul, "msprop_mul_cst"));
2986 setOrigin(&I, getOrigin(OtherArg));
2987 }
2988
2989 void visitMul(BinaryOperator &I) {
2990 Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
2991 Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
2992 if (constOp0 && !constOp1)
2993 handleMulByConstant(I, constOp0, I.getOperand(1));
2994 else if (constOp1 && !constOp0)
2995 handleMulByConstant(I, constOp1, I.getOperand(0));
2996 else
2997 handleShadowOr(I);
2998 }
2999
3000 void visitFAdd(BinaryOperator &I) { handleShadowOr(I); }
3001 void visitFSub(BinaryOperator &I) { handleShadowOr(I); }
3002 void visitFMul(BinaryOperator &I) { handleShadowOr(I); }
3003 void visitAdd(BinaryOperator &I) { handleShadowOr(I); }
3004 void visitSub(BinaryOperator &I) { handleShadowOr(I); }
3005 void visitXor(BinaryOperator &I) { handleShadowOr(I); }
3006
3007 void handleIntegerDiv(Instruction &I) {
3008 IRBuilder<> IRB(&I);
3009 // Strict on the second argument.
3010 insertCheckShadowOf(I.getOperand(1), &I);
3011 setShadow(&I, getShadow(&I, 0));
3012 setOrigin(&I, getOrigin(&I, 0));
3013 }
3014
3015 void visitUDiv(BinaryOperator &I) { handleIntegerDiv(I); }
3016 void visitSDiv(BinaryOperator &I) { handleIntegerDiv(I); }
3017 void visitURem(BinaryOperator &I) { handleIntegerDiv(I); }
3018 void visitSRem(BinaryOperator &I) { handleIntegerDiv(I); }
3019
3020 // Floating point division is side-effect free. We can not require that the
3021 // divisor is fully initialized and must propagate shadow. See PR37523.
3022 void visitFDiv(BinaryOperator &I) { handleShadowOr(I); }
3023 void visitFRem(BinaryOperator &I) { handleShadowOr(I); }
3024
3025 /// Instrument == and != comparisons.
3026 ///
3027 /// Sometimes the comparison result is known even if some of the bits of the
3028 /// arguments are not.
3029 void handleEqualityComparison(ICmpInst &I) {
3030 IRBuilder<> IRB(&I);
3031 Value *A = I.getOperand(0);
3032 Value *B = I.getOperand(1);
3033 Value *Sa = getShadow(A);
3034 Value *Sb = getShadow(B);
3035
3036 Value *Si = propagateEqualityComparison(IRB, A, B, Sa, Sb);
3037
3038 setShadow(&I, Si);
3039 setOriginForNaryOp(I);
3040 }
3041
3042 /// Instrument relational comparisons.
3043 ///
3044 /// This function does exact shadow propagation for all relational
3045 /// comparisons of integers, pointers and vectors of those.
3046 /// FIXME: output seems suboptimal when one of the operands is a constant
3047 void handleRelationalComparisonExact(ICmpInst &I) {
3048 IRBuilder<> IRB(&I);
3049 Value *A = I.getOperand(0);
3050 Value *B = I.getOperand(1);
3051 Value *Sa = getShadow(A);
3052 Value *Sb = getShadow(B);
3053
3054 // Get rid of pointers and vectors of pointers.
3055 // For ints (and vectors of ints), types of A and Sa match,
3056 // and this is a no-op.
3057 A = IRB.CreatePointerCast(A, Sa->getType());
3058 B = IRB.CreatePointerCast(B, Sb->getType());
3059
3060 // Let [a0, a1] be the interval of possible values of A, taking into account
3061 // its undefined bits. Let [b0, b1] be the interval of possible values of B.
3062 // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
3063 bool IsSigned = I.isSigned();
3064
3065 auto GetMinMaxUnsigned = [&](Value *V, Value *S) {
3066 if (IsSigned) {
3067 // Sign-flip to map from signed range to unsigned range. Relation A vs B
3068 // should be preserved, if checked with `getUnsignedPredicate()`.
3069 // Relationship between Amin, Amax, Bmin, Bmax also will not be
3070 // affected, as they are created by effectively adding/substructing from
3071 // A (or B) a value, derived from shadow, with no overflow, either
3072 // before or after sign flip.
3073 APInt MinVal =
3074 APInt::getSignedMinValue(V->getType()->getScalarSizeInBits());
3075 V = IRB.CreateXor(V, ConstantInt::get(V->getType(), MinVal));
3076 }
3077 // Minimize undefined bits.
3078 Value *Min = IRB.CreateAnd(V, IRB.CreateNot(S));
3079 Value *Max = IRB.CreateOr(V, S);
3080 return std::make_pair(Min, Max);
3081 };
3082
3083 auto [Amin, Amax] = GetMinMaxUnsigned(A, Sa);
3084 auto [Bmin, Bmax] = GetMinMaxUnsigned(B, Sb);
3085 Value *S1 = IRB.CreateICmp(I.getUnsignedPredicate(), Amin, Bmax);
3086 Value *S2 = IRB.CreateICmp(I.getUnsignedPredicate(), Amax, Bmin);
3087
3088 Value *Si = IRB.CreateXor(S1, S2);
3089 setShadow(&I, Si);
3090 setOriginForNaryOp(I);
3091 }
3092
3093 /// Instrument signed relational comparisons.
3094 ///
3095 /// Handle sign bit tests: x<0, x>=0, x<=-1, x>-1 by propagating the highest
3096 /// bit of the shadow. Everything else is delegated to handleShadowOr().
3097 void handleSignedRelationalComparison(ICmpInst &I) {
3098 Constant *constOp;
3099 Value *op = nullptr;
3101 if ((constOp = dyn_cast<Constant>(I.getOperand(1)))) {
3102 op = I.getOperand(0);
3103 pre = I.getPredicate();
3104 } else if ((constOp = dyn_cast<Constant>(I.getOperand(0)))) {
3105 op = I.getOperand(1);
3106 pre = I.getSwappedPredicate();
3107 } else {
3108 handleShadowOr(I);
3109 return;
3110 }
3111
3112 if ((constOp->isNullValue() &&
3113 (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) ||
3114 (constOp->isAllOnesValue() &&
3115 (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE))) {
3116 IRBuilder<> IRB(&I);
3117 Value *Shadow = IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op),
3118 "_msprop_icmp_s");
3119 setShadow(&I, Shadow);
3120 setOrigin(&I, getOrigin(op));
3121 } else {
3122 handleShadowOr(I);
3123 }
3124 }
3125
3126 void visitICmpInst(ICmpInst &I) {
3127 if (!Opts.msan_handle_icmp) {
3128 handleShadowOr(I);
3129 return;
3130 }
3131 if (I.isEquality()) {
3132 handleEqualityComparison(I);
3133 return;
3134 }
3135
3136 assert(I.isRelational());
3137 if (Opts.msan_handle_icmp_exact) {
3138 handleRelationalComparisonExact(I);
3139 return;
3140 }
3141 if (I.isSigned()) {
3142 handleSignedRelationalComparison(I);
3143 return;
3144 }
3145
3146 assert(I.isUnsigned());
3147 if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
3148 handleRelationalComparisonExact(I);
3149 return;
3150 }
3151
3152 handleShadowOr(I);
3153 }
3154
3155 void visitFCmpInst(FCmpInst &I) { handleShadowOr(I); }
3156
3157 void handleShift(BinaryOperator &I) {
3158 IRBuilder<> IRB(&I);
3159 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3160 // Otherwise perform the same shift on S1.
3161 Value *S1 = getShadow(&I, 0);
3162 Value *S2 = getShadow(&I, 1);
3163 Value *S2Conv =
3164 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
3165 Value *V2 = I.getOperand(1);
3166 Value *Shift = IRB.CreateBinOp(I.getOpcode(), S1, V2);
3167 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3168 setOriginForNaryOp(I);
3169 }
3170
3171 void visitShl(BinaryOperator &I) { handleShift(I); }
3172 void visitAShr(BinaryOperator &I) { handleShift(I); }
3173 void visitLShr(BinaryOperator &I) { handleShift(I); }
3174
3175 void handleFunnelShift(IntrinsicInst &I) {
3176 IRBuilder<> IRB(&I);
3177 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3178 // Otherwise perform the same shift on S0 and S1.
3179 Value *S0 = getShadow(&I, 0);
3180 Value *S1 = getShadow(&I, 1);
3181 Value *S2 = getShadow(&I, 2);
3182 Value *S2Conv =
3183 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
3184 Value *V2 = I.getOperand(2);
3185 Value *Shift = IRB.CreateIntrinsic(I.getIntrinsicID(), S2Conv->getType(),
3186 {S0, S1, V2});
3187 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3188 setOriginForNaryOp(I);
3189 }
3190
3191 // Instrument bit manipulation intrinsics.
3192 // All of these intrinsics are Z = I(SRC, MASK)
3193 // where the types of all operands and the result match.
3194 // The following instrumentation happens to work for all of them:
3195 // Sz = I(Ssrc, MASK) | (sext (Smask != 0))
3196 void handleGenericBitManipulation(IntrinsicInst &I) {
3197 IRBuilder<> IRB(&I);
3198 Type *ShadowTy = getShadowTy(&I);
3199
3200 // If any bit of the mask operand is poisoned, then the whole thing is.
3201 Value *SMask = getShadow(&I, 1);
3202 SMask = IRB.CreateSExt(IRB.CreateICmpNE(SMask, getCleanShadow(ShadowTy)),
3203 ShadowTy);
3204 // Apply the same intrinsic to the shadow of the first operand.
3205 Value *S;
3206 if (Function *Func = I.getCalledFunction())
3207 S = IRB.CreateCall(Func, {getShadow(&I, 0), I.getOperand(1)});
3208 else
3209 S = IRB.CreateIntrinsic(I.getIntrinsicID(), ShadowTy,
3210 {getShadow(&I, 0), I.getOperand(1)});
3211
3212 setShadow(&I, IRB.CreateOr(SMask, S));
3213 setOriginForNaryOp(I);
3214 }
3215
3216 /// Instrument llvm.memmove
3217 ///
3218 /// At this point we don't know if llvm.memmove will be inlined or not.
3219 /// If we don't instrument it and it gets inlined,
3220 /// our interceptor will not kick in and we will lose the memmove.
3221 /// If we instrument the call here, but it does not get inlined,
3222 /// we will memmove the shadow twice: which is bad in case
3223 /// of overlapping regions. So, we simply lower the intrinsic to a call.
3224 ///
3225 /// Similar situation exists for memcpy and memset.
3226 void visitMemMoveInst(MemMoveInst &I) {
3227 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
3228 IRBuilder<> IRB(&I);
3229 IRB.CreateCall(MS.MemmoveFn,
3230 {I.getArgOperand(0), I.getArgOperand(1),
3231 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3233 }
3234
3235 /// Instrument memcpy
3236 ///
3237 /// Similar to memmove: avoid copying shadow twice. This is somewhat
3238 /// unfortunate as it may slowdown small constant memcpys.
3239 /// FIXME: consider doing manual inline for small constant sizes and proper
3240 /// alignment.
3241 ///
3242 /// Note: This also handles memcpy.inline, which promises no calls to external
3243 /// functions as an optimization. However, with instrumentation enabled this
3244 /// is difficult to promise; additionally, we know that the MSan runtime
3245 /// exists and provides __msan_memcpy(). Therefore, we assume that with
3246 /// instrumentation it's safe to turn memcpy.inline into a call to
3247 /// __msan_memcpy(). Should this be wrong, such as when implementing memcpy()
3248 /// itself, instrumentation should be disabled with the no_sanitize attribute.
3249 void visitMemCpyInst(MemCpyInst &I) {
3250 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
3251 IRBuilder<> IRB(&I);
3252 IRB.CreateCall(MS.MemcpyFn,
3253 {I.getArgOperand(0), I.getArgOperand(1),
3254 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3256 }
3257
3258 // Same as memcpy.
3259 void visitMemSetInst(MemSetInst &I) {
3260 IRBuilder<> IRB(&I);
3261 IRB.CreateCall(
3262 MS.MemsetFn,
3263 {I.getArgOperand(0),
3264 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3265 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3267 }
3268
3269 void visitVAStartInst(VAStartInst &I) { VAHelper->visitVAStartInst(I); }
3270
3271 void visitVACopyInst(VACopyInst &I) { VAHelper->visitVACopyInst(I); }
3272
3273 /// Handle vector store-like intrinsics.
3274 ///
3275 /// Instrument intrinsics that look like a simple SIMD store: writes memory,
3276 /// has 1 pointer argument and 1 vector argument, returns void.
3277 bool handleVectorStoreIntrinsic(IntrinsicInst &I) {
3278 assert(I.arg_size() == 2);
3279
3280 IRBuilder<> IRB(&I);
3281 Value *Addr = I.getArgOperand(0);
3282 Value *Shadow = getShadow(&I, 1);
3283 Value *ShadowPtr, *OriginPtr;
3284
3285 // We don't know the pointer alignment (could be unaligned SSE store!).
3286 // Have to assume to worst case.
3287 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3288 Addr, IRB, Shadow->getType(), Align(1), /*isStore*/ true);
3289 IRB.CreateAlignedStore(Shadow, ShadowPtr, Align(1));
3290
3291 if (Opts.msan_check_access_address)
3292 insertCheckShadowOf(Addr, &I);
3293
3294 // FIXME: factor out common code from materializeStores
3295 if (MS.TrackOrigins)
3296 IRB.CreateStore(getOrigin(&I, 1), OriginPtr);
3297 return true;
3298 }
3299
3300 /// Handle vector load-like intrinsics.
3301 ///
3302 /// Instrument intrinsics that look like a simple SIMD load: reads memory,
3303 /// has 1 pointer argument, returns a vector.
3304 bool handleVectorLoadIntrinsic(IntrinsicInst &I) {
3305 assert(I.arg_size() == 1);
3306
3307 IRBuilder<> IRB(&I);
3308 Value *Addr = I.getArgOperand(0);
3309
3310 Type *ShadowTy = getShadowTy(&I);
3311 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
3312 if (PropagateShadow) {
3313 // We don't know the pointer alignment (could be unaligned SSE load!).
3314 // Have to assume to worst case.
3315 const Align Alignment = Align(1);
3316 std::tie(ShadowPtr, OriginPtr) =
3317 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
3318 setShadow(&I,
3319 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
3320 } else {
3321 setShadow(&I, getCleanShadow(&I));
3322 }
3323
3324 if (Opts.msan_check_access_address)
3325 insertCheckShadowOf(Addr, &I);
3326
3327 if (MS.TrackOrigins) {
3328 if (PropagateShadow)
3329 setOrigin(&I, IRB.CreateLoad(MS.OriginTy, OriginPtr));
3330 else
3331 setOrigin(&I, getCleanOrigin());
3332 }
3333 return true;
3334 }
3335
3336 /// Handle (SIMD arithmetic)-like intrinsics.
3337 ///
3338 /// Instrument intrinsics with any number of arguments of the same type [*],
3339 /// equal to the return type, plus a specified number of trailing flags of
3340 /// any type.
3341 ///
3342 /// [*] The type should be simple (no aggregates or pointers; vectors are
3343 /// fine).
3344 ///
3345 /// Caller guarantees that this intrinsic does not access memory.
3346 ///
3347 /// TODO: "horizontal"/"pairwise" intrinsics are often incorrectly matched by
3348 /// by this handler. See horizontalReduce().
3349 ///
3350 /// TODO: permutation intrinsics are also often incorrectly matched.
3351 [[maybe_unused]] bool
3352 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I,
3353 unsigned int trailingFlags) {
3354 Type *RetTy = I.getType();
3355 if (!(RetTy->isIntOrIntVectorTy() || RetTy->isFPOrFPVectorTy()))
3356 return false;
3357
3358 unsigned NumArgOperands = I.arg_size();
3359 assert(NumArgOperands >= trailingFlags);
3360 for (unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3361 Type *Ty = I.getArgOperand(i)->getType();
3362 if (Ty != RetTy)
3363 return false;
3364 }
3365
3366 IRBuilder<> IRB(&I);
3367 ShadowAndOriginCombiner SC(this, IRB);
3368 for (unsigned i = 0; i < NumArgOperands; ++i)
3369 SC.Add(I.getArgOperand(i));
3370 SC.Done(&I);
3371
3372 return true;
3373 }
3374
3375 /// Returns whether it was able to heuristically instrument unknown
3376 /// intrinsics.
3377 ///
3378 /// The main purpose of this code is to do something reasonable with all
3379 /// random intrinsics we might encounter, most importantly - SIMD intrinsics.
3380 /// We recognize several classes of intrinsics by their argument types and
3381 /// ModRefBehaviour and apply special instrumentation when we are reasonably
3382 /// sure that we know what the intrinsic does.
3383 ///
3384 /// We special-case intrinsics where this approach fails. See llvm.bswap
3385 /// handling as an example of that.
3386 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &I) {
3387 unsigned NumArgOperands = I.arg_size();
3388 if (NumArgOperands == 0)
3389 return false;
3390
3391 if (NumArgOperands == 2 && I.getArgOperand(0)->getType()->isPointerTy() &&
3392 I.getArgOperand(1)->getType()->isVectorTy() &&
3393 I.getType()->isVoidTy() && !I.onlyReadsMemory()) {
3394 // This looks like a vector store.
3395 return handleVectorStoreIntrinsic(I);
3396 }
3397
3398 if (NumArgOperands == 1 && I.getArgOperand(0)->getType()->isPointerTy() &&
3399 I.getType()->isVectorTy() && I.onlyReadsMemory()) {
3400 // This looks like a vector load.
3401 return handleVectorLoadIntrinsic(I);
3402 }
3403
3404 if (I.doesNotAccessMemory())
3405 if (maybeHandleSimpleNomemIntrinsic(I, /*trailingFlags=*/0))
3406 return true;
3407
3408 // FIXME: detect and handle SSE maskstore/maskload?
3409 // Some cases are now handled in handleAVXMasked{Load,Store}.
3410 return false;
3411 }
3412
3413 bool maybeHandleUnknownIntrinsic(IntrinsicInst &I) {
3414 if (maybeHandleUnknownIntrinsicUnlogged(I)) {
3415 if (Opts.msan_dump_heuristic_instructions)
3416 dumpInst(I, "Heuristic");
3417
3418 LLVM_DEBUG(dbgs() << "UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " << I
3419 << "\n");
3420 return true;
3421 } else
3422 return false;
3423 }
3424
3425 void handleInvariantGroup(IntrinsicInst &I) {
3426 setShadow(&I, getShadow(&I, 0));
3427 setOrigin(&I, getOrigin(&I, 0));
3428 }
3429
3430 void handleLifetimeStart(IntrinsicInst &I) {
3431 if (!PoisonStack)
3432 return;
3433 AllocaInst *AI = dyn_cast<AllocaInst>(I.getArgOperand(0));
3434 if (AI)
3435 LifetimeStartList.push_back(std::make_pair(&I, AI));
3436 }
3437
3438 void handleBswap(IntrinsicInst &I) {
3439 IRBuilder<> IRB(&I);
3440 Value *Op = I.getArgOperand(0);
3441 Type *OpType = Op->getType();
3442 setShadow(&I, IRB.CreateIntrinsic(Intrinsic::bswap, ArrayRef(&OpType, 1),
3443 getShadow(Op)));
3444 setOrigin(&I, getOrigin(Op));
3445 }
3446
3447 // Uninitialized bits are ok if they appear after the leading/trailing 0's
3448 // and a 1. If the input is all zero, it is fully initialized iff
3449 // !is_zero_poison.
3450 //
3451 // e.g., for ctlz, with little-endian, if 0/1 are initialized bits with
3452 // concrete value 0/1, and ? is an uninitialized bit:
3453 // - 0001 0??? is fully initialized
3454 // - 000? ???? is fully uninitialized (*)
3455 // - ???? ???? is fully uninitialized
3456 // - 0000 0000 is fully uninitialized if is_zero_poison,
3457 // fully initialized otherwise
3458 //
3459 // (*) TODO: arguably, since the number of zeros is in the range [3, 8], we
3460 // only need to poison 4 bits.
3461 //
3462 // OutputShadow =
3463 // ((ConcreteZerosCount >= ShadowZerosCount) && !AllZeroShadow)
3464 // || (is_zero_poison && AllZeroSrc)
3465 void handleCountLeadingTrailingZeros(IntrinsicInst &I) {
3466 IRBuilder<> IRB(&I);
3467 Value *Src = I.getArgOperand(0);
3468 Value *SrcShadow = getShadow(Src);
3469
3470 Value *False = IRB.getInt1(false);
3471 Value *ConcreteZerosCount = IRB.CreateIntrinsic(
3472 I.getType(), I.getIntrinsicID(), {Src, /*is_zero_poison=*/False});
3473 Value *ShadowZerosCount = IRB.CreateIntrinsic(
3474 I.getType(), I.getIntrinsicID(), {SrcShadow, /*is_zero_poison=*/False});
3475
3476 Value *CompareConcreteZeros = IRB.CreateICmpUGE(
3477 ConcreteZerosCount, ShadowZerosCount, "_mscz_cmp_zeros");
3478
3479 Value *NotAllZeroShadow =
3480 IRB.CreateIsNotNull(SrcShadow, "_mscz_shadow_not_null");
3481 Value *OutputShadow =
3482 IRB.CreateAnd(CompareConcreteZeros, NotAllZeroShadow, "_mscz_main");
3483
3484 // If zero poison is requested, mix in with the shadow
3485 Constant *IsZeroPoison = cast<Constant>(I.getOperand(1));
3486 if (!IsZeroPoison->isNullValue()) {
3487 Value *BoolZeroPoison = IRB.CreateIsNull(Src, "_mscz_bzp");
3488 OutputShadow = IRB.CreateOr(OutputShadow, BoolZeroPoison, "_mscz_bs");
3489 }
3490
3491 OutputShadow = IRB.CreateSExt(OutputShadow, getShadowTy(Src), "_mscz_os");
3492
3493 setShadow(&I, OutputShadow);
3494 setOriginForNaryOp(I);
3495 }
3496
3497 /// Some instructions have additional zero-elements in the return type
3498 /// e.g., <16 x i8> @llvm.x86.avx512.mask.pmov.qb.512(<8 x i64>, ...)
3499 ///
3500 /// This function will return a vector type with the same number of elements
3501 /// as the input, but same per-element width as the return value e.g.,
3502 /// <8 x i8>.
3503 FixedVectorType *maybeShrinkVectorShadowType(Value *Src, IntrinsicInst &I) {
3504 assert(isa<FixedVectorType>(getShadowTy(&I)));
3505 FixedVectorType *ShadowType = cast<FixedVectorType>(getShadowTy(&I));
3506
3507 // TODO: generalize beyond 2x?
3508 if (ShadowType->getElementCount() ==
3509 cast<VectorType>(Src->getType())->getElementCount() * 2)
3510 ShadowType = FixedVectorType::getHalfElementsVectorType(ShadowType);
3511
3512 assert(ShadowType->getElementCount() ==
3513 cast<VectorType>(Src->getType())->getElementCount());
3514
3515 return ShadowType;
3516 }
3517
3518 /// Doubles the length of a vector shadow (extending with zeros) if necessary
3519 /// to match the length of the shadow for the instruction.
3520 /// If scalar types of the vectors are different, it will use the type of the
3521 /// input vector.
3522 /// This is more type-safe than CreateShadowCast().
3523 Value *maybeExtendVectorShadowWithZeros(Value *Shadow, IntrinsicInst &I) {
3524 IRBuilder<> IRB(&I);
3526 assert(isa<FixedVectorType>(I.getType()));
3527
3528 Value *FullShadow = getCleanShadow(&I);
3529 unsigned ShadowNumElems =
3530 cast<FixedVectorType>(Shadow->getType())->getNumElements();
3531 unsigned FullShadowNumElems =
3532 cast<FixedVectorType>(FullShadow->getType())->getNumElements();
3533
3534 assert((ShadowNumElems == FullShadowNumElems) ||
3535 (ShadowNumElems * 2 == FullShadowNumElems));
3536
3537 if (ShadowNumElems == FullShadowNumElems) {
3538 FullShadow = Shadow;
3539 } else {
3540 // TODO: generalize beyond 2x?
3541 SmallVector<int, 32> ShadowMask(FullShadowNumElems);
3542 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3543
3544 // Append zeros
3545 FullShadow =
3546 IRB.CreateShuffleVector(Shadow, getCleanShadow(Shadow), ShadowMask);
3547 }
3548
3549 return FullShadow;
3550 }
3551
3552 /// Handle x86 SSE vector conversion.
3553 ///
3554 /// e.g., single-precision to half-precision conversion:
3555 /// <8 x i16> @llvm.x86.vcvtps2ph.256(<8 x float> %a0, i32 0)
3556 /// <8 x i16> @llvm.x86.vcvtps2ph.128(<4 x float> %a0, i32 0)
3557 ///
3558 /// floating-point to integer:
3559 /// <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float>)
3560 /// <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double>)
3561 ///
3562 /// Note: if the output has more elements, they are zero-initialized (and
3563 /// therefore the shadow will also be initialized).
3564 ///
3565 /// This differs from handleSSEVectorConvertIntrinsic() because it
3566 /// propagates uninitialized shadow (instead of checking the shadow).
3567 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &I,
3568 bool HasRoundingMode) {
3569 if (HasRoundingMode) {
3570 assert(I.arg_size() == 2);
3571 [[maybe_unused]] Value *RoundingMode = I.getArgOperand(1);
3572 assert(RoundingMode->getType()->isIntegerTy());
3573 } else {
3574 assert(I.arg_size() == 1);
3575 }
3576
3577 Value *Src = I.getArgOperand(0);
3578 assert(Src->getType()->isVectorTy());
3579
3580 // The return type might have more elements than the input.
3581 // Temporarily shrink the return type's number of elements.
3582 VectorType *ShadowType = maybeShrinkVectorShadowType(Src, I);
3583
3584 IRBuilder<> IRB(&I);
3585 Value *S0 = getShadow(&I, 0);
3586
3587 /// For scalars:
3588 /// Since they are converting to and/or from floating-point, the output is:
3589 /// - fully uninitialized if *any* bit of the input is uninitialized
3590 /// - fully ininitialized if all bits of the input are ininitialized
3591 /// We apply the same principle on a per-field basis for vectors.
3592 Value *Shadow =
3593 IRB.CreateSExt(IRB.CreateICmpNE(S0, getCleanShadow(S0)), ShadowType);
3594
3595 // The return type might have more elements than the input.
3596 // Extend the return type back to its original width if necessary.
3597 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow, I);
3598
3599 setShadow(&I, FullShadow);
3600 setOriginForNaryOp(I);
3601 }
3602
3603 // Instrument x86 SSE vector convert intrinsic.
3604 //
3605 // This function instruments intrinsics like cvtsi2ss:
3606 // %Out = int_xxx_cvtyyy(%ConvertOp)
3607 // or
3608 // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp)
3609 // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same
3610 // number \p Out elements, and (if has 2 arguments) copies the rest of the
3611 // elements from \p CopyOp.
3612 // In most cases conversion involves floating-point value which may trigger a
3613 // hardware exception when not fully initialized. For this reason we require
3614 // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise.
3615 // We copy the shadow of \p CopyOp[NumUsedElements:] to \p
3616 // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
3617 // return a fully initialized value.
3618 //
3619 // For Arm NEON vector convert intrinsics, see
3620 // handleNEONVectorConvertIntrinsic().
3621 void handleSSEVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
3622 bool HasRoundingMode = false) {
3623 IRBuilder<> IRB(&I);
3624 Value *CopyOp, *ConvertOp;
3625
3626 assert((!HasRoundingMode ||
3627 isa<ConstantInt>(I.getArgOperand(I.arg_size() - 1))) &&
3628 "Invalid rounding mode");
3629
3630 switch (I.arg_size() - HasRoundingMode) {
3631 case 2:
3632 CopyOp = I.getArgOperand(0);
3633 ConvertOp = I.getArgOperand(1);
3634 break;
3635 case 1:
3636 ConvertOp = I.getArgOperand(0);
3637 CopyOp = nullptr;
3638 break;
3639 default:
3640 llvm_unreachable("Cvt intrinsic with unsupported number of arguments.");
3641 }
3642
3643 // The first *NumUsedElements* elements of ConvertOp are converted to the
3644 // same number of output elements. The rest of the output is copied from
3645 // CopyOp, or (if not available) filled with zeroes.
3646 // Combine shadow for elements of ConvertOp that are used in this operation,
3647 // and insert a check.
3648 // FIXME: consider propagating shadow of ConvertOp, at least in the case of
3649 // int->any conversion.
3650 Value *ConvertShadow = getShadow(ConvertOp);
3651 Value *AggShadow = nullptr;
3652 if (ConvertOp->getType()->isVectorTy()) {
3653 AggShadow = IRB.CreateExtractElement(
3654 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
3655 for (int i = 1; i < NumUsedElements; ++i) {
3656 Value *MoreShadow = IRB.CreateExtractElement(
3657 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), i));
3658 AggShadow = IRB.CreateOr(AggShadow, MoreShadow);
3659 }
3660 } else {
3661 AggShadow = ConvertShadow;
3662 }
3663 assert(AggShadow->getType()->isIntegerTy());
3664 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &I);
3665
3666 // Build result shadow by zero-filling parts of CopyOp shadow that come from
3667 // ConvertOp.
3668 if (CopyOp) {
3669 assert(CopyOp->getType() == I.getType());
3670 assert(CopyOp->getType()->isVectorTy());
3671 Value *ResultShadow = getShadow(CopyOp);
3672 Type *EltTy = cast<VectorType>(ResultShadow->getType())->getElementType();
3673 for (int i = 0; i < NumUsedElements; ++i) {
3674 ResultShadow = IRB.CreateInsertElement(
3675 ResultShadow, ConstantInt::getNullValue(EltTy),
3676 ConstantInt::get(IRB.getInt32Ty(), i));
3677 }
3678 setShadow(&I, ResultShadow);
3679 setOrigin(&I, getOrigin(CopyOp));
3680 } else {
3681 setShadow(&I, getCleanShadow(&I));
3682 setOrigin(&I, getCleanOrigin());
3683 }
3684 }
3685
3686 // Given a scalar or vector, extract lower 64 bits (or less), and return all
3687 // zeroes if it is zero, and all ones otherwise.
3688 Value *Lower64ShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3689 if (S->getType()->isVectorTy())
3690 S = CreateShadowCast(IRB, S, IRB.getInt64Ty(), /* Signed */ true);
3691 assert(S->getType()->getPrimitiveSizeInBits() <= 64);
3692 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3693 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3694 }
3695
3696 // Given a vector, extract its first element, and return all
3697 // zeroes if it is zero, and all ones otherwise.
3698 Value *LowerElementShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3699 Value *S1 = IRB.CreateExtractElement(S, (uint64_t)0);
3700 Value *S2 = IRB.CreateICmpNE(S1, getCleanShadow(S1));
3701 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3702 }
3703
3704 Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) {
3705 Type *T = S->getType();
3706 assert(T->isVectorTy());
3707 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3708 return IRB.CreateSExt(S2, T);
3709 }
3710
3711 // Instrument vector shift intrinsic.
3712 //
3713 // This function instruments intrinsics like int_x86_avx2_psll_w.
3714 // Intrinsic shifts %In by %ShiftSize bits.
3715 // %ShiftSize may be a vector. In that case the lower 64 bits determine shift
3716 // size, and the rest is ignored. Behavior is defined even if shift size is
3717 // greater than register (or field) width.
3718 void handleVectorShiftIntrinsic(IntrinsicInst &I, bool Variable) {
3719 assert(I.arg_size() == 2);
3720 IRBuilder<> IRB(&I);
3721 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3722 // Otherwise perform the same shift on S1.
3723 Value *S1 = getShadow(&I, 0);
3724 Value *S2 = getShadow(&I, 1);
3725 Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
3726 : Lower64ShadowExtend(IRB, S2, getShadowTy(&I));
3727 Value *V1 = I.getOperand(0);
3728 Value *V2 = I.getOperand(1);
3729 Value *Shift = IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(),
3730 {IRB.CreateBitCast(S1, V1->getType()), V2});
3731 Shift = IRB.CreateBitCast(Shift, getShadowTy(&I));
3732 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3733 setOriginForNaryOp(I);
3734 }
3735
3736 // Get an MMX-sized (64-bit) vector type, or optionally, other sized
3737 // vectors.
3738 Type *getMMXVectorTy(unsigned EltSizeInBits,
3739 unsigned X86_MMXSizeInBits = 64) {
3740 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3741 "Illegal MMX vector element size");
3742 return FixedVectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
3743 X86_MMXSizeInBits / EltSizeInBits);
3744 }
3745
3746 // Returns a signed counterpart for an (un)signed-saturate-and-pack
3747 // intrinsic.
3748 Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
3749 switch (id) {
3750 case Intrinsic::x86_sse2_packsswb_128:
3751 case Intrinsic::x86_sse2_packuswb_128:
3752 return Intrinsic::x86_sse2_packsswb_128;
3753
3754 case Intrinsic::x86_sse2_packssdw_128:
3755 case Intrinsic::x86_sse41_packusdw:
3756 return Intrinsic::x86_sse2_packssdw_128;
3757
3758 case Intrinsic::x86_avx2_packsswb:
3759 case Intrinsic::x86_avx2_packuswb:
3760 return Intrinsic::x86_avx2_packsswb;
3761
3762 case Intrinsic::x86_avx2_packssdw:
3763 case Intrinsic::x86_avx2_packusdw:
3764 return Intrinsic::x86_avx2_packssdw;
3765
3766 case Intrinsic::x86_mmx_packsswb:
3767 case Intrinsic::x86_mmx_packuswb:
3768 return Intrinsic::x86_mmx_packsswb;
3769
3770 case Intrinsic::x86_mmx_packssdw:
3771 return Intrinsic::x86_mmx_packssdw;
3772
3773 case Intrinsic::x86_avx512_packssdw_512:
3774 case Intrinsic::x86_avx512_packusdw_512:
3775 return Intrinsic::x86_avx512_packssdw_512;
3776
3777 case Intrinsic::x86_avx512_packsswb_512:
3778 case Intrinsic::x86_avx512_packuswb_512:
3779 return Intrinsic::x86_avx512_packsswb_512;
3780
3781 default:
3782 llvm_unreachable("unexpected intrinsic id");
3783 }
3784 }
3785
3786 // Instrument vector pack intrinsic.
3787 //
3788 // This function instruments intrinsics like x86_mmx_packsswb, that
3789 // packs elements of 2 input vectors into half as many bits with saturation.
3790 // Shadow is propagated with the signed variant of the same intrinsic applied
3791 // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
3792 // MMXEltSizeInBits is used only for x86mmx arguments.
3793 //
3794 // TODO: consider using GetMinMaxUnsigned() to handle saturation precisely
3795 void handleVectorPackIntrinsic(IntrinsicInst &I,
3796 unsigned MMXEltSizeInBits = 0) {
3797 assert(I.arg_size() == 2);
3798 IRBuilder<> IRB(&I);
3799 Value *S1 = getShadow(&I, 0);
3800 Value *S2 = getShadow(&I, 1);
3801 assert(S1->getType()->isVectorTy());
3802
3803 // SExt and ICmpNE below must apply to individual elements of input vectors.
3804 // In case of x86mmx arguments, cast them to appropriate vector types and
3805 // back.
3806 Type *T =
3807 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) : S1->getType();
3808 if (MMXEltSizeInBits) {
3809 S1 = IRB.CreateBitCast(S1, T);
3810 S2 = IRB.CreateBitCast(S2, T);
3811 }
3812 Value *S1_ext =
3814 Value *S2_ext =
3816 if (MMXEltSizeInBits) {
3817 S1_ext = IRB.CreateBitCast(S1_ext, getMMXVectorTy(64));
3818 S2_ext = IRB.CreateBitCast(S2_ext, getMMXVectorTy(64));
3819 }
3820
3821 Value *S = IRB.CreateIntrinsic(getSignedPackIntrinsic(I.getIntrinsicID()),
3822 {S1_ext, S2_ext}, /*FMFSource=*/nullptr,
3823 "_msprop_vector_pack");
3824 if (MMXEltSizeInBits)
3825 S = IRB.CreateBitCast(S, getShadowTy(&I));
3826 setShadow(&I, S);
3827 setOriginForNaryOp(I);
3828 }
3829
3830 // Convert `Mask` into `<n x i1>`.
3831 Constant *createDppMask(unsigned Width, unsigned Mask) {
3832 SmallVector<Constant *, 4> R(Width);
3833 for (auto &M : R) {
3834 M = ConstantInt::getBool(F.getContext(), Mask & 1);
3835 Mask >>= 1;
3836 }
3837 return ConstantVector::get(R);
3838 }
3839
3840 // Calculate output shadow as array of booleans `<n x i1>`, assuming if any
3841 // arg is poisoned, entire dot product is poisoned.
3842 Value *findDppPoisonedOutput(IRBuilder<> &IRB, Value *S, unsigned SrcMask,
3843 unsigned DstMask) {
3844 const unsigned Width =
3845 cast<FixedVectorType>(S->getType())->getNumElements();
3846
3847 S = IRB.CreateSelect(createDppMask(Width, SrcMask), S,
3849 Value *SElem = IRB.CreateOrReduce(S);
3850 Value *IsClean = IRB.CreateIsNull(SElem, "_msdpp");
3851 Value *DstMaskV = createDppMask(Width, DstMask);
3852
3853 return IRB.CreateSelect(
3854 IsClean, Constant::getNullValue(DstMaskV->getType()), DstMaskV);
3855 }
3856
3857 // See `Intel Intrinsics Guide` for `_dp_p*` instructions.
3858 //
3859 // 2 and 4 element versions produce single scalar of dot product, and then
3860 // puts it into elements of output vector, selected by 4 lowest bits of the
3861 // mask. Top 4 bits of the mask control which elements of input to use for dot
3862 // product.
3863 //
3864 // 8 element version mask still has only 4 bit for input, and 4 bit for output
3865 // mask. According to the spec it just operates as 4 element version on first
3866 // 4 elements of inputs and output, and then on last 4 elements of inputs and
3867 // output.
3868 void handleDppIntrinsic(IntrinsicInst &I) {
3869 IRBuilder<> IRB(&I);
3870
3871 Value *S0 = getShadow(&I, 0);
3872 Value *S1 = getShadow(&I, 1);
3873 Value *S = IRB.CreateOr(S0, S1);
3874
3875 const unsigned Width =
3876 cast<FixedVectorType>(S->getType())->getNumElements();
3877 assert(Width == 2 || Width == 4 || Width == 8);
3878
3879 const unsigned Mask = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
3880 const unsigned SrcMask = Mask >> 4;
3881 const unsigned DstMask = Mask & 0xf;
3882
3883 // Calculate shadow as `<n x i1>`.
3884 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3885 if (Width == 8) {
3886 // First 4 elements of shadow are already calculated. `makeDppShadow`
3887 // operats on 32 bit masks, so we can just shift masks, and repeat.
3888 SI1 = IRB.CreateOr(
3889 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3890 }
3891 // Extend to real size of shadow, poisoning either all or none bits of an
3892 // element.
3893 S = IRB.CreateSExt(SI1, S->getType(), "_msdpp");
3894
3895 setShadow(&I, S);
3896 setOriginForNaryOp(I);
3897 }
3898
3899 Value *convertBlendvToSelectMask(IRBuilder<> &IRB, Value *C) {
3900 C = CreateAppToShadowCast(IRB, C);
3901 FixedVectorType *FVT = cast<FixedVectorType>(C->getType());
3902 unsigned ElSize = FVT->getElementType()->getPrimitiveSizeInBits();
3903 C = IRB.CreateAShr(C, ElSize - 1);
3904 FVT = FixedVectorType::get(IRB.getInt1Ty(), FVT->getNumElements());
3905 return IRB.CreateTrunc(C, FVT);
3906 }
3907
3908 // `blendv(f, t, c)` is effectively `select(c[top_bit], t, f)`.
3909 void handleBlendvIntrinsic(IntrinsicInst &I) {
3910 Value *C = I.getOperand(2);
3911 Value *T = I.getOperand(1);
3912 Value *F = I.getOperand(0);
3913
3914 Value *Sc = getShadow(&I, 2);
3915 Value *Oc = MS.TrackOrigins ? getOrigin(C) : nullptr;
3916
3917 {
3918 IRBuilder<> IRB(&I);
3919 // Extract top bit from condition and its shadow.
3920 C = convertBlendvToSelectMask(IRB, C);
3921 Sc = convertBlendvToSelectMask(IRB, Sc);
3922
3923 setShadow(C, Sc);
3924 setOrigin(C, Oc);
3925 }
3926
3927 handleSelectLikeInst(I, C, T, F);
3928 }
3929
3930 // Instrument sum-of-absolute-differences intrinsic.
3931 void handleVectorSadIntrinsic(IntrinsicInst &I, bool IsMMX = false) {
3932 const unsigned SignificantBitsPerResultElement = 16;
3933 Type *ResTy = IsMMX ? IntegerType::get(*MS.C, 64) : I.getType();
3934 unsigned ZeroBitsPerResultElement =
3935 ResTy->getScalarSizeInBits() - SignificantBitsPerResultElement;
3936
3937 IRBuilder<> IRB(&I);
3938 auto *Shadow0 = getShadow(&I, 0);
3939 auto *Shadow1 = getShadow(&I, 1);
3940 Value *S = IRB.CreateOr(Shadow0, Shadow1);
3941 S = IRB.CreateBitCast(S, ResTy);
3942 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
3943 ResTy);
3944 S = IRB.CreateLShr(S, ZeroBitsPerResultElement);
3945 S = IRB.CreateBitCast(S, getShadowTy(&I));
3946 setShadow(&I, S);
3947 setOriginForNaryOp(I);
3948 }
3949
3950 // Instrument dot-product / multiply-add(-accumulate)? intrinsics.
3951 //
3952 // e.g., Two operands:
3953 // <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a, <8 x i16> %b)
3954 //
3955 // Two operands which require an EltSizeInBits override:
3956 // <1 x i64> @llvm.x86.mmx.pmadd.wd(<1 x i64> %a, <1 x i64> %b)
3957 //
3958 // Three operands:
3959 // <4 x i32> @llvm.x86.avx512.vpdpbusd.128
3960 // (<4 x i32> %s, <16 x i8> %a, <16 x i8> %b)
3961 // <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16
3962 // (<2 x float> %acc, <4 x bfloat> %a, <4 x bfloat> %b)
3963 // (these are equivalent to multiply-add on %a and %b, followed by
3964 // adding/"accumulating" %s. "Accumulation" stores the result in one
3965 // of the source registers, but this accumulate vs. add distinction
3966 // is lost when dealing with LLVM intrinsics.)
3967 //
3968 // ZeroPurifies means that multiplying a known-zero with an uninitialized
3969 // value results in an initialized value. This is applicable for integer
3970 // multiplication, but not floating-point (counter-example: NaN).
3971 void handleVectorDotProductIntrinsic(IntrinsicInst &I,
3972 unsigned ReductionFactor,
3973 bool ZeroPurifies,
3974 unsigned EltSizeInBits,
3975 enum OddOrEvenLanes Lanes) {
3976 IRBuilder<> IRB(&I);
3977
3978 [[maybe_unused]] FixedVectorType *ReturnType =
3979 cast<FixedVectorType>(I.getType());
3980 assert(isa<FixedVectorType>(ReturnType));
3981
3982 // Vectors A and B, and shadows
3983 Value *Va = nullptr;
3984 Value *Vb = nullptr;
3985 Value *Sa = nullptr;
3986 Value *Sb = nullptr;
3987
3988 assert(I.arg_size() == 2 || I.arg_size() == 3);
3989 if (I.arg_size() == 2) {
3990 assert(Lanes == kBothLanes);
3991
3992 Va = I.getOperand(0);
3993 Vb = I.getOperand(1);
3994
3995 Sa = getShadow(&I, 0);
3996 Sb = getShadow(&I, 1);
3997 } else if (I.arg_size() == 3) {
3998 // Operand 0 is the accumulator. We will deal with that below.
3999 Va = I.getOperand(1);
4000 Vb = I.getOperand(2);
4001
4002 Sa = getShadow(&I, 1);
4003 Sb = getShadow(&I, 2);
4004
4005 if (Lanes == kEvenLanes || Lanes == kOddLanes) {
4006 // Convert < S0, S1, S2, S3, S4, S5, S6, S7 >
4007 // to < S0, S0, S2, S2, S4, S4, S6, S6 > (if even)
4008 // to < S1, S1, S3, S3, S5, S5, S7, S7 > (if odd)
4009 //
4010 // Note: for aarch64.neon.bfmlalb/t, the odd/even-indexed values are
4011 // zeroed, not duplicated. However, for shadow propagation, this
4012 // distinction is unimportant because Step 1 below will squeeze
4013 // each pair of elements (e.g., [S0, S0]) into a single bit, and
4014 // we only care if it is fully initialized.
4015
4016 FixedVectorType *InputShadowType = cast<FixedVectorType>(Sa->getType());
4017 unsigned Width = InputShadowType->getNumElements();
4018
4019 Sa = IRB.CreateShuffleVector(
4020 Sa, getPclmulMask(Width, /*OddElements=*/Lanes == kOddLanes));
4021 Sb = IRB.CreateShuffleVector(
4022 Sb, getPclmulMask(Width, /*OddElements=*/Lanes == kOddLanes));
4023 }
4024 }
4025
4026 FixedVectorType *ParamType = cast<FixedVectorType>(Va->getType());
4027 assert(ParamType == Vb->getType());
4028
4029 assert(ParamType->getPrimitiveSizeInBits() ==
4030 ReturnType->getPrimitiveSizeInBits());
4031
4032 if (I.arg_size() == 3) {
4033 [[maybe_unused]] auto *AccumulatorType =
4034 cast<FixedVectorType>(I.getOperand(0)->getType());
4035 assert(AccumulatorType == ReturnType);
4036 }
4037
4038 FixedVectorType *ImplicitReturnType =
4039 cast<FixedVectorType>(getShadowTy(ReturnType));
4040 // Step 1: instrument multiplication of corresponding vector elements
4041 if (EltSizeInBits) {
4042 ImplicitReturnType = cast<FixedVectorType>(
4043 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4044 ParamType->getPrimitiveSizeInBits()));
4045 ParamType = cast<FixedVectorType>(
4046 getMMXVectorTy(EltSizeInBits, ParamType->getPrimitiveSizeInBits()));
4047
4048 Va = IRB.CreateBitCast(Va, ParamType);
4049 Vb = IRB.CreateBitCast(Vb, ParamType);
4050
4051 Sa = IRB.CreateBitCast(Sa, getShadowTy(ParamType));
4052 Sb = IRB.CreateBitCast(Sb, getShadowTy(ParamType));
4053 } else {
4054 assert(ParamType->getNumElements() ==
4055 ReturnType->getNumElements() * ReductionFactor);
4056 }
4057
4058 // Each element of the vector is represented by a single bit (poisoned or
4059 // not) e.g., <8 x i1>.
4060 Value *SaNonZero = IRB.CreateIsNotNull(Sa);
4061 Value *SbNonZero = IRB.CreateIsNotNull(Sb);
4062 Value *And;
4063 if (ZeroPurifies) {
4064 // Multiplying an *initialized* zero by an uninitialized element results
4065 // in an initialized zero element.
4066 //
4067 // This is analogous to bitwise AND, where "AND" of 0 and a poisoned value
4068 // results in an unpoisoned value.
4069 Value *VaInt = Va;
4070 Value *VbInt = Vb;
4071 if (!Va->getType()->isIntegerTy()) {
4072 VaInt = CreateAppToShadowCast(IRB, Va);
4073 VbInt = CreateAppToShadowCast(IRB, Vb);
4074 }
4075
4076 // We check for non-zero on a per-element basis, not per-bit.
4077 Value *VaNonZero = IRB.CreateIsNotNull(VaInt);
4078 Value *VbNonZero = IRB.CreateIsNotNull(VbInt);
4079
4080 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4081 } else {
4082 And = IRB.CreateOr({SaNonZero, SbNonZero});
4083 }
4084
4085 // Extend <8 x i1> to <8 x i16>.
4086 // (The real pmadd intrinsic would have computed intermediate values of
4087 // <8 x i32>, but that is irrelevant for our shadow purposes because we
4088 // consider each element to be either fully initialized or fully
4089 // uninitialized.)
4090 And = IRB.CreateSExt(And, Sa->getType());
4091
4092 // Step 2: instrument horizontal add
4093 // We don't need bit-precise horizontalReduce because we only want to check
4094 // if each pair/quad of elements is fully zero.
4095 // Cast to <4 x i32>.
4096 Value *Horizontal = IRB.CreateBitCast(And, ImplicitReturnType);
4097
4098 // Compute <4 x i1>, then extend back to <4 x i32>.
4099 Value *OutShadow = IRB.CreateSExt(
4100 IRB.CreateICmpNE(Horizontal,
4101 Constant::getNullValue(Horizontal->getType())),
4102 ImplicitReturnType);
4103
4104 // Cast it back to the required fake return type (if MMX: <1 x i64>; for
4105 // AVX, it is already correct).
4106 if (EltSizeInBits)
4107 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&I));
4108
4109 // Step 3 (if applicable): instrument accumulator
4110 if (I.arg_size() == 3)
4111 OutShadow = IRB.CreateOr(OutShadow, getShadow(&I, 0));
4112
4113 setShadow(&I, OutShadow);
4114 setOriginForNaryOp(I);
4115 }
4116
4117 // Instrument compare-packed intrinsic.
4118 //
4119 // x86 has the predicate as the third operand, which is ImmArg e.g.,
4120 // - <4 x double> @llvm.x86.avx.cmp.pd.256(<4 x double>, <4 x double>, i8)
4121 // - <2 x double> @llvm.x86.sse2.cmp.pd(<2 x double>, <2 x double>, i8)
4122 //
4123 // while Arm has separate intrinsics for >= and > e.g.,
4124 // - <2 x i32> @llvm.aarch64.neon.facge.v2i32.v2f32
4125 // (<2 x float> %A, <2 x float>)
4126 // - <2 x i32> @llvm.aarch64.neon.facgt.v2i32.v2f32
4127 // (<2 x float> %A, <2 x float>)
4128 //
4129 // Bonus: this also handles scalar cases e.g.,
4130 // - i32 @llvm.aarch64.neon.facgt.i32.f32(float %A, float %B)
4131 void handleVectorComparePackedIntrinsic(IntrinsicInst &I,
4132 bool PredicateAsOperand) {
4133 if (PredicateAsOperand) {
4134 assert(I.arg_size() == 3);
4135 assert(I.paramHasAttr(2, Attribute::ImmArg));
4136 } else
4137 assert(I.arg_size() == 2);
4138
4139 IRBuilder<> IRB(&I);
4140
4141 // Basically, an or followed by sext(icmp ne 0) to end up with all-zeros or
4142 // all-ones shadow.
4143 Type *ResTy = getShadowTy(&I);
4144 auto *Shadow0 = getShadow(&I, 0);
4145 auto *Shadow1 = getShadow(&I, 1);
4146 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
4147 Value *S = IRB.CreateSExt(
4148 IRB.CreateICmpNE(S0, Constant::getNullValue(ResTy)), ResTy);
4149 setShadow(&I, S);
4150 setOriginForNaryOp(I);
4151 }
4152
4153 // Instrument compare-scalar intrinsic.
4154 // This handles both cmp* intrinsics which return the result in the first
4155 // element of a vector, and comi* which return the result as i32.
4156 void handleVectorCompareScalarIntrinsic(IntrinsicInst &I) {
4157 IRBuilder<> IRB(&I);
4158 auto *Shadow0 = getShadow(&I, 0);
4159 auto *Shadow1 = getShadow(&I, 1);
4160 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
4161 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&I));
4162 setShadow(&I, S);
4163 setOriginForNaryOp(I);
4164 }
4165
4166 // Instrument generic vector reduction intrinsics
4167 // by ORing together all their fields.
4168 //
4169 // If AllowShadowCast is true, the return type does not need to be the same
4170 // type as the fields
4171 // e.g., declare i32 @llvm.aarch64.neon.uaddv.i32.v16i8(<16 x i8>)
4172 void handleVectorReduceIntrinsic(IntrinsicInst &I, bool AllowShadowCast) {
4173 assert(I.arg_size() == 1);
4174
4175 IRBuilder<> IRB(&I);
4176 Value *S = IRB.CreateOrReduce(getShadow(&I, 0));
4177 if (AllowShadowCast)
4178 S = CreateShadowCast(IRB, S, getShadowTy(&I));
4179 else
4180 assert(S->getType() == getShadowTy(&I));
4181 setShadow(&I, S);
4182 setOriginForNaryOp(I);
4183 }
4184
4185 // Similar to handleVectorReduceIntrinsic but with an initial starting value.
4186 // e.g., call float @llvm.vector.reduce.fadd.f32.v2f32(float %a0, <2 x float>
4187 // %a1)
4188 // shadow = shadow[a0] | shadow[a1.0] | shadow[a1.1]
4189 //
4190 // The type of the return value, initial starting value, and elements of the
4191 // vector must be identical.
4192 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &I) {
4193 assert(I.arg_size() == 2);
4194
4195 IRBuilder<> IRB(&I);
4196 Value *Shadow0 = getShadow(&I, 0);
4197 Value *Shadow1 = IRB.CreateOrReduce(getShadow(&I, 1));
4198 assert(Shadow0->getType() == Shadow1->getType());
4199 Value *S = IRB.CreateOr(Shadow0, Shadow1);
4200 assert(S->getType() == getShadowTy(&I));
4201 setShadow(&I, S);
4202 setOriginForNaryOp(I);
4203 }
4204
4205 // e.g., <4 x i32> @llvm.vector.partial.reduce.add (<4 x i32>, <8 x i32>)
4206 // acc addends
4207 // <4 x fp16> @llvm.vector.partial.reduce.fadd(<4 x fp16>, <8 x fp16>)
4208 // acc addends
4209 //
4210 // output[i] = acc[i] + addend[i] + addend[i+4]
4211 //
4212 // We approximate this as "all-or-nothing" for each element of the vector
4213 // i.e., even a single uninitialized bit in acc[i], addend[i], or
4214 // addend[i+4] will make output[i] fully uninitialized.
4215 //
4216 // By converting each vector element to a single value (0 or 1) representing
4217 // whether it is uninitialized, we can apply vector.partial.reduce.add to
4218 // compute the output shadow.
4219 //
4220 // N.B. this function is ready for scalable vectors, but its dependencies
4221 // are not.
4222 void handleVectorPartialReduceAddIntrinsic(IntrinsicInst &I) {
4223 IRBuilder<> IRB(&I);
4224
4225 assert(I.arg_size() == 2);
4226 [[maybe_unused]] Value *Accumulator = I.getArgOperand(0);
4227 [[maybe_unused]] Value *Addends = I.getArgOperand(1);
4228 assert(isa<VectorType>(Accumulator->getType()));
4229 assert(isa<VectorType>(Addends->getType()));
4230
4231 assert(I.getType() == Accumulator->getType());
4232
4233 assert(cast<VectorType>(Addends->getType())->getElementType() ==
4234 cast<VectorType>(I.getType())->getElementType());
4235 assert(cast<VectorType>(Addends->getType())
4236 ->getElementCount()
4237 .isKnownMultipleOf(
4238 cast<VectorType>(I.getType())->getElementCount()));
4239
4240 // e.g., <4 x i32>, <8 x i32>
4241 Value *SAcc = getShadow(&I, 0);
4242 Value *SAdd = getShadow(&I, 1);
4243
4244 // All-or-nothing shadows
4245 // e.g., <4 x i1>, <8 x i1>
4246 SAcc = IRB.CreateICmpNE(SAcc, getCleanShadow(SAcc));
4247 SAdd = IRB.CreateICmpNE(SAdd, getCleanShadow(SAdd));
4248
4249 // If we applied vector.partial.reduce.add to (<M x i1>, <N x i1>) shadows,
4250 // the sums might wrap around. Zero-extend to avoid this.
4251 // 16-bit for each sum (up to 65535) ought to be enough for anybody.
4252 SAcc = IRB.CreateZExt(
4253 SAcc,
4254 VectorType::get(IRB.getInt16Ty(),
4255 cast<VectorType>(SAcc->getType())->getElementCount()));
4256 SAdd = IRB.CreateZExt(
4257 SAdd,
4258 VectorType::get(IRB.getInt16Ty(),
4259 cast<VectorType>(SAdd->getType())->getElementCount()));
4260
4261 Value *SOutput = IRB.CreateIntrinsic(
4262 SAcc->getType(), Intrinsic::vector_partial_reduce_add, {SAcc, SAdd});
4263
4264 SOutput = IRB.CreateSExt(IRB.CreateICmpNE(SOutput, getCleanShadow(SOutput)),
4265 getShadowTy(&I));
4266
4267 setShadow(&I, SOutput);
4268 setOriginForNaryOp(I);
4269 }
4270
4271 // Instrument vector.reduce.or intrinsic.
4272 // Valid (non-poisoned) set bits in the operand pull low the
4273 // corresponding shadow bits.
4274 void handleVectorReduceOrIntrinsic(IntrinsicInst &I) {
4275 assert(I.arg_size() == 1);
4276
4277 IRBuilder<> IRB(&I);
4278 Value *OperandShadow = getShadow(&I, 0);
4279 Value *OperandUnsetBits = IRB.CreateNot(I.getOperand(0));
4280 Value *OperandUnsetOrPoison = IRB.CreateOr(OperandUnsetBits, OperandShadow);
4281 // Bit N is clean if any field's bit N is 1 and unpoison
4282 Value *OutShadowMask = IRB.CreateAndReduce(OperandUnsetOrPoison);
4283 // Otherwise, it is clean if every field's bit N is unpoison
4284 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
4285 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
4286
4287 setShadow(&I, S);
4288 setOrigin(&I, getOrigin(&I, 0));
4289 }
4290
4291 // Instrument vector.reduce.and intrinsic.
4292 // Valid (non-poisoned) unset bits in the operand pull down the
4293 // corresponding shadow bits.
4294 void handleVectorReduceAndIntrinsic(IntrinsicInst &I) {
4295 assert(I.arg_size() == 1);
4296
4297 IRBuilder<> IRB(&I);
4298 Value *OperandShadow = getShadow(&I, 0);
4299 Value *OperandSetOrPoison = IRB.CreateOr(I.getOperand(0), OperandShadow);
4300 // Bit N is clean if any field's bit N is 0 and unpoison
4301 Value *OutShadowMask = IRB.CreateAndReduce(OperandSetOrPoison);
4302 // Otherwise, it is clean if every field's bit N is unpoison
4303 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
4304 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
4305
4306 setShadow(&I, S);
4307 setOrigin(&I, getOrigin(&I, 0));
4308 }
4309
4310 void handleStmxcsr(IntrinsicInst &I) {
4311 IRBuilder<> IRB(&I);
4312 Value *Addr = I.getArgOperand(0);
4313 Type *Ty = IRB.getInt32Ty();
4314 Value *ShadowPtr =
4315 getShadowOriginPtr(Addr, IRB, Ty, Align(1), /*isStore*/ true).first;
4316
4317 IRB.CreateStore(getCleanShadow(Ty), ShadowPtr);
4318
4319 if (Opts.msan_check_access_address)
4320 insertCheckShadowOf(Addr, &I);
4321 }
4322
4323 void handleLdmxcsr(IntrinsicInst &I) {
4324 if (!InsertChecks)
4325 return;
4326
4327 IRBuilder<> IRB(&I);
4328 Value *Addr = I.getArgOperand(0);
4329 Type *Ty = IRB.getInt32Ty();
4330 const Align Alignment = Align(1);
4331 Value *ShadowPtr, *OriginPtr;
4332 std::tie(ShadowPtr, OriginPtr) =
4333 getShadowOriginPtr(Addr, IRB, Ty, Alignment, /*isStore*/ false);
4334
4335 if (Opts.msan_check_access_address)
4336 insertCheckShadowOf(Addr, &I);
4337
4338 Value *Shadow = IRB.CreateAlignedLoad(Ty, ShadowPtr, Alignment, "_ldmxcsr");
4339 Value *Origin = MS.TrackOrigins ? IRB.CreateLoad(MS.OriginTy, OriginPtr)
4340 : getCleanOrigin();
4341 insertCheckShadow(Shadow, Origin, &I);
4342 }
4343
4344 void handleMaskedExpandLoad(IntrinsicInst &I) {
4345 IRBuilder<> IRB(&I);
4346 Value *Ptr = I.getArgOperand(0);
4347 MaybeAlign Align = I.getParamAlign(0);
4348 Value *Mask = I.getArgOperand(1);
4349 Value *PassThru = I.getArgOperand(2);
4350
4351 if (Opts.msan_check_access_address) {
4352 insertCheckShadowOf(Ptr, &I);
4353 insertCheckShadowOf(Mask, &I);
4354 }
4355
4356 if (!PropagateShadow) {
4357 setShadow(&I, getCleanShadow(&I));
4358 setOrigin(&I, getCleanOrigin());
4359 return;
4360 }
4361
4362 Type *ShadowTy = getShadowTy(&I);
4363 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
4364 auto [ShadowPtr, OriginPtr] =
4365 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align, /*isStore*/ false);
4366
4367 Value *Shadow =
4368 IRB.CreateMaskedExpandLoad(ShadowTy, ShadowPtr, Align, Mask,
4369 getShadow(PassThru), "_msmaskedexpload");
4370
4371 setShadow(&I, Shadow);
4372
4373 // TODO: Store origins.
4374 setOrigin(&I, getCleanOrigin());
4375 }
4376
4377 void handleMaskedCompressStore(IntrinsicInst &I) {
4378 IRBuilder<> IRB(&I);
4379 Value *Values = I.getArgOperand(0);
4380 Value *Ptr = I.getArgOperand(1);
4381 MaybeAlign Align = I.getParamAlign(1);
4382 Value *Mask = I.getArgOperand(2);
4383
4384 if (Opts.msan_check_access_address) {
4385 insertCheckShadowOf(Ptr, &I);
4386 insertCheckShadowOf(Mask, &I);
4387 }
4388
4389 Value *Shadow = getShadow(Values);
4390 Type *ElementShadowTy =
4391 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
4392 auto [ShadowPtr, OriginPtrs] =
4393 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align, /*isStore*/ true);
4394
4395 IRB.CreateMaskedCompressStore(Shadow, ShadowPtr, Align, Mask);
4396
4397 // TODO: Store origins.
4398 }
4399
4400 void handleMaskedGather(IntrinsicInst &I) {
4401 IRBuilder<> IRB(&I);
4402 Value *Ptrs = I.getArgOperand(0);
4403 const Align Alignment = I.getParamAlign(0).valueOrOne();
4404 Value *Mask = I.getArgOperand(1);
4405 Value *PassThru = I.getArgOperand(2);
4406
4407 Type *PtrsShadowTy = getShadowTy(Ptrs);
4408 if (Opts.msan_check_access_address) {
4409 insertCheckShadowOf(Mask, &I);
4410 Value *MaskedPtrShadow = IRB.CreateSelect(
4411 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
4412 "_msmaskedptrs");
4413 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &I);
4414 }
4415
4416 if (!PropagateShadow) {
4417 setShadow(&I, getCleanShadow(&I));
4418 setOrigin(&I, getCleanOrigin());
4419 return;
4420 }
4421
4422 Type *ShadowTy = getShadowTy(&I);
4423 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
4424 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4425 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ false);
4426
4427 Value *Shadow =
4428 IRB.CreateMaskedGather(ShadowTy, ShadowPtrs, Alignment, Mask,
4429 getShadow(PassThru), "_msmaskedgather");
4430
4431 setShadow(&I, Shadow);
4432
4433 // TODO: Store origins.
4434 setOrigin(&I, getCleanOrigin());
4435 }
4436
4437 void handleMaskedScatter(IntrinsicInst &I) {
4438 IRBuilder<> IRB(&I);
4439 Value *Values = I.getArgOperand(0);
4440 Value *Ptrs = I.getArgOperand(1);
4441 const Align Alignment = I.getParamAlign(1).valueOrOne();
4442 Value *Mask = I.getArgOperand(2);
4443
4444 Type *PtrsShadowTy = getShadowTy(Ptrs);
4445 if (Opts.msan_check_access_address) {
4446 insertCheckShadowOf(Mask, &I);
4447 Value *MaskedPtrShadow = IRB.CreateSelect(
4448 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
4449 "_msmaskedptrs");
4450 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &I);
4451 }
4452
4453 Value *Shadow = getShadow(Values);
4454 Type *ElementShadowTy =
4455 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
4456 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4457 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ true);
4458
4459 IRB.CreateMaskedScatter(Shadow, ShadowPtrs, Alignment, Mask);
4460
4461 // TODO: Store origin.
4462 }
4463
4464 // Intrinsic::masked_store
4465 //
4466 // Note: handleAVXMaskedStore handles AVX/AVX2 variants, though AVX512 masked
4467 // stores are lowered to Intrinsic::masked_store.
4468 void handleMaskedStore(IntrinsicInst &I) {
4469 IRBuilder<> IRB(&I);
4470 Value *V = I.getArgOperand(0);
4471 Value *Ptr = I.getArgOperand(1);
4472 const Align Alignment = I.getParamAlign(1).valueOrOne();
4473 Value *Mask = I.getArgOperand(2);
4474 Value *Shadow = getShadow(V);
4475
4476 if (Opts.msan_check_access_address) {
4477 insertCheckShadowOf(Ptr, &I);
4478 insertCheckShadowOf(Mask, &I);
4479 }
4480
4481 Value *ShadowPtr;
4482 Value *OriginPtr;
4483 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4484 Ptr, IRB, Shadow->getType(), Alignment, /*isStore*/ true);
4485
4486 IRB.CreateMaskedStore(Shadow, ShadowPtr, Alignment, Mask);
4487
4488 if (!MS.TrackOrigins)
4489 return;
4490
4491 auto &DL = F.getDataLayout();
4492 paintOrigin(IRB, getOrigin(V), OriginPtr,
4493 DL.getTypeStoreSize(Shadow->getType()),
4494 std::max(Alignment, kMinOriginAlignment));
4495 }
4496
4497 // Intrinsic::masked_load
4498 //
4499 // Note: handleAVXMaskedLoad handles AVX/AVX2 variants, though AVX512 masked
4500 // loads are lowered to Intrinsic::masked_load.
4501 void handleMaskedLoad(IntrinsicInst &I) {
4502 IRBuilder<> IRB(&I);
4503 Value *Ptr = I.getArgOperand(0);
4504 const Align Alignment = I.getParamAlign(0).valueOrOne();
4505 Value *Mask = I.getArgOperand(1);
4506 Value *PassThru = I.getArgOperand(2);
4507
4508 if (Opts.msan_check_access_address) {
4509 insertCheckShadowOf(Ptr, &I);
4510 insertCheckShadowOf(Mask, &I);
4511 }
4512
4513 if (!PropagateShadow) {
4514 setShadow(&I, getCleanShadow(&I));
4515 setOrigin(&I, getCleanOrigin());
4516 return;
4517 }
4518
4519 Type *ShadowTy = getShadowTy(&I);
4520 Value *ShadowPtr, *OriginPtr;
4521 std::tie(ShadowPtr, OriginPtr) =
4522 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment, /*isStore*/ false);
4523 setShadow(&I, IRB.CreateMaskedLoad(ShadowTy, ShadowPtr, Alignment, Mask,
4524 getShadow(PassThru), "_msmaskedld"));
4525
4526 if (!MS.TrackOrigins)
4527 return;
4528
4529 // Choose between PassThru's and the loaded value's origins.
4530 Value *MaskedPassThruShadow = IRB.CreateAnd(
4531 getShadow(PassThru), IRB.CreateSExt(IRB.CreateNeg(Mask), ShadowTy));
4532
4533 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB, "_mscmp");
4534
4535 Value *PtrOrigin = IRB.CreateLoad(MS.OriginTy, OriginPtr);
4536 Value *Origin = IRB.CreateSelect(NotNull, getOrigin(PassThru), PtrOrigin);
4537
4538 setOrigin(&I, Origin);
4539 }
4540
4541 // e.g., <4 x i32> @llvm.masked.udiv.v4i32(<4 x i32> %dividend,
4542 // <4 x i32> %divisor,
4543 // <4 x i1> %mask)
4544 //
4545 // As handleIntegerDiv(), but per-lane: strict on the divisor and propagating
4546 // the dividend, both only on the enabled lanes. Disabled lanes cannot cause
4547 // undefined behaviour, and their result is poison.
4548 void handleMaskedIntegerDivRem(IntrinsicInst &I) {
4549 assert(I.arg_size() == 3);
4550 IRBuilder<> IRB(&I);
4551 Value *Dividend = I.getArgOperand(0);
4552 Value *Divisor = I.getArgOperand(1);
4553 Value *Mask = I.getArgOperand(2);
4554
4555 insertCheckShadowOf(Mask, &I);
4556
4557 Value *MaskedDivisorShadow = IRB.CreateSelect(
4558 Mask, getShadow(Divisor), getCleanShadow(Divisor), "_msmaskeddivisor");
4559 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &I);
4560
4561 if (!PropagateShadow) {
4562 setShadow(&I, getCleanShadow(&I));
4563 setOrigin(&I, getCleanOrigin());
4564 return;
4565 }
4566
4567 setShadow(&I, IRB.CreateSelect(Mask, getShadow(Dividend),
4568 getPoisonedShadow(&I), "_msmaskeddiv"));
4569 setOrigin(&I, getOrigin(Dividend));
4570 }
4571
4572 // e.g., i32 @llvm.experimental.vector.extract.last.active.v4i32(
4573 // <4 x i32> %data, <4 x i1> %mask, i32 %passthru)
4574 void handleVectorExtractLastActive(IntrinsicInst &I) {
4575 assert(I.arg_size() == 3);
4576 IRBuilder<> IRB(&I);
4577 Value *Data = I.getArgOperand(0);
4578 Value *Mask = I.getArgOperand(1);
4579 Value *PassThru = I.getArgOperand(2);
4580
4581 assert(isa<VectorType>(Data->getType()));
4582 assert(isa<VectorType>(Mask->getType()));
4583 assert(!isa<VectorType>(PassThru->getType()));
4584 assert(!isa<VectorType>(I.getType()));
4585 assert(I.getType() == PassThru->getType());
4586 assert(cast<VectorType>(Data->getType())->getElementType() == I.getType());
4587 assert(cast<VectorType>(Mask->getType())->getElementType() ==
4588 IRB.getInt1Ty());
4589 assert(cast<VectorType>(Data->getType())->getElementCount() ==
4590 cast<VectorType>(Mask->getType())->getElementCount());
4591
4592 insertCheckShadowOf(Mask, &I);
4593
4594 if (!PropagateShadow) {
4595 setShadow(&I, getCleanShadow(&I));
4596 setOrigin(&I, getCleanOrigin());
4597 return;
4598 }
4599
4600 Value *DataShadow = getShadow(Data);
4601 Value *Shadow = IRB.CreateIntrinsic(
4602 Intrinsic::experimental_vector_extract_last_active,
4603 {DataShadow->getType()}, {DataShadow, Mask, getShadow(PassThru)},
4604 /*FMFSource=*/{}, "_msprop_vector_extract_last_active");
4605 setShadow(&I, Shadow);
4606
4607 if (MS.TrackOrigins) {
4608 Value *AnyActive = IRB.CreateOrReduce(Mask);
4609 setOrigin(&I, IRB.CreateSelect(AnyActive, getOrigin(Data),
4610 getOrigin(PassThru)));
4611 }
4612 }
4613
4614 // e.g., void @llvm.x86.avx.maskstore.ps.256(ptr, <8 x i32>, <8 x float>)
4615 // dst mask src
4616 //
4617 // AVX512 masked stores are lowered to Intrinsic::masked_load and are handled
4618 // by handleMaskedStore.
4619 //
4620 // This function handles AVX and AVX2 masked stores; these use the MSBs of a
4621 // vector of integers, unlike the LLVM masked intrinsics, which require a
4622 // vector of booleans. X86InstCombineIntrinsic.cpp::simplifyX86MaskedLoad
4623 // mentions that the x86 backend does not know how to efficiently convert
4624 // from a vector of booleans back into the AVX mask format; therefore, they
4625 // (and we) do not reduce AVX/AVX2 masked intrinsics into LLVM masked
4626 // intrinsics.
4627 void handleAVXMaskedStore(IntrinsicInst &I) {
4628 assert(I.arg_size() == 3);
4629
4630 IRBuilder<> IRB(&I);
4631
4632 Value *Dst = I.getArgOperand(0);
4633 assert(Dst->getType()->isPointerTy() && "Destination is not a pointer!");
4634
4635 Value *Mask = I.getArgOperand(1);
4636 assert(isa<VectorType>(Mask->getType()) && "Mask is not a vector!");
4637
4638 Value *Src = I.getArgOperand(2);
4639 assert(isa<VectorType>(Src->getType()) && "Source is not a vector!");
4640
4641 const Align Alignment = Align(1);
4642
4643 Value *SrcShadow = getShadow(Src);
4644
4645 if (Opts.msan_check_access_address) {
4646 insertCheckShadowOf(Dst, &I);
4647 insertCheckShadowOf(Mask, &I);
4648 }
4649
4650 Value *DstShadowPtr;
4651 Value *DstOriginPtr;
4652 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4653 Dst, IRB, SrcShadow->getType(), Alignment, /*isStore*/ true);
4654
4655 SmallVector<Value *, 2> ShadowArgs;
4656 ShadowArgs.append(1, DstShadowPtr);
4657 ShadowArgs.append(1, Mask);
4658 // The intrinsic may require floating-point but shadows can be arbitrary
4659 // bit patterns, of which some would be interpreted as "invalid"
4660 // floating-point values (NaN etc.); we assume the intrinsic will happily
4661 // copy them.
4662 ShadowArgs.append(1, IRB.CreateBitCast(SrcShadow, Src->getType()));
4663
4664 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4665 IRB.getVoidTy(), I.getIntrinsicID(), ShadowArgs);
4666 setShadow(&I, CI);
4667
4668 if (!MS.TrackOrigins)
4669 return;
4670
4671 // Approximation only
4672 auto &DL = F.getDataLayout();
4673 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4674 DL.getTypeStoreSize(SrcShadow->getType()),
4675 std::max(Alignment, kMinOriginAlignment));
4676 }
4677
4678 // e.g., <8 x float> @llvm.x86.avx.maskload.ps.256(ptr, <8 x i32>)
4679 // return src mask
4680 //
4681 // Masked-off values are replaced with 0, which conveniently also represents
4682 // initialized memory.
4683 //
4684 // AVX512 masked stores are lowered to Intrinsic::masked_load and are handled
4685 // by handleMaskedStore.
4686 //
4687 // We do not combine this with handleMaskedLoad; see comment in
4688 // handleAVXMaskedStore for the rationale.
4689 //
4690 // This is subtly different than handleIntrinsicByApplyingToShadow(I, 1)
4691 // because we need to apply getShadowOriginPtr, not getShadow, to the first
4692 // parameter.
4693 void handleAVXMaskedLoad(IntrinsicInst &I) {
4694 assert(I.arg_size() == 2);
4695
4696 IRBuilder<> IRB(&I);
4697
4698 Value *Src = I.getArgOperand(0);
4699 assert(Src->getType()->isPointerTy() && "Source is not a pointer!");
4700
4701 Value *Mask = I.getArgOperand(1);
4702 assert(isa<VectorType>(Mask->getType()) && "Mask is not a vector!");
4703
4704 const Align Alignment = Align(1);
4705
4706 if (Opts.msan_check_access_address) {
4707 insertCheckShadowOf(Mask, &I);
4708 }
4709
4710 Type *SrcShadowTy = getShadowTy(Src);
4711 Value *SrcShadowPtr, *SrcOriginPtr;
4712 std::tie(SrcShadowPtr, SrcOriginPtr) =
4713 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment, /*isStore*/ false);
4714
4715 SmallVector<Value *, 2> ShadowArgs;
4716 ShadowArgs.append(1, SrcShadowPtr);
4717 ShadowArgs.append(1, Mask);
4718
4719 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4720 I.getType(), I.getIntrinsicID(), ShadowArgs);
4721 // The AVX masked load intrinsics do not have integer variants. We use the
4722 // floating-point variants, which will happily copy the shadows even if
4723 // they are interpreted as "invalid" floating-point values (NaN etc.).
4724 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4725
4726 if (!MS.TrackOrigins)
4727 return;
4728
4729 // The "pass-through" value is always zero (initialized). To the extent
4730 // that that results in initialized aligned 4-byte chunks, the origin value
4731 // is ignored. It is therefore correct to simply copy the origin from src.
4732 Value *PtrSrcOrigin = IRB.CreateLoad(MS.OriginTy, SrcOriginPtr);
4733 setOrigin(&I, PtrSrcOrigin);
4734 }
4735
4736 // Test whether the mask indices are initialized, only checking the bits that
4737 // are actually used.
4738 //
4739 // e.g., if Idx is <32 x i16>, only (log2(32) == 5) bits of each index are
4740 // used/checked.
4741 void maskedCheckAVXIndexShadow(IRBuilder<> &IRB, Value *Idx, Instruction *I) {
4742 assert(isFixedIntVector(Idx));
4743 auto IdxVectorSize =
4744 cast<FixedVectorType>(Idx->getType())->getNumElements();
4745 assert(isPowerOf2_64(IdxVectorSize));
4746
4747 // Compiler isn't smart enough, let's help it
4748 if (isa<Constant>(Idx))
4749 return;
4750
4751 auto *IdxShadow = getShadow(Idx);
4752 Value *Truncated = IRB.CreateTrunc(
4753 IdxShadow,
4754 FixedVectorType::get(Type::getIntNTy(*MS.C, Log2_64(IdxVectorSize)),
4755 IdxVectorSize));
4756 insertCheckShadow(Truncated, getOrigin(Idx), I);
4757 }
4758
4759 // Instrument AVX permutation intrinsic.
4760 // We apply the same permutation (argument index 1) to the shadow.
4761 void handleAVXVpermilvar(IntrinsicInst &I) {
4762 IRBuilder<> IRB(&I);
4763 Value *Shadow = getShadow(&I, 0);
4764 maskedCheckAVXIndexShadow(IRB, I.getArgOperand(1), &I);
4765
4766 // Shadows are integer-ish types but some intrinsics require a
4767 // different (e.g., floating-point) type.
4768 Shadow = IRB.CreateBitCast(Shadow, I.getArgOperand(0)->getType());
4769 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4770 I.getType(), I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4771
4772 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4773 setOriginForNaryOp(I);
4774 }
4775
4776 // Instrument AVX permutation intrinsic.
4777 // We apply the same permutation (argument index 1) to the shadows.
4778 void handleAVXVpermi2var(IntrinsicInst &I) {
4779 assert(I.arg_size() == 3);
4780 assert(isa<FixedVectorType>(I.getArgOperand(0)->getType()));
4781 assert(isa<FixedVectorType>(I.getArgOperand(1)->getType()));
4782 assert(isa<FixedVectorType>(I.getArgOperand(2)->getType()));
4783 [[maybe_unused]] auto ArgVectorSize =
4784 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4785 assert(cast<FixedVectorType>(I.getArgOperand(1)->getType())
4786 ->getNumElements() == ArgVectorSize);
4787 assert(cast<FixedVectorType>(I.getArgOperand(2)->getType())
4788 ->getNumElements() == ArgVectorSize);
4789 assert(I.getArgOperand(0)->getType() == I.getArgOperand(2)->getType());
4790 assert(I.getType() == I.getArgOperand(0)->getType());
4791 assert(I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4792 IRBuilder<> IRB(&I);
4793 Value *AShadow = getShadow(&I, 0);
4794 Value *Idx = I.getArgOperand(1);
4795 Value *BShadow = getShadow(&I, 2);
4796
4797 maskedCheckAVXIndexShadow(IRB, Idx, &I);
4798
4799 // Shadows are integer-ish types but some intrinsics require a
4800 // different (e.g., floating-point) type.
4801 AShadow = IRB.CreateBitCast(AShadow, I.getArgOperand(0)->getType());
4802 BShadow = IRB.CreateBitCast(BShadow, I.getArgOperand(2)->getType());
4803 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4804 I.getType(), I.getIntrinsicID(), {AShadow, Idx, BShadow});
4805 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4806 setOriginForNaryOp(I);
4807 }
4808
4809 [[maybe_unused]] static bool isFixedIntVectorTy(const Type *T) {
4810 return isa<FixedVectorType>(T) && T->isIntOrIntVectorTy();
4811 }
4812
4813 [[maybe_unused]] static bool isFixedFPVectorTy(const Type *T) {
4814 return isa<FixedVectorType>(T) && T->isFPOrFPVectorTy();
4815 }
4816
4817 [[maybe_unused]] static bool isFixedIntVector(const Value *V) {
4818 return isFixedIntVectorTy(V->getType());
4819 }
4820
4821 [[maybe_unused]] static bool isFixedFPVector(const Value *V) {
4822 return isFixedFPVectorTy(V->getType());
4823 }
4824
4825 // e.g., <16 x i32> @llvm.x86.avx512.mask.cvtps2dq.512
4826 // (<16 x float> a, <16 x i32> writethru, i16 mask,
4827 // i32 rounding)
4828 //
4829 // Inconveniently, some similar intrinsics have a different operand order:
4830 // <16 x i16> @llvm.x86.avx512.mask.vcvtps2ph.512
4831 // (<16 x float> a, i32 rounding, <16 x i16> writethru,
4832 // i16 mask)
4833 //
4834 // If the return type has more elements than A, the excess elements are
4835 // zeroed (and the corresponding shadow is initialized).
4836 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.128
4837 // (<4 x float> a, i32 rounding, <8 x i16> writethru,
4838 // i8 mask)
4839 //
4840 // dst[i] = mask[i] ? convert(a[i]) : writethru[i]
4841 // dst_shadow[i] = mask[i] ? all_or_nothing(a_shadow[i]) : writethru_shadow[i]
4842 // where all_or_nothing(x) is fully uninitialized if x has any
4843 // uninitialized bits
4844 void handleAVX512VectorConvertFPToInt(IntrinsicInst &I, bool LastMask) {
4845 IRBuilder<> IRB(&I);
4846
4847 assert(I.arg_size() == 4);
4848 Value *A = I.getOperand(0);
4849 Value *WriteThrough;
4850 Value *Mask;
4852 if (LastMask) {
4853 WriteThrough = I.getOperand(2);
4854 Mask = I.getOperand(3);
4855 RoundingMode = I.getOperand(1);
4856 } else {
4857 WriteThrough = I.getOperand(1);
4858 Mask = I.getOperand(2);
4859 RoundingMode = I.getOperand(3);
4860 }
4861
4862 assert(isFixedFPVector(A));
4863 assert(isFixedIntVector(WriteThrough));
4864
4865 unsigned ANumElements =
4866 cast<FixedVectorType>(A->getType())->getNumElements();
4867 [[maybe_unused]] unsigned WriteThruNumElements =
4868 cast<FixedVectorType>(WriteThrough->getType())->getNumElements();
4869 assert(ANumElements == WriteThruNumElements ||
4870 ANumElements * 2 == WriteThruNumElements);
4871
4872 assert(Mask->getType()->isIntegerTy());
4873 unsigned MaskNumElements = Mask->getType()->getScalarSizeInBits();
4874 assert(ANumElements == MaskNumElements ||
4875 ANumElements * 2 == MaskNumElements);
4876
4877 assert(WriteThruNumElements == MaskNumElements);
4878
4879 // Some bits of the mask may be unused, though it's unusual to have partly
4880 // uninitialized bits.
4881 insertCheckShadowOf(Mask, &I);
4882
4883 assert(RoundingMode->getType()->isIntegerTy());
4884 // Only some bits of the rounding mode are used, though it's very
4885 // unusual to have uninitialized bits there (more commonly, it's a
4886 // constant).
4887 insertCheckShadowOf(RoundingMode, &I);
4888
4889 assert(I.getType() == WriteThrough->getType());
4890
4891 Value *AShadow = getShadow(A);
4892 AShadow = maybeExtendVectorShadowWithZeros(AShadow, I);
4893
4894 if (ANumElements * 2 == MaskNumElements) {
4895 // Ensure that the irrelevant bits of the mask are zero, hence selecting
4896 // from the zeroed shadow instead of the writethrough's shadow.
4897 Mask =
4898 IRB.CreateTrunc(Mask, IRB.getIntNTy(ANumElements), "_ms_mask_trunc");
4899 Mask =
4900 IRB.CreateZExt(Mask, IRB.getIntNTy(MaskNumElements), "_ms_mask_zext");
4901 }
4902
4903 // Convert i16 mask to <16 x i1>
4904 Mask = IRB.CreateBitCast(
4905 Mask, FixedVectorType::get(IRB.getInt1Ty(), MaskNumElements),
4906 "_ms_mask_bitcast");
4907
4908 /// For floating-point to integer conversion, the output is:
4909 /// - fully uninitialized if *any* bit of the input is uninitialized
4910 /// - fully ininitialized if all bits of the input are ininitialized
4911 /// We apply the same principle on a per-element basis for vectors.
4912 ///
4913 /// We use the scalar width of the return type instead of A's.
4914 AShadow = IRB.CreateSExt(
4915 IRB.CreateICmpNE(AShadow, getCleanShadow(AShadow->getType())),
4916 getShadowTy(&I), "_ms_a_shadow");
4917
4918 Value *WriteThroughShadow = getShadow(WriteThrough);
4919 Value *Shadow = IRB.CreateSelect(Mask, AShadow, WriteThroughShadow,
4920 "_ms_writethru_select");
4921
4922 setShadow(&I, Shadow);
4923 setOriginForNaryOp(I);
4924 }
4925
4926 static SmallVector<int, 8> getPclmulMask(unsigned Width, bool OddElements) {
4927 SmallVector<int, 8> Mask;
4928 for (unsigned X = OddElements ? 1 : 0; X < Width; X += 2) {
4929 Mask.append(2, X);
4930 }
4931 return Mask;
4932 }
4933
4934 // Instrument pclmul intrinsics.
4935 // These intrinsics operate either on odd or on even elements of the input
4936 // vectors, depending on the constant in the 3rd argument, ignoring the rest.
4937 // Replace the unused elements with copies of the used ones, ex:
4938 // (0, 1, 2, 3) -> (0, 0, 2, 2) (even case)
4939 // or
4940 // (0, 1, 2, 3) -> (1, 1, 3, 3) (odd case)
4941 // and then apply the usual shadow combining logic.
4942 void handlePclmulIntrinsic(IntrinsicInst &I) {
4943 IRBuilder<> IRB(&I);
4944 unsigned Width =
4945 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4946 assert(isa<ConstantInt>(I.getArgOperand(2)) &&
4947 "pclmul 3rd operand must be a constant");
4948 unsigned Imm = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
4949 Value *Shuf0 = IRB.CreateShuffleVector(getShadow(&I, 0),
4950 getPclmulMask(Width, Imm & 0x01));
4951 Value *Shuf1 = IRB.CreateShuffleVector(getShadow(&I, 1),
4952 getPclmulMask(Width, Imm & 0x10));
4953 ShadowAndOriginCombiner SOC(this, IRB);
4954 SOC.Add(Shuf0, getOrigin(&I, 0));
4955 SOC.Add(Shuf1, getOrigin(&I, 1));
4956 SOC.Done(&I);
4957 }
4958
4959 // Instrument _mm_*_sd|ss intrinsics
4960 void handleUnarySdSsIntrinsic(IntrinsicInst &I) {
4961 IRBuilder<> IRB(&I);
4962 unsigned Width =
4963 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4964 Value *First = getShadow(&I, 0);
4965 Value *Second = getShadow(&I, 1);
4966 // First element of second operand, remaining elements of first operand
4967 SmallVector<int, 16> Mask;
4968 Mask.push_back(Width);
4969 for (unsigned i = 1; i < Width; i++)
4970 Mask.push_back(i);
4971 Value *Shadow = IRB.CreateShuffleVector(First, Second, Mask);
4972
4973 setShadow(&I, Shadow);
4974 setOriginForNaryOp(I);
4975 }
4976
4977 void handleVtestIntrinsic(IntrinsicInst &I) {
4978 IRBuilder<> IRB(&I);
4979 Value *Shadow0 = getShadow(&I, 0);
4980 Value *Shadow1 = getShadow(&I, 1);
4981 Value *Or = IRB.CreateOr(Shadow0, Shadow1);
4982 Value *NZ = IRB.CreateICmpNE(Or, Constant::getNullValue(Or->getType()));
4983 Value *Scalar = convertShadowToScalar(NZ, IRB);
4984 Value *Shadow = IRB.CreateZExt(Scalar, getShadowTy(&I));
4985
4986 setShadow(&I, Shadow);
4987 setOriginForNaryOp(I);
4988 }
4989
4990 void handleBinarySdSsIntrinsic(IntrinsicInst &I) {
4991 IRBuilder<> IRB(&I);
4992 unsigned Width =
4993 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4994 Value *First = getShadow(&I, 0);
4995 Value *Second = getShadow(&I, 1);
4996 Value *OrShadow = IRB.CreateOr(First, Second);
4997 // First element of both OR'd together, remaining elements of first operand
4998 SmallVector<int, 16> Mask;
4999 Mask.push_back(Width);
5000 for (unsigned i = 1; i < Width; i++)
5001 Mask.push_back(i);
5002 Value *Shadow = IRB.CreateShuffleVector(First, OrShadow, Mask);
5003
5004 setShadow(&I, Shadow);
5005 setOriginForNaryOp(I);
5006 }
5007
5008 // _mm_round_ps / _mm_round_ps.
5009 // Similar to maybeHandleSimpleNomemIntrinsic except
5010 // the second argument is guaranteed to be a constant integer.
5011 void handleRoundPdPsIntrinsic(IntrinsicInst &I) {
5012 assert(I.getArgOperand(0)->getType() == I.getType());
5013 assert(I.arg_size() == 2);
5014 assert(isa<ConstantInt>(I.getArgOperand(1)));
5015
5016 IRBuilder<> IRB(&I);
5017 ShadowAndOriginCombiner SC(this, IRB);
5018 SC.Add(I.getArgOperand(0));
5019 SC.Done(&I);
5020 }
5021
5022 // Instrument @llvm.abs intrinsic.
5023 //
5024 // e.g., i32 @llvm.abs.i32 (i32 <Src>, i1 <is_int_min_poison>)
5025 // <4 x i32> @llvm.abs.v4i32(<4 x i32> <Src>, i1 <is_int_min_poison>)
5026 void handleAbsIntrinsic(IntrinsicInst &I) {
5027 assert(I.arg_size() == 2);
5028 Value *Src = I.getArgOperand(0);
5029 Value *IsIntMinPoison = I.getArgOperand(1);
5030
5031 assert(I.getType()->isIntOrIntVectorTy());
5032
5033 assert(Src->getType() == I.getType());
5034
5035 assert(IsIntMinPoison->getType()->isIntegerTy());
5036 assert(IsIntMinPoison->getType()->getIntegerBitWidth() == 1);
5037
5038 IRBuilder<> IRB(&I);
5039 Value *SrcShadow = getShadow(Src);
5040
5041 APInt MinVal =
5042 APInt::getSignedMinValue(Src->getType()->getScalarSizeInBits());
5043 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5044 Value *SrcIsMin = IRB.CreateICmp(CmpInst::ICMP_EQ, Src, MinValVec);
5045
5046 Value *PoisonedShadow = getPoisonedShadow(Src);
5047 Value *PoisonedIfIntMinShadow =
5048 IRB.CreateSelect(SrcIsMin, PoisonedShadow, SrcShadow);
5049 Value *Shadow =
5050 IRB.CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5051
5052 setShadow(&I, Shadow);
5053 setOrigin(&I, getOrigin(&I, 0));
5054 }
5055
5056 void handleIsFpClass(IntrinsicInst &I) {
5057 IRBuilder<> IRB(&I);
5058 Value *Shadow = getShadow(&I, 0);
5059 setShadow(&I, IRB.CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5060 setOrigin(&I, getOrigin(&I, 0));
5061 }
5062
5063 void handleArithmeticWithOverflow(IntrinsicInst &I) {
5064 IRBuilder<> IRB(&I);
5065 Value *Shadow0 = getShadow(&I, 0);
5066 Value *Shadow1 = getShadow(&I, 1);
5067 Value *ShadowElt0 = IRB.CreateOr(Shadow0, Shadow1);
5068 Value *ShadowElt1 =
5069 IRB.CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5070
5071 Value *Shadow = PoisonValue::get(getShadowTy(&I));
5072 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt0, 0);
5073 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt1, 1);
5074
5075 setShadow(&I, Shadow);
5076 setOriginForNaryOp(I);
5077 }
5078
5079 void handleModfOrSincos(IntrinsicInst &I) {
5080 IRBuilder<> IRB(&I);
5081 Value *ArgShadow = getShadow(&I, 0);
5082 Value *Shadow = PoisonValue::get(getShadowTy(&I));
5083 Shadow = IRB.CreateInsertValue(Shadow, ArgShadow, 0);
5084 Shadow = IRB.CreateInsertValue(Shadow, ArgShadow, 1);
5085 setShadow(&I, Shadow);
5086 setOrigin(&I, getOrigin(&I, 0));
5087 }
5088
5089 Value *extractLowerShadow(IRBuilder<> &IRB, Value *V) {
5090 assert(isa<FixedVectorType>(V->getType()));
5091 assert(cast<FixedVectorType>(V->getType())->getNumElements() > 0);
5092 Value *Shadow = getShadow(V);
5093 return IRB.CreateExtractElement(Shadow,
5094 ConstantInt::get(IRB.getInt32Ty(), 0));
5095 }
5096
5097 // Handle llvm.x86.avx512.mask.pmov{,s,us}.*.{128,256,512}
5098 //
5099 // e.g., call <16 x i8> @llvm.x86.avx512.mask.pmov.qb.512
5100 // (<8 x i64>, <16 x i8>, i8)
5101 // A WriteThru Mask
5102 //
5103 // call <16 x i8> @llvm.x86.avx512.mask.pmovs.db.512
5104 // (<16 x i32>, <16 x i8>, i16)
5105 //
5106 // Dst[i] = Mask[i] ? truncate_or_saturate(A[i]) : WriteThru[i]
5107 // Dst_shadow[i] = Mask[i] ? truncate(A_shadow[i]) : WriteThru_shadow[i]
5108 //
5109 // If Dst has more elements than A, the excess elements are zeroed (and the
5110 // corresponding shadow is initialized).
5111 //
5112 // Note: for PMOV (truncation), handleIntrinsicByApplyingToShadow is precise
5113 // and is much faster than this handler.
5114 void handleAVX512VectorDownConvert(IntrinsicInst &I) {
5115 IRBuilder<> IRB(&I);
5116
5117 assert(I.arg_size() == 3);
5118 Value *A = I.getOperand(0);
5119 Value *WriteThrough = I.getOperand(1);
5120 Value *Mask = I.getOperand(2);
5121
5122 assert(isFixedIntVector(A));
5123 assert(isFixedIntVector(WriteThrough));
5124
5125 unsigned ANumElements =
5126 cast<FixedVectorType>(A->getType())->getNumElements();
5127 unsigned OutputNumElements =
5128 cast<FixedVectorType>(WriteThrough->getType())->getNumElements();
5129 assert(ANumElements == OutputNumElements ||
5130 ANumElements * 2 == OutputNumElements);
5131 // N.B. some PMOV{,S,US} instructions have a 4x or even 8x ratio in the
5132 // number of elements e.g.,
5133 // <16 x i8> @llvm.x86.avx512.mask.pmovs.qb.256
5134 // (<4 x i64>, <16 x i8>, i8)
5135 // <16 x i8> @llvm.x86.avx512.mask.pmovs.qb.128
5136 // (<2 x i64>, <16 x i8>, i8)
5137 // However, we currently handle those elsewhere.
5138
5139 assert(Mask->getType()->isIntegerTy());
5140 insertCheckShadowOf(Mask, &I);
5141
5142 // The mask has 1 bit per element of A, but a minimum of 8 bits.
5143 if (Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5144 Mask = IRB.CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5145 assert(Mask->getType()->getScalarSizeInBits() == ANumElements);
5146
5147 assert(I.getType() == WriteThrough->getType());
5148
5149 // Widen the mask, if necessary, to have one bit per element of the output
5150 // vector.
5151 // We want the extra bits to have '1's, so that the CreateSelect will
5152 // select the values from AShadow instead of WriteThroughShadow ("maskless"
5153 // versions of the intrinsics are sometimes implemented using an all-1's
5154 // mask and an undefined value for WriteThroughShadow). We accomplish this
5155 // by using bitwise NOT before and after the ZExt.
5156 if (ANumElements != OutputNumElements) {
5157 Mask = IRB.CreateNot(Mask);
5158 Mask = IRB.CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5159 "_ms_widen_mask");
5160 Mask = IRB.CreateNot(Mask);
5161 }
5162 Mask = IRB.CreateBitCast(
5163 Mask, FixedVectorType::get(IRB.getInt1Ty(), OutputNumElements));
5164
5165 Value *AShadow = getShadow(A);
5166
5167 // The return type might have more elements than the input.
5168 // Temporarily shrink the return type's number of elements.
5169 VectorType *ShadowType = maybeShrinkVectorShadowType(A, I);
5170
5171 // PMOV truncates; PMOVS/PMOVUS uses signed/unsigned saturation.
5172 // This handler treats them all as truncation, which leads to some rare
5173 // false positives in the cases where the truncated bytes could
5174 // unambiguously saturate the value e.g., if A = ??????10 ????????
5175 // (big-endian), the unsigned saturated byte conversion is 11111111 i.e.,
5176 // fully defined, but the truncated byte is ????????.
5177 //
5178 // TODO: use GetMinMaxUnsigned() to handle saturation precisely.
5179 AShadow = IRB.CreateTrunc(AShadow, ShadowType, "_ms_trunc_shadow");
5180 AShadow = maybeExtendVectorShadowWithZeros(AShadow, I);
5181
5182 Value *WriteThroughShadow = getShadow(WriteThrough);
5183
5184 Value *Shadow = IRB.CreateSelect(Mask, AShadow, WriteThroughShadow);
5185 setShadow(&I, Shadow);
5186 setOriginForNaryOp(I);
5187 }
5188
5189 // Handle llvm.x86.avx512.* instructions that take vector(s) of floating-point
5190 // values and perform an operation whose shadow propagation should be handled
5191 // as all-or-nothing [*], with masking provided by a vector and a mask
5192 // supplied as an integer.
5193 //
5194 // [*] if all bits of a vector element are initialized, the output is fully
5195 // initialized; otherwise, the output is fully uninitialized
5196 //
5197 // e.g., <16 x float> @llvm.x86.avx512.rsqrt14.ps.512
5198 // (<16 x float>, <16 x float>, i16)
5199 // A WriteThru Mask
5200 //
5201 // <2 x double> @llvm.x86.avx512.rcp14.pd.128
5202 // (<2 x double>, <2 x double>, i8)
5203 // A WriteThru Mask
5204 //
5205 // <8 x double> @llvm.x86.avx512.mask.rndscale.pd.512
5206 // (<8 x double>, i32, <8 x double>, i8, i32)
5207 // A Imm WriteThru Mask Rounding
5208 //
5209 // <16 x float> @llvm.x86.avx512.mask.scalef.ps.512
5210 // (<16 x float>, <16 x float>, <16 x float>, i16, i32)
5211 // WriteThru A B Mask Rnd
5212 //
5213 // All operands other than A, B, ..., and WriteThru (e.g., Mask, Imm,
5214 // Rounding) must be fully initialized.
5215 //
5216 // Dst[i] = Mask[i] ? some_op(A[i], B[i], ...)
5217 // : WriteThru[i]
5218 // Dst_shadow[i] = Mask[i] ? all_or_nothing(A_shadow[i] | B_shadow[i] | ...)
5219 // : WriteThru_shadow[i]
5220 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &I,
5221 SmallVector<unsigned, 4> DataIndices,
5222 unsigned WriteThruIndex,
5223 unsigned MaskIndex) {
5224 IRBuilder<> IRB(&I);
5225
5226 unsigned NumArgs = I.arg_size();
5227
5228 assert(WriteThruIndex < NumArgs);
5229 assert(MaskIndex < NumArgs);
5230 assert(WriteThruIndex != MaskIndex);
5231 Value *WriteThru = I.getOperand(WriteThruIndex);
5232
5233 unsigned OutputNumElements =
5234 cast<FixedVectorType>(WriteThru->getType())->getNumElements();
5235
5236 assert(DataIndices.size() > 0);
5237
5238 bool isData[16] = {false};
5239 assert(NumArgs <= 16);
5240 for (unsigned i : DataIndices) {
5241 assert(i < NumArgs);
5242 assert(i != WriteThruIndex);
5243 assert(i != MaskIndex);
5244
5245 isData[i] = true;
5246
5247 Value *A = I.getOperand(i);
5248 assert(isFixedFPVector(A));
5249 [[maybe_unused]] unsigned ANumElements =
5250 cast<FixedVectorType>(A->getType())->getNumElements();
5251 assert(ANumElements == OutputNumElements);
5252 }
5253
5254 Value *Mask = I.getOperand(MaskIndex);
5255
5256 assert(isFixedFPVector(WriteThru));
5257
5258 for (unsigned i = 0; i < NumArgs; ++i) {
5259 if (!isData[i] && i != WriteThruIndex) {
5260 // Imm, Mask, Rounding etc. are "control" data, hence we require that
5261 // they be fully initialized.
5262 assert(I.getOperand(i)->getType()->isIntegerTy());
5263 insertCheckShadowOf(I.getOperand(i), &I);
5264 }
5265 }
5266
5267 // The mask has 1 bit per element of A, but a minimum of 8 bits.
5268 if (Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5269 Mask = IRB.CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5270 assert(Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5271
5272 assert(I.getType() == WriteThru->getType());
5273
5274 Mask = IRB.CreateBitCast(
5275 Mask, FixedVectorType::get(IRB.getInt1Ty(), OutputNumElements));
5276
5277 Value *DataShadow = nullptr;
5278 for (unsigned i : DataIndices) {
5279 Value *A = I.getOperand(i);
5280 if (DataShadow)
5281 DataShadow = IRB.CreateOr(DataShadow, getShadow(A));
5282 else
5283 DataShadow = getShadow(A);
5284 }
5285
5286 // All-or-nothing shadow
5287 DataShadow =
5288 IRB.CreateSExt(IRB.CreateICmpNE(DataShadow, getCleanShadow(DataShadow)),
5289 DataShadow->getType());
5290
5291 Value *WriteThruShadow = getShadow(WriteThru);
5292
5293 Value *Shadow = IRB.CreateSelect(Mask, DataShadow, WriteThruShadow);
5294 setShadow(&I, Shadow);
5295
5296 setOriginForNaryOp(I);
5297 }
5298
5299 // AVX512 Floating-Point Classification
5300 //
5301 // e.g.,
5302 // - < 8 x i1> @llvm.x86.avx512.fpclass.pd.512
5303 // (<8 x double> %input, i32 %classifiers)
5304 // - <16 x i1> @llvm.x86.avx512.fpclass.ps.512
5305 // (<16 x float> %input, i32 %classifiers)
5306 void handleAVX512FPClass(IntrinsicInst &I) {
5307 IRBuilder<> IRB(&I);
5308
5309 assert(I.arg_size() == 2);
5310
5311 Value *Input = I.getOperand(0);
5312 assert(isFixedFPVector(Input));
5313 [[maybe_unused]] FixedVectorType *InputType = cast<FixedVectorType>(Input->getType());
5314
5315 Value *Classifiers = I.getOperand(1);
5316 assert(isa<ConstantInt>(Classifiers));
5317 // No shadow check needed for constants
5318
5319 assert(isFixedIntVectorTy(I.getType()));
5320 FixedVectorType *OutputType = cast<FixedVectorType>(I.getType());
5321 assert(OutputType->getScalarSizeInBits() == 1);
5322
5323 assert(OutputType->getNumElements() == InputType->getNumElements());
5324
5325 Value *OutputShadow;
5326 if (cast<ConstantInt>(Classifiers)->isZero())
5327 // Each bit specifies whether a particular classifier is enabled.
5328 // If Classifiers == 0, the output is trivially known to be zero, thus
5329 // the output is fully initialized.
5330 OutputShadow = getCleanShadow(OutputType);
5331 else
5332 // Approximate each bit of the output shadow based on whether the
5333 // corresponding input element is fully initialized. It is only
5334 // approximate because some classifications do not rely on all bits of
5335 // the input element.
5336 OutputShadow = IRB.CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5337
5338 setShadow(&I, OutputShadow);
5339
5340 setOriginForNaryOp(I);
5341 }
5342
5343 // For sh.* compiler intrinsics:
5344 // llvm.x86.avx512fp16.mask.{add/sub/mul/div/max/min}.sh.round
5345 // (<8 x half>, <8 x half>, <8 x half>, i8, i32)
5346 // A B WriteThru Mask RoundingMode
5347 //
5348 // DstShadow[0] = Mask[0] ? (AShadow[0] | BShadow[0]) : WriteThruShadow[0]
5349 // DstShadow[1..7] = AShadow[1..7]
5350 void visitGenericScalarHalfwordInst(IntrinsicInst &I) {
5351 IRBuilder<> IRB(&I);
5352
5353 assert(I.arg_size() == 5);
5354 Value *A = I.getOperand(0);
5355 Value *B = I.getOperand(1);
5356 Value *WriteThrough = I.getOperand(2);
5357 Value *Mask = I.getOperand(3);
5358 Value *RoundingMode = I.getOperand(4);
5359
5360 // Technically, we could probably just check whether the LSB is
5361 // initialized, but intuitively it feels like a partly uninitialized mask
5362 // is unintended, and we should warn the user immediately.
5363 insertCheckShadowOf(Mask, &I);
5364 insertCheckShadowOf(RoundingMode, &I);
5365
5366 assert(isa<FixedVectorType>(A->getType()));
5367 unsigned NumElements =
5368 cast<FixedVectorType>(A->getType())->getNumElements();
5369 assert(NumElements == 8);
5370 assert(A->getType() == B->getType());
5371 assert(B->getType() == WriteThrough->getType());
5372 assert(Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5373 assert(RoundingMode->getType()->isIntegerTy());
5374
5375 Value *ALowerShadow = extractLowerShadow(IRB, A);
5376 Value *BLowerShadow = extractLowerShadow(IRB, B);
5377
5378 Value *ABLowerShadow = IRB.CreateOr(ALowerShadow, BLowerShadow);
5379
5380 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5381
5382 Mask = IRB.CreateBitCast(
5383 Mask, FixedVectorType::get(IRB.getInt1Ty(), NumElements));
5384 Value *MaskLower =
5385 IRB.CreateExtractElement(Mask, ConstantInt::get(IRB.getInt32Ty(), 0));
5386
5387 Value *AShadow = getShadow(A);
5388 Value *DstLowerShadow =
5389 IRB.CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5390 Value *DstShadow = IRB.CreateInsertElement(
5391 AShadow, DstLowerShadow, ConstantInt::get(IRB.getInt32Ty(), 0),
5392 "_msprop");
5393
5394 setShadow(&I, DstShadow);
5395 setOriginForNaryOp(I);
5396 }
5397
5398 // Approximately handle AVX Galois Field Affine Transformation
5399 //
5400 // e.g.,
5401 // <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8>, <16 x i8>, i8)
5402 // <32 x i8> @llvm.x86.vgf2p8affineqb.256(<32 x i8>, <32 x i8>, i8)
5403 // <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8>, <64 x i8>, i8)
5404 // Out A x b
5405 // where A and x are packed matrices, b is a vector,
5406 // Out = A * x + b in GF(2)
5407 //
5408 // Multiplication in GF(2) is equivalent to bitwise AND. However, the matrix
5409 // computation also includes a parity calculation.
5410 //
5411 // For the bitwise AND of bits V1 and V2, the exact shadow is:
5412 // Out_Shadow = (V1_Shadow & V2_Shadow)
5413 // | (V1 & V2_Shadow)
5414 // | (V1_Shadow & V2 )
5415 //
5416 // We approximate the shadow of gf2p8affineqb using:
5417 // Out_Shadow = gf2p8affineqb(x_Shadow, A_shadow, 0)
5418 // | gf2p8affineqb(x, A_shadow, 0)
5419 // | gf2p8affineqb(x_Shadow, A, 0)
5420 // | set1_epi8(b_Shadow)
5421 //
5422 // This approximation has false negatives: if an intermediate dot-product
5423 // contains an even number of 1's, the parity is 0.
5424 // It has no false positives.
5425 void handleAVXGF2P8Affine(IntrinsicInst &I) {
5426 IRBuilder<> IRB(&I);
5427
5428 assert(I.arg_size() == 3);
5429 Value *A = I.getOperand(0);
5430 Value *X = I.getOperand(1);
5431 Value *B = I.getOperand(2);
5432
5433 assert(isFixedIntVector(A));
5434 assert(cast<VectorType>(A->getType())
5435 ->getElementType()
5436 ->getScalarSizeInBits() == 8);
5437
5438 assert(A->getType() == X->getType());
5439
5440 assert(B->getType()->isIntegerTy());
5441 assert(B->getType()->getScalarSizeInBits() == 8);
5442
5443 assert(I.getType() == A->getType());
5444
5445 Value *AShadow = getShadow(A);
5446 Value *XShadow = getShadow(X);
5447 Value *BZeroShadow = getCleanShadow(B);
5448
5449 Value *AShadowXShadow = IRB.CreateIntrinsic(
5450 I.getType(), I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5451 Value *AShadowX = IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(),
5452 {X, AShadow, BZeroShadow});
5453 Value *XShadowA = IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(),
5454 {XShadow, A, BZeroShadow});
5455
5456 unsigned NumElements = cast<FixedVectorType>(I.getType())->getNumElements();
5457 Value *BShadow = getShadow(B);
5458 Value *BBroadcastShadow = getCleanShadow(AShadow);
5459 // There is no LLVM IR intrinsic for _mm512_set1_epi8.
5460 // This loop generates a lot of LLVM IR, which we expect that CodeGen will
5461 // lower appropriately (e.g., VPBROADCASTB).
5462 // Besides, b is often a constant, in which case it is fully initialized.
5463 for (unsigned i = 0; i < NumElements; i++)
5464 BBroadcastShadow = IRB.CreateInsertElement(BBroadcastShadow, BShadow, i);
5465
5466 setShadow(&I, IRB.CreateOr(
5467 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5468 setOriginForNaryOp(I);
5469 }
5470
5471 // Handle Arm NEON vector load intrinsics (vld*).
5472 //
5473 // The WithLane instructions (ld[234]lane) are similar to:
5474 // call {<4 x i32>, <4 x i32>, <4 x i32>}
5475 // @llvm.aarch64.neon.ld3lane.v4i32.p0
5476 // (<4 x i32> %L1, <4 x i32> %L2, <4 x i32> %L3, i64 %lane, ptr
5477 // %A)
5478 //
5479 // The non-WithLane instructions (ld[234], ld1x[234], ld[234]r) are similar
5480 // to:
5481 // call {<8 x i8>, <8 x i8>} @llvm.aarch64.neon.ld2.v8i8.p0(ptr %A)
5482 void handleNEONVectorLoad(IntrinsicInst &I, bool WithLane) {
5483 unsigned int numArgs = I.arg_size();
5484
5485 // Return type is a struct of vectors of integers or floating-point
5486 assert(I.getType()->isStructTy());
5487 [[maybe_unused]] StructType *RetTy = cast<StructType>(I.getType());
5488 assert(RetTy->getNumElements() > 0);
5490 RetTy->getElementType(0)->isFPOrFPVectorTy());
5491 for (unsigned int i = 0; i < RetTy->getNumElements(); i++)
5492 assert(RetTy->getElementType(i) == RetTy->getElementType(0));
5493
5494 if (WithLane) {
5495 // 2, 3 or 4 vectors, plus lane number, plus input pointer
5496 assert(4 <= numArgs && numArgs <= 6);
5497
5498 // Return type is a struct of the input vectors
5499 assert(RetTy->getNumElements() + 2 == numArgs);
5500 for (unsigned int i = 0; i < RetTy->getNumElements(); i++)
5501 assert(I.getArgOperand(i)->getType() == RetTy->getElementType(0));
5502 } else {
5503 assert(numArgs == 1);
5504 }
5505
5506 IRBuilder<> IRB(&I);
5507
5508 SmallVector<Value *, 6> ShadowArgs;
5509 if (WithLane) {
5510 for (unsigned int i = 0; i < numArgs - 2; i++)
5511 ShadowArgs.push_back(getShadow(I.getArgOperand(i)));
5512
5513 // Lane number, passed verbatim
5514 Value *LaneNumber = I.getArgOperand(numArgs - 2);
5515 ShadowArgs.push_back(LaneNumber);
5516
5517 // TODO: blend shadow of lane number into output shadow?
5518 insertCheckShadowOf(LaneNumber, &I);
5519 }
5520
5521 Value *Src = I.getArgOperand(numArgs - 1);
5522 assert(Src->getType()->isPointerTy() && "Source is not a pointer!");
5523
5524 Type *SrcShadowTy = getShadowTy(Src);
5525 auto [SrcShadowPtr, SrcOriginPtr] =
5526 getShadowOriginPtr(Src, IRB, SrcShadowTy, Align(1), /*isStore*/ false);
5527 ShadowArgs.push_back(SrcShadowPtr);
5528
5529 // The NEON vector load instructions handled by this function all have
5530 // integer variants. It is easier to use those rather than trying to cast
5531 // a struct of vectors of floats into a struct of vectors of integers.
5532 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
5533 getShadowTy(&I), I.getIntrinsicID(), ShadowArgs);
5534 setShadow(&I, CI);
5535
5536 if (!MS.TrackOrigins)
5537 return;
5538
5539 Value *PtrSrcOrigin = IRB.CreateLoad(MS.OriginTy, SrcOriginPtr);
5540 setOrigin(&I, PtrSrcOrigin);
5541 }
5542
5543 /// Handle Arm NEON vector store intrinsics (vst{2,3,4}, vst1x_{2,3,4},
5544 /// and vst{2,3,4}lane).
5545 ///
5546 /// Arm NEON vector store intrinsics have the output address (pointer) as the
5547 /// last argument, with the initial arguments being the inputs (and lane
5548 /// number for vst{2,3,4}lane). They return void.
5549 ///
5550 /// - st4 interleaves the output e.g., st4 (inA, inB, inC, inD, outP) writes
5551 /// abcdabcdabcdabcd... into *outP
5552 /// - st1_x4 is non-interleaved e.g., st1_x4 (inA, inB, inC, inD, outP)
5553 /// writes aaaa...bbbb...cccc...dddd... into *outP
5554 /// - st4lane has arguments of (inA, inB, inC, inD, lane, outP)
5555 /// These instructions can all be instrumented with essentially the same
5556 /// MSan logic, simply by applying the corresponding intrinsic to the shadow.
5557 void handleNEONVectorStoreIntrinsic(IntrinsicInst &I, bool useLane) {
5558 IRBuilder<> IRB(&I);
5559
5560 // Don't use getNumOperands() because it includes the callee
5561 int numArgOperands = I.arg_size();
5562
5563 // The last arg operand is the output (pointer)
5564 assert(numArgOperands >= 1);
5565 Value *Addr = I.getArgOperand(numArgOperands - 1);
5566 assert(Addr->getType()->isPointerTy());
5567 int skipTrailingOperands = 1;
5568
5569 if (Opts.msan_check_access_address)
5570 insertCheckShadowOf(Addr, &I);
5571
5572 // Second-last operand is the lane number (for vst{2,3,4}lane)
5573 if (useLane) {
5574 skipTrailingOperands++;
5575 assert(numArgOperands >= static_cast<int>(skipTrailingOperands));
5577 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5578 }
5579
5580 SmallVector<Value *, 8> ShadowArgs;
5581 // All the initial operands are the inputs
5582 for (int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5583 assert(isa<FixedVectorType>(I.getArgOperand(i)->getType()));
5584 Value *Shadow = getShadow(&I, i);
5585 ShadowArgs.append(1, Shadow);
5586 }
5587
5588 // MSan's GetShadowTy assumes the LHS is the type we want the shadow for
5589 // e.g., for:
5590 // [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to i128
5591 // we know the type of the output (and its shadow) is <16 x i8>.
5592 //
5593 // Arm NEON VST is unusual because the last argument is the output address:
5594 // define void @st2_16b(<16 x i8> %A, <16 x i8> %B, ptr %P) {
5595 // call void @llvm.aarch64.neon.st2.v16i8.p0
5596 // (<16 x i8> [[A]], <16 x i8> [[B]], ptr [[P]])
5597 // and we have no type information about P's operand. We must manually
5598 // compute the type (<16 x i8> x 2).
5599 FixedVectorType *OutputVectorTy = FixedVectorType::get(
5600 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getElementType(),
5601 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements() *
5602 (numArgOperands - skipTrailingOperands));
5603 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5604
5605 if (useLane)
5606 ShadowArgs.append(1,
5607 I.getArgOperand(numArgOperands - skipTrailingOperands));
5608
5609 Value *OutputShadowPtr, *OutputOriginPtr;
5610 // AArch64 NEON does not need alignment (unless OS requires it)
5611 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5612 Addr, IRB, OutputShadowTy, Align(1), /*isStore*/ true);
5613 ShadowArgs.append(1, OutputShadowPtr);
5614
5615 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
5616 IRB.getVoidTy(), I.getIntrinsicID(), ShadowArgs);
5617 setShadow(&I, CI);
5618
5619 if (MS.TrackOrigins) {
5620 // TODO: if we modelled the vst* instruction more precisely, we could
5621 // more accurately track the origins (e.g., if both inputs are
5622 // uninitialized for vst2, we currently blame the second input, even
5623 // though part of the output depends only on the first input).
5624 //
5625 // This is particularly imprecise for vst{2,3,4}lane, since only one
5626 // lane of each input is actually copied to the output.
5627 OriginCombiner OC(this, IRB);
5628 for (int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5629 OC.Add(I.getArgOperand(i));
5630
5631 const DataLayout &DL = F.getDataLayout();
5632 OC.DoneAndStoreOrigin(DL.getTypeStoreSize(OutputVectorTy),
5633 OutputOriginPtr);
5634 }
5635 }
5636
5637 // Integer matrix multiplication:
5638 // - <4 x i32> @llvm.aarch64.neon.{s,u,us}mmla.v4i32.v16i8
5639 // (<4 x i32> %R, <16 x i8> %A, <16 x i8> %B)
5640 // - <4 x i32> is a 2x2 matrix
5641 // - <16 x i8> %A and %B are 2x8 and 8x2 matrices respectively
5642 //
5643 // Floating-point matrix multiplication:
5644 // - <4 x float> @llvm.aarch64.neon.bfmmla
5645 // (<4 x float> %R, <8 x bfloat> %A, <8 x bfloat> %B)
5646 // - <4 x float> is a 2x2 matrix
5647 // - <8 x bfloat> %A and %B are 2x4 and 4x2 matrices respectively
5648 //
5649 // The general shadow propagation approach is:
5650 // 1) get the shadows of the input matrices %A and %B
5651 // 2) map each shadow value to 0x1 if the corresponding value is fully
5652 // initialized, and 0x0 otherwise
5653 // 3) perform a matrix multiplication on the shadows of %A and %B [*].
5654 // The output will be a 2x2 matrix. For each element, a value of 0x8
5655 // (for {s,u,us}mmla) or 0x4 (for bfmmla) means all the corresponding
5656 // inputs were clean; if so, set the shadow to zero, otherwise set to -1.
5657 // 4) blend in the shadow of %R
5658 //
5659 // [*] Since shadows are integral, the obvious approach is to always apply
5660 // ummla to the shadows. Unfortunately, Armv8.2+bf16 supports bfmmla,
5661 // but not ummla. Thus, for bfmmla, our instrumentation reuses bfmmla.
5662 //
5663 // TODO: consider allowing multiplication of zero with an uninitialized value
5664 // to result in an initialized value.
5665 void handleNEONMatrixMultiply(IntrinsicInst &I) {
5666 IRBuilder<> IRB(&I);
5667
5668 assert(I.arg_size() == 3);
5669 Value *R = I.getArgOperand(0);
5670 Value *A = I.getArgOperand(1);
5671 Value *B = I.getArgOperand(2);
5672
5673 assert(I.getType() == R->getType());
5674
5675 assert(isa<FixedVectorType>(R->getType()));
5676 assert(isa<FixedVectorType>(A->getType()));
5677 assert(isa<FixedVectorType>(B->getType()));
5678
5679 FixedVectorType *RTy = cast<FixedVectorType>(R->getType());
5680 FixedVectorType *ATy = cast<FixedVectorType>(A->getType());
5681 FixedVectorType *BTy = cast<FixedVectorType>(B->getType());
5682 assert(ATy->getElementType() == BTy->getElementType());
5683
5684 if (RTy->getElementType()->isIntegerTy()) {
5685 // <4 x i32> @llvm.aarch64.neon.ummla.v4i32.v16i8
5686 // (<4 x i32> %R, <16 x i8> %X, <16 x i8> %Y)
5687 assert(RTy == FixedVectorType::get(IntegerType::get(*MS.C, 32), 4));
5688 assert(ATy == FixedVectorType::get(IntegerType::get(*MS.C, 8), 16));
5689 assert(BTy == FixedVectorType::get(IntegerType::get(*MS.C, 8), 16));
5690 } else {
5691 // <4 x float> @llvm.aarch64.neon.bfmmla
5692 // (<4 x float> %R, <8 x bfloat> %X, <8 x bfloat> %Y)
5693 assert(RTy == FixedVectorType::get(Type::getFloatTy(*MS.C), 4));
5694 assert(ATy == FixedVectorType::get(Type::getBFloatTy(*MS.C), 8));
5695 assert(BTy == FixedVectorType::get(Type::getBFloatTy(*MS.C), 8));
5696 }
5697
5698 Value *ShadowR = getShadow(&I, 0);
5699 Value *ShadowA = getShadow(&I, 1);
5700 Value *ShadowB = getShadow(&I, 2);
5701
5702 Value *ShadowAB;
5703 Value *FullyInit;
5704
5705 if (RTy->getElementType()->isIntegerTy()) {
5706 // If the value is fully initialized, the shadow will be 000...001.
5707 // Otherwise, the shadow will be all zero.
5708 // (This is the opposite of how we typically handle shadows.)
5709 ShadowA = IRB.CreateZExt(IRB.CreateICmpEQ(ShadowA, getCleanShadow(ATy)),
5710 getShadowTy(ATy));
5711 ShadowB = IRB.CreateZExt(IRB.CreateICmpEQ(ShadowB, getCleanShadow(BTy)),
5712 getShadowTy(BTy));
5713 // TODO: the CreateSelect approach used below for floating-point is more
5714 // generic than CreateZExt. Investigate whether it is worthwhile
5715 // unifying the two approaches.
5716
5717 ShadowAB = IRB.CreateIntrinsic(RTy, Intrinsic::aarch64_neon_ummla,
5718 {getCleanShadow(RTy), ShadowA, ShadowB});
5719
5720 // ummla multiplies a 2x8 matrix with an 8x2 matrix. If all entries of the
5721 // input matrices are equal to 0x1, all entries of the output matrix will
5722 // be 0x8.
5723 FullyInit = ConstantVector::getSplat(
5724 RTy->getElementCount(), ConstantInt::get(RTy->getElementType(), 0x8));
5725
5726 ShadowAB = IRB.CreateICmpNE(ShadowAB, FullyInit);
5727 } else {
5729 ATy->getElementCount(), ConstantFP::get(ATy->getElementType(), 0));
5731 ATy->getElementCount(), ConstantFP::get(ATy->getElementType(), 1));
5732
5733 // As per the integer case, if the shadow is clean, we store 0x1,
5734 // otherwise we store 0x0 (the opposite of usual shadow arithmetic).
5735 ShadowA = IRB.CreateSelect(IRB.CreateICmpEQ(ShadowA, getCleanShadow(ATy)),
5736 ABOnes, ABZeros);
5737 ShadowB = IRB.CreateSelect(IRB.CreateICmpEQ(ShadowB, getCleanShadow(BTy)),
5738 ABOnes, ABZeros);
5739
5741 RTy->getElementCount(), ConstantFP::get(RTy->getElementType(), 0));
5742
5743 ShadowAB = IRB.CreateIntrinsic(RTy, Intrinsic::aarch64_neon_bfmmla,
5744 {RZeros, ShadowA, ShadowB});
5745
5746 // bfmmla multiplies a 2x4 matrix with an 4x2 matrix. If all entries of
5747 // the input matrices are equal to 0x1, all entries of the output matrix
5748 // will be 4.0. (To avoid floating-point error, we check if each entry
5749 // < 3.5.)
5750 FullyInit = ConstantVector::getSplat(
5751 RTy->getElementCount(), ConstantFP::get(RTy->getElementType(), 3.5));
5752
5753 // FCmpULT: "yields true if either operand is a QNAN or op1 is less than"
5754 // op2"
5755 ShadowAB = IRB.CreateFCmpULT(ShadowAB, FullyInit);
5756 }
5757
5758 ShadowR = IRB.CreateICmpNE(ShadowR, getCleanShadow(RTy));
5759 ShadowR = IRB.CreateOr(ShadowAB, ShadowR);
5760
5761 setShadow(&I, IRB.CreateSExt(ShadowR, getShadowTy(RTy)));
5762
5763 setOriginForNaryOp(I);
5764 }
5765
5766 /// Handle intrinsics by applying the intrinsic to the shadows.
5767 ///
5768 /// For example, this can be applied to the Arm NEON vector table intrinsics
5769 /// (tbl{1,2,3,4}).
5770 ///
5771 /// Typically, shadowIntrinsicID will be specified by the caller to be
5772 /// I.getIntrinsicID(), but the caller can choose to replace it with another
5773 /// intrinsic of the same type.
5774 ///
5775 /// verbatimArgIndices specifies which arguments are passed unmodified to the
5776 /// intrinsic, though such arguments will also taint the shadow. Non-negative
5777 /// indices are zero-indexed, while negative indices count from the last
5778 /// argument. For example, if an intrinsic has one trailing verbatim argument
5779 /// (specified with verbatimArgIndices = {-1}):
5780 /// out = intrinsic(var1, var2, opType)
5781 /// we compute:
5782 /// shadow[out] =
5783 /// intrinsic(shadow[var1], shadow[var2], opType) | shadow[opType]
5784 ///
5785 /// If an intrinsic is called with floating-point arguments, we will
5786 /// typically cast the shadows to floating-point, apply the intrinsic [*],
5787 /// then cast the result back to integer/shadow.
5788 ///
5789 /// In cases where we know the intrinsic is compatible with integer
5790 /// arguments, 'forceIntegerIntrinsic' will apply the integer variant, even
5791 /// if the arguments are floating-point, thus avoiding unnecessary casts
5792 /// e.g., if I is:
5793 /// <16 x float> @llvm.x86.avx512.mask.compress
5794 /// (<16 x float>, <16 x float>, <16 x i1> %mask)
5795 /// we would prefer to compute the shadows using:
5796 /// <16 x i32> @llvm.x86.avx512.mask.compress
5797 /// (<16 x i32>, <16 x i32>, <16 x i1> %mask)
5798 ///
5799 /// [*] CAUTION: this assumes that the intrinsic will handle arbitrary
5800 /// bit-patterns (for example, if the intrinsic accepts floats
5801 /// for var1, we require that it doesn't care if inputs are
5802 /// NaNs).
5803 ///
5804 /// The origin is approximated using setOriginForNaryOp.
5805 void handleIntrinsicByApplyingToShadow(IntrinsicInst &I,
5806 Intrinsic::ID shadowIntrinsicID,
5807 ArrayRef<int> verbatimArgIndices,
5808 bool forceIntegerIntrinsic) {
5809 IRBuilder<> IRB(&I);
5810
5811 assert(verbatimArgIndices.size() <= I.arg_size());
5812
5813 // verbatimArgIndices may have negative indices, and the indices may be in
5814 // any order (e.g., [5, -1, 2]). Convert it to a lookup table.
5815 SmallVector<bool, 4> verbatimArgLookup(I.arg_size(), false);
5816
5817 for (int index : verbatimArgIndices) {
5818 if (index < 0)
5819 index += I.arg_size();
5820 assert(index >= 0 && static_cast<unsigned int>(index) < I.arg_size());
5821 verbatimArgLookup[index] = true;
5822 }
5823
5824 SmallVector<Value *, 8> ShadowArgs;
5825 // Don't use getNumOperands() because it includes the callee
5826 for (unsigned int i = 0; i < I.arg_size(); i++) {
5827 if (verbatimArgLookup[i]) {
5828 Value *Arg = I.getArgOperand(i);
5829
5830 if (forceIntegerIntrinsic)
5832
5833 ShadowArgs.push_back(Arg);
5834 } else {
5835 Value *Shadow = getShadow(&I, i);
5836
5837 if (forceIntegerIntrinsic)
5838 ShadowArgs.push_back(Shadow);
5839 else
5840 ShadowArgs.push_back(
5841 IRB.CreateBitCast(Shadow, I.getArgOperand(i)->getType()));
5842 }
5843 }
5844
5845 Value *CombinedShadow;
5846 if (forceIntegerIntrinsic) {
5847 CombinedShadow =
5848 IRB.CreateIntrinsic(getShadowTy(&I), shadowIntrinsicID, ShadowArgs);
5849 } else {
5850 Value *CI =
5851 IRB.CreateIntrinsic(I.getType(), shadowIntrinsicID, ShadowArgs);
5852 CombinedShadow = IRB.CreateBitCast(CI, getShadowTy(&I));
5853 }
5854
5855 // Combine the computed shadow with the shadow of verbatim args
5856 //
5857 // N.B. we could merge this with the earlier loop, but we keep it separate
5858 // for the IR to be byte-identical with the existing tests.
5859 for (unsigned int i = 0; i < I.arg_size(); i++) {
5860 if (!verbatimArgLookup[i])
5861 continue;
5862
5863 Value *Shadow =
5864 CreateShadowCast(IRB, getShadow(&I, i), CombinedShadow->getType());
5865 CombinedShadow = IRB.CreateOr(Shadow, CombinedShadow, "_msprop");
5866 }
5867
5868 setShadow(&I, CombinedShadow);
5869
5870 setOriginForNaryOp(I);
5871 }
5872
5873 // Approximation only
5874 //
5875 // e.g., <16 x i8> @llvm.aarch64.neon.pmull64(i64, i64)
5876 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &I) {
5877 assert(I.arg_size() == 2);
5878
5879 handleShadowOr(I);
5880 }
5881
5882 // Handles:
5883 // <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane
5884 // (<4 x half>, <8 x i8>, <16 x i8>, i32)
5885 // accumulator A B lane
5886 //
5887 // <8 x half> @llvm.aarch64.neon.fp8.fdot2.lane
5888 // (<8 x half>, <16 x i8>, <16 x i8>, i32)
5889 // <2 x float> @llvm.aarch64.neon.fp8.fdot4.lane
5890 // (<2 x float>, <8 x i8>, <16 x i8>, i32)
5891 // <4 x float> @llvm.aarch64.neon.fp8.fdot4.lane
5892 // (<4 x float>, <16 x i8>, <16 x i8>, i32)
5893 //
5894 // The lane specifies which pair (fdot2) or quad (fdot4) of numbers to
5895 // extract from B, which is then splatted before being used in the dot
5896 // products e.g., for
5897 // <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane:
5898 // (<4 x half>, <8 x i8>, <16 x i8>, 1)
5899 //
5900 // acc[0] acc[1] acc[2] acc[3]
5901 // + + + + + + + +
5902 // A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7]
5903 // * * * * * * * *
5904 // B[2] B[3] B[2] B[3] B[2] B[3] B[2] B[3]
5905 //
5906 // Notice that if any bit of B[2] or B[3] is uninitialized, every accumulator
5907 // value will become tainted; we approximate this by marking the output as
5908 // fully uninitialized. This permits a 'Select' optimization.
5909 //
5910 // This function is separate from handleVectorDotProductIntrinsic(), because
5911 // the non-overlapping features (e.g., odd/even lanes vs. numbered lanes,
5912 // ZeroPurifies, EltSizeInBits) and optimizations make clean code reuse
5913 // difficult.
5914 void handleNEONDotProductLaneIntrinsic(IntrinsicInst &I,
5915 unsigned ReductionFactor) {
5916 IRBuilder<> IRB(&I);
5917 assert(I.arg_size() == 4);
5918
5919 [[maybe_unused]] Value *VAcc = I.getOperand(0);
5920 [[maybe_unused]] Value *Va = I.getOperand(1);
5921 [[maybe_unused]] Value *Vb = I.getOperand(2);
5922 Value *Lane = I.getOperand(3);
5923
5925 assert(VAcc->getType() == I.getType());
5926
5929 I.getType()->getPrimitiveSizeInBits());
5930
5931 assert(cast<FixedVectorType>(Va->getType())->getNumElements() ==
5932 cast<FixedVectorType>(I.getType())->getNumElements() *
5933 ReductionFactor);
5934
5936 // Deliberately not strict equality
5938 I.getType()->getPrimitiveSizeInBits());
5939
5940 assert(Lane->getType()->isIntegerTy());
5941
5942 // (<4 x 16>, <8 x i8>, <16 x i8>)
5943 // SAcc Sa Sb
5944 Value *SAcc = getShadow(&I, 0);
5945 Value *Sa = getShadow(&I, 1);
5946 Value *Sb = getShadow(&I, 2);
5947
5948 // Cast the shadows to:
5949 // (<4 x i16>, <4 x i16>, <8 x i16>)
5950 // SAcc Sa Sb
5951 Sa = IRB.CreateBitCast(Sa, SAcc->getType());
5952 Sb = IRB.CreateBitCast(
5953 Sb, FixedVectorType::getWithSizeAndScalar(
5955 cast<FixedVectorType>(SAcc->getType())->getElementType()));
5956
5957 // All-or-nothing shadows
5958 Sa =
5959 IRB.CreateSExt(IRB.CreateICmpNE(Sa, getCleanShadow(Sa)), Sa->getType());
5960
5961 // Extract the specific lane from Sb to get i16, then turn it into a single
5962 // bit representing if it is fully initialized.
5963 Sb = IRB.CreateExtractElement(Sb, Lane);
5964 Value *SbClean = IRB.CreateIsNull(Sb);
5965
5966 Value *SOutput = IRB.CreateOr(SAcc, Sa);
5967
5968 // Select is cheaper than broadcasting Sb into <4 x i16>.
5969 SOutput = IRB.CreateSelect(SbClean, SOutput, getPoisonedShadow(SOutput));
5970
5971 setShadow(&I, SOutput);
5972 setOriginForNaryOp(I);
5973 }
5974
5975 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &I) {
5976 switch (I.getIntrinsicID()) {
5977 case Intrinsic::uadd_with_overflow:
5978 case Intrinsic::sadd_with_overflow:
5979 case Intrinsic::usub_with_overflow:
5980 case Intrinsic::ssub_with_overflow:
5981 case Intrinsic::umul_with_overflow:
5982 case Intrinsic::smul_with_overflow:
5983 handleArithmeticWithOverflow(I);
5984 break;
5985 case Intrinsic::modf:
5986 case Intrinsic::sincos:
5987 case Intrinsic::sincospi:
5988 handleModfOrSincos(I);
5989 break;
5990 case Intrinsic::abs:
5991 handleAbsIntrinsic(I);
5992 break;
5993 case Intrinsic::bitreverse:
5994 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
5995 /*verbatimArgIndices=*/{},
5996 /*forceIntegerIntrinsic=*/false);
5997 break;
5998 case Intrinsic::is_fpclass:
5999 handleIsFpClass(I);
6000 break;
6001 case Intrinsic::lifetime_start:
6002 handleLifetimeStart(I);
6003 break;
6004 case Intrinsic::launder_invariant_group:
6005 handleInvariantGroup(I);
6006 break;
6007 case Intrinsic::bswap:
6008 handleBswap(I);
6009 break;
6010 case Intrinsic::ctlz:
6011 case Intrinsic::cttz:
6012 handleCountLeadingTrailingZeros(I);
6013 break;
6014 case Intrinsic::masked_compressstore:
6015 handleMaskedCompressStore(I);
6016 break;
6017 case Intrinsic::masked_expandload:
6018 handleMaskedExpandLoad(I);
6019 break;
6020 case Intrinsic::masked_gather:
6021 handleMaskedGather(I);
6022 break;
6023 case Intrinsic::masked_scatter:
6024 handleMaskedScatter(I);
6025 break;
6026 case Intrinsic::masked_store:
6027 handleMaskedStore(I);
6028 break;
6029 case Intrinsic::masked_load:
6030 handleMaskedLoad(I);
6031 break;
6032 case Intrinsic::masked_udiv:
6033 case Intrinsic::masked_sdiv:
6034 case Intrinsic::masked_urem:
6035 case Intrinsic::masked_srem:
6036 handleMaskedIntegerDivRem(I);
6037 break;
6038 case Intrinsic::vector_reduce_and:
6039 handleVectorReduceAndIntrinsic(I);
6040 break;
6041 case Intrinsic::vector_reduce_or:
6042 handleVectorReduceOrIntrinsic(I);
6043 break;
6044
6045 case Intrinsic::vector_reduce_add:
6046 case Intrinsic::vector_reduce_xor:
6047 case Intrinsic::vector_reduce_mul:
6048 // Signed/Unsigned Min/Max
6049 // TODO: handling similarly to AND/OR may be more precise.
6050 case Intrinsic::vector_reduce_smax:
6051 case Intrinsic::vector_reduce_smin:
6052 case Intrinsic::vector_reduce_umax:
6053 case Intrinsic::vector_reduce_umin:
6054 // TODO: this has no false positives, but arguably we should check that all
6055 // the bits are initialized.
6056 case Intrinsic::vector_reduce_fmax:
6057 case Intrinsic::vector_reduce_fmin:
6058 handleVectorReduceIntrinsic(I, /*AllowShadowCast=*/false);
6059 break;
6060
6061 case Intrinsic::vector_reduce_fadd:
6062 case Intrinsic::vector_reduce_fmul:
6063 handleVectorReduceWithStarterIntrinsic(I);
6064 break;
6065
6066 // e.g., <4 x i32> @llvm.vector.partial.reduce.add(<4 x i32>, <8 x i32>)
6067 case Intrinsic::vector_partial_reduce_add:
6068 case Intrinsic::vector_partial_reduce_fadd:
6069 handleVectorPartialReduceAddIntrinsic(I);
6070 break;
6071
6072 case Intrinsic::experimental_vector_extract_last_active:
6073 handleVectorExtractLastActive(I);
6074 break;
6075
6076 case Intrinsic::scmp:
6077 case Intrinsic::ucmp: {
6078 handleShadowOr(I);
6079 break;
6080 }
6081
6082 case Intrinsic::fshl:
6083 case Intrinsic::fshr:
6084 handleFunnelShift(I);
6085 break;
6086
6087 case Intrinsic::pdep:
6088 case Intrinsic::pext:
6089 handleGenericBitManipulation(I);
6090 break;
6091
6092 case Intrinsic::is_constant:
6093 // The result of llvm.is.constant() is always defined.
6094 setShadow(&I, getCleanShadow(&I));
6095 setOrigin(&I, getCleanOrigin());
6096 break;
6097
6098 // The non-saturating versions are handled by visitFPTo[US]IInst().
6099 //
6100 // N.B. some platform-specific intrinsics, such as AArch64 fcvtz[us], are
6101 // lowered to these cross-platform intrinsics.
6102 case Intrinsic::fptosi_sat:
6103 case Intrinsic::fptoui_sat:
6104 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
6105 break;
6106
6107 // e.g.,
6108 // notail call void (...) @llvm.fake.use(i64 %x)
6109 // notail call void (...) @llvm.fake.use(i32 %y)
6110 // notail call void (...) @llvm.fake.use(ptr %z)
6111 case Intrinsic::fake_use:
6112 assert(I.getType()->isVoidTy());
6113 // fake_uses aren't real, they can't hurt you. If the use isn't real, it
6114 // can't be a real use-of-uninitialized memory. Silently skip over
6115 // fake_use.
6116 return true;
6117
6118 default:
6119 return false;
6120 }
6121
6122 return true;
6123 }
6124
6125 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &I) {
6126 switch (I.getIntrinsicID()) {
6127 case Intrinsic::x86_sse_stmxcsr:
6128 handleStmxcsr(I);
6129 break;
6130 case Intrinsic::x86_sse_ldmxcsr:
6131 handleLdmxcsr(I);
6132 break;
6133
6134 // Convert Scalar Double Precision Floating-Point Value
6135 // to Unsigned Doubleword Integer
6136 // etc.
6137 case Intrinsic::x86_avx512_vcvtsd2usi64:
6138 case Intrinsic::x86_avx512_vcvtsd2usi32:
6139 case Intrinsic::x86_avx512_vcvtss2usi64:
6140 case Intrinsic::x86_avx512_vcvtss2usi32:
6141 case Intrinsic::x86_avx512_cvttss2usi64:
6142 case Intrinsic::x86_avx512_cvttss2usi:
6143 case Intrinsic::x86_avx512_cvttsd2usi64:
6144 case Intrinsic::x86_avx512_cvttsd2usi:
6145 case Intrinsic::x86_avx512_cvtusi2ss:
6146 case Intrinsic::x86_avx512_cvtusi642sd:
6147 case Intrinsic::x86_avx512_cvtusi642ss:
6148 handleSSEVectorConvertIntrinsic(I, 1, true);
6149 break;
6150 case Intrinsic::x86_sse2_cvtsd2si64:
6151 case Intrinsic::x86_sse2_cvtsd2si:
6152 case Intrinsic::x86_sse2_cvtsd2ss:
6153 case Intrinsic::x86_sse2_cvttsd2si64:
6154 case Intrinsic::x86_sse2_cvttsd2si:
6155 case Intrinsic::x86_sse_cvtss2si64:
6156 case Intrinsic::x86_sse_cvtss2si:
6157 case Intrinsic::x86_sse_cvttss2si64:
6158 case Intrinsic::x86_sse_cvttss2si:
6159 handleSSEVectorConvertIntrinsic(I, 1);
6160 break;
6161 case Intrinsic::x86_sse_cvtps2pi:
6162 case Intrinsic::x86_sse_cvttps2pi:
6163 handleSSEVectorConvertIntrinsic(I, 2);
6164 break;
6165
6166 // TODO:
6167 // <1 x i64> @llvm.x86.sse.cvtpd2pi(<2 x double>)
6168 // <2 x double> @llvm.x86.sse.cvtpi2pd(<1 x i64>)
6169 // <4 x float> @llvm.x86.sse.cvtpi2ps(<4 x float>, <1 x i64>)
6170
6171 case Intrinsic::x86_vcvtps2ph_128:
6172 case Intrinsic::x86_vcvtps2ph_256: {
6173 handleSSEVectorConvertIntrinsicByProp(I, /*HasRoundingMode=*/true);
6174 break;
6175 }
6176
6177 // Convert Packed Single Precision Floating-Point Values
6178 // to Packed Signed Doubleword Integer Values
6179 //
6180 // <16 x i32> @llvm.x86.avx512.mask.cvtps2dq.512
6181 // (<16 x float>, <16 x i32>, i16, i32)
6182 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6183 handleAVX512VectorConvertFPToInt(I, /*LastMask=*/false);
6184 break;
6185
6186 // Convert Packed Double Precision Floating-Point Values
6187 // to Packed Single Precision Floating-Point Values
6188 case Intrinsic::x86_sse2_cvtpd2ps:
6189 case Intrinsic::x86_sse2_cvtps2dq:
6190 case Intrinsic::x86_sse2_cvtpd2dq:
6191 case Intrinsic::x86_sse2_cvttps2dq:
6192 case Intrinsic::x86_sse2_cvttpd2dq:
6193 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6194 case Intrinsic::x86_avx_cvt_ps2dq_256:
6195 case Intrinsic::x86_avx_cvt_pd2dq_256:
6196 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6197 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6198 handleSSEVectorConvertIntrinsicByProp(I, /*HasRoundingMode=*/false);
6199 break;
6200 }
6201
6202 // Convert Single-Precision FP Value to 16-bit FP Value
6203 // <16 x i16> @llvm.x86.avx512.mask.vcvtps2ph.512
6204 // (<16 x float>, i32, <16 x i16>, i16)
6205 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.128
6206 // (<4 x float>, i32, <8 x i16>, i8)
6207 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.256
6208 // (<8 x float>, i32, <8 x i16>, i8)
6209 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6210 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6211 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6212 handleAVX512VectorConvertFPToInt(I, /*LastMask=*/true);
6213 break;
6214
6215 // Shift Packed Data (Left Logical, Right Arithmetic, Right Logical)
6216 case Intrinsic::x86_avx512_psll_w_512:
6217 case Intrinsic::x86_avx512_psll_d_512:
6218 case Intrinsic::x86_avx512_psll_q_512:
6219 case Intrinsic::x86_avx512_pslli_w_512:
6220 case Intrinsic::x86_avx512_pslli_d_512:
6221 case Intrinsic::x86_avx512_pslli_q_512:
6222 case Intrinsic::x86_avx512_psrl_w_512:
6223 case Intrinsic::x86_avx512_psrl_d_512:
6224 case Intrinsic::x86_avx512_psrl_q_512:
6225 case Intrinsic::x86_avx512_psra_w_512:
6226 case Intrinsic::x86_avx512_psra_d_512:
6227 case Intrinsic::x86_avx512_psra_q_512:
6228 case Intrinsic::x86_avx512_psrli_w_512:
6229 case Intrinsic::x86_avx512_psrli_d_512:
6230 case Intrinsic::x86_avx512_psrli_q_512:
6231 case Intrinsic::x86_avx512_psrai_w_512:
6232 case Intrinsic::x86_avx512_psrai_d_512:
6233 case Intrinsic::x86_avx512_psrai_q_512:
6234 case Intrinsic::x86_avx512_psra_q_256:
6235 case Intrinsic::x86_avx512_psra_q_128:
6236 case Intrinsic::x86_avx512_psrai_q_256:
6237 case Intrinsic::x86_avx512_psrai_q_128:
6238 case Intrinsic::x86_avx2_psll_w:
6239 case Intrinsic::x86_avx2_psll_d:
6240 case Intrinsic::x86_avx2_psll_q:
6241 case Intrinsic::x86_avx2_pslli_w:
6242 case Intrinsic::x86_avx2_pslli_d:
6243 case Intrinsic::x86_avx2_pslli_q:
6244 case Intrinsic::x86_avx2_psrl_w:
6245 case Intrinsic::x86_avx2_psrl_d:
6246 case Intrinsic::x86_avx2_psrl_q:
6247 case Intrinsic::x86_avx2_psra_w:
6248 case Intrinsic::x86_avx2_psra_d:
6249 case Intrinsic::x86_avx2_psrli_w:
6250 case Intrinsic::x86_avx2_psrli_d:
6251 case Intrinsic::x86_avx2_psrli_q:
6252 case Intrinsic::x86_avx2_psrai_w:
6253 case Intrinsic::x86_avx2_psrai_d:
6254 case Intrinsic::x86_sse2_psll_w:
6255 case Intrinsic::x86_sse2_psll_d:
6256 case Intrinsic::x86_sse2_psll_q:
6257 case Intrinsic::x86_sse2_pslli_w:
6258 case Intrinsic::x86_sse2_pslli_d:
6259 case Intrinsic::x86_sse2_pslli_q:
6260 case Intrinsic::x86_sse2_psrl_w:
6261 case Intrinsic::x86_sse2_psrl_d:
6262 case Intrinsic::x86_sse2_psrl_q:
6263 case Intrinsic::x86_sse2_psra_w:
6264 case Intrinsic::x86_sse2_psra_d:
6265 case Intrinsic::x86_sse2_psrli_w:
6266 case Intrinsic::x86_sse2_psrli_d:
6267 case Intrinsic::x86_sse2_psrli_q:
6268 case Intrinsic::x86_sse2_psrai_w:
6269 case Intrinsic::x86_sse2_psrai_d:
6270 case Intrinsic::x86_mmx_psll_w:
6271 case Intrinsic::x86_mmx_psll_d:
6272 case Intrinsic::x86_mmx_psll_q:
6273 case Intrinsic::x86_mmx_pslli_w:
6274 case Intrinsic::x86_mmx_pslli_d:
6275 case Intrinsic::x86_mmx_pslli_q:
6276 case Intrinsic::x86_mmx_psrl_w:
6277 case Intrinsic::x86_mmx_psrl_d:
6278 case Intrinsic::x86_mmx_psrl_q:
6279 case Intrinsic::x86_mmx_psra_w:
6280 case Intrinsic::x86_mmx_psra_d:
6281 case Intrinsic::x86_mmx_psrli_w:
6282 case Intrinsic::x86_mmx_psrli_d:
6283 case Intrinsic::x86_mmx_psrli_q:
6284 case Intrinsic::x86_mmx_psrai_w:
6285 case Intrinsic::x86_mmx_psrai_d:
6286 handleVectorShiftIntrinsic(I, /* Variable */ false);
6287 break;
6288 case Intrinsic::x86_avx2_psllv_d:
6289 case Intrinsic::x86_avx2_psllv_d_256:
6290 case Intrinsic::x86_avx512_psllv_d_512:
6291 case Intrinsic::x86_avx2_psllv_q:
6292 case Intrinsic::x86_avx2_psllv_q_256:
6293 case Intrinsic::x86_avx512_psllv_q_512:
6294 case Intrinsic::x86_avx2_psrlv_d:
6295 case Intrinsic::x86_avx2_psrlv_d_256:
6296 case Intrinsic::x86_avx512_psrlv_d_512:
6297 case Intrinsic::x86_avx2_psrlv_q:
6298 case Intrinsic::x86_avx2_psrlv_q_256:
6299 case Intrinsic::x86_avx512_psrlv_q_512:
6300 case Intrinsic::x86_avx2_psrav_d:
6301 case Intrinsic::x86_avx2_psrav_d_256:
6302 case Intrinsic::x86_avx512_psrav_d_512:
6303 case Intrinsic::x86_avx512_psrav_q_128:
6304 case Intrinsic::x86_avx512_psrav_q_256:
6305 case Intrinsic::x86_avx512_psrav_q_512:
6306 handleVectorShiftIntrinsic(I, /* Variable */ true);
6307 break;
6308
6309 // Pack with Signed/Unsigned Saturation
6310 case Intrinsic::x86_sse2_packsswb_128:
6311 case Intrinsic::x86_sse2_packssdw_128:
6312 case Intrinsic::x86_sse2_packuswb_128:
6313 case Intrinsic::x86_sse41_packusdw:
6314 case Intrinsic::x86_avx2_packsswb:
6315 case Intrinsic::x86_avx2_packssdw:
6316 case Intrinsic::x86_avx2_packuswb:
6317 case Intrinsic::x86_avx2_packusdw:
6318 // e.g., <64 x i8> @llvm.x86.avx512.packsswb.512
6319 // (<32 x i16> %a, <32 x i16> %b)
6320 // <32 x i16> @llvm.x86.avx512.packssdw.512
6321 // (<16 x i32> %a, <16 x i32> %b)
6322 // Note: AVX512 masked variants are auto-upgraded by LLVM.
6323 case Intrinsic::x86_avx512_packsswb_512:
6324 case Intrinsic::x86_avx512_packssdw_512:
6325 case Intrinsic::x86_avx512_packuswb_512:
6326 case Intrinsic::x86_avx512_packusdw_512:
6327 handleVectorPackIntrinsic(I);
6328 break;
6329
6330 case Intrinsic::x86_sse41_pblendvb:
6331 case Intrinsic::x86_sse41_blendvpd:
6332 case Intrinsic::x86_sse41_blendvps:
6333 case Intrinsic::x86_avx_blendv_pd_256:
6334 case Intrinsic::x86_avx_blendv_ps_256:
6335 case Intrinsic::x86_avx2_pblendvb:
6336 handleBlendvIntrinsic(I);
6337 break;
6338
6339 case Intrinsic::x86_avx_dp_ps_256:
6340 case Intrinsic::x86_sse41_dppd:
6341 case Intrinsic::x86_sse41_dpps:
6342 handleDppIntrinsic(I);
6343 break;
6344
6345 case Intrinsic::x86_mmx_packsswb:
6346 case Intrinsic::x86_mmx_packuswb:
6347 handleVectorPackIntrinsic(I, 16);
6348 break;
6349
6350 case Intrinsic::x86_mmx_packssdw:
6351 handleVectorPackIntrinsic(I, 32);
6352 break;
6353
6354 case Intrinsic::x86_mmx_psad_bw:
6355 handleVectorSadIntrinsic(I, true);
6356 break;
6357 case Intrinsic::x86_sse2_psad_bw:
6358 case Intrinsic::x86_avx2_psad_bw:
6359 handleVectorSadIntrinsic(I);
6360 break;
6361
6362 // Multiply and Add Packed Words
6363 // < 4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16>, <8 x i16>)
6364 // < 8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16>, <16 x i16>)
6365 // <16 x i32> @llvm.x86.avx512.pmaddw.d.512(<32 x i16>, <32 x i16>)
6366 //
6367 // Multiply and Add Packed Signed and Unsigned Bytes
6368 // < 8 x i16> @llvm.x86.ssse3.pmadd.ub.sw.128(<16 x i8>, <16 x i8>)
6369 // <16 x i16> @llvm.x86.avx2.pmadd.ub.sw(<32 x i8>, <32 x i8>)
6370 // <32 x i16> @llvm.x86.avx512.pmaddubs.w.512(<64 x i8>, <64 x i8>)
6371 //
6372 // These intrinsics are auto-upgraded into non-masked forms:
6373 // < 4 x i32> @llvm.x86.avx512.mask.pmaddw.d.128
6374 // (<8 x i16>, <8 x i16>, <4 x i32>, i8)
6375 // < 8 x i32> @llvm.x86.avx512.mask.pmaddw.d.256
6376 // (<16 x i16>, <16 x i16>, <8 x i32>, i8)
6377 // <16 x i32> @llvm.x86.avx512.mask.pmaddw.d.512
6378 // (<32 x i16>, <32 x i16>, <16 x i32>, i16)
6379 // < 8 x i16> @llvm.x86.avx512.mask.pmaddubs.w.128
6380 // (<16 x i8>, <16 x i8>, <8 x i16>, i8)
6381 // <16 x i16> @llvm.x86.avx512.mask.pmaddubs.w.256
6382 // (<32 x i8>, <32 x i8>, <16 x i16>, i16)
6383 // <32 x i16> @llvm.x86.avx512.mask.pmaddubs.w.512
6384 // (<64 x i8>, <64 x i8>, <32 x i16>, i32)
6385 case Intrinsic::x86_sse2_pmadd_wd:
6386 case Intrinsic::x86_avx2_pmadd_wd:
6387 case Intrinsic::x86_avx512_pmaddw_d_512:
6388 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6389 case Intrinsic::x86_avx2_pmadd_ub_sw:
6390 case Intrinsic::x86_avx512_pmaddubs_w_512:
6391 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6392 /*ZeroPurifies=*/true,
6393 /*EltSizeInBits=*/0,
6394 /*Lanes=*/kBothLanes);
6395 break;
6396
6397 // <1 x i64> @llvm.x86.ssse3.pmadd.ub.sw(<1 x i64>, <1 x i64>)
6398 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6399 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6400 /*ZeroPurifies=*/true,
6401 /*EltSizeInBits=*/8,
6402 /*Lanes=*/kBothLanes);
6403 break;
6404
6405 // <1 x i64> @llvm.x86.mmx.pmadd.wd(<1 x i64>, <1 x i64>)
6406 case Intrinsic::x86_mmx_pmadd_wd:
6407 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6408 /*ZeroPurifies=*/true,
6409 /*EltSizeInBits=*/16,
6410 /*Lanes=*/kBothLanes);
6411 break;
6412
6413 // BFloat16 multiply-add to single-precision
6414 // <4 x float> llvm.aarch64.neon.bfmlalt
6415 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6416 case Intrinsic::aarch64_neon_bfmlalt:
6417 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6418 /*ZeroPurifies=*/false,
6419 /*EltSizeInBits=*/0,
6420 /*Lanes=*/kOddLanes);
6421 break;
6422
6423 // <4 x float> llvm.aarch64.neon.bfmlalb
6424 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6425 case Intrinsic::aarch64_neon_bfmlalb:
6426 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6427 /*ZeroPurifies=*/false,
6428 /*EltSizeInBits=*/0,
6429 /*Lanes=*/kEvenLanes);
6430 break;
6431
6432 // AVX Vector Neural Network Instructions: bytes
6433 //
6434 // Multiply and Add Signed Bytes
6435 // < 4 x i32> @llvm.x86.avx2.vpdpbssd.128
6436 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6437 // < 8 x i32> @llvm.x86.avx2.vpdpbssd.256
6438 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6439 // <16 x i32> @llvm.x86.avx10.vpdpbssd.512
6440 // (<16 x i32>, <64 x i8>, <64 x i8>)
6441 //
6442 // Multiply and Add Signed Bytes With Saturation
6443 // < 4 x i32> @llvm.x86.avx2.vpdpbssds.128
6444 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6445 // < 8 x i32> @llvm.x86.avx2.vpdpbssds.256
6446 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6447 // <16 x i32> @llvm.x86.avx10.vpdpbssds.512
6448 // (<16 x i32>, <64 x i8>, <64 x i8>)
6449 //
6450 // Multiply and Add Signed and Unsigned Bytes
6451 // < 4 x i32> @llvm.x86.avx2.vpdpbsud.128
6452 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6453 // < 8 x i32> @llvm.x86.avx2.vpdpbsud.256
6454 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6455 // <16 x i32> @llvm.x86.avx10.vpdpbsud.512
6456 // (<16 x i32>, <64 x i8>, <64 x i8>)
6457 //
6458 // Multiply and Add Signed and Unsigned Bytes With Saturation
6459 // < 4 x i32> @llvm.x86.avx2.vpdpbsuds.128
6460 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6461 // < 8 x i32> @llvm.x86.avx2.vpdpbsuds.256
6462 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6463 // <16 x i32> @llvm.x86.avx512.vpdpbusds.512
6464 // (<16 x i32>, <64 x i8>, <64 x i8>)
6465 //
6466 // Multiply and Add Unsigned and Signed Bytes
6467 // < 4 x i32> @llvm.x86.avx512.vpdpbusd.128
6468 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6469 // < 8 x i32> @llvm.x86.avx512.vpdpbusd.256
6470 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6471 // <16 x i32> @llvm.x86.avx512.vpdpbusd.512
6472 // (<16 x i32>, <64 x i8>, <64 x i8>)
6473 //
6474 // Multiply and Add Unsigned and Signed Bytes With Saturation
6475 // < 4 x i32> @llvm.x86.avx512.vpdpbusds.128
6476 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6477 // < 8 x i32> @llvm.x86.avx512.vpdpbusds.256
6478 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6479 // <16 x i32> @llvm.x86.avx10.vpdpbsuds.512
6480 // (<16 x i32>, <64 x i8>, <64 x i8>)
6481 //
6482 // Multiply and Add Unsigned Bytes
6483 // < 4 x i32> @llvm.x86.avx2.vpdpbuud.128
6484 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6485 // < 8 x i32> @llvm.x86.avx2.vpdpbuud.256
6486 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6487 // <16 x i32> @llvm.x86.avx10.vpdpbuud.512
6488 // (<16 x i32>, <64 x i8>, <64 x i8>)
6489 //
6490 // Multiply and Add Unsigned Bytes With Saturation
6491 // < 4 x i32> @llvm.x86.avx2.vpdpbuuds.128
6492 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6493 // < 8 x i32> @llvm.x86.avx2.vpdpbuuds.256
6494 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6495 // <16 x i32> @llvm.x86.avx10.vpdpbuuds.512
6496 // (<16 x i32>, <64 x i8>, <64 x i8>)
6497 //
6498 // These intrinsics are auto-upgraded into non-masked forms:
6499 // <4 x i32> @llvm.x86.avx512.mask.vpdpbusd.128
6500 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6501 // <4 x i32> @llvm.x86.avx512.maskz.vpdpbusd.128
6502 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6503 // <8 x i32> @llvm.x86.avx512.mask.vpdpbusd.256
6504 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6505 // <8 x i32> @llvm.x86.avx512.maskz.vpdpbusd.256
6506 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6507 // <16 x i32> @llvm.x86.avx512.mask.vpdpbusd.512
6508 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6509 // <16 x i32> @llvm.x86.avx512.maskz.vpdpbusd.512
6510 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6511 //
6512 // <4 x i32> @llvm.x86.avx512.mask.vpdpbusds.128
6513 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6514 // <4 x i32> @llvm.x86.avx512.maskz.vpdpbusds.128
6515 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6516 // <8 x i32> @llvm.x86.avx512.mask.vpdpbusds.256
6517 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6518 // <8 x i32> @llvm.x86.avx512.maskz.vpdpbusds.256
6519 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6520 // <16 x i32> @llvm.x86.avx512.mask.vpdpbusds.512
6521 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6522 // <16 x i32> @llvm.x86.avx512.maskz.vpdpbusds.512
6523 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6524 case Intrinsic::x86_avx512_vpdpbusd_128:
6525 case Intrinsic::x86_avx512_vpdpbusd_256:
6526 case Intrinsic::x86_avx512_vpdpbusd_512:
6527 case Intrinsic::x86_avx512_vpdpbusds_128:
6528 case Intrinsic::x86_avx512_vpdpbusds_256:
6529 case Intrinsic::x86_avx512_vpdpbusds_512:
6530 case Intrinsic::x86_avx2_vpdpbssd_128:
6531 case Intrinsic::x86_avx2_vpdpbssd_256:
6532 case Intrinsic::x86_avx10_vpdpbssd_512:
6533 case Intrinsic::x86_avx2_vpdpbssds_128:
6534 case Intrinsic::x86_avx2_vpdpbssds_256:
6535 case Intrinsic::x86_avx10_vpdpbssds_512:
6536 case Intrinsic::x86_avx2_vpdpbsud_128:
6537 case Intrinsic::x86_avx2_vpdpbsud_256:
6538 case Intrinsic::x86_avx10_vpdpbsud_512:
6539 case Intrinsic::x86_avx2_vpdpbsuds_128:
6540 case Intrinsic::x86_avx2_vpdpbsuds_256:
6541 case Intrinsic::x86_avx10_vpdpbsuds_512:
6542 case Intrinsic::x86_avx2_vpdpbuud_128:
6543 case Intrinsic::x86_avx2_vpdpbuud_256:
6544 case Intrinsic::x86_avx10_vpdpbuud_512:
6545 case Intrinsic::x86_avx2_vpdpbuuds_128:
6546 case Intrinsic::x86_avx2_vpdpbuuds_256:
6547 case Intrinsic::x86_avx10_vpdpbuuds_512:
6548 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
6549 /*ZeroPurifies=*/true,
6550 /*EltSizeInBits=*/0,
6551 /*Lanes=*/kBothLanes);
6552 break;
6553
6554 // AVX Vector Neural Network Instructions: words
6555 //
6556 // Multiply and Add Signed Word Integers
6557 // < 4 x i32> @llvm.x86.avx512.vpdpwssd.128
6558 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6559 // < 8 x i32> @llvm.x86.avx512.vpdpwssd.256
6560 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6561 // <16 x i32> @llvm.x86.avx512.vpdpwssd.512
6562 // (<16 x i32>, <32 x i16>, <32 x i16>)
6563 //
6564 // Multiply and Add Signed Word Integers With Saturation
6565 // < 4 x i32> @llvm.x86.avx512.vpdpwssds.128
6566 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6567 // < 8 x i32> @llvm.x86.avx512.vpdpwssds.256
6568 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6569 // <16 x i32> @llvm.x86.avx512.vpdpwssds.512
6570 // (<16 x i32>, <32 x i16>, <32 x i16>)
6571 //
6572 // Multiply and Add Signed and Unsigned Word Integers
6573 // < 4 x i32> @llvm.x86.avx2.vpdpwsud.128
6574 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6575 // < 8 x i32> @llvm.x86.avx2.vpdpwsud.256
6576 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6577 // <16 x i32> @llvm.x86.avx10.vpdpwsud.512
6578 // (<16 x i32>, <32 x i16>, <32 x i16>)
6579 //
6580 // Multiply and Add Signed and Unsigned Word Integers With Saturation
6581 // < 4 x i32> @llvm.x86.avx2.vpdpwsuds.128
6582 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6583 // < 8 x i32> @llvm.x86.avx2.vpdpwsuds.256
6584 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6585 // <16 x i32> @llvm.x86.avx10.vpdpwsuds.512
6586 // (<16 x i32>, <32 x i16>, <32 x i16>)
6587 //
6588 // Multiply and Add Unsigned and Signed Word Integers
6589 // < 4 x i32> @llvm.x86.avx2.vpdpwusd.128
6590 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6591 // < 8 x i32> @llvm.x86.avx2.vpdpwusd.256
6592 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6593 // <16 x i32> @llvm.x86.avx10.vpdpwusd.512
6594 // (<16 x i32>, <32 x i16>, <32 x i16>)
6595 //
6596 // Multiply and Add Unsigned and Signed Word Integers With Saturation
6597 // < 4 x i32> @llvm.x86.avx2.vpdpwusds.128
6598 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6599 // < 8 x i32> @llvm.x86.avx2.vpdpwusds.256
6600 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6601 // <16 x i32> @llvm.x86.avx10.vpdpwusds.512
6602 // (<16 x i32>, <32 x i16>, <32 x i16>)
6603 //
6604 // Multiply and Add Unsigned and Unsigned Word Integers
6605 // < 4 x i32> @llvm.x86.avx2.vpdpwuud.128
6606 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6607 // < 8 x i32> @llvm.x86.avx2.vpdpwuud.256
6608 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6609 // <16 x i32> @llvm.x86.avx10.vpdpwuud.512
6610 // (<16 x i32>, <32 x i16>, <32 x i16>)
6611 //
6612 // Multiply and Add Unsigned and Unsigned Word Integers With Saturation
6613 // < 4 x i32> @llvm.x86.avx2.vpdpwuuds.128
6614 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6615 // < 8 x i32> @llvm.x86.avx2.vpdpwuuds.256
6616 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6617 // <16 x i32> @llvm.x86.avx10.vpdpwuuds.512
6618 // (<16 x i32>, <32 x i16>, <32 x i16>)
6619 //
6620 // These intrinsics are auto-upgraded into non-masked forms:
6621 // <4 x i32> @llvm.x86.avx512.mask.vpdpwssd.128
6622 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6623 // <4 x i32> @llvm.x86.avx512.maskz.vpdpwssd.128
6624 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6625 // <8 x i32> @llvm.x86.avx512.mask.vpdpwssd.256
6626 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6627 // <8 x i32> @llvm.x86.avx512.maskz.vpdpwssd.256
6628 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6629 // <16 x i32> @llvm.x86.avx512.mask.vpdpwssd.512
6630 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6631 // <16 x i32> @llvm.x86.avx512.maskz.vpdpwssd.512
6632 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6633 //
6634 // <4 x i32> @llvm.x86.avx512.mask.vpdpwssds.128
6635 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6636 // <4 x i32> @llvm.x86.avx512.maskz.vpdpwssds.128
6637 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6638 // <8 x i32> @llvm.x86.avx512.mask.vpdpwssds.256
6639 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6640 // <8 x i32> @llvm.x86.avx512.maskz.vpdpwssds.256
6641 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6642 // <16 x i32> @llvm.x86.avx512.mask.vpdpwssds.512
6643 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6644 // <16 x i32> @llvm.x86.avx512.maskz.vpdpwssds.512
6645 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6646 case Intrinsic::x86_avx512_vpdpwssd_128:
6647 case Intrinsic::x86_avx512_vpdpwssd_256:
6648 case Intrinsic::x86_avx512_vpdpwssd_512:
6649 case Intrinsic::x86_avx512_vpdpwssds_128:
6650 case Intrinsic::x86_avx512_vpdpwssds_256:
6651 case Intrinsic::x86_avx512_vpdpwssds_512:
6652 case Intrinsic::x86_avx2_vpdpwsud_128:
6653 case Intrinsic::x86_avx2_vpdpwsud_256:
6654 case Intrinsic::x86_avx10_vpdpwsud_512:
6655 case Intrinsic::x86_avx2_vpdpwsuds_128:
6656 case Intrinsic::x86_avx2_vpdpwsuds_256:
6657 case Intrinsic::x86_avx10_vpdpwsuds_512:
6658 case Intrinsic::x86_avx2_vpdpwusd_128:
6659 case Intrinsic::x86_avx2_vpdpwusd_256:
6660 case Intrinsic::x86_avx10_vpdpwusd_512:
6661 case Intrinsic::x86_avx2_vpdpwusds_128:
6662 case Intrinsic::x86_avx2_vpdpwusds_256:
6663 case Intrinsic::x86_avx10_vpdpwusds_512:
6664 case Intrinsic::x86_avx2_vpdpwuud_128:
6665 case Intrinsic::x86_avx2_vpdpwuud_256:
6666 case Intrinsic::x86_avx10_vpdpwuud_512:
6667 case Intrinsic::x86_avx2_vpdpwuuds_128:
6668 case Intrinsic::x86_avx2_vpdpwuuds_256:
6669 case Intrinsic::x86_avx10_vpdpwuuds_512:
6670 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6671 /*ZeroPurifies=*/true,
6672 /*EltSizeInBits=*/0,
6673 /*Lanes=*/kBothLanes);
6674 break;
6675
6676 // Dot Product of BF16 Pairs Accumulated Into Packed Single
6677 // Precision
6678 // <4 x float> @llvm.x86.avx512bf16.dpbf16ps.128
6679 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6680 // <8 x float> @llvm.x86.avx512bf16.dpbf16ps.256
6681 // (<8 x float>, <16 x bfloat>, <16 x bfloat>)
6682 // <16 x float> @llvm.x86.avx512bf16.dpbf16ps.512
6683 // (<16 x float>, <32 x bfloat>, <32 x bfloat>)
6684 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6685 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6686 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6687 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6688 /*ZeroPurifies=*/false,
6689 /*EltSizeInBits=*/0,
6690 /*Lanes=*/kBothLanes);
6691 break;
6692
6693 case Intrinsic::x86_sse_cmp_ss:
6694 case Intrinsic::x86_sse2_cmp_sd:
6695 case Intrinsic::x86_sse_comieq_ss:
6696 case Intrinsic::x86_sse_comilt_ss:
6697 case Intrinsic::x86_sse_comile_ss:
6698 case Intrinsic::x86_sse_comigt_ss:
6699 case Intrinsic::x86_sse_comige_ss:
6700 case Intrinsic::x86_sse_comineq_ss:
6701 case Intrinsic::x86_sse_ucomieq_ss:
6702 case Intrinsic::x86_sse_ucomilt_ss:
6703 case Intrinsic::x86_sse_ucomile_ss:
6704 case Intrinsic::x86_sse_ucomigt_ss:
6705 case Intrinsic::x86_sse_ucomige_ss:
6706 case Intrinsic::x86_sse_ucomineq_ss:
6707 case Intrinsic::x86_sse2_comieq_sd:
6708 case Intrinsic::x86_sse2_comilt_sd:
6709 case Intrinsic::x86_sse2_comile_sd:
6710 case Intrinsic::x86_sse2_comigt_sd:
6711 case Intrinsic::x86_sse2_comige_sd:
6712 case Intrinsic::x86_sse2_comineq_sd:
6713 case Intrinsic::x86_sse2_ucomieq_sd:
6714 case Intrinsic::x86_sse2_ucomilt_sd:
6715 case Intrinsic::x86_sse2_ucomile_sd:
6716 case Intrinsic::x86_sse2_ucomigt_sd:
6717 case Intrinsic::x86_sse2_ucomige_sd:
6718 case Intrinsic::x86_sse2_ucomineq_sd:
6719 handleVectorCompareScalarIntrinsic(I);
6720 break;
6721
6722 case Intrinsic::x86_avx_cmp_pd_256:
6723 case Intrinsic::x86_avx_cmp_ps_256:
6724 case Intrinsic::x86_sse2_cmp_pd:
6725 case Intrinsic::x86_sse_cmp_ps:
6726 handleVectorComparePackedIntrinsic(I, /*PredicateAsOperand=*/true);
6727 break;
6728
6729 case Intrinsic::x86_bmi_bextr_32:
6730 case Intrinsic::x86_bmi_bextr_64:
6731 case Intrinsic::x86_bmi_bzhi_32:
6732 case Intrinsic::x86_bmi_bzhi_64:
6733 handleGenericBitManipulation(I);
6734 break;
6735
6736 case Intrinsic::x86_pclmulqdq:
6737 case Intrinsic::x86_pclmulqdq_256:
6738 case Intrinsic::x86_pclmulqdq_512:
6739 handlePclmulIntrinsic(I);
6740 break;
6741
6742 case Intrinsic::x86_avx_round_pd_256:
6743 case Intrinsic::x86_avx_round_ps_256:
6744 case Intrinsic::x86_sse41_round_pd:
6745 case Intrinsic::x86_sse41_round_ps:
6746 handleRoundPdPsIntrinsic(I);
6747 break;
6748
6749 case Intrinsic::x86_sse41_round_sd:
6750 case Intrinsic::x86_sse41_round_ss:
6751 handleUnarySdSsIntrinsic(I);
6752 break;
6753
6754 case Intrinsic::x86_sse2_max_sd:
6755 case Intrinsic::x86_sse_max_ss:
6756 case Intrinsic::x86_sse2_min_sd:
6757 case Intrinsic::x86_sse_min_ss:
6758 handleBinarySdSsIntrinsic(I);
6759 break;
6760
6761 case Intrinsic::x86_avx_vtestc_pd:
6762 case Intrinsic::x86_avx_vtestc_pd_256:
6763 case Intrinsic::x86_avx_vtestc_ps:
6764 case Intrinsic::x86_avx_vtestc_ps_256:
6765 case Intrinsic::x86_avx_vtestnzc_pd:
6766 case Intrinsic::x86_avx_vtestnzc_pd_256:
6767 case Intrinsic::x86_avx_vtestnzc_ps:
6768 case Intrinsic::x86_avx_vtestnzc_ps_256:
6769 case Intrinsic::x86_avx_vtestz_pd:
6770 case Intrinsic::x86_avx_vtestz_pd_256:
6771 case Intrinsic::x86_avx_vtestz_ps:
6772 case Intrinsic::x86_avx_vtestz_ps_256:
6773 case Intrinsic::x86_avx_ptestc_256:
6774 case Intrinsic::x86_avx_ptestnzc_256:
6775 case Intrinsic::x86_avx_ptestz_256:
6776 case Intrinsic::x86_sse41_ptestc:
6777 case Intrinsic::x86_sse41_ptestnzc:
6778 case Intrinsic::x86_sse41_ptestz:
6779 handleVtestIntrinsic(I);
6780 break;
6781
6782 // Packed Horizontal Add/Subtract
6783 case Intrinsic::x86_ssse3_phadd_w:
6784 case Intrinsic::x86_ssse3_phadd_w_128:
6785 case Intrinsic::x86_ssse3_phsub_w:
6786 case Intrinsic::x86_ssse3_phsub_w_128:
6787 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6788 /*ReinterpretElemWidth=*/16);
6789 break;
6790
6791 case Intrinsic::x86_avx2_phadd_w:
6792 case Intrinsic::x86_avx2_phsub_w:
6793 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6794 /*ReinterpretElemWidth=*/16);
6795 break;
6796
6797 // Packed Horizontal Add/Subtract
6798 case Intrinsic::x86_ssse3_phadd_d:
6799 case Intrinsic::x86_ssse3_phadd_d_128:
6800 case Intrinsic::x86_ssse3_phsub_d:
6801 case Intrinsic::x86_ssse3_phsub_d_128:
6802 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6803 /*ReinterpretElemWidth=*/32);
6804 break;
6805
6806 case Intrinsic::x86_avx2_phadd_d:
6807 case Intrinsic::x86_avx2_phsub_d:
6808 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6809 /*ReinterpretElemWidth=*/32);
6810 break;
6811
6812 // Packed Horizontal Add/Subtract and Saturate
6813 case Intrinsic::x86_ssse3_phadd_sw:
6814 case Intrinsic::x86_ssse3_phadd_sw_128:
6815 case Intrinsic::x86_ssse3_phsub_sw:
6816 case Intrinsic::x86_ssse3_phsub_sw_128:
6817 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6818 /*ReinterpretElemWidth=*/16);
6819 break;
6820
6821 case Intrinsic::x86_avx2_phadd_sw:
6822 case Intrinsic::x86_avx2_phsub_sw:
6823 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6824 /*ReinterpretElemWidth=*/16);
6825 break;
6826
6827 // Packed Single/Double Precision Floating-Point Horizontal Add
6828 case Intrinsic::x86_sse3_hadd_ps:
6829 case Intrinsic::x86_sse3_hadd_pd:
6830 case Intrinsic::x86_sse3_hsub_ps:
6831 case Intrinsic::x86_sse3_hsub_pd:
6832 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1);
6833 break;
6834
6835 case Intrinsic::x86_avx_hadd_pd_256:
6836 case Intrinsic::x86_avx_hadd_ps_256:
6837 case Intrinsic::x86_avx_hsub_pd_256:
6838 case Intrinsic::x86_avx_hsub_ps_256:
6839 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2);
6840 break;
6841
6842 case Intrinsic::x86_avx_maskstore_ps:
6843 case Intrinsic::x86_avx_maskstore_pd:
6844 case Intrinsic::x86_avx_maskstore_ps_256:
6845 case Intrinsic::x86_avx_maskstore_pd_256:
6846 case Intrinsic::x86_avx2_maskstore_d:
6847 case Intrinsic::x86_avx2_maskstore_q:
6848 case Intrinsic::x86_avx2_maskstore_d_256:
6849 case Intrinsic::x86_avx2_maskstore_q_256: {
6850 handleAVXMaskedStore(I);
6851 break;
6852 }
6853
6854 case Intrinsic::x86_avx_maskload_ps:
6855 case Intrinsic::x86_avx_maskload_pd:
6856 case Intrinsic::x86_avx_maskload_ps_256:
6857 case Intrinsic::x86_avx_maskload_pd_256:
6858 case Intrinsic::x86_avx2_maskload_d:
6859 case Intrinsic::x86_avx2_maskload_q:
6860 case Intrinsic::x86_avx2_maskload_d_256:
6861 case Intrinsic::x86_avx2_maskload_q_256: {
6862 handleAVXMaskedLoad(I);
6863 break;
6864 }
6865
6866 // Packed
6867 case Intrinsic::x86_avx512fp16_add_ph_512:
6868 case Intrinsic::x86_avx512fp16_sub_ph_512:
6869 case Intrinsic::x86_avx512fp16_mul_ph_512:
6870 case Intrinsic::x86_avx512fp16_div_ph_512:
6871 case Intrinsic::x86_avx512fp16_max_ph_512:
6872 case Intrinsic::x86_avx512fp16_min_ph_512:
6873 case Intrinsic::x86_avx512_min_ps_512:
6874 case Intrinsic::x86_avx512_min_pd_512:
6875 case Intrinsic::x86_avx512_max_ps_512:
6876 case Intrinsic::x86_avx512_max_pd_512: {
6877 // These AVX512 variants contain the rounding mode as a trailing flag.
6878 // Earlier variants do not have a trailing flag and are already handled
6879 // by maybeHandleSimpleNomemIntrinsic(I, 0) via
6880 // maybeHandleUnknownIntrinsic.
6881 [[maybe_unused]] bool Success =
6882 maybeHandleSimpleNomemIntrinsic(I, /*trailingFlags=*/1);
6883 assert(Success);
6884 break;
6885 }
6886
6887 case Intrinsic::x86_avx_vpermilvar_pd:
6888 case Intrinsic::x86_avx_vpermilvar_pd_256:
6889 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6890 case Intrinsic::x86_avx_vpermilvar_ps:
6891 case Intrinsic::x86_avx_vpermilvar_ps_256:
6892 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6893 handleAVXVpermilvar(I);
6894 break;
6895 }
6896
6897 case Intrinsic::x86_avx512_vpermi2var_d_128:
6898 case Intrinsic::x86_avx512_vpermi2var_d_256:
6899 case Intrinsic::x86_avx512_vpermi2var_d_512:
6900 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6901 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6902 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6903 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6904 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6905 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6906 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6907 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6908 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6909 case Intrinsic::x86_avx512_vpermi2var_q_128:
6910 case Intrinsic::x86_avx512_vpermi2var_q_256:
6911 case Intrinsic::x86_avx512_vpermi2var_q_512:
6912 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6913 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6914 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6915 handleAVXVpermi2var(I);
6916 break;
6917
6918 // Packed Shuffle
6919 // llvm.x86.sse.pshuf.w(<1 x i64>, i8)
6920 // llvm.x86.ssse3.pshuf.b(<1 x i64>, <1 x i64>)
6921 // llvm.x86.ssse3.pshuf.b.128(<16 x i8>, <16 x i8>)
6922 // llvm.x86.avx2.pshuf.b(<32 x i8>, <32 x i8>)
6923 // llvm.x86.avx512.pshuf.b.512(<64 x i8>, <64 x i8>)
6924 //
6925 // The following intrinsics are auto-upgraded:
6926 // llvm.x86.sse2.pshuf.d(<4 x i32>, i8)
6927 // llvm.x86.sse2.gpshufh.w(<8 x i16>, i8)
6928 // llvm.x86.sse2.pshufl.w(<8 x i16>, i8)
6929 case Intrinsic::x86_avx2_pshuf_b:
6930 case Intrinsic::x86_sse_pshuf_w:
6931 case Intrinsic::x86_ssse3_pshuf_b_128:
6932 case Intrinsic::x86_ssse3_pshuf_b:
6933 case Intrinsic::x86_avx512_pshuf_b_512:
6934 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
6935 /*verbatimArgsIndices=*/{-1},
6936 /*forceIntegerIntrinsic=*/false);
6937 break;
6938
6939 // AVX512 PMOV: Packed MOV, with truncation
6940 // Precisely handled by applying the same intrinsic to the shadow
6941 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6942 case Intrinsic::x86_avx512_mask_pmov_db_128:
6943 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6944 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6945 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6946 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6947 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6948 case Intrinsic::x86_avx512_mask_pmov_db_256:
6949 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6950 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6951 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6952 case Intrinsic::x86_avx512_mask_pmov_db_512:
6953 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6954 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6955 // Intrinsic::x86_avx512_mask_pmov_{qd,wb}_{256,512} were removed in
6956 // f608dc1f5775ee880e8ea30e2d06ab5a4a935c22
6957 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
6958 /*verbatimArgIndices=*/{-1},
6959 /*forceIntegerIntrinsic=*/false);
6960 break;
6961 }
6962
6963 // AVX512 PMOV{S,US}: Packed MOV, with signed/unsigned saturation
6964 // Approximately handled using the corresponding truncation intrinsic
6965 // TODO: improve handleAVX512VectorDownConvert to precisely model saturation
6966 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6967 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6968 handleIntrinsicByApplyingToShadow(
6969 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6970 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
6971 break;
6972 }
6973
6974 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6975 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6976 handleIntrinsicByApplyingToShadow(
6977 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6978 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
6979 break;
6980
6981 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6982 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6983 handleIntrinsicByApplyingToShadow(
6984 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6985 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
6986 break;
6987
6988 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6989 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6990 handleIntrinsicByApplyingToShadow(
6991 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6992 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
6993 break;
6994 }
6995
6996 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6997 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6998 handleIntrinsicByApplyingToShadow(
6999 I, Intrinsic::x86_avx512_mask_pmov_db_256,
7000 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7001 break;
7002
7003 case Intrinsic::x86_avx512_mask_pmovs_db_128:
7004 case Intrinsic::x86_avx512_mask_pmovus_db_128:
7005 handleIntrinsicByApplyingToShadow(
7006 I, Intrinsic::x86_avx512_mask_pmov_db_128,
7007 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7008 break;
7009
7010 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
7011 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
7012 handleIntrinsicByApplyingToShadow(
7013 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
7014 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7015 break;
7016 }
7017
7018 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
7019 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
7020 handleIntrinsicByApplyingToShadow(
7021 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
7022 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7023 break;
7024
7025 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
7026 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
7027 handleIntrinsicByApplyingToShadow(
7028 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
7029 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7030 break;
7031
7032 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
7033 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
7034 handleIntrinsicByApplyingToShadow(
7035 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
7036 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7037 break;
7038 }
7039
7040 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
7041 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
7042 handleIntrinsicByApplyingToShadow(
7043 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
7044 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7045 break;
7046
7047 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
7048 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
7049 handleIntrinsicByApplyingToShadow(
7050 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
7051 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7052 break;
7053
7054 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
7055 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
7056 handleIntrinsicByApplyingToShadow(
7057 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
7058 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7059 break;
7060
7061 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
7062 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
7063 handleIntrinsicByApplyingToShadow(
7064 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
7065 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7066 break;
7067
7068 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
7069 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
7070 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
7071 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
7072 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
7073 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
7074 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
7075 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
7076 // Since Intrinsic::x86_avx512_mask_pmov_{qd,wb}_{256,512} do not exist,
7077 // we cannot use handleIntrinsicByApplyingToShadow. Instead, we call the
7078 // slow-path handler.
7079 handleAVX512VectorDownConvert(I);
7080 break;
7081 }
7082
7083 // e.g.,
7084 // <16 x float> @llvm.x86.avx512.mask.compress
7085 // (<16 x float> %data, <16 x float> %passthru,
7086 // <16 x i1> %mask)
7087 // <16 x i32> @llvm.x86.avx512.mask.compress
7088 // (<16 x i32> %data, <16 x i32> %passthru,
7089 // <16 x i1> %mask)
7090 case Intrinsic::x86_avx512_mask_compress:
7091 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
7092 /*verbatimArgIndices=*/{-1},
7093 /*forceIntegerIntrinsic=*/true);
7094 break;
7095
7096 // AVX512/AVX10 Reciprocal
7097 // <16 x float> @llvm.x86.avx512.rsqrt14.ps.512
7098 // (<16 x float>, <16 x float>, i16)
7099 // <8 x float> @llvm.x86.avx512.rsqrt14.ps.256
7100 // (<8 x float>, <8 x float>, i8)
7101 // <4 x float> @llvm.x86.avx512.rsqrt14.ps.128
7102 // (<4 x float>, <4 x float>, i8)
7103 //
7104 // <8 x double> @llvm.x86.avx512.rsqrt14.pd.512
7105 // (<8 x double>, <8 x double>, i8)
7106 // <4 x double> @llvm.x86.avx512.rsqrt14.pd.256
7107 // (<4 x double>, <4 x double>, i8)
7108 // <2 x double> @llvm.x86.avx512.rsqrt14.pd.128
7109 // (<2 x double>, <2 x double>, i8)
7110 //
7111 // <32 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.512
7112 // (<32 x bfloat>, <32 x bfloat>, i32)
7113 // <16 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.256
7114 // (<16 x bfloat>, <16 x bfloat>, i16)
7115 // <8 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.128
7116 // (<8 x bfloat>, <8 x bfloat>, i8)
7117 //
7118 // <32 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.512
7119 // (<32 x half>, <32 x half>, i32)
7120 // <16 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.256
7121 // (<16 x half>, <16 x half>, i16)
7122 // <8 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.128
7123 // (<8 x half>, <8 x half>, i8)
7124 //
7125 // TODO: 3-operand variants are not handled:
7126 // <2 x double> @llvm.x86.avx512.rsqrt14.sd
7127 // (<2 x double>, <2 x double>, <2 x double>, i8)
7128 // <4 x float> @llvm.x86.avx512.rsqrt14.ss
7129 // (<4 x float>, <4 x float>, <4 x float>, i8)
7130 // <8 x half> @llvm.x86.avx512fp16.mask.rsqrt.sh
7131 // (<8 x half>, <8 x half>, <8 x half>, i8)
7132 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7133 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7134 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7135 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7136 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7137 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7138 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7139 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7140 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7141 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7142 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7143 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7144 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7145 /*WriteThruIndex=*/1,
7146 /*MaskIndex=*/2);
7147 break;
7148
7149 // AVX512/AVX10 Reciprocal Square Root
7150 // <16 x float> @llvm.x86.avx512.rcp14.ps.512
7151 // (<16 x float>, <16 x float>, i16)
7152 // <8 x float> @llvm.x86.avx512.rcp14.ps.256
7153 // (<8 x float>, <8 x float>, i8)
7154 // <4 x float> @llvm.x86.avx512.rcp14.ps.128
7155 // (<4 x float>, <4 x float>, i8)
7156 //
7157 // <8 x double> @llvm.x86.avx512.rcp14.pd.512
7158 // (<8 x double>, <8 x double>, i8)
7159 // <4 x double> @llvm.x86.avx512.rcp14.pd.256
7160 // (<4 x double>, <4 x double>, i8)
7161 // <2 x double> @llvm.x86.avx512.rcp14.pd.128
7162 // (<2 x double>, <2 x double>, i8)
7163 //
7164 // <32 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.512
7165 // (<32 x bfloat>, <32 x bfloat>, i32)
7166 // <16 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.256
7167 // (<16 x bfloat>, <16 x bfloat>, i16)
7168 // <8 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.128
7169 // (<8 x bfloat>, <8 x bfloat>, i8)
7170 //
7171 // <32 x half> @llvm.x86.avx512fp16.mask.rcp.ph.512
7172 // (<32 x half>, <32 x half>, i32)
7173 // <16 x half> @llvm.x86.avx512fp16.mask.rcp.ph.256
7174 // (<16 x half>, <16 x half>, i16)
7175 // <8 x half> @llvm.x86.avx512fp16.mask.rcp.ph.128
7176 // (<8 x half>, <8 x half>, i8)
7177 //
7178 // TODO: 3-operand variants are not handled:
7179 // <2 x double> @llvm.x86.avx512.rcp14.sd
7180 // (<2 x double>, <2 x double>, <2 x double>, i8)
7181 // <4 x float> @llvm.x86.avx512.rcp14.ss
7182 // (<4 x float>, <4 x float>, <4 x float>, i8)
7183 // <8 x half> @llvm.x86.avx512fp16.mask.rcp.sh
7184 // (<8 x half>, <8 x half>, <8 x half>, i8)
7185 case Intrinsic::x86_avx512_rcp14_ps_512:
7186 case Intrinsic::x86_avx512_rcp14_ps_256:
7187 case Intrinsic::x86_avx512_rcp14_ps_128:
7188 case Intrinsic::x86_avx512_rcp14_pd_512:
7189 case Intrinsic::x86_avx512_rcp14_pd_256:
7190 case Intrinsic::x86_avx512_rcp14_pd_128:
7191 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7192 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7193 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7194 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7195 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7196 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7197 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7198 /*WriteThruIndex=*/1,
7199 /*MaskIndex=*/2);
7200 break;
7201
7202 // <32 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.512
7203 // (<32 x half>, i32, <32 x half>, i32, i32)
7204 // <16 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.256
7205 // (<16 x half>, i32, <16 x half>, i32, i16)
7206 // <8 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.128
7207 // (<8 x half>, i32, <8 x half>, i32, i8)
7208 //
7209 // <16 x float> @llvm.x86.avx512.mask.rndscale.ps.512
7210 // (<16 x float>, i32, <16 x float>, i16, i32)
7211 // <8 x float> @llvm.x86.avx512.mask.rndscale.ps.256
7212 // (<8 x float>, i32, <8 x float>, i8)
7213 // <4 x float> @llvm.x86.avx512.mask.rndscale.ps.128
7214 // (<4 x float>, i32, <4 x float>, i8)
7215 //
7216 // <8 x double> @llvm.x86.avx512.mask.rndscale.pd.512
7217 // (<8 x double>, i32, <8 x double>, i8, i32)
7218 // A Imm WriteThru Mask Rounding
7219 // <4 x double> @llvm.x86.avx512.mask.rndscale.pd.256
7220 // (<4 x double>, i32, <4 x double>, i8)
7221 // <2 x double> @llvm.x86.avx512.mask.rndscale.pd.128
7222 // (<2 x double>, i32, <2 x double>, i8)
7223 // A Imm WriteThru Mask
7224 //
7225 // <32 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.512
7226 // (<32 x bfloat>, i32, <32 x bfloat>, i32)
7227 // <16 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.256
7228 // (<16 x bfloat>, i32, <16 x bfloat>, i16)
7229 // <8 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.128
7230 // (<8 x bfloat>, i32, <8 x bfloat>, i8)
7231 //
7232 // Not supported: three vectors
7233 // - <8 x half> @llvm.x86.avx512fp16.mask.rndscale.sh
7234 // (<8 x half>, <8 x half>,<8 x half>, i8, i32, i32)
7235 // - <4 x float> @llvm.x86.avx512.mask.rndscale.ss
7236 // (<4 x float>, <4 x float>, <4 x float>, i8, i32, i32)
7237 // - <2 x double> @llvm.x86.avx512.mask.rndscale.sd
7238 // (<2 x double>, <2 x double>, <2 x double>, i8, i32,
7239 // i32)
7240 // A B WriteThru Mask Imm
7241 // Rounding
7242 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7243 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7244 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7245 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7246 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7247 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7248 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7249 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7250 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7251 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7252 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7253 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7254 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7255 /*WriteThruIndex=*/2,
7256 /*MaskIndex=*/3);
7257 break;
7258
7259 // AVX512 Vector Scale Float* Packed
7260 //
7261 // < 8 x double> @llvm.x86.avx512.mask.scalef.pd.512
7262 // (<8 x double>, <8 x double>, <8 x double>, i8, i32)
7263 // A B WriteThru Msk Round
7264 // < 4 x double> @llvm.x86.avx512.mask.scalef.pd.256
7265 // (<4 x double>, <4 x double>, <4 x double>, i8)
7266 // < 2 x double> @llvm.x86.avx512.mask.scalef.pd.128
7267 // (<2 x double>, <2 x double>, <2 x double>, i8)
7268 //
7269 // <16 x float> @llvm.x86.avx512.mask.scalef.ps.512
7270 // (<16 x float>, <16 x float>, <16 x float>, i16, i32)
7271 // < 8 x float> @llvm.x86.avx512.mask.scalef.ps.256
7272 // (<8 x float>, <8 x float>, <8 x float>, i8)
7273 // < 4 x float> @llvm.x86.avx512.mask.scalef.ps.128
7274 // (<4 x float>, <4 x float>, <4 x float>, i8)
7275 //
7276 // <32 x half> @llvm.x86.avx512fp16.mask.scalef.ph.512
7277 // (<32 x half>, <32 x half>, <32 x half>, i32, i32)
7278 // <16 x half> @llvm.x86.avx512fp16.mask.scalef.ph.256
7279 // (<16 x half>, <16 x half>, <16 x half>, i16)
7280 // < 8 x half> @llvm.x86.avx512fp16.mask.scalef.ph.128
7281 // (<8 x half>, <8 x half>, <8 x half>, i8)
7282 //
7283 // TODO: AVX10
7284 // <32 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.512
7285 // (<32 x bfloat>, <32 x bfloat>, <32 x bfloat>, i32)
7286 // <16 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.256
7287 // (<16 x bfloat>, <16 x bfloat>, <16 x bfloat>, i16)
7288 // < 8 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.128
7289 // (<8 x bfloat>, <8 x bfloat>, <8 x bfloat>, i8)
7290 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7291 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7292 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7293 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7294 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7295 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7296 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7297 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7298 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7299 // The AVX512 512-bit operand variants have an extra operand (the
7300 // Rounding mode). The extra operand, if present, will be
7301 // automatically checked by the handler.
7302 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0, 1},
7303 /*WriteThruIndex=*/2,
7304 /*MaskIndex=*/3);
7305 break;
7306
7307 // TODO: AVX512 Vector Scale Float* Scalar
7308 //
7309 // This is different from the Packed variant, because some bits are copied,
7310 // and some bits are zeroed.
7311 //
7312 // < 4 x float> @llvm.x86.avx512.mask.scalef.ss
7313 // (<4 x float>, <4 x float>, <4 x float>, i8, i32)
7314 //
7315 // < 2 x double> @llvm.x86.avx512.mask.scalef.sd
7316 // (<2 x double>, <2 x double>, <2 x double>, i8, i32)
7317 //
7318 // < 8 x half> @llvm.x86.avx512fp16.mask.scalef.sh
7319 // (<8 x half>, <8 x half>, <8 x half>, i8, i32)
7320
7321 // AVX512 FP16 Arithmetic
7322 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7323 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7324 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7325 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7326 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7327 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7328 visitGenericScalarHalfwordInst(I);
7329 break;
7330 }
7331
7332 // AVX512 Floating-Point Classification
7333 // - <8 x i1> @llvm.x86.avx512.fpclass.pd.512(<8 x double>, i32)
7334 // - <16 x i1> @llvm.x86.avx512.fpclass.ps.512(<16 x float>, i32)
7335 case Intrinsic::x86_avx512_fpclass_pd_512:
7336 case Intrinsic::x86_avx512_fpclass_ps_512:
7337 handleAVX512FPClass(I);
7338 break;
7339
7340 // AVX Galois Field New Instructions
7341 case Intrinsic::x86_vgf2p8affineqb_128:
7342 case Intrinsic::x86_vgf2p8affineqb_256:
7343 case Intrinsic::x86_vgf2p8affineqb_512:
7344 handleAVXGF2P8Affine(I);
7345 break;
7346
7347 default:
7348 return false;
7349 }
7350
7351 return true;
7352 }
7353
7354 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &I) {
7355 switch (I.getIntrinsicID()) {
7356 // Two operands e.g.,
7357 // - <8 x i8> @llvm.aarch64.neon.rshrn.v8i8 (<8 x i16>, i32)
7358 // - <4 x i16> @llvm.aarch64.neon.uqrshl.v4i16(<4 x i16>, <4 x i16>)
7359 case Intrinsic::aarch64_neon_rshrn:
7360 case Intrinsic::aarch64_neon_sqrshl:
7361 case Intrinsic::aarch64_neon_sqrshrn:
7362 case Intrinsic::aarch64_neon_sqrshrun:
7363 case Intrinsic::aarch64_neon_sqshl:
7364 case Intrinsic::aarch64_neon_sqshlu:
7365 case Intrinsic::aarch64_neon_sqshrn:
7366 case Intrinsic::aarch64_neon_sqshrun:
7367 case Intrinsic::aarch64_neon_srshl:
7368 case Intrinsic::aarch64_neon_sshl:
7369 case Intrinsic::aarch64_neon_uqrshl:
7370 case Intrinsic::aarch64_neon_uqrshrn:
7371 case Intrinsic::aarch64_neon_uqshl:
7372 case Intrinsic::aarch64_neon_uqshrn:
7373 case Intrinsic::aarch64_neon_urshl:
7374 case Intrinsic::aarch64_neon_ushl:
7375 handleVectorShiftIntrinsic(I, /* Variable */ false);
7376 break;
7377
7378 // Vector Shift Left/Right and Insert
7379 //
7380 // Three operands e.g.,
7381 // - <4 x i16> @llvm.aarch64.neon.vsli.v4i16
7382 // (<4 x i16> %a, <4 x i16> %b, i32 %n)
7383 // - <16 x i8> @llvm.aarch64.neon.vsri.v16i8
7384 // (<16 x i8> %a, <16 x i8> %b, i32 %n)
7385 //
7386 // %b is shifted by %n bits, and the "missing" bits are filled in with %a
7387 // (instead of zero-extending/sign-extending).
7388 case Intrinsic::aarch64_neon_vsli:
7389 case Intrinsic::aarch64_neon_vsri:
7390 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
7391 /*verbatimArgIndices=*/{-1},
7392 /*forceIntegerIntrinsic=*/false);
7393 break;
7394
7395 // TODO: handling max/min similarly to AND/OR may be more precise
7396 // Floating-Point Maximum/Minimum Pairwise
7397 case Intrinsic::aarch64_neon_fmaxp:
7398 case Intrinsic::aarch64_neon_fminp:
7399 // Floating-Point Maximum/Minimum Number Pairwise
7400 case Intrinsic::aarch64_neon_fmaxnmp:
7401 case Intrinsic::aarch64_neon_fminnmp:
7402 // Signed/Unsigned Maximum/Minimum Pairwise
7403 case Intrinsic::aarch64_neon_smaxp:
7404 case Intrinsic::aarch64_neon_sminp:
7405 case Intrinsic::aarch64_neon_umaxp:
7406 case Intrinsic::aarch64_neon_uminp:
7407 // Add Pairwise
7408 case Intrinsic::aarch64_neon_addp:
7409 // Floating-point Add Pairwise
7410 case Intrinsic::aarch64_neon_faddp:
7411 // Add Long Pairwise
7412 case Intrinsic::aarch64_neon_saddlp:
7413 case Intrinsic::aarch64_neon_uaddlp: {
7414 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1);
7415 break;
7416 }
7417
7418 // Floating-point Convert to integer, rounding to nearest with ties to Away
7419 case Intrinsic::aarch64_neon_fcvtas:
7420 case Intrinsic::aarch64_neon_fcvtau:
7421 // Floating-point convert to integer, rounding toward minus infinity
7422 case Intrinsic::aarch64_neon_fcvtms:
7423 case Intrinsic::aarch64_neon_fcvtmu:
7424 // Floating-point convert to integer, rounding to nearest with ties to even
7425 case Intrinsic::aarch64_neon_fcvtns:
7426 case Intrinsic::aarch64_neon_fcvtnu:
7427 // Floating-point convert to integer, rounding toward plus infinity
7428 case Intrinsic::aarch64_neon_fcvtps:
7429 case Intrinsic::aarch64_neon_fcvtpu:
7430 // Floating-point Convert to integer, rounding toward Zero
7431 case Intrinsic::aarch64_neon_fcvtzs:
7432 case Intrinsic::aarch64_neon_fcvtzu:
7433 // Floating-point convert to lower precision narrow, rounding to odd
7434 case Intrinsic::aarch64_neon_fcvtxn:
7435 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
7436 break;
7437
7438 // Vector Conversions Between Fixed-Point and Floating-Point
7439 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7440 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7441 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7442 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7443 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/true);
7444 break;
7445
7446 // TODO: bfloat conversions
7447 // - bfloat @llvm.aarch64.neon.bfcvt(float)
7448 // - <8 x bfloat> @llvm.aarch64.neon.bfcvtn(<4 x float>)
7449 // - <8 x bfloat> @llvm.aarch64.neon.bfcvtn2(<8 x bfloat>, <4 x float>)
7450
7451 // Add reduction to scalar
7452 case Intrinsic::aarch64_neon_faddv:
7453 case Intrinsic::aarch64_neon_saddv:
7454 case Intrinsic::aarch64_neon_uaddv:
7455 // Signed/Unsigned min/max (Vector)
7456 // TODO: handling similarly to AND/OR may be more precise.
7457 case Intrinsic::aarch64_neon_smaxv:
7458 case Intrinsic::aarch64_neon_sminv:
7459 case Intrinsic::aarch64_neon_umaxv:
7460 case Intrinsic::aarch64_neon_uminv:
7461 // Floating-point min/max (vector)
7462 // The f{min,max}"nm"v variants handle NaN differently than f{min,max}v,
7463 // but our shadow propagation is the same.
7464 case Intrinsic::aarch64_neon_fmaxv:
7465 case Intrinsic::aarch64_neon_fminv:
7466 case Intrinsic::aarch64_neon_fmaxnmv:
7467 case Intrinsic::aarch64_neon_fminnmv:
7468 // Sum long across vector
7469 case Intrinsic::aarch64_neon_saddlv:
7470 case Intrinsic::aarch64_neon_uaddlv:
7471 handleVectorReduceIntrinsic(I, /*AllowShadowCast=*/true);
7472 break;
7473
7474 case Intrinsic::aarch64_neon_ld1x2:
7475 case Intrinsic::aarch64_neon_ld1x3:
7476 case Intrinsic::aarch64_neon_ld1x4:
7477 case Intrinsic::aarch64_neon_ld2:
7478 case Intrinsic::aarch64_neon_ld3:
7479 case Intrinsic::aarch64_neon_ld4:
7480 case Intrinsic::aarch64_neon_ld2r:
7481 case Intrinsic::aarch64_neon_ld3r:
7482 case Intrinsic::aarch64_neon_ld4r: {
7483 handleNEONVectorLoad(I, /*WithLane=*/false);
7484 break;
7485 }
7486
7487 case Intrinsic::aarch64_neon_ld2lane:
7488 case Intrinsic::aarch64_neon_ld3lane:
7489 case Intrinsic::aarch64_neon_ld4lane: {
7490 handleNEONVectorLoad(I, /*WithLane=*/true);
7491 break;
7492 }
7493
7494 // Saturating extract narrow
7495 case Intrinsic::aarch64_neon_sqxtn:
7496 case Intrinsic::aarch64_neon_sqxtun:
7497 case Intrinsic::aarch64_neon_uqxtn:
7498 // These only have one argument, but we (ab)use handleShadowOr because it
7499 // does work on single argument intrinsics and will typecast the shadow
7500 // (and update the origin).
7501 handleShadowOr(I);
7502 break;
7503
7504 case Intrinsic::aarch64_neon_st1x2:
7505 case Intrinsic::aarch64_neon_st1x3:
7506 case Intrinsic::aarch64_neon_st1x4:
7507 case Intrinsic::aarch64_neon_st2:
7508 case Intrinsic::aarch64_neon_st3:
7509 case Intrinsic::aarch64_neon_st4: {
7510 handleNEONVectorStoreIntrinsic(I, false);
7511 break;
7512 }
7513
7514 case Intrinsic::aarch64_neon_st2lane:
7515 case Intrinsic::aarch64_neon_st3lane:
7516 case Intrinsic::aarch64_neon_st4lane: {
7517 handleNEONVectorStoreIntrinsic(I, true);
7518 break;
7519 }
7520
7521 // Arm NEON vector table intrinsics have the source/table register(s) as
7522 // arguments, followed by the index register. They return the output.
7523 //
7524 // 'TBL writes a zero if an index is out-of-range, while TBX leaves the
7525 // original value unchanged in the destination register.'
7526 // Conveniently, zero denotes a clean shadow, which means out-of-range
7527 // indices for TBL will initialize the user data with zero and also clean
7528 // the shadow. (For TBX, neither the user data nor the shadow will be
7529 // updated, which is also correct.)
7530 case Intrinsic::aarch64_neon_tbl1:
7531 case Intrinsic::aarch64_neon_tbl2:
7532 case Intrinsic::aarch64_neon_tbl3:
7533 case Intrinsic::aarch64_neon_tbl4:
7534 case Intrinsic::aarch64_neon_tbx1:
7535 case Intrinsic::aarch64_neon_tbx2:
7536 case Intrinsic::aarch64_neon_tbx3:
7537 case Intrinsic::aarch64_neon_tbx4: {
7538 // The last trailing argument (index register) should be handled verbatim
7539 handleIntrinsicByApplyingToShadow(
7540 I, /*shadowIntrinsicID=*/I.getIntrinsicID(),
7541 /*verbatimArgIndices=*/{-1}, /*forceIntegerIntrinsic=*/false);
7542 break;
7543 }
7544
7545 case Intrinsic::aarch64_neon_fmulx:
7546 case Intrinsic::aarch64_neon_pmul:
7547 case Intrinsic::aarch64_neon_pmull:
7548 case Intrinsic::aarch64_neon_smull:
7549 case Intrinsic::aarch64_neon_pmull64:
7550 case Intrinsic::aarch64_neon_umull: {
7551 handleNEONVectorMultiplyIntrinsic(I);
7552 break;
7553 }
7554
7555 case Intrinsic::aarch64_neon_smmla:
7556 case Intrinsic::aarch64_neon_ummla:
7557 case Intrinsic::aarch64_neon_usmmla:
7558 case Intrinsic::aarch64_neon_bfmmla:
7559 handleNEONMatrixMultiply(I);
7560 break;
7561
7562 // <2 x i32> @llvm.aarch64.neon.{u,s,us}dot.v2i32.v8i8
7563 // (<2 x i32> %acc, <8 x i8> %a, <8 x i8> %b)
7564 // <4 x i32> @llvm.aarch64.neon.{u,s,us}dot.v4i32.v16i8
7565 // (<4 x i32> %acc, <16 x i8> %a, <16 x i8> %b)
7566 case Intrinsic::aarch64_neon_sdot:
7567 case Intrinsic::aarch64_neon_udot:
7568 case Intrinsic::aarch64_neon_usdot:
7569 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
7570 /*ZeroPurifies=*/true,
7571 /*EltSizeInBits=*/0,
7572 /*Lanes=*/kBothLanes);
7573 break;
7574
7575 // <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16
7576 // (<2 x float> %acc, <4 x bfloat> %a, <4 x bfloat> %b)
7577 // <4 x float> @llvm.aarch64.neon.bfdot.v4f32.v8bf16
7578 // (<4 x float> %acc, <8 x bfloat> %a, <8 x bfloat> %b)
7579 case Intrinsic::aarch64_neon_bfdot:
7580 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
7581 /*ZeroPurifies=*/false,
7582 /*EltSizeInBits=*/0,
7583 /*Lanes=*/kBothLanes);
7584 break;
7585
7586 // <4 x half > @llvm.aarch64.neon.fp8.fdot2
7587 // (<4 x half >, < 8 x i8>, < 8 x i8>)
7588 // <8 x half > @llvm.aarch64.neon.fp8.fdot2
7589 // (<8 x half >, <16 x i8>, <16 x i8>)
7590 //
7591 // N.B. although the multiplicands are i8, they are actually fp8, thus
7592 // ZeroPurifies is not applicable.
7593 case Intrinsic::aarch64_neon_fp8_fdot2:
7594 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
7595 /*ZeroPurifies=*/false,
7596 /*EltSizeInBits=*/0,
7597 /*Lanes=*/kBothLanes);
7598 break;
7599
7600 // <2 x float> @llvm.aarch64.neon.fp8.fdot4
7601 // (<2 x float>, < 8 x i8>, < 8 x i8>)
7602 // <4 x float> @llvm.aarch64.neon.fp8.fdot4
7603 // (<4 x float>, <16 x i8>, <16 x i8>)
7604 //
7605 // N.B. although the multiplicands are i8, they are actually fp8, thus
7606 // ZeroPurifies is not applicable.
7607 case Intrinsic::aarch64_neon_fp8_fdot4:
7608 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
7609 /*ZeroPurifies=*/false,
7610 /*EltSizeInBits=*/0,
7611 /*Lanes=*/kBothLanes);
7612 break;
7613
7614 // <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane
7615 // (<4 x half>, <8 x i8>, <16 x i8>, i32)
7616 // <8 x half> @llvm.aarch64.neon.fp8.fdot2.lane
7617 // (<8 x half>, <16 x i8>, <16 x i8>, i32)
7618 case Intrinsic::aarch64_neon_fp8_fdot2_lane:
7619 handleNEONDotProductLaneIntrinsic(I, /*ReductionFactor=*/2);
7620 break;
7621
7622 // <2 x float> @llvm.aarch64.neon.fp8.fdot4.lane
7623 // (<2 x float>, <8 x i8>, <16 x i8>, i32)
7624 // <4 x float> @llvm.aarch64.neon.fp8.fdot4.lane
7625 // (<4 x float>, <16 x i8>, <16 x i8>, i32)
7626 case Intrinsic::aarch64_neon_fp8_fdot4_lane:
7627 handleNEONDotProductLaneIntrinsic(I, /*ReductionFactor=*/4);
7628 break;
7629
7630 // Floating-Point Absolute Compare Greater Than/Equal
7631 case Intrinsic::aarch64_neon_facge:
7632 case Intrinsic::aarch64_neon_facgt:
7633 handleVectorComparePackedIntrinsic(I, /*PredicateAsOperand=*/false);
7634 break;
7635
7636 default:
7637 return false;
7638 }
7639
7640 return true;
7641 }
7642
7643 void visitIntrinsicInst(IntrinsicInst &I) {
7644 if (maybeHandleCrossPlatformIntrinsic(I))
7645 return;
7646
7647 if (maybeHandleX86SIMDIntrinsic(I))
7648 return;
7649
7650 if (maybeHandleArmSIMDIntrinsic(I))
7651 return;
7652
7653 if (maybeHandleUnknownIntrinsic(I))
7654 return;
7655
7656 visitInstruction(I);
7657 }
7658
7659 void visitLibAtomicLoad(CallBase &CB) {
7660 // Since we use getNextNode here, we can't have CB terminate the BB.
7661 assert(isa<CallInst>(CB));
7662
7663 IRBuilder<> IRB(&CB);
7664 Value *Size = CB.getArgOperand(0);
7665 Value *SrcPtr = CB.getArgOperand(1);
7666 Value *DstPtr = CB.getArgOperand(2);
7667 Value *Ordering = CB.getArgOperand(3);
7668 // Convert the call to have at least Acquire ordering to make sure
7669 // the shadow operations aren't reordered before it.
7670 Value *NewOrdering =
7671 IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
7672 CB.setArgOperand(3, NewOrdering);
7673
7674 NextNodeIRBuilder NextIRB(&CB);
7675 Value *SrcShadowPtr, *SrcOriginPtr;
7676 std::tie(SrcShadowPtr, SrcOriginPtr) =
7677 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
7678 /*isStore*/ false);
7679 Value *DstShadowPtr =
7680 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
7681 /*isStore*/ true)
7682 .first;
7683
7684 NextIRB.CreateMemCpy(DstShadowPtr, Align(1), SrcShadowPtr, Align(1), Size);
7685 if (MS.TrackOrigins) {
7686 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7688 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7689 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7690 }
7691 }
7692
7693 void visitLibAtomicStore(CallBase &CB) {
7694 IRBuilder<> IRB(&CB);
7695 Value *Size = CB.getArgOperand(0);
7696 Value *DstPtr = CB.getArgOperand(2);
7697 Value *Ordering = CB.getArgOperand(3);
7698 // Convert the call to have at least Release ordering to make sure
7699 // the shadow operations aren't reordered after it.
7700 Value *NewOrdering =
7701 IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
7702 CB.setArgOperand(3, NewOrdering);
7703
7704 Value *DstShadowPtr =
7705 getShadowOriginPtr(DstPtr, IRB, IRB.getInt8Ty(), Align(1),
7706 /*isStore*/ true)
7707 .first;
7708
7709 // Atomic store always paints clean shadow/origin. See file header.
7710 IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
7711 Align(1));
7712 }
7713
7714 void visitCallBase(CallBase &CB) {
7715 assert(!CB.getMetadata(LLVMContext::MD_nosanitize));
7716 if (CB.isInlineAsm()) {
7717 // For inline asm (either a call to asm function, or callbr instruction),
7718 // do the usual thing: check argument shadow and mark all outputs as
7719 // clean. Note that any side effects of the inline asm that are not
7720 // immediately visible in its constraints are not handled.
7721 if (Opts.msan_handle_asm_conservative)
7722 visitAsmInstruction(CB);
7723 else
7724 visitInstruction(CB);
7725 return;
7726 }
7727 LibFunc LF = TLI->getLibFunc(CB);
7728 if (LF != NotLibFunc) {
7729 // libatomic.a functions need to have special handling because there isn't
7730 // a good way to intercept them or compile the library with
7731 // instrumentation.
7732 switch (LF) {
7733 case LibFunc_atomic_load:
7734 if (!isa<CallInst>(CB)) {
7735 llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
7736 "Ignoring!\n";
7737 break;
7738 }
7739 visitLibAtomicLoad(CB);
7740 return;
7741 case LibFunc_atomic_store:
7742 visitLibAtomicStore(CB);
7743 return;
7744 default:
7745 break;
7746 }
7747 }
7748
7749 if (auto *Call = dyn_cast<CallInst>(&CB)) {
7750 assert(!isa<IntrinsicInst>(Call) && "intrinsics are handled elsewhere");
7751
7752 // We are going to insert code that relies on the fact that the callee
7753 // will become a non-readonly function after it is instrumented by us. To
7754 // prevent this code from being optimized out, mark that function
7755 // non-readonly in advance.
7756 // TODO: We can likely do better than dropping memory() completely here.
7757 AttributeMask B;
7758 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7759
7761 if (Function *Func = Call->getCalledFunction()) {
7762 Func->removeFnAttrs(B);
7763 }
7764
7766 }
7767 IRBuilder<> IRB(&CB);
7768 bool MayCheckCall = MS.EagerChecks;
7769 if (Function *Func = CB.getCalledFunction()) {
7770 // __sanitizer_unaligned_{load,store} functions may be called by users
7771 // and always expects shadows in the TLS. So don't check them.
7772 MayCheckCall &= !Func->getName().starts_with("__sanitizer_unaligned_");
7773 }
7774
7775 unsigned ArgOffset = 0;
7776 LLVM_DEBUG(dbgs() << " CallSite: " << CB << "\n");
7777 for (const auto &[i, A] : llvm::enumerate(CB.args())) {
7778 if (!A->getType()->isSized()) {
7779 LLVM_DEBUG(dbgs() << "Arg " << i << " is not sized: " << CB << "\n");
7780 continue;
7781 }
7782
7783 if (A->getType()->isScalableTy()) {
7784 LLVM_DEBUG(dbgs() << "Arg " << i << " is vscale: " << CB << "\n");
7785 // Handle as noundef, but don't reserve tls slots.
7786 insertCheckShadowOf(A, &CB);
7787 continue;
7788 }
7789
7790 unsigned Size = 0;
7791 const DataLayout &DL = F.getDataLayout();
7792
7793 bool ByVal = CB.isByValArgument(i);
7794 bool NoUndef = CB.paramHasAttr(i, Attribute::NoUndef);
7795 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7796
7797 if (EagerCheck) {
7798 insertCheckShadowOf(A, &CB);
7799 Size = DL.getTypeAllocSize(A->getType());
7800 } else {
7801 [[maybe_unused]] Value *Store = nullptr;
7802 // Compute the Shadow for arg even if it is ByVal, because
7803 // in that case getShadow() will copy the actual arg shadow to
7804 // __msan_param_tls.
7805 Value *ArgShadow = getShadow(A);
7806 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7807 LLVM_DEBUG(dbgs() << " Arg#" << i << ": " << *A
7808 << " Shadow: " << *ArgShadow << "\n");
7809 if (ByVal) {
7810 // ByVal requires some special handling as it's too big for a single
7811 // load
7812 assert(A->getType()->isPointerTy() &&
7813 "ByVal argument is not a pointer!");
7814 Size = DL.getTypeAllocSize(CB.getParamByValType(i));
7815 if (ArgOffset + Size > kParamTLSSize)
7816 break;
7817 const MaybeAlign ParamAlignment(CB.getParamAlign(i));
7818 MaybeAlign Alignment = std::nullopt;
7819 if (ParamAlignment)
7820 Alignment = std::min(*ParamAlignment, kShadowTLSAlignment);
7821 Value *AShadowPtr, *AOriginPtr;
7822 std::tie(AShadowPtr, AOriginPtr) =
7823 getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
7824 /*isStore*/ false);
7825 if (!PropagateShadow) {
7826 Store = IRB.CreateMemSet(ArgShadowBase,
7828 Size, Alignment);
7829 } else {
7830 Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr,
7831 Alignment, Size);
7832 if (MS.TrackOrigins) {
7833 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7834 // FIXME: OriginSize should be:
7835 // alignTo(A % kMinOriginAlignment + Size, kMinOriginAlignment)
7836 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
7837 IRB.CreateMemCpy(
7838 ArgOriginBase,
7839 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
7840 AOriginPtr,
7841 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginSize);
7842 }
7843 }
7844 } else {
7845 // Any other parameters mean we need bit-grained tracking of uninit
7846 // data
7847 Size = DL.getTypeAllocSize(A->getType());
7848 if (ArgOffset + Size > kParamTLSSize)
7849 break;
7850 Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
7852 Constant *Cst = dyn_cast<Constant>(ArgShadow);
7853 if (MS.TrackOrigins && !(Cst && Cst->isNullValue())) {
7854 IRB.CreateStore(getOrigin(A),
7855 getOriginPtrForArgument(IRB, ArgOffset));
7856 }
7857 }
7858 assert(Store != nullptr);
7859 LLVM_DEBUG(dbgs() << " Param:" << *Store << "\n");
7860 }
7861 assert(Size != 0);
7862 ArgOffset += alignTo(Size, kShadowTLSAlignment);
7863 }
7864 LLVM_DEBUG(dbgs() << " done with call args\n");
7865
7866 FunctionType *FT = CB.getFunctionType();
7867 if (FT->isVarArg()) {
7868 VAHelper->visitCallBase(CB, IRB);
7869 }
7870
7871 // Now, get the shadow for the RetVal.
7872 if (!CB.getType()->isSized())
7873 return;
7874 // Don't emit the epilogue for musttail call returns.
7875 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
7876 return;
7877
7878 if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
7879 setShadow(&CB, getCleanShadow(&CB));
7880 setOrigin(&CB, getCleanOrigin());
7881 return;
7882 }
7883
7884 IRBuilder<> IRBBefore(&CB);
7885 // Until we have full dynamic coverage, make sure the retval shadow is 0.
7886 Value *Base = getShadowPtrForRetval(IRBBefore);
7887 IRBBefore.CreateAlignedStore(getCleanShadow(&CB), Base,
7889 BasicBlock::iterator NextInsn;
7890 if (isa<CallInst>(CB)) {
7891 NextInsn = ++CB.getIterator();
7892 assert(NextInsn != CB.getParent()->end());
7893 } else {
7894 BasicBlock *NormalDest = cast<InvokeInst>(CB).getNormalDest();
7895 if (!NormalDest->getSinglePredecessor()) {
7896 // FIXME: this case is tricky, so we are just conservative here.
7897 // Perhaps we need to split the edge between this BB and NormalDest,
7898 // but a naive attempt to use SplitEdge leads to a crash.
7899 setShadow(&CB, getCleanShadow(&CB));
7900 setOrigin(&CB, getCleanOrigin());
7901 return;
7902 }
7903 // FIXME: NextInsn is likely in a basic block that has not been visited
7904 // yet. Anything inserted there will be instrumented by MSan later!
7905 NextInsn = NormalDest->getFirstInsertionPt();
7906 assert(NextInsn != NormalDest->end() &&
7907 "Could not find insertion point for retval shadow load");
7908 }
7909 IRBuilder<> IRBAfter(&*NextInsn);
7910 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7911 getShadowTy(&CB), getShadowPtrForRetval(IRBAfter), kShadowTLSAlignment,
7912 "_msret");
7913 setShadow(&CB, RetvalShadow);
7914 if (MS.TrackOrigins)
7915 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7916 }
7917
7918 bool isAMustTailRetVal(Value *RetVal) {
7919 if (auto *I = dyn_cast<BitCastInst>(RetVal)) {
7920 RetVal = I->getOperand(0);
7921 }
7922 if (auto *I = dyn_cast<CallInst>(RetVal)) {
7923 return I->isMustTailCall();
7924 }
7925 return false;
7926 }
7927
7928 void visitReturnInst(ReturnInst &I) {
7929 IRBuilder<> IRB(&I);
7930 Value *RetVal = I.getReturnValue();
7931 if (!RetVal)
7932 return;
7933 // Don't emit the epilogue for musttail call returns.
7934 if (isAMustTailRetVal(RetVal))
7935 return;
7936 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7937 bool HasNoUndef = F.hasRetAttribute(Attribute::NoUndef);
7938 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7939 // FIXME: Consider using SpecialCaseList to specify a list of functions that
7940 // must always return fully initialized values. For now, we hardcode "main".
7941 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (F.getName() == "main");
7942
7943 Value *Shadow = getShadow(RetVal);
7944 bool StoreOrigin = true;
7945 if (EagerCheck) {
7946 insertCheckShadowOf(RetVal, &I);
7947 Shadow = getCleanShadow(RetVal);
7948 StoreOrigin = false;
7949 }
7950
7951 // The caller may still expect information passed over TLS if we pass our
7952 // check
7953 if (StoreShadow) {
7954 IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
7955 if (MS.TrackOrigins && StoreOrigin)
7956 IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7957 }
7958 }
7959
7960 void visitPHINode(PHINode &I) {
7961 IRBuilder<> IRB(&I);
7962 if (!PropagateShadow) {
7963 setShadow(&I, getCleanShadow(&I));
7964 setOrigin(&I, getCleanOrigin());
7965 return;
7966 }
7967
7968 ShadowPHINodes.push_back(&I);
7969 setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
7970 "_msphi_s"));
7971 if (MS.TrackOrigins)
7972 setOrigin(
7973 &I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(), "_msphi_o"));
7974 }
7975
7976 Value *getLocalVarIdptr(AllocaInst &I) {
7977 ConstantInt *IntConst =
7978 ConstantInt::get(Type::getInt32Ty((*F.getParent()).getContext()), 0);
7979 return new GlobalVariable(*F.getParent(), IntConst->getType(),
7980 /*isConstant=*/false, GlobalValue::PrivateLinkage,
7981 IntConst);
7982 }
7983
7984 Value *getLocalVarDescription(AllocaInst &I) {
7985 return createPrivateConstGlobalForString(*F.getParent(), I.getName());
7986 }
7987
7988 void poisonAllocaUserspace(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
7989 if (PoisonStack && Opts.msan_poison_stack_with_call) {
7990 IRB.CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7991 } else {
7992 Value *ShadowBase, *OriginBase;
7993 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7994 &I, IRB, IRB.getInt8Ty(), Align(1), /*isStore*/ true);
7995
7996 Value *PoisonValue =
7997 IRB.getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
7998 IRB.CreateMemSet(ShadowBase, PoisonValue, Len, I.getAlign());
7999 }
8000
8001 if (PoisonStack && MS.TrackOrigins) {
8002 Value *Idptr = getLocalVarIdptr(I);
8003 if (Opts.msan_print_stack_names) {
8004 Value *Descr = getLocalVarDescription(I);
8005 IRB.CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
8006 {&I, Len, Idptr, Descr});
8007 } else {
8008 IRB.CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
8009 }
8010 }
8011 }
8012
8013 void poisonAllocaKmsan(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
8014 Value *Descr = getLocalVarDescription(I);
8015 if (PoisonStack) {
8016 IRB.CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
8017 } else {
8018 IRB.CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
8019 }
8020 }
8021
8022 void instrumentAlloca(AllocaInst &I, Instruction *InsPoint = nullptr) {
8023 if (!InsPoint)
8024 InsPoint = &I;
8025 NextNodeIRBuilder IRB(InsPoint);
8026 Value *Len = IRB.CreateAllocationSize(MS.IntptrTy, &I);
8027
8028 if (MS.CompileKernel)
8029 poisonAllocaKmsan(I, IRB, Len);
8030 else
8031 poisonAllocaUserspace(I, IRB, Len);
8032 }
8033
8034 void visitAllocaInst(AllocaInst &I) {
8035 setShadow(&I, getCleanShadow(&I));
8036 setOrigin(&I, getCleanOrigin());
8037 // We'll get to this alloca later unless it's poisoned at the corresponding
8038 // llvm.lifetime.start.
8039 AllocaSet.insert(&I);
8040 }
8041
8042 void visitSelectInst(SelectInst &I) {
8043 // a = select b, c, d
8044 Value *B = I.getCondition();
8045 Value *C = I.getTrueValue();
8046 Value *D = I.getFalseValue();
8047
8048 handleSelectLikeInst(I, B, C, D);
8049 }
8050
8051 void handleSelectLikeInst(Instruction &I, Value *B, Value *C, Value *D) {
8052 IRBuilder<> IRB(&I);
8053
8054 Value *Sb = getShadow(B);
8055 Value *Sc = getShadow(C);
8056 Value *Sd = getShadow(D);
8057
8058 Value *Ob = MS.TrackOrigins ? getOrigin(B) : nullptr;
8059 Value *Oc = MS.TrackOrigins ? getOrigin(C) : nullptr;
8060 Value *Od = MS.TrackOrigins ? getOrigin(D) : nullptr;
8061
8062 // Result shadow if condition shadow is 0.
8063 Value *Sa0 = IRB.CreateSelect(B, Sc, Sd);
8064 Value *Sa1;
8065 if (I.getType()->isAggregateType()) {
8066 // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do
8067 // an extra "select". This results in much more compact IR.
8068 // Sa = select Sb, poisoned, (select b, Sc, Sd)
8069 Sa1 = getPoisonedShadow(getShadowTy(I.getType()));
8070 } else if (isScalableNonVectorType(I.getType())) {
8071 // This is intended to handle target("aarch64.svcount"), which can't be
8072 // handled in the else branch because of incompatibility with CreateXor
8073 // ("The supported LLVM operations on this type are limited to load,
8074 // store, phi, select and alloca instructions").
8075
8076 // TODO: this currently underapproximates. Use Arm SVE EOR in the else
8077 // branch as needed instead.
8078 Sa1 = getCleanShadow(getShadowTy(I.getType()));
8079 } else {
8080 // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ]
8081 // If Sb (condition is poisoned), look for bits in c and d that are equal
8082 // and both unpoisoned.
8083 // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd.
8084
8085 // Cast arguments to shadow-compatible type.
8086 C = CreateAppToShadowCast(IRB, C);
8087 D = CreateAppToShadowCast(IRB, D);
8088
8089 // Result shadow if condition shadow is 1.
8090 Sa1 = IRB.CreateOr({IRB.CreateXor(C, D), Sc, Sd});
8091 }
8092 Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
8093 setShadow(&I, Sa);
8094 if (MS.TrackOrigins) {
8095 // Origins are always i32, so any vector conditions must be flattened.
8096 // FIXME: consider tracking vector origins for app vectors?
8097 if (B->getType()->isVectorTy()) {
8098 B = convertToBool(B, IRB);
8099 Sb = convertToBool(Sb, IRB);
8100 }
8101 // a = select b, c, d
8102 // Oa = Sb ? Ob : (b ? Oc : Od)
8103 setOrigin(&I, IRB.CreateSelect(Sb, Ob, IRB.CreateSelect(B, Oc, Od)));
8104 }
8105 }
8106
8107 void visitLandingPadInst(LandingPadInst &I) {
8108 // Do nothing.
8109 // See https://github.com/google/sanitizers/issues/504
8110 setShadow(&I, getCleanShadow(&I));
8111 setOrigin(&I, getCleanOrigin());
8112 }
8113
8114 void visitCatchSwitchInst(CatchSwitchInst &I) {
8115 setShadow(&I, getCleanShadow(&I));
8116 setOrigin(&I, getCleanOrigin());
8117 }
8118
8119 void visitFuncletPadInst(FuncletPadInst &I) {
8120 setShadow(&I, getCleanShadow(&I));
8121 setOrigin(&I, getCleanOrigin());
8122 }
8123
8124 void visitGetElementPtrInst(GetElementPtrInst &I) { handleShadowOr(I); }
8125
8126 void visitExtractValueInst(ExtractValueInst &I) {
8127 IRBuilder<> IRB(&I);
8128 Value *Agg = I.getAggregateOperand();
8129 LLVM_DEBUG(dbgs() << "ExtractValue: " << I << "\n");
8130 Value *AggShadow = getShadow(Agg);
8131 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
8132 Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
8133 LLVM_DEBUG(dbgs() << " ResShadow: " << *ResShadow << "\n");
8134 setShadow(&I, ResShadow);
8135 setOriginForNaryOp(I);
8136 }
8137
8138 void visitInsertValueInst(InsertValueInst &I) {
8139 IRBuilder<> IRB(&I);
8140 LLVM_DEBUG(dbgs() << "InsertValue: " << I << "\n");
8141 Value *AggShadow = getShadow(I.getAggregateOperand());
8142 Value *InsShadow = getShadow(I.getInsertedValueOperand());
8143 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
8144 LLVM_DEBUG(dbgs() << " InsShadow: " << *InsShadow << "\n");
8145 Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
8146 LLVM_DEBUG(dbgs() << " Res: " << *Res << "\n");
8147 setShadow(&I, Res);
8148 setOriginForNaryOp(I);
8149 }
8150
8151 void dumpInst(Instruction &I, const Twine &Prefix) {
8152 // Instruction name only
8153 // For intrinsics, the full/overloaded name is used
8154 //
8155 // e.g., "call llvm.aarch64.neon.uqsub.v16i8"
8156 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
8157 errs() << "ZZZ:" << Prefix << " call "
8158 << CI->getCalledFunction()->getName() << "\n";
8159 } else {
8160 errs() << "ZZZ:" << Prefix << " " << I.getOpcodeName() << "\n";
8161 }
8162
8163 // Instruction prototype (including return type and parameter types)
8164 // For intrinsics, we use the base/non-overloaded name
8165 //
8166 // e.g., "call <16 x i8> @llvm.aarch64.neon.uqsub(<16 x i8>, <16 x i8>)"
8167 unsigned NumOperands = I.getNumOperands();
8168 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
8169 errs() << "YYY:" << Prefix << " call " << *I.getType() << " @";
8170
8171 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI))
8172 errs() << Intrinsic::getBaseName(II->getIntrinsicID());
8173 else
8174 errs() << CI->getCalledFunction()->getName();
8175
8176 errs() << "(";
8177
8178 // The last operand of a CallInst is the function itself.
8179 NumOperands--;
8180 } else
8181 errs() << "YYY:" << Prefix << " " << *I.getType() << " "
8182 << I.getOpcodeName() << "(";
8183
8184 for (size_t i = 0; i < NumOperands; i++) {
8185 if (i > 0)
8186 errs() << ", ";
8187
8188 errs() << *(I.getOperand(i)->getType());
8189 }
8190
8191 errs() << ")\n";
8192
8193 // Full instruction, including types and operand values
8194 // For intrinsics, the full/overloaded name is used
8195 //
8196 // e.g., "%vqsubq_v.i15 = call noundef <16 x i8>
8197 // @llvm.aarch64.neon.uqsub.v16i8(<16 x i8> %vext21.i,
8198 // <16 x i8> splat (i8 1)), !dbg !66"
8199 errs() << "QQQ:" << Prefix << " " << I << "\n";
8200 }
8201
8202 void visitResumeInst(ResumeInst &I) {
8203 LLVM_DEBUG(dbgs() << "Resume: " << I << "\n");
8204 // Nothing to do here.
8205 }
8206
8207 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8208 LLVM_DEBUG(dbgs() << "CleanupReturn: " << CRI << "\n");
8209 // Nothing to do here.
8210 }
8211
8212 void visitCatchReturnInst(CatchReturnInst &CRI) {
8213 LLVM_DEBUG(dbgs() << "CatchReturn: " << CRI << "\n");
8214 // Nothing to do here.
8215 }
8216
8217 void instrumentAsmArgument(Value *Operand, Type *ElemTy, Instruction &I,
8218 IRBuilder<> &IRB, const DataLayout &DL,
8219 bool isOutput) {
8220 // For each assembly argument, we check its value for being initialized.
8221 // If the argument is a pointer, we assume it points to a single element
8222 // of the corresponding type (or to a 8-byte word, if the type is unsized).
8223 // Each such pointer is instrumented with a call to the runtime library.
8224 Type *OpType = Operand->getType();
8225 // Check the operand value itself.
8226 insertCheckShadowOf(Operand, &I);
8227 if (!OpType->isPointerTy() || !isOutput) {
8228 assert(!isOutput);
8229 return;
8230 }
8231 if (!ElemTy->isSized())
8232 return;
8233 auto Size = DL.getTypeStoreSize(ElemTy);
8234 Value *SizeVal = IRB.CreateTypeSize(MS.IntptrTy, Size);
8235 if (MS.CompileKernel) {
8236 IRB.CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8237 } else {
8238 // ElemTy, derived from elementtype(), does not encode the alignment of
8239 // the pointer. Conservatively assume that the shadow memory is unaligned.
8240 // When Size is large, avoid StoreInst as it would expand to many
8241 // instructions.
8242 auto [ShadowPtr, _] =
8243 getShadowOriginPtrUserspace(Operand, IRB, IRB.getInt8Ty(), Align(1));
8244 if (Size <= 32)
8245 IRB.CreateAlignedStore(getCleanShadow(ElemTy), ShadowPtr, Align(1));
8246 else
8247 IRB.CreateMemSet(ShadowPtr, ConstantInt::getNullValue(IRB.getInt8Ty()),
8248 SizeVal, Align(1));
8249 }
8250 }
8251
8252 /// Get the number of output arguments returned by pointers.
8253 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8254 int NumRetOutputs = 0;
8255 int NumOutputs = 0;
8256 Type *RetTy = cast<Value>(CB)->getType();
8257 if (!RetTy->isVoidTy()) {
8258 // Register outputs are returned via the CallInst return value.
8259 auto *ST = dyn_cast<StructType>(RetTy);
8260 if (ST)
8261 NumRetOutputs = ST->getNumElements();
8262 else
8263 NumRetOutputs = 1;
8264 }
8265 InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
8266 for (const InlineAsm::ConstraintInfo &Info : Constraints) {
8267 switch (Info.Type) {
8269 NumOutputs++;
8270 break;
8271 default:
8272 break;
8273 }
8274 }
8275 return NumOutputs - NumRetOutputs;
8276 }
8277
8278 void visitAsmInstruction(Instruction &I) {
8279 // Conservative inline assembly handling: check for poisoned shadow of
8280 // asm() arguments, then unpoison the result and all the memory locations
8281 // pointed to by those arguments.
8282 // An inline asm() statement in C++ contains lists of input and output
8283 // arguments used by the assembly code. These are mapped to operands of the
8284 // CallInst as follows:
8285 // - nR register outputs ("=r) are returned by value in a single structure
8286 // (SSA value of the CallInst);
8287 // - nO other outputs ("=m" and others) are returned by pointer as first
8288 // nO operands of the CallInst;
8289 // - nI inputs ("r", "m" and others) are passed to CallInst as the
8290 // remaining nI operands.
8291 // The total number of asm() arguments in the source is nR+nO+nI, and the
8292 // corresponding CallInst has nO+nI+1 operands (the last operand is the
8293 // function to be called).
8294 const DataLayout &DL = F.getDataLayout();
8295 CallBase *CB = cast<CallBase>(&I);
8296 IRBuilder<> IRB(&I);
8297 InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
8298 int OutputArgs = getNumOutputArgs(IA, CB);
8299 // The last operand of a CallInst is the function itself.
8300 int NumOperands = CB->getNumOperands() - 1;
8301
8302 // Check input arguments. Doing so before unpoisoning output arguments, so
8303 // that we won't overwrite uninit values before checking them.
8304 for (int i = OutputArgs; i < NumOperands; i++) {
8305 Value *Operand = CB->getOperand(i);
8306 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
8307 /*isOutput*/ false);
8308 }
8309 // Unpoison output arguments. This must happen before the actual InlineAsm
8310 // call, so that the shadow for memory published in the asm() statement
8311 // remains valid.
8312 for (int i = 0; i < OutputArgs; i++) {
8313 Value *Operand = CB->getOperand(i);
8314 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
8315 /*isOutput*/ true);
8316 }
8317
8318 setShadow(&I, getCleanShadow(&I));
8319 setOrigin(&I, getCleanOrigin());
8320 }
8321
8322 void visitFreezeInst(FreezeInst &I) {
8323 // Freeze always returns a fully defined value.
8324 setShadow(&I, getCleanShadow(&I));
8325 setOrigin(&I, getCleanOrigin());
8326 }
8327
8328 void visitInstruction(Instruction &I) {
8329 // Everything else: stop propagating and check for poisoned shadow.
8330 if (Opts.msan_dump_strict_instructions)
8331 dumpInst(I, "Strict");
8332 LLVM_DEBUG(dbgs() << "DEFAULT: " << I << "\n");
8333 for (size_t i = 0, n = I.getNumOperands(); i < n; i++) {
8334 Value *Operand = I.getOperand(i);
8335 if (Operand->getType()->isSized())
8336 insertCheckShadowOf(Operand, &I);
8337 }
8338 setShadow(&I, getCleanShadow(&I));
8339 setOrigin(&I, getCleanOrigin());
8340 }
8341};
8342
8343struct VarArgHelperBase : public VarArgHelper {
8344 Function &F;
8345 MemorySanitizer &MS;
8346 MemorySanitizerVisitor &MSV;
8347 SmallVector<CallInst *, 16> VAStartInstrumentationList;
8348 const unsigned VAListTagSize;
8349
8350 VarArgHelperBase(Function &F, MemorySanitizer &MS,
8351 MemorySanitizerVisitor &MSV, unsigned VAListTagSize)
8352 : F(F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8353
8354 Value *getShadowAddrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
8355 Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
8356 return IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8357 }
8358
8359 /// Compute the shadow address for a given va_arg.
8360 Value *getShadowPtrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
8361 return IRB.CreatePtrAddWithUnsignedOffset(MS.VAArgTLS, ArgOffset,
8362 "_msarg_va_s");
8363 }
8364
8365 /// Compute the shadow address for a given va_arg.
8366 Value *getShadowPtrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset,
8367 unsigned ArgSize) {
8368 // Make sure we don't overflow __msan_va_arg_tls.
8369 if (ArgOffset + ArgSize > kParamTLSSize)
8370 return nullptr;
8371 return getShadowPtrForVAArgument(IRB, ArgOffset);
8372 }
8373
8374 /// Compute the origin address for a given va_arg.
8375 Value *getOriginPtrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
8376 // getOriginPtrForVAArgument() is always called after
8377 // getShadowPtrForVAArgument(), so __msan_va_arg_origin_tls can never
8378 // overflow.
8379 return IRB.CreatePtrAddWithUnsignedOffset(MS.VAArgOriginTLS, ArgOffset,
8380 "_msarg_va_o");
8381 }
8382
8383 void CleanUnusedTLS(IRBuilder<> &IRB, Value *ShadowBase,
8384 unsigned BaseOffset) {
8385 // The tails of __msan_va_arg_tls is not large enough to fit full
8386 // value shadow, but it will be copied to backup anyway. Make it
8387 // clean.
8388 if (BaseOffset >= kParamTLSSize)
8389 return;
8390 Value *TailSize =
8391 ConstantInt::getSigned(IRB.getInt32Ty(), kParamTLSSize - BaseOffset);
8392 IRB.CreateMemSet(ShadowBase, ConstantInt::getNullValue(IRB.getInt8Ty()),
8393 TailSize, Align(8));
8394 }
8395
8396 void unpoisonVAListTagForInst(IntrinsicInst &I) {
8397 IRBuilder<> IRB(&I);
8398 Value *VAListTag = I.getArgOperand(0);
8399 const Align Alignment = Align(8);
8400 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8401 VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
8402 // Unpoison the whole __va_list_tag.
8403 IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
8404 VAListTagSize, Alignment, false);
8405 }
8406
8407 void visitVAStartInst(VAStartInst &I) override {
8408 if (F.getCallingConv() == CallingConv::Win64)
8409 return;
8410 VAStartInstrumentationList.push_back(&I);
8411 unpoisonVAListTagForInst(I);
8412 }
8413
8414 void visitVACopyInst(VACopyInst &I) override {
8415 if (F.getCallingConv() == CallingConv::Win64)
8416 return;
8417 unpoisonVAListTagForInst(I);
8418 }
8419};
8420
8421/// AMD64-specific implementation of VarArgHelper.
8422struct VarArgAMD64Helper : public VarArgHelperBase {
8423 // An unfortunate workaround for asymmetric lowering of va_arg stuff.
8424 // See a comment in visitCallBase for more details.
8425 static const unsigned AMD64GpEndOffset = 48; // AMD64 ABI Draft 0.99.6 p3.5.7
8426 static const unsigned AMD64FpEndOffsetSSE = 176;
8427 // If SSE is disabled, fp_offset in va_list is zero.
8428 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8429
8430 unsigned AMD64FpEndOffset;
8431 AllocaInst *VAArgTLSCopy = nullptr;
8432 AllocaInst *VAArgTLSOriginCopy = nullptr;
8433 Value *VAArgOverflowSize = nullptr;
8434
8435 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8436
8437 VarArgAMD64Helper(Function &F, MemorySanitizer &MS,
8438 MemorySanitizerVisitor &MSV)
8439 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/24) {
8440 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8441 for (const auto &Attr : F.getAttributes().getFnAttrs()) {
8442 if (Attr.isStringAttribute() &&
8443 (Attr.getKindAsString() == "target-features")) {
8444 if (Attr.getValueAsString().contains("-sse"))
8445 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8446 break;
8447 }
8448 }
8449 }
8450
8451 ArgKind classifyArgument(Value *arg) {
8452 // A very rough approximation of X86_64 argument classification rules.
8453 Type *T = arg->getType();
8454 if (T->isX86_FP80Ty())
8455 return AK_Memory;
8456 if (T->isFPOrFPVectorTy())
8457 return AK_FloatingPoint;
8458 if (T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64)
8459 return AK_GeneralPurpose;
8460 if (T->isPointerTy())
8461 return AK_GeneralPurpose;
8462 return AK_Memory;
8463 }
8464
8465 // For VarArg functions, store the argument shadow in an ABI-specific format
8466 // that corresponds to va_list layout.
8467 // We do this because Clang lowers va_arg in the frontend, and this pass
8468 // only sees the low level code that deals with va_list internals.
8469 // A much easier alternative (provided that Clang emits va_arg instructions)
8470 // would have been to associate each live instance of va_list with a copy of
8471 // MSanParamTLS, and extract shadow on va_arg() call in the argument list
8472 // order.
8473 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8474 unsigned GpOffset = 0;
8475 unsigned FpOffset = AMD64GpEndOffset;
8476 unsigned OverflowOffset = AMD64FpEndOffset;
8477 const DataLayout &DL = F.getDataLayout();
8478
8479 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8480 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8481 bool IsByVal = CB.isByValArgument(ArgNo);
8482 if (IsByVal) {
8483 // ByVal arguments always go to the overflow area.
8484 // Fixed arguments passed through the overflow area will be stepped
8485 // over by va_start, so don't count them towards the offset.
8486 if (IsFixed)
8487 continue;
8488 assert(A->getType()->isPointerTy());
8489 Type *RealTy = CB.getParamByValType(ArgNo);
8490 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
8491 uint64_t AlignedSize = alignTo(ArgSize, 8);
8492 unsigned BaseOffset = OverflowOffset;
8493 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8494 Value *OriginBase = nullptr;
8495 if (MS.TrackOrigins)
8496 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8497 OverflowOffset += AlignedSize;
8498
8499 if (OverflowOffset > kParamTLSSize) {
8500 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8501 continue; // We have no space to copy shadow there.
8502 }
8503
8504 Value *ShadowPtr, *OriginPtr;
8505 std::tie(ShadowPtr, OriginPtr) =
8506 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), kShadowTLSAlignment,
8507 /*isStore*/ false);
8508 IRB.CreateMemCpy(ShadowBase, kShadowTLSAlignment, ShadowPtr,
8509 kShadowTLSAlignment, ArgSize);
8510 if (MS.TrackOrigins)
8511 IRB.CreateMemCpy(OriginBase, kShadowTLSAlignment, OriginPtr,
8512 kShadowTLSAlignment, ArgSize);
8513 } else {
8514 ArgKind AK = classifyArgument(A);
8515 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8516 AK = AK_Memory;
8517 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8518 AK = AK_Memory;
8519 Value *ShadowBase, *OriginBase = nullptr;
8520 switch (AK) {
8521 case AK_GeneralPurpose:
8522 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8523 if (MS.TrackOrigins)
8524 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8525 GpOffset += 8;
8526 assert(GpOffset <= kParamTLSSize);
8527 break;
8528 case AK_FloatingPoint:
8529 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8530 if (MS.TrackOrigins)
8531 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8532 FpOffset += 16;
8533 assert(FpOffset <= kParamTLSSize);
8534 break;
8535 case AK_Memory:
8536 if (IsFixed)
8537 continue;
8538 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8539 uint64_t AlignedSize = alignTo(ArgSize, 8);
8540 unsigned BaseOffset = OverflowOffset;
8541 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8542 if (MS.TrackOrigins) {
8543 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8544 }
8545 OverflowOffset += AlignedSize;
8546 if (OverflowOffset > kParamTLSSize) {
8547 // We have no space to copy shadow there.
8548 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8549 continue;
8550 }
8551 }
8552 // Take fixed arguments into account for GpOffset and FpOffset,
8553 // but don't actually store shadows for them.
8554 // TODO(glider): don't call get*PtrForVAArgument() for them.
8555 if (IsFixed)
8556 continue;
8557 Value *Shadow = MSV.getShadow(A);
8558 IRB.CreateAlignedStore(Shadow, ShadowBase, kShadowTLSAlignment);
8559 if (MS.TrackOrigins) {
8560 Value *Origin = MSV.getOrigin(A);
8561 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
8562 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8564 }
8565 }
8566 }
8567 Constant *OverflowSize =
8568 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8569 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8570 }
8571
8572 void finalizeInstrumentation() override {
8573 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8574 "finalizeInstrumentation called twice");
8575 if (!VAStartInstrumentationList.empty()) {
8576 // If there is a va_start in this function, make a backup copy of
8577 // va_arg_tls somewhere in the function entry block.
8578 IRBuilder<> IRB(MSV.FnPrologueEnd);
8579 VAArgOverflowSize =
8580 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8581 Value *CopySize = IRB.CreateAdd(
8582 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8583 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8584 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8585 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8586 CopySize, kShadowTLSAlignment, false);
8587
8588 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8589 Intrinsic::umin, CopySize,
8590 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
8591 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8592 kShadowTLSAlignment, SrcSize);
8593 if (MS.TrackOrigins) {
8594 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8595 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
8596 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
8597 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
8598 }
8599 }
8600
8601 // Instrument va_start.
8602 // Copy va_list shadow from the backup copy of the TLS contents.
8603 for (CallInst *OrigInst : VAStartInstrumentationList) {
8604 NextNodeIRBuilder IRB(OrigInst);
8605 Value *VAListTag = OrigInst->getArgOperand(0);
8606
8607 Value *RegSaveAreaPtrPtr =
8608 IRB.CreatePtrAddWithUnsignedOffset(VAListTag, 16);
8609 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
8610 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8611 const Align Alignment = Align(16);
8612 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8613 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8614 Alignment, /*isStore*/ true);
8615 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8616 AMD64FpEndOffset);
8617 if (MS.TrackOrigins)
8618 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8619 Alignment, AMD64FpEndOffset);
8620 Value *OverflowArgAreaPtrPtr =
8621 IRB.CreatePtrAddWithUnsignedOffset(VAListTag, 8);
8622 Value *OverflowArgAreaPtr =
8623 IRB.CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8624 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8625 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8626 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
8627 Alignment, /*isStore*/ true);
8628 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
8629 AMD64FpEndOffset);
8630 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8631 VAArgOverflowSize);
8632 if (MS.TrackOrigins) {
8633 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
8634 AMD64FpEndOffset);
8635 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8636 VAArgOverflowSize);
8637 }
8638 }
8639 }
8640};
8641
8642/// AArch64-specific implementation of VarArgHelper.
8643struct VarArgAArch64Helper : public VarArgHelperBase {
8644 static const unsigned kAArch64GrArgSize = 64;
8645 static const unsigned kAArch64VrArgSize = 128;
8646
8647 static const unsigned AArch64GrBegOffset = 0;
8648 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8649 // Make VR space aligned to 16 bytes.
8650 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8651 static const unsigned AArch64VrEndOffset =
8652 AArch64VrBegOffset + kAArch64VrArgSize;
8653 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8654
8655 AllocaInst *VAArgTLSCopy = nullptr;
8656 Value *VAArgOverflowSize = nullptr;
8657
8658 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8659
8660 VarArgAArch64Helper(Function &F, MemorySanitizer &MS,
8661 MemorySanitizerVisitor &MSV)
8662 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/32) {}
8663
8664 // A very rough approximation of aarch64 argument classification rules.
8665 std::pair<ArgKind, uint64_t> classifyArgument(Type *T) {
8666 if (T->isIntOrPtrTy() && T->getPrimitiveSizeInBits() <= 64)
8667 return {AK_GeneralPurpose, 1};
8668 if (T->isFloatingPointTy() && T->getPrimitiveSizeInBits() <= 128)
8669 return {AK_FloatingPoint, 1};
8670
8671 if (T->isArrayTy()) {
8672 auto R = classifyArgument(T->getArrayElementType());
8673 R.second *= T->getScalarType()->getArrayNumElements();
8674 return R;
8675 }
8676
8677 if (const FixedVectorType *FV = dyn_cast<FixedVectorType>(T)) {
8678 auto R = classifyArgument(FV->getScalarType());
8679 R.second *= FV->getNumElements();
8680 return R;
8681 }
8682
8683 LLVM_DEBUG(errs() << "Unknown vararg type: " << *T << "\n");
8684 return {AK_Memory, 0};
8685 }
8686
8687 // The instrumentation stores the argument shadow in a non ABI-specific
8688 // format because it does not know which argument is named (since Clang,
8689 // like x86_64 case, lowers the va_args in the frontend and this pass only
8690 // sees the low level code that deals with va_list internals).
8691 // The first seven GR registers are saved in the first 56 bytes of the
8692 // va_arg tls arra, followed by the first 8 FP/SIMD registers, and then
8693 // the remaining arguments.
8694 // Using constant offset within the va_arg TLS array allows fast copy
8695 // in the finalize instrumentation.
8696 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8697 unsigned GrOffset = AArch64GrBegOffset;
8698 unsigned VrOffset = AArch64VrBegOffset;
8699 unsigned OverflowOffset = AArch64VAEndOffset;
8700
8701 const DataLayout &DL = F.getDataLayout();
8702 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8703 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8704 auto [AK, RegNum] = classifyArgument(A->getType());
8705 if (AK == AK_GeneralPurpose &&
8706 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8707 AK = AK_Memory;
8708 if (AK == AK_FloatingPoint &&
8709 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8710 AK = AK_Memory;
8711 Value *Base;
8712 switch (AK) {
8713 case AK_GeneralPurpose:
8714 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8715 GrOffset += 8 * RegNum;
8716 break;
8717 case AK_FloatingPoint:
8718 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8719 VrOffset += 16 * RegNum;
8720 break;
8721 case AK_Memory:
8722 // Don't count fixed arguments in the overflow area - va_start will
8723 // skip right over them.
8724 if (IsFixed)
8725 continue;
8726 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8727 uint64_t AlignedSize = alignTo(ArgSize, 8);
8728 unsigned BaseOffset = OverflowOffset;
8729 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8730 OverflowOffset += AlignedSize;
8731 if (OverflowOffset > kParamTLSSize) {
8732 // We have no space to copy shadow there.
8733 CleanUnusedTLS(IRB, Base, BaseOffset);
8734 continue;
8735 }
8736 break;
8737 }
8738 // Count Gp/Vr fixed arguments to their respective offsets, but don't
8739 // bother to actually store a shadow.
8740 if (IsFixed)
8741 continue;
8742 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
8743 }
8744 Constant *OverflowSize =
8745 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8746 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8747 }
8748
8749 // Retrieve a va_list field of 'void*' size.
8750 Value *getVAField64(IRBuilder<> &IRB, Value *VAListTag, unsigned Offset) {
8751 Value *SaveAreaPtrPtr =
8752 IRB.CreatePtrAddWithUnsignedOffset(VAListTag, Offset);
8753 return IRB.CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8754 }
8755
8756 // Retrieve a va_list field of 'int' size.
8757 Value *getVAField32(IRBuilder<> &IRB, Value *VAListTag, unsigned Offset) {
8758 Value *SaveAreaPtr = IRB.CreatePtrAddWithUnsignedOffset(VAListTag, Offset);
8759 Value *SaveArea32 = IRB.CreateLoad(IRB.getInt32Ty(), SaveAreaPtr);
8760 return IRB.CreateSExt(SaveArea32, MS.IntptrTy);
8761 }
8762
8763 void finalizeInstrumentation() override {
8764 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8765 "finalizeInstrumentation called twice");
8766 if (!VAStartInstrumentationList.empty()) {
8767 // If there is a va_start in this function, make a backup copy of
8768 // va_arg_tls somewhere in the function entry block.
8769 IRBuilder<> IRB(MSV.FnPrologueEnd);
8770 VAArgOverflowSize =
8771 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8772 Value *CopySize = IRB.CreateAdd(
8773 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8774 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8775 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8776 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8777 CopySize, kShadowTLSAlignment, false);
8778
8779 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8780 Intrinsic::umin, CopySize,
8781 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
8782 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8783 kShadowTLSAlignment, SrcSize);
8784 }
8785
8786 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8787 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8788
8789 // Instrument va_start, copy va_list shadow from the backup copy of
8790 // the TLS contents.
8791 for (CallInst *OrigInst : VAStartInstrumentationList) {
8792 NextNodeIRBuilder IRB(OrigInst);
8793
8794 Value *VAListTag = OrigInst->getArgOperand(0);
8795
8796 // The variadic ABI for AArch64 creates two areas to save the incoming
8797 // argument registers (one for 64-bit general register xn-x7 and another
8798 // for 128-bit FP/SIMD vn-v7).
8799 // We need then to propagate the shadow arguments on both regions
8800 // 'va::__gr_top + va::__gr_offs' and 'va::__vr_top + va::__vr_offs'.
8801 // The remaining arguments are saved on shadow for 'va::stack'.
8802 // One caveat is it requires only to propagate the non-named arguments,
8803 // however on the call site instrumentation 'all' the arguments are
8804 // saved. So to copy the shadow values from the va_arg TLS array
8805 // we need to adjust the offset for both GR and VR fields based on
8806 // the __{gr,vr}_offs value (since they are stores based on incoming
8807 // named arguments).
8808 Type *RegSaveAreaPtrTy = IRB.getPtrTy();
8809
8810 // Read the stack pointer from the va_list.
8811 Value *StackSaveAreaPtr =
8812 IRB.CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8813
8814 // Read both the __gr_top and __gr_off and add them up.
8815 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8816 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8817
8818 Value *GrRegSaveAreaPtr = IRB.CreateIntToPtr(
8819 IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8820
8821 // Read both the __vr_top and __vr_off and add them up.
8822 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8823 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8824
8825 Value *VrRegSaveAreaPtr = IRB.CreateIntToPtr(
8826 IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8827
8828 // It does not know how many named arguments is being used and, on the
8829 // callsite all the arguments were saved. Since __gr_off is defined as
8830 // '0 - ((8 - named_gr) * 8)', the idea is to just propagate the variadic
8831 // argument by ignoring the bytes of shadow from named arguments.
8832 Value *GrRegSaveAreaShadowPtrOff =
8833 IRB.CreateAdd(GrArgSize, GrOffSaveArea);
8834
8835 Value *GrRegSaveAreaShadowPtr =
8836 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8837 Align(8), /*isStore*/ true)
8838 .first;
8839
8840 Value *GrSrcPtr =
8841 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy, GrRegSaveAreaShadowPtrOff);
8842 Value *GrCopySize = IRB.CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8843
8844 IRB.CreateMemCpy(GrRegSaveAreaShadowPtr, Align(8), GrSrcPtr, Align(8),
8845 GrCopySize);
8846
8847 // Again, but for FP/SIMD values.
8848 Value *VrRegSaveAreaShadowPtrOff =
8849 IRB.CreateAdd(VrArgSize, VrOffSaveArea);
8850
8851 Value *VrRegSaveAreaShadowPtr =
8852 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8853 Align(8), /*isStore*/ true)
8854 .first;
8855
8856 Value *VrSrcPtr = IRB.CreateInBoundsPtrAdd(
8857 IRB.CreatePtrAddWithUnsignedOffset(VAArgTLSCopy, AArch64VrBegOffset,
8859 VrRegSaveAreaShadowPtrOff);
8860 Value *VrCopySize = IRB.CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8861
8862 IRB.CreateMemCpy(VrRegSaveAreaShadowPtr, Align(8), VrSrcPtr, Align(8),
8863 VrCopySize);
8864
8865 // And finally for remaining arguments.
8866 Value *StackSaveAreaShadowPtr =
8867 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.getInt8Ty(),
8868 Align(16), /*isStore*/ true)
8869 .first;
8870
8871 Value *StackSrcPtr = IRB.CreatePtrAddWithUnsignedOffset(
8872 VAArgTLSCopy, AArch64VAEndOffset, "", GEPNoWrapFlags::inBounds());
8873
8874 IRB.CreateMemCpy(StackSaveAreaShadowPtr, Align(16), StackSrcPtr,
8875 Align(16), VAArgOverflowSize);
8876 }
8877 }
8878};
8879
8880/// PowerPC64-specific implementation of VarArgHelper.
8881struct VarArgPowerPC64Helper : public VarArgHelperBase {
8882 AllocaInst *VAArgTLSCopy = nullptr;
8883 Value *VAArgSize = nullptr;
8884
8885 VarArgPowerPC64Helper(Function &F, MemorySanitizer &MS,
8886 MemorySanitizerVisitor &MSV)
8887 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/8) {}
8888
8889 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8890 // For PowerPC, we need to deal with alignment of stack arguments -
8891 // they are mostly aligned to 8 bytes, but vectors and i128 arrays
8892 // are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
8893 // For that reason, we compute current offset from stack pointer (which is
8894 // always properly aligned), and offset for the first vararg, then subtract
8895 // them.
8896 unsigned VAArgBase;
8897 Triple TargetTriple(F.getParent()->getTargetTriple());
8898 // Parameter save area starts at 48 bytes from frame pointer for ABIv1,
8899 // and 32 bytes for ABIv2. This is usually determined by target
8900 // endianness, but in theory could be overridden by function attribute.
8901 if (TargetTriple.isPPC64ELFv2ABI())
8902 VAArgBase = 32;
8903 else
8904 VAArgBase = 48;
8905 unsigned VAArgOffset = VAArgBase;
8906 const DataLayout &DL = F.getDataLayout();
8907 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8908 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8909 bool IsByVal = CB.isByValArgument(ArgNo);
8910 if (IsByVal) {
8911 assert(A->getType()->isPointerTy());
8912 Type *RealTy = CB.getParamByValType(ArgNo);
8913 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
8914 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(8));
8915 if (ArgAlign < 8)
8916 ArgAlign = Align(8);
8917 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
8918 if (!IsFixed) {
8919 Value *Base =
8920 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8921 if (Base) {
8922 Value *AShadowPtr, *AOriginPtr;
8923 std::tie(AShadowPtr, AOriginPtr) =
8924 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
8925 kShadowTLSAlignment, /*isStore*/ false);
8926
8927 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
8928 kShadowTLSAlignment, ArgSize);
8929 }
8930 }
8931 VAArgOffset += alignTo(ArgSize, Align(8));
8932 } else {
8933 Value *Base;
8934 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8935 Align ArgAlign = Align(8);
8936 if (A->getType()->isArrayTy()) {
8937 // Arrays are aligned to element size, except for long double
8938 // arrays, which are aligned to 8 bytes.
8939 Type *ElementTy = A->getType()->getArrayElementType();
8940 if (!ElementTy->isPPC_FP128Ty())
8941 ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
8942 } else if (A->getType()->isVectorTy()) {
8943 // Vectors are naturally aligned.
8944 ArgAlign = Align(ArgSize);
8945 }
8946 if (ArgAlign < 8)
8947 ArgAlign = Align(8);
8948 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
8949 if (DL.isBigEndian()) {
8950 // Adjusting the shadow for argument with size < 8 to match the
8951 // placement of bits in big endian system
8952 if (ArgSize < 8)
8953 VAArgOffset += (8 - ArgSize);
8954 }
8955 if (!IsFixed) {
8956 Base =
8957 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8958 if (Base)
8959 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
8960 }
8961 VAArgOffset += ArgSize;
8962 VAArgOffset = alignTo(VAArgOffset, Align(8));
8963 }
8964 if (IsFixed)
8965 VAArgBase = VAArgOffset;
8966 }
8967
8968 Constant *TotalVAArgSize =
8969 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8970 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
8971 // a new class member i.e. it is the total size of all VarArgs.
8972 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8973 }
8974
8975 void finalizeInstrumentation() override {
8976 assert(!VAArgSize && !VAArgTLSCopy &&
8977 "finalizeInstrumentation called twice");
8978 IRBuilder<> IRB(MSV.FnPrologueEnd);
8979 VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8980 Value *CopySize = VAArgSize;
8981
8982 if (!VAStartInstrumentationList.empty()) {
8983 // If there is a va_start in this function, make a backup copy of
8984 // va_arg_tls somewhere in the function entry block.
8985
8986 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8987 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8988 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8989 CopySize, kShadowTLSAlignment, false);
8990
8991 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8992 Intrinsic::umin, CopySize,
8993 ConstantInt::get(IRB.getInt64Ty(), kParamTLSSize));
8994 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8995 kShadowTLSAlignment, SrcSize);
8996 }
8997
8998 // Instrument va_start.
8999 // Copy va_list shadow from the backup copy of the TLS contents.
9000 for (CallInst *OrigInst : VAStartInstrumentationList) {
9001 NextNodeIRBuilder IRB(OrigInst);
9002 Value *VAListTag = OrigInst->getArgOperand(0);
9003 Value *RegSaveAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
9004
9005 RegSaveAreaPtrPtr = IRB.CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9006
9007 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
9008 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9009 const DataLayout &DL = F.getDataLayout();
9010 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9011 const Align Alignment = Align(IntptrSize);
9012 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9013 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9014 Alignment, /*isStore*/ true);
9015 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9016 CopySize);
9017 }
9018 }
9019};
9020
9021/// PowerPC32-specific implementation of VarArgHelper.
9022struct VarArgPowerPC32Helper : public VarArgHelperBase {
9023 AllocaInst *VAArgTLSCopy = nullptr;
9024 Value *VAArgSize = nullptr;
9025
9026 VarArgPowerPC32Helper(Function &F, MemorySanitizer &MS,
9027 MemorySanitizerVisitor &MSV)
9028 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/12) {}
9029
9030 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9031 unsigned VAArgBase;
9032 // Parameter save area is 8 bytes from frame pointer in PPC32
9033 VAArgBase = 8;
9034 unsigned VAArgOffset = VAArgBase;
9035 const DataLayout &DL = F.getDataLayout();
9036 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9037 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9038 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9039 bool IsByVal = CB.isByValArgument(ArgNo);
9040 if (IsByVal) {
9041 assert(A->getType()->isPointerTy());
9042 Type *RealTy = CB.getParamByValType(ArgNo);
9043 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
9044 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(IntptrSize));
9045 if (ArgAlign < IntptrSize)
9046 ArgAlign = Align(IntptrSize);
9047 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9048 if (!IsFixed) {
9049 Value *Base =
9050 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
9051 if (Base) {
9052 Value *AShadowPtr, *AOriginPtr;
9053 std::tie(AShadowPtr, AOriginPtr) =
9054 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
9055 kShadowTLSAlignment, /*isStore*/ false);
9056
9057 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
9058 kShadowTLSAlignment, ArgSize);
9059 }
9060 }
9061 VAArgOffset += alignTo(ArgSize, Align(IntptrSize));
9062 } else {
9063 Value *Base;
9064 Type *ArgTy = A->getType();
9065
9066 // On PPC 32 floating point variable arguments are stored in separate
9067 // area: fp_save_area = reg_save_area + 4*8. We do not copy shaodow for
9068 // them as they will be found when checking call arguments.
9069 if (!ArgTy->isFloatingPointTy()) {
9070 uint64_t ArgSize = DL.getTypeAllocSize(ArgTy);
9071 Align ArgAlign = Align(IntptrSize);
9072 if (ArgTy->isArrayTy()) {
9073 // Arrays are aligned to element size, except for long double
9074 // arrays, which are aligned to 8 bytes.
9075 Type *ElementTy = ArgTy->getArrayElementType();
9076 if (!ElementTy->isPPC_FP128Ty())
9077 ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
9078 } else if (ArgTy->isVectorTy()) {
9079 // Vectors are naturally aligned.
9080 ArgAlign = Align(ArgSize);
9081 }
9082 if (ArgAlign < IntptrSize)
9083 ArgAlign = Align(IntptrSize);
9084 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9085 if (DL.isBigEndian()) {
9086 // Adjusting the shadow for argument with size < IntptrSize to match
9087 // the placement of bits in big endian system
9088 if (ArgSize < IntptrSize)
9089 VAArgOffset += (IntptrSize - ArgSize);
9090 }
9091 if (!IsFixed) {
9092 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
9093 ArgSize);
9094 if (Base)
9095 IRB.CreateAlignedStore(MSV.getShadow(A), Base,
9097 }
9098 VAArgOffset += ArgSize;
9099 VAArgOffset = alignTo(VAArgOffset, Align(IntptrSize));
9100 }
9101 }
9102 }
9103
9104 Constant *TotalVAArgSize =
9105 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
9106 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9107 // a new class member i.e. it is the total size of all VarArgs.
9108 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9109 }
9110
9111 void finalizeInstrumentation() override {
9112 assert(!VAArgSize && !VAArgTLSCopy &&
9113 "finalizeInstrumentation called twice");
9114 IRBuilder<> IRB(MSV.FnPrologueEnd);
9115 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9116 Value *CopySize = VAArgSize;
9117
9118 if (!VAStartInstrumentationList.empty()) {
9119 // If there is a va_start in this function, make a backup copy of
9120 // va_arg_tls somewhere in the function entry block.
9121
9122 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9123 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9124 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9125 CopySize, kShadowTLSAlignment, false);
9126
9127 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9128 Intrinsic::umin, CopySize,
9129 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9130 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9131 kShadowTLSAlignment, SrcSize);
9132 }
9133
9134 // Instrument va_start.
9135 // Copy va_list shadow from the backup copy of the TLS contents.
9136 for (CallInst *OrigInst : VAStartInstrumentationList) {
9137 NextNodeIRBuilder IRB(OrigInst);
9138 Value *VAListTag = OrigInst->getArgOperand(0);
9139 Value *RegSaveAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
9140 Value *RegSaveAreaSize = CopySize;
9141
9142 // In PPC32 va_list_tag is a struct
9143 RegSaveAreaPtrPtr =
9144 IRB.CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9145
9146 // On PPC 32 reg_save_area can only hold 32 bytes of data
9147 RegSaveAreaSize = IRB.CreateBinaryIntrinsic(
9148 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9149
9150 RegSaveAreaPtrPtr = IRB.CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9151 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
9152
9153 const DataLayout &DL = F.getDataLayout();
9154 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9155 const Align Alignment = Align(IntptrSize);
9156
9157 { // Copy reg save area
9158 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9159 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9160 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9161 Alignment, /*isStore*/ true);
9162 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9163 Alignment, RegSaveAreaSize);
9164
9165 RegSaveAreaShadowPtr =
9166 IRB.CreatePtrToInt(RegSaveAreaShadowPtr, MS.IntptrTy);
9167 Value *FPSaveArea = IRB.CreateAdd(RegSaveAreaShadowPtr,
9168 ConstantInt::get(MS.IntptrTy, 32));
9169 FPSaveArea = IRB.CreateIntToPtr(FPSaveArea, MS.PtrTy);
9170 // We fill fp shadow with zeroes as uninitialized fp args should have
9171 // been found during call base check
9172 IRB.CreateMemSet(FPSaveArea, ConstantInt::getNullValue(IRB.getInt8Ty()),
9173 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9174 }
9175
9176 { // Copy overflow area
9177 // RegSaveAreaSize is min(CopySize, 32) -> no overflow can occur
9178 Value *OverflowAreaSize = IRB.CreateSub(CopySize, RegSaveAreaSize);
9179
9180 Value *OverflowAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
9181 OverflowAreaPtrPtr =
9182 IRB.CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9183 OverflowAreaPtrPtr = IRB.CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9184
9185 Value *OverflowAreaPtr = IRB.CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9186
9187 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9188 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9189 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.getInt8Ty(),
9190 Alignment, /*isStore*/ true);
9191
9192 Value *OverflowVAArgTLSCopyPtr =
9193 IRB.CreatePtrToInt(VAArgTLSCopy, MS.IntptrTy);
9194 OverflowVAArgTLSCopyPtr =
9195 IRB.CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9196
9197 OverflowVAArgTLSCopyPtr =
9198 IRB.CreateIntToPtr(OverflowVAArgTLSCopyPtr, MS.PtrTy);
9199 IRB.CreateMemCpy(OverflowAreaShadowPtr, Alignment,
9200 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9201 }
9202 }
9203 }
9204};
9205
9206/// SystemZ-specific implementation of VarArgHelper.
9207struct VarArgSystemZHelper : public VarArgHelperBase {
9208 static const unsigned SystemZGpOffset = 16;
9209 static const unsigned SystemZGpEndOffset = 56;
9210 static const unsigned SystemZFpOffset = 128;
9211 static const unsigned SystemZFpEndOffset = 160;
9212 static const unsigned SystemZMaxVrArgs = 8;
9213 static const unsigned SystemZRegSaveAreaSize = 160;
9214 static const unsigned SystemZOverflowOffset = 160;
9215 static const unsigned SystemZVAListTagSize = 32;
9216 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9217 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9218
9219 bool IsSoftFloatABI;
9220 AllocaInst *VAArgTLSCopy = nullptr;
9221 AllocaInst *VAArgTLSOriginCopy = nullptr;
9222 Value *VAArgOverflowSize = nullptr;
9223
9224 enum class ArgKind {
9225 GeneralPurpose,
9226 FloatingPoint,
9227 Vector,
9228 Memory,
9229 Indirect,
9230 };
9231
9232 enum class ShadowExtension { None, Zero, Sign };
9233
9234 VarArgSystemZHelper(Function &F, MemorySanitizer &MS,
9235 MemorySanitizerVisitor &MSV)
9236 : VarArgHelperBase(F, MS, MSV, SystemZVAListTagSize),
9237 IsSoftFloatABI(F.getFnAttribute("use-soft-float").getValueAsBool()) {}
9238
9239 ArgKind classifyArgument(Type *T) {
9240 // T is a SystemZABIInfo::classifyArgumentType() output, and there are
9241 // only a few possibilities of what it can be. In particular, enums, single
9242 // element structs and large types have already been taken care of.
9243
9244 // Some i128 and fp128 arguments are converted to pointers only in the
9245 // back end.
9246 if (T->isIntegerTy(128) || T->isFP128Ty())
9247 return ArgKind::Indirect;
9248 if (T->isFloatingPointTy())
9249 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9250 if (T->isIntegerTy() || T->isPointerTy())
9251 return ArgKind::GeneralPurpose;
9252 if (T->isVectorTy())
9253 return ArgKind::Vector;
9254 return ArgKind::Memory;
9255 }
9256
9257 ShadowExtension getShadowExtension(const CallBase &CB, unsigned ArgNo) {
9258 // ABI says: "One of the simple integer types no more than 64 bits wide.
9259 // ... If such an argument is shorter than 64 bits, replace it by a full
9260 // 64-bit integer representing the same number, using sign or zero
9261 // extension". Shadow for an integer argument has the same type as the
9262 // argument itself, so it can be sign or zero extended as well.
9263 bool ZExt = CB.paramHasAttr(ArgNo, Attribute::ZExt);
9264 bool SExt = CB.paramHasAttr(ArgNo, Attribute::SExt);
9265 if (ZExt) {
9266 assert(!SExt);
9267 return ShadowExtension::Zero;
9268 }
9269 if (SExt) {
9270 assert(!ZExt);
9271 return ShadowExtension::Sign;
9272 }
9273 return ShadowExtension::None;
9274 }
9275
9276 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9277 unsigned GpOffset = SystemZGpOffset;
9278 unsigned FpOffset = SystemZFpOffset;
9279 unsigned VrIndex = 0;
9280 unsigned OverflowOffset = SystemZOverflowOffset;
9281 const DataLayout &DL = F.getDataLayout();
9282 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9283 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9284 // SystemZABIInfo does not produce ByVal parameters.
9285 assert(!CB.isByValArgument(ArgNo));
9286 Type *T = A->getType();
9287 ArgKind AK = classifyArgument(T);
9288 if (AK == ArgKind::Indirect) {
9289 T = MS.PtrTy;
9290 AK = ArgKind::GeneralPurpose;
9291 }
9292 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9293 AK = ArgKind::Memory;
9294 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9295 AK = ArgKind::Memory;
9296 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9297 AK = ArgKind::Memory;
9298 Value *ShadowBase = nullptr;
9299 Value *OriginBase = nullptr;
9300 ShadowExtension SE = ShadowExtension::None;
9301 switch (AK) {
9302 case ArgKind::GeneralPurpose: {
9303 // Always keep track of GpOffset, but store shadow only for varargs.
9304 uint64_t ArgSize = 8;
9305 if (GpOffset + ArgSize <= kParamTLSSize) {
9306 if (!IsFixed) {
9307 SE = getShadowExtension(CB, ArgNo);
9308 uint64_t GapSize = 0;
9309 if (SE == ShadowExtension::None) {
9310 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
9311 assert(ArgAllocSize <= ArgSize);
9312 GapSize = ArgSize - ArgAllocSize;
9313 }
9314 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9315 if (MS.TrackOrigins)
9316 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9317 }
9318 GpOffset += ArgSize;
9319 } else {
9320 GpOffset = kParamTLSSize;
9321 }
9322 break;
9323 }
9324 case ArgKind::FloatingPoint: {
9325 // Always keep track of FpOffset, but store shadow only for varargs.
9326 uint64_t ArgSize = 8;
9327 if (FpOffset + ArgSize <= kParamTLSSize) {
9328 if (!IsFixed) {
9329 // PoP says: "A short floating-point datum requires only the
9330 // left-most 32 bit positions of a floating-point register".
9331 // Therefore, in contrast to AK_GeneralPurpose and AK_Memory,
9332 // don't extend shadow and don't mind the gap.
9333 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9334 if (MS.TrackOrigins)
9335 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9336 }
9337 FpOffset += ArgSize;
9338 } else {
9339 FpOffset = kParamTLSSize;
9340 }
9341 break;
9342 }
9343 case ArgKind::Vector: {
9344 // Keep track of VrIndex. No need to store shadow, since vector varargs
9345 // go through AK_Memory.
9346 assert(IsFixed);
9347 VrIndex++;
9348 break;
9349 }
9350 case ArgKind::Memory: {
9351 // Keep track of OverflowOffset and store shadow only for varargs.
9352 // Ignore fixed args, since we need to copy only the vararg portion of
9353 // the overflow area shadow.
9354 if (!IsFixed) {
9355 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
9356 uint64_t ArgSize = alignTo(ArgAllocSize, 8);
9357 if (OverflowOffset + ArgSize <= kParamTLSSize) {
9358 SE = getShadowExtension(CB, ArgNo);
9359 uint64_t GapSize =
9360 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9361 ShadowBase =
9362 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9363 if (MS.TrackOrigins)
9364 OriginBase =
9365 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9366 OverflowOffset += ArgSize;
9367 } else {
9368 OverflowOffset = kParamTLSSize;
9369 }
9370 }
9371 break;
9372 }
9373 case ArgKind::Indirect:
9374 llvm_unreachable("Indirect must be converted to GeneralPurpose");
9375 }
9376 if (ShadowBase == nullptr)
9377 continue;
9378 Value *Shadow = MSV.getShadow(A);
9379 if (SE != ShadowExtension::None)
9380 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.getInt64Ty(),
9381 /*Signed*/ SE == ShadowExtension::Sign);
9382 ShadowBase = IRB.CreateIntToPtr(ShadowBase, MS.PtrTy, "_msarg_va_s");
9383 IRB.CreateStore(Shadow, ShadowBase);
9384 if (MS.TrackOrigins) {
9385 Value *Origin = MSV.getOrigin(A);
9386 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
9387 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9389 }
9390 }
9391 Constant *OverflowSize = ConstantInt::get(
9392 IRB.getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9393 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9394 }
9395
9396 void copyRegSaveArea(IRBuilder<> &IRB, Value *VAListTag) {
9397 Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
9398 IRB.CreateAdd(
9399 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9400 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9401 MS.PtrTy);
9402 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
9403 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9404 const Align Alignment = Align(8);
9405 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9406 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), Alignment,
9407 /*isStore*/ true);
9408 // TODO(iii): copy only fragments filled by visitCallBase()
9409 // TODO(iii): support packed-stack && !use-soft-float
9410 // For use-soft-float functions, it is enough to copy just the GPRs.
9411 unsigned RegSaveAreaSize =
9412 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9413 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9414 RegSaveAreaSize);
9415 if (MS.TrackOrigins)
9416 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9417 Alignment, RegSaveAreaSize);
9418 }
9419
9420 // FIXME: This implementation limits OverflowOffset to kParamTLSSize, so we
9421 // don't know real overflow size and can't clear shadow beyond kParamTLSSize.
9422 void copyOverflowArea(IRBuilder<> &IRB, Value *VAListTag) {
9423 Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
9424 IRB.CreateAdd(
9425 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9426 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9427 MS.PtrTy);
9428 Value *OverflowArgAreaPtr = IRB.CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9429 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9430 const Align Alignment = Align(8);
9431 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9432 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
9433 Alignment, /*isStore*/ true);
9434 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
9435 SystemZOverflowOffset);
9436 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9437 VAArgOverflowSize);
9438 if (MS.TrackOrigins) {
9439 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
9440 SystemZOverflowOffset);
9441 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9442 VAArgOverflowSize);
9443 }
9444 }
9445
9446 void finalizeInstrumentation() override {
9447 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9448 "finalizeInstrumentation called twice");
9449 if (!VAStartInstrumentationList.empty()) {
9450 // If there is a va_start in this function, make a backup copy of
9451 // va_arg_tls somewhere in the function entry block.
9452 IRBuilder<> IRB(MSV.FnPrologueEnd);
9453 VAArgOverflowSize =
9454 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
9455 Value *CopySize =
9456 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9457 VAArgOverflowSize);
9458 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9459 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9460 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9461 CopySize, kShadowTLSAlignment, false);
9462
9463 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9464 Intrinsic::umin, CopySize,
9465 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9466 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9467 kShadowTLSAlignment, SrcSize);
9468 if (MS.TrackOrigins) {
9469 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9470 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
9471 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
9472 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
9473 }
9474 }
9475
9476 // Instrument va_start.
9477 // Copy va_list shadow from the backup copy of the TLS contents.
9478 for (CallInst *OrigInst : VAStartInstrumentationList) {
9479 NextNodeIRBuilder IRB(OrigInst);
9480 Value *VAListTag = OrigInst->getArgOperand(0);
9481 copyRegSaveArea(IRB, VAListTag);
9482 copyOverflowArea(IRB, VAListTag);
9483 }
9484 }
9485};
9486
9487/// i386-specific implementation of VarArgHelper.
9488struct VarArgI386Helper : public VarArgHelperBase {
9489 AllocaInst *VAArgTLSCopy = nullptr;
9490 Value *VAArgSize = nullptr;
9491
9492 VarArgI386Helper(Function &F, MemorySanitizer &MS,
9493 MemorySanitizerVisitor &MSV)
9494 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/4) {}
9495
9496 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9497 const DataLayout &DL = F.getDataLayout();
9498 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9499 unsigned VAArgOffset = 0;
9500 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9501 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9502 bool IsByVal = CB.isByValArgument(ArgNo);
9503 if (IsByVal) {
9504 assert(A->getType()->isPointerTy());
9505 Type *RealTy = CB.getParamByValType(ArgNo);
9506 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
9507 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(IntptrSize));
9508 if (ArgAlign < IntptrSize)
9509 ArgAlign = Align(IntptrSize);
9510 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9511 if (!IsFixed) {
9512 Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9513 if (Base) {
9514 Value *AShadowPtr, *AOriginPtr;
9515 std::tie(AShadowPtr, AOriginPtr) =
9516 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
9517 kShadowTLSAlignment, /*isStore*/ false);
9518
9519 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
9520 kShadowTLSAlignment, ArgSize);
9521 }
9522 VAArgOffset += alignTo(ArgSize, Align(IntptrSize));
9523 }
9524 } else {
9525 Value *Base;
9526 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
9527 Align ArgAlign = Align(IntptrSize);
9528 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9529 if (DL.isBigEndian()) {
9530 // Adjusting the shadow for argument with size < IntptrSize to match
9531 // the placement of bits in big endian system
9532 if (ArgSize < IntptrSize)
9533 VAArgOffset += (IntptrSize - ArgSize);
9534 }
9535 if (!IsFixed) {
9536 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9537 if (Base)
9538 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
9539 VAArgOffset += ArgSize;
9540 VAArgOffset = alignTo(VAArgOffset, Align(IntptrSize));
9541 }
9542 }
9543 }
9544
9545 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9546 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9547 // a new class member i.e. it is the total size of all VarArgs.
9548 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9549 }
9550
9551 void finalizeInstrumentation() override {
9552 assert(!VAArgSize && !VAArgTLSCopy &&
9553 "finalizeInstrumentation called twice");
9554 IRBuilder<> IRB(MSV.FnPrologueEnd);
9555 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9556 Value *CopySize = VAArgSize;
9557
9558 if (!VAStartInstrumentationList.empty()) {
9559 // If there is a va_start in this function, make a backup copy of
9560 // va_arg_tls somewhere in the function entry block.
9561 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9562 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9563 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9564 CopySize, kShadowTLSAlignment, false);
9565
9566 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9567 Intrinsic::umin, CopySize,
9568 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9569 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9570 kShadowTLSAlignment, SrcSize);
9571 }
9572
9573 // Instrument va_start.
9574 // Copy va_list shadow from the backup copy of the TLS contents.
9575 for (CallInst *OrigInst : VAStartInstrumentationList) {
9576 NextNodeIRBuilder IRB(OrigInst);
9577 Value *VAListTag = OrigInst->getArgOperand(0);
9578 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9579 Value *RegSaveAreaPtrPtr =
9580 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9581 PointerType::get(*MS.C, 0));
9582 Value *RegSaveAreaPtr =
9583 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9584 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9585 const DataLayout &DL = F.getDataLayout();
9586 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9587 const Align Alignment = Align(IntptrSize);
9588 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9589 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9590 Alignment, /*isStore*/ true);
9591 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9592 CopySize);
9593 }
9594 }
9595};
9596
9597/// Implementation of VarArgHelper that is used for ARM32, MIPS, RISCV,
9598/// LoongArch64.
9599struct VarArgGenericHelper : public VarArgHelperBase {
9600 AllocaInst *VAArgTLSCopy = nullptr;
9601 Value *VAArgSize = nullptr;
9602
9603 VarArgGenericHelper(Function &F, MemorySanitizer &MS,
9604 MemorySanitizerVisitor &MSV, const unsigned VAListTagSize)
9605 : VarArgHelperBase(F, MS, MSV, VAListTagSize) {}
9606
9607 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9608 unsigned VAArgOffset = 0;
9609 const DataLayout &DL = F.getDataLayout();
9610 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9611 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9612 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9613 if (IsFixed)
9614 continue;
9615 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
9616 if (DL.isBigEndian()) {
9617 // Adjusting the shadow for argument with size < IntptrSize to match the
9618 // placement of bits in big endian system
9619 if (ArgSize < IntptrSize)
9620 VAArgOffset += (IntptrSize - ArgSize);
9621 }
9622 Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9623 VAArgOffset += ArgSize;
9624 VAArgOffset = alignTo(VAArgOffset, IntptrSize);
9625 if (!Base)
9626 continue;
9627 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
9628 }
9629
9630 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9631 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9632 // a new class member i.e. it is the total size of all VarArgs.
9633 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9634 }
9635
9636 void finalizeInstrumentation() override {
9637 assert(!VAArgSize && !VAArgTLSCopy &&
9638 "finalizeInstrumentation called twice");
9639 IRBuilder<> IRB(MSV.FnPrologueEnd);
9640 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9641 Value *CopySize = VAArgSize;
9642
9643 if (!VAStartInstrumentationList.empty()) {
9644 // If there is a va_start in this function, make a backup copy of
9645 // va_arg_tls somewhere in the function entry block.
9646 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9647 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9648 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9649 CopySize, kShadowTLSAlignment, false);
9650
9651 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9652 Intrinsic::umin, CopySize,
9653 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9654 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9655 kShadowTLSAlignment, SrcSize);
9656 }
9657
9658 // Instrument va_start.
9659 // Copy va_list shadow from the backup copy of the TLS contents.
9660 for (CallInst *OrigInst : VAStartInstrumentationList) {
9661 NextNodeIRBuilder IRB(OrigInst);
9662 Value *VAListTag = OrigInst->getArgOperand(0);
9663 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9664 Value *RegSaveAreaPtrPtr =
9665 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9666 PointerType::get(*MS.C, 0));
9667 Value *RegSaveAreaPtr =
9668 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9669 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9670 const DataLayout &DL = F.getDataLayout();
9671 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9672 const Align Alignment = Align(IntptrSize);
9673 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9674 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9675 Alignment, /*isStore*/ true);
9676 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9677 CopySize);
9678 }
9679 }
9680};
9681
9682// ARM32, Loongarch64, MIPS and RISCV share the same calling conventions
9683// regarding VAArgs.
9684using VarArgARM32Helper = VarArgGenericHelper;
9685using VarArgRISCVHelper = VarArgGenericHelper;
9686using VarArgMIPSHelper = VarArgGenericHelper;
9687using VarArgLoongArch64Helper = VarArgGenericHelper;
9688using VarArgHexagonHelper = VarArgGenericHelper;
9689
9690/// A no-op implementation of VarArgHelper.
9691struct VarArgNoOpHelper : public VarArgHelper {
9692 VarArgNoOpHelper(Function &F, MemorySanitizer &MS,
9693 MemorySanitizerVisitor &MSV) {}
9694
9695 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {}
9696
9697 void visitVAStartInst(VAStartInst &I) override {}
9698
9699 void visitVACopyInst(VACopyInst &I) override {}
9700
9701 void finalizeInstrumentation() override {}
9702};
9703
9704} // end anonymous namespace
9705
9706static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
9707 MemorySanitizerVisitor &Visitor) {
9708 // VarArg handling is only implemented on AMD64. False positives are possible
9709 // on other platforms.
9710 Triple TargetTriple(Func.getParent()->getTargetTriple());
9711
9712 if (TargetTriple.getArch() == Triple::x86)
9713 return new VarArgI386Helper(Func, Msan, Visitor);
9714
9715 if (TargetTriple.getArch() == Triple::x86_64)
9716 return new VarArgAMD64Helper(Func, Msan, Visitor);
9717
9718 if (TargetTriple.isARM())
9719 return new VarArgARM32Helper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9720
9721 if (TargetTriple.isAArch64())
9722 return new VarArgAArch64Helper(Func, Msan, Visitor);
9723
9724 if (TargetTriple.isSystemZ())
9725 return new VarArgSystemZHelper(Func, Msan, Visitor);
9726
9727 // On PowerPC32 VAListTag is a struct
9728 // {char, char, i16 padding, char *, char *}
9729 if (TargetTriple.isPPC32())
9730 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9731
9732 if (TargetTriple.isPPC64())
9733 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9734
9735 if (TargetTriple.isRISCV32())
9736 return new VarArgRISCVHelper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9737
9738 if (TargetTriple.isRISCV64())
9739 return new VarArgRISCVHelper(Func, Msan, Visitor, /*VAListTagSize=*/8);
9740
9741 if (TargetTriple.isMIPS32())
9742 return new VarArgMIPSHelper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9743
9744 if (TargetTriple.isMIPS64())
9745 return new VarArgMIPSHelper(Func, Msan, Visitor, /*VAListTagSize=*/8);
9746
9747 if (TargetTriple.isLoongArch64())
9748 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9749 /*VAListTagSize=*/8);
9750
9751 if (TargetTriple.getArch() == Triple::hexagon)
9752 return new VarArgHexagonHelper(Func, Msan, Visitor, /*VAListTagSize=*/12);
9753
9754 return new VarArgNoOpHelper(Func, Msan, Visitor);
9755}
9756
9757bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
9758 if (!CompileKernel && F.getName() == kMsanModuleCtorName)
9759 return false;
9760
9761 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9762 return false;
9763
9764 MemorySanitizerVisitor Visitor(F, *this, TLI);
9765
9766 // Clear out memory attributes.
9768 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
9769 F.removeFnAttrs(B);
9770
9771 return Visitor.runOnFunction();
9772}
#define Success
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
constexpr LLT S1
AMDGPU Uniform Intrinsic Combine
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isStore(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static const size_t kNumberOfAccessSizes
VarLocInsertPt getNextNode(const DbgRecord *DVR)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool insertModuleCtor(Module &M)
Definition CopyProf.cpp:77
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_S390X_MemoryMapParams
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_AArch64_MemoryMapParams
static bool isAMustTailRetVal(Value *RetVal)
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
#define op(i)
Hexagon Common GEP
#define _
Module.h This file contains the declarations for the Module class.
static LVOptions Options
Definition LVOptions.cpp:25
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Definition Lint.cpp:540
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static MemorySanitizerOptions resolveOptions(const InstrumentationOptions &Opts, MemorySanitizerOptions O)
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static const Align kShadowTLSAlignment
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
OddOrEvenLanes
@ kOddLanes
@ kEvenLanes
@ kBothLanes
static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
static GlobalVariable * createPrivateConstGlobalForString(Module &M, StringRef Str)
Create a non-const global initialized with the given string.
static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
static const size_t kNumberOfAccessSizes
static VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static const MemoryMapParams Linux_Hexagon_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static const unsigned kRetvalTLSSize
static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
const char kMsanModuleCtorName[]
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
#define T
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
if(PassOpts->AAPipeline)
SmallVector< MachineOperand, 4 > Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
static const char * name
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
Value * RHS
Value * LHS
unsigned countr_zero() const
Count the number of trailing zero bits.
Definition APInt.h:1659
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition APInt.h:215
void setAlignment(Align Align)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const T & front() const
Get the first element.
Definition ArrayRef.h:144
size_t size() const
Get the array size.
Definition ArrayRef.h:141
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
iterator end()
Definition BasicBlock.h:453
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
void removeFnAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the function.
void setCannotMerge()
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Value * getCalledOperand() const
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true, bool ByteString=false)
This method constructs a CDS and initializes it with a text string.
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
Definition Constant.h:44
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition Constant.h:65
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
Definition Constants.cpp:62
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static bool shouldExecute(CounterInfo &Counter)
bool empty() const
Definition DenseMap.h:716
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
static FixedVectorType * getHalfElementsVectorType(FixedVectorType *VTy)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
static GEPNoWrapFlags inBounds()
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:287
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
Analysis pass providing a never-invalidated alias analysis result.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Definition IRBuilder.h:440
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
LLVM_ABI Value * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2709
Value * CreatePtrAddWithUnsignedOffset(Value *Ptr, uint64_t Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Create a ptradd with an unsigned constant offset.
Definition IRBuilder.h:2108
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition IRBuilder.h:2024
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1880
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition IRBuilder.h:507
LLVM_ABI CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2763
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2697
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition IRBuilder.h:535
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1934
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Definition IRBuilder.h:651
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2337
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2756
LLVM_ABI CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Definition IRBuilder.h:176
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2173
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2278
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1528
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:522
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Definition IRBuilder.h:455
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition IRBuilder.h:527
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1469
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2426
IntegerType * getInt16Ty()
Fetch the type representing a 16-bit integer.
Definition IRBuilder.h:517
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2011
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Definition IRBuilder.h:1826
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI Value * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:465
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2587
Value * CreateNot(Value *V, const Twine &Name="")
Definition IRBuilder.h:1850
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2422
LLVM_ABI DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Definition IRBuilder.cpp:66
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1435
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2283
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
Definition IRBuilder.h:475
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1907
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1507
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Definition IRBuilder.h:596
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2161
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition IRBuilder.h:2731
LLVMContext & getContext() const
Definition IRBuilder.h:177
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1566
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1925
LLVM_ABI CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1418
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2273
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Definition IRBuilder.h:2803
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2601
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2147
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:565
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1727
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2454
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2434
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2363
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
Definition IRBuilder.h:2798
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:196
Type * getVoidTy()
Fetch the type representing void.
Definition IRBuilder.h:560
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition IRBuilder.h:1953
LLVM_ABI CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Definition IRBuilder.h:2100
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1547
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1618
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2532
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1588
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:512
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1452
LLVM_ABI CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
LLVM_ABI CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
Value * CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2517
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2949
std::vector< ConstraintInfo > ConstraintInfoVector
Definition InlineAsm.h:123
void visit(Iterator Start, Iterator End)
Definition InstVisitor.h:87
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition MDBuilder.cpp:48
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Definition Analysis.h:171
bool remove(const value_type &X)
Remove an item from the set vector.
Definition SetVector.h:187
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:467
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
Definition Triple.h:1133
@ loongarch64
Definition Triple.h:66
bool isRISCV32() const
Tests whether the target is 32-bit RISC-V.
Definition Triple.h:1171
bool isPPC32() const
Tests whether the target is 32-bit PowerPC (little and big endian).
Definition Triple.h:1147
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:515
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
Definition Triple.h:1176
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
Definition Triple.h:1122
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
Definition Triple.h:1128
bool isARM() const
Tests whether the target is ARM (little and big endian).
Definition Triple.h:1006
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
Definition Triple.h:1152
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
Definition Triple.h:1099
bool isSystemZ() const
Tests whether the target is SystemZ.
Definition Triple.h:1195
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition Type.h:274
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:258
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
Type * getArrayElementType() const
Definition Type.h:420
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
Definition Type.h:167
bool isSized() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
Definition Type.h:265
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition ValueMap.h:156
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:389
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
Function * Kernel
Summary of a kernel (=entry point for target offloading).
Definition OpenMPOpt.h:21
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition MathExtras.h:339
@ Offset
Definition DWP.cpp:577
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Done
Definition Threading.h:60
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition Alignment.h:139
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI std::pair< Instruction *, Value * > SplitBlockAndInsertSimpleForLoop(Value *End, BasicBlock::iterator SplitBefore)
Insert a for (int i = 0; i < End; i++) loop structure (with the exception that End is assumed > 0,...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:332
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
Definition Local.cpp:2916
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
@ Add
Sum of integers.
IntPtrTy
Definition InstrProf.h:82
DWARFExpression::Operation Op
RoundingMode
Rounding mode.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
constexpr bool valueOr(BoolOrDefault X, bool Default)
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
Definition Local.cpp:3909
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
std::string itostr(int64_t X)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:82
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)