LLVM 20.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 memory
19/// 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
152#include "llvm/ADT/APInt.h"
153#include "llvm/ADT/ArrayRef.h"
154#include "llvm/ADT/DenseMap.h"
156#include "llvm/ADT/SetVector.h"
157#include "llvm/ADT/SmallPtrSet.h"
158#include "llvm/ADT/SmallVector.h"
160#include "llvm/ADT/StringRef.h"
164#include "llvm/IR/Argument.h"
166#include "llvm/IR/Attributes.h"
167#include "llvm/IR/BasicBlock.h"
168#include "llvm/IR/CallingConv.h"
169#include "llvm/IR/Constant.h"
170#include "llvm/IR/Constants.h"
171#include "llvm/IR/DataLayout.h"
172#include "llvm/IR/DerivedTypes.h"
173#include "llvm/IR/Function.h"
174#include "llvm/IR/GlobalValue.h"
176#include "llvm/IR/IRBuilder.h"
177#include "llvm/IR/InlineAsm.h"
178#include "llvm/IR/InstVisitor.h"
179#include "llvm/IR/InstrTypes.h"
180#include "llvm/IR/Instruction.h"
181#include "llvm/IR/Instructions.h"
183#include "llvm/IR/Intrinsics.h"
184#include "llvm/IR/IntrinsicsAArch64.h"
185#include "llvm/IR/IntrinsicsX86.h"
186#include "llvm/IR/MDBuilder.h"
187#include "llvm/IR/Module.h"
188#include "llvm/IR/Type.h"
189#include "llvm/IR/Value.h"
190#include "llvm/IR/ValueMap.h"
193#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 <string>
211#include <tuple>
212
213using namespace llvm;
214
215#define DEBUG_TYPE "msan"
216
217DEBUG_COUNTER(DebugInsertCheck, "msan-insert-check",
218 "Controls which checks to insert");
219
220DEBUG_COUNTER(DebugInstrumentInstruction, "msan-instrument-instruction",
221 "Controls which instruction to instrument");
222
223static const unsigned kOriginSize = 4;
226
227// These constants must be kept in sync with the ones in msan.h.
228static const unsigned kParamTLSSize = 800;
229static const unsigned kRetvalTLSSize = 800;
230
231// Accesses sizes are powers of two: 1, 2, 4, 8.
232static const size_t kNumberOfAccessSizes = 4;
233
234/// Track origins of uninitialized values.
235///
236/// Adds a section to MemorySanitizer report that points to the allocation
237/// (stack or heap) the uninitialized bits came from originally.
239 "msan-track-origins",
240 cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden,
241 cl::init(0));
242
243static cl::opt<bool> ClKeepGoing("msan-keep-going",
244 cl::desc("keep going after reporting a UMR"),
245 cl::Hidden, cl::init(false));
246
247static cl::opt<bool>
248 ClPoisonStack("msan-poison-stack",
249 cl::desc("poison uninitialized stack variables"), cl::Hidden,
250 cl::init(true));
251
253 "msan-poison-stack-with-call",
254 cl::desc("poison uninitialized stack variables with a call"), cl::Hidden,
255 cl::init(false));
256
258 "msan-poison-stack-pattern",
259 cl::desc("poison uninitialized stack variables with the given pattern"),
260 cl::Hidden, cl::init(0xff));
261
262static cl::opt<bool>
263 ClPrintStackNames("msan-print-stack-names",
264 cl::desc("Print name of local stack variable"),
265 cl::Hidden, cl::init(true));
266
267static cl::opt<bool> ClPoisonUndef("msan-poison-undef",
268 cl::desc("poison undef temps"), cl::Hidden,
269 cl::init(true));
270
271static cl::opt<bool>
272 ClHandleICmp("msan-handle-icmp",
273 cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
274 cl::Hidden, cl::init(true));
275
276static cl::opt<bool>
277 ClHandleICmpExact("msan-handle-icmp-exact",
278 cl::desc("exact handling of relational integer ICmp"),
279 cl::Hidden, cl::init(false));
280
282 "msan-handle-lifetime-intrinsics",
283 cl::desc(
284 "when possible, poison scoped variables at the beginning of the scope "
285 "(slower, but more precise)"),
286 cl::Hidden, cl::init(true));
287
288// When compiling the Linux kernel, we sometimes see false positives related to
289// MSan being unable to understand that inline assembly calls may initialize
290// local variables.
291// This flag makes the compiler conservatively unpoison every memory location
292// passed into an assembly call. Note that this may cause false positives.
293// Because it's impossible to figure out the array sizes, we can only unpoison
294// the first sizeof(type) bytes for each type* pointer.
296 "msan-handle-asm-conservative",
297 cl::desc("conservative handling of inline assembly"), cl::Hidden,
298 cl::init(true));
299
300// This flag controls whether we check the shadow of the address
301// operand of load or store. Such bugs are very rare, since load from
302// a garbage address typically results in SEGV, but still happen
303// (e.g. only lower bits of address are garbage, or the access happens
304// early at program startup where malloc-ed memory is more likely to
305// be zeroed. As of 2012-08-28 this flag adds 20% slowdown.
307 "msan-check-access-address",
308 cl::desc("report accesses through a pointer which has poisoned shadow"),
309 cl::Hidden, cl::init(true));
310
312 "msan-eager-checks",
313 cl::desc("check arguments and return values at function call boundaries"),
314 cl::Hidden, cl::init(false));
315
317 "msan-dump-strict-instructions",
318 cl::desc("print out instructions with default strict semantics"),
319 cl::Hidden, cl::init(false));
320
322 "msan-instrumentation-with-call-threshold",
323 cl::desc(
324 "If the function being instrumented requires more than "
325 "this number of checks and origin stores, use callbacks instead of "
326 "inline checks (-1 means never use callbacks)."),
327 cl::Hidden, cl::init(3500));
328
329static cl::opt<bool>
330 ClEnableKmsan("msan-kernel",
331 cl::desc("Enable KernelMemorySanitizer instrumentation"),
332 cl::Hidden, cl::init(false));
333
334static cl::opt<bool>
335 ClDisableChecks("msan-disable-checks",
336 cl::desc("Apply no_sanitize to the whole file"), cl::Hidden,
337 cl::init(false));
338
339static cl::opt<bool>
340 ClCheckConstantShadow("msan-check-constant-shadow",
341 cl::desc("Insert checks for constant shadow values"),
342 cl::Hidden, cl::init(true));
343
344// This is off by default because of a bug in gold:
345// https://sourceware.org/bugzilla/show_bug.cgi?id=19002
346static cl::opt<bool>
347 ClWithComdat("msan-with-comdat",
348 cl::desc("Place MSan constructors in comdat sections"),
349 cl::Hidden, cl::init(false));
350
351// These options allow to specify custom memory map parameters
352// See MemoryMapParams for details.
353static cl::opt<uint64_t> ClAndMask("msan-and-mask",
354 cl::desc("Define custom MSan AndMask"),
355 cl::Hidden, cl::init(0));
356
357static cl::opt<uint64_t> ClXorMask("msan-xor-mask",
358 cl::desc("Define custom MSan XorMask"),
359 cl::Hidden, cl::init(0));
360
361static cl::opt<uint64_t> ClShadowBase("msan-shadow-base",
362 cl::desc("Define custom MSan ShadowBase"),
363 cl::Hidden, cl::init(0));
364
365static cl::opt<uint64_t> ClOriginBase("msan-origin-base",
366 cl::desc("Define custom MSan OriginBase"),
367 cl::Hidden, cl::init(0));
368
369static cl::opt<int>
370 ClDisambiguateWarning("msan-disambiguate-warning-threshold",
371 cl::desc("Define threshold for number of checks per "
372 "debug location to force origin update."),
373 cl::Hidden, cl::init(3));
374
375const char kMsanModuleCtorName[] = "msan.module_ctor";
376const char kMsanInitName[] = "__msan_init";
377
378namespace {
379
380// Memory map parameters used in application-to-shadow address calculation.
381// Offset = (Addr & ~AndMask) ^ XorMask
382// Shadow = ShadowBase + Offset
383// Origin = OriginBase + Offset
384struct MemoryMapParams {
385 uint64_t AndMask;
386 uint64_t XorMask;
387 uint64_t ShadowBase;
388 uint64_t OriginBase;
389};
390
391struct PlatformMemoryMapParams {
392 const MemoryMapParams *bits32;
393 const MemoryMapParams *bits64;
394};
395
396} // end anonymous namespace
397
398// i386 Linux
399static const MemoryMapParams Linux_I386_MemoryMapParams = {
400 0x000080000000, // AndMask
401 0, // XorMask (not used)
402 0, // ShadowBase (not used)
403 0x000040000000, // OriginBase
404};
405
406// x86_64 Linux
407static const MemoryMapParams Linux_X86_64_MemoryMapParams = {
408 0, // AndMask (not used)
409 0x500000000000, // XorMask
410 0, // ShadowBase (not used)
411 0x100000000000, // OriginBase
412};
413
414// mips64 Linux
415static const MemoryMapParams Linux_MIPS64_MemoryMapParams = {
416 0, // AndMask (not used)
417 0x008000000000, // XorMask
418 0, // ShadowBase (not used)
419 0x002000000000, // OriginBase
420};
421
422// ppc64 Linux
423static const MemoryMapParams Linux_PowerPC64_MemoryMapParams = {
424 0xE00000000000, // AndMask
425 0x100000000000, // XorMask
426 0x080000000000, // ShadowBase
427 0x1C0000000000, // OriginBase
428};
429
430// s390x Linux
431static const MemoryMapParams Linux_S390X_MemoryMapParams = {
432 0xC00000000000, // AndMask
433 0, // XorMask (not used)
434 0x080000000000, // ShadowBase
435 0x1C0000000000, // OriginBase
436};
437
438// aarch64 Linux
439static const MemoryMapParams Linux_AArch64_MemoryMapParams = {
440 0, // AndMask (not used)
441 0x0B00000000000, // XorMask
442 0, // ShadowBase (not used)
443 0x0200000000000, // OriginBase
444};
445
446// loongarch64 Linux
447static const MemoryMapParams Linux_LoongArch64_MemoryMapParams = {
448 0, // AndMask (not used)
449 0x500000000000, // XorMask
450 0, // ShadowBase (not used)
451 0x100000000000, // OriginBase
452};
453
454// aarch64 FreeBSD
455static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams = {
456 0x1800000000000, // AndMask
457 0x0400000000000, // XorMask
458 0x0200000000000, // ShadowBase
459 0x0700000000000, // OriginBase
460};
461
462// i386 FreeBSD
463static const MemoryMapParams FreeBSD_I386_MemoryMapParams = {
464 0x000180000000, // AndMask
465 0x000040000000, // XorMask
466 0x000020000000, // ShadowBase
467 0x000700000000, // OriginBase
468};
469
470// x86_64 FreeBSD
471static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams = {
472 0xc00000000000, // AndMask
473 0x200000000000, // XorMask
474 0x100000000000, // ShadowBase
475 0x380000000000, // OriginBase
476};
477
478// x86_64 NetBSD
479static const MemoryMapParams NetBSD_X86_64_MemoryMapParams = {
480 0, // AndMask
481 0x500000000000, // XorMask
482 0, // ShadowBase
483 0x100000000000, // OriginBase
484};
485
486static const PlatformMemoryMapParams Linux_X86_MemoryMapParams = {
489};
490
491static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams = {
492 nullptr,
494};
495
496static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams = {
497 nullptr,
499};
500
501static const PlatformMemoryMapParams Linux_S390_MemoryMapParams = {
502 nullptr,
504};
505
506static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams = {
507 nullptr,
509};
510
511static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams = {
512 nullptr,
514};
515
516static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams = {
517 nullptr,
519};
520
521static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams = {
524};
525
526static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams = {
527 nullptr,
529};
530
531namespace {
532
533/// Instrument functions of a module to detect uninitialized reads.
534///
535/// Instantiating MemorySanitizer inserts the msan runtime library API function
536/// declarations into the module if they don't exist already. Instantiating
537/// ensures the __msan_init function is in the list of global constructors for
538/// the module.
539class MemorySanitizer {
540public:
541 MemorySanitizer(Module &M, MemorySanitizerOptions Options)
542 : CompileKernel(Options.Kernel), TrackOrigins(Options.TrackOrigins),
543 Recover(Options.Recover), EagerChecks(Options.EagerChecks) {
544 initializeModule(M);
545 }
546
547 // MSan cannot be moved or copied because of MapParams.
548 MemorySanitizer(MemorySanitizer &&) = delete;
549 MemorySanitizer &operator=(MemorySanitizer &&) = delete;
550 MemorySanitizer(const MemorySanitizer &) = delete;
551 MemorySanitizer &operator=(const MemorySanitizer &) = delete;
552
553 bool sanitizeFunction(Function &F, TargetLibraryInfo &TLI);
554
555private:
556 friend struct MemorySanitizerVisitor;
557 friend struct VarArgHelperBase;
558 friend struct VarArgAMD64Helper;
559 friend struct VarArgMIPS64Helper;
560 friend struct VarArgAArch64Helper;
561 friend struct VarArgPowerPC64Helper;
562 friend struct VarArgSystemZHelper;
563
564 void initializeModule(Module &M);
565 void initializeCallbacks(Module &M, const TargetLibraryInfo &TLI);
566 void createKernelApi(Module &M, const TargetLibraryInfo &TLI);
567 void createUserspaceApi(Module &M, const TargetLibraryInfo &TLI);
568
569 template <typename... ArgsTy>
570 FunctionCallee getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
571 ArgsTy... Args);
572
573 /// True if we're compiling the Linux kernel.
574 bool CompileKernel;
575 /// Track origins (allocation points) of uninitialized values.
576 int TrackOrigins;
577 bool Recover;
578 bool EagerChecks;
579
580 Triple TargetTriple;
581 LLVMContext *C;
582 Type *IntptrTy; ///< Integer type with the size of a ptr in default AS.
583 Type *OriginTy;
584 PointerType *PtrTy; ///< Integer type with the size of a ptr in default AS.
585
586 // XxxTLS variables represent the per-thread state in MSan and per-task state
587 // in KMSAN.
588 // For the userspace these point to thread-local globals. In the kernel land
589 // they point to the members of a per-task struct obtained via a call to
590 // __msan_get_context_state().
591
592 /// Thread-local shadow storage for function parameters.
593 Value *ParamTLS;
594
595 /// Thread-local origin storage for function parameters.
596 Value *ParamOriginTLS;
597
598 /// Thread-local shadow storage for function return value.
599 Value *RetvalTLS;
600
601 /// Thread-local origin storage for function return value.
602 Value *RetvalOriginTLS;
603
604 /// Thread-local shadow storage for in-register va_arg function.
605 Value *VAArgTLS;
606
607 /// Thread-local shadow storage for in-register va_arg function.
608 Value *VAArgOriginTLS;
609
610 /// Thread-local shadow storage for va_arg overflow area.
611 Value *VAArgOverflowSizeTLS;
612
613 /// Are the instrumentation callbacks set up?
614 bool CallbacksInitialized = false;
615
616 /// The run-time callback to print a warning.
617 FunctionCallee WarningFn;
618
619 // These arrays are indexed by log2(AccessSize).
620 FunctionCallee MaybeWarningFn[kNumberOfAccessSizes];
621 FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes];
622
623 /// Run-time helper that generates a new origin value for a stack
624 /// allocation.
625 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
626 // No description version
627 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
628
629 /// Run-time helper that poisons stack on function entry.
630 FunctionCallee MsanPoisonStackFn;
631
632 /// Run-time helper that records a store (or any event) of an
633 /// uninitialized value and returns an updated origin id encoding this info.
634 FunctionCallee MsanChainOriginFn;
635
636 /// Run-time helper that paints an origin over a region.
637 FunctionCallee MsanSetOriginFn;
638
639 /// MSan runtime replacements for memmove, memcpy and memset.
640 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
641
642 /// KMSAN callback for task-local function argument shadow.
643 StructType *MsanContextStateTy;
644 FunctionCallee MsanGetContextStateFn;
645
646 /// Functions for poisoning/unpoisoning local variables
647 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
648
649 /// Pair of shadow/origin pointers.
650 Type *MsanMetadata;
651
652 /// Each of the MsanMetadataPtrXxx functions returns a MsanMetadata.
653 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
654 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
655 FunctionCallee MsanMetadataPtrForStore_1_8[4];
656 FunctionCallee MsanInstrumentAsmStoreFn;
657
658 /// Storage for return values of the MsanMetadataPtrXxx functions.
659 Value *MsanMetadataAlloca;
660
661 /// Helper to choose between different MsanMetadataPtrXxx().
662 FunctionCallee getKmsanShadowOriginAccessFn(bool isStore, int size);
663
664 /// Memory map parameters used in application-to-shadow calculation.
665 const MemoryMapParams *MapParams;
666
667 /// Custom memory map parameters used when -msan-shadow-base or
668 // -msan-origin-base is provided.
669 MemoryMapParams CustomMapParams;
670
671 MDNode *ColdCallWeights;
672
673 /// Branch weights for origin store.
674 MDNode *OriginStoreWeights;
675};
676
677void insertModuleCtor(Module &M) {
680 /*InitArgTypes=*/{},
681 /*InitArgs=*/{},
682 // This callback is invoked when the functions are created the first
683 // time. Hook them into the global ctors list in that case:
684 [&](Function *Ctor, FunctionCallee) {
685 if (!ClWithComdat) {
686 appendToGlobalCtors(M, Ctor, 0);
687 return;
688 }
689 Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
690 Ctor->setComdat(MsanCtorComdat);
691 appendToGlobalCtors(M, Ctor, 0, Ctor);
692 });
693}
694
695template <class T> T getOptOrDefault(const cl::opt<T> &Opt, T Default) {
696 return (Opt.getNumOccurrences() > 0) ? Opt : Default;
697}
698
699} // end anonymous namespace
700
702 bool EagerChecks)
703 : Kernel(getOptOrDefault(ClEnableKmsan, K)),
704 TrackOrigins(getOptOrDefault(ClTrackOrigins, Kernel ? 2 : TO)),
705 Recover(getOptOrDefault(ClKeepGoing, Kernel || R)),
706 EagerChecks(getOptOrDefault(ClEagerChecks, EagerChecks)) {}
707
710 // Return early if nosanitize_memory module flag is present for the module.
711 if (checkIfAlreadyInstrumented(M, "nosanitize_memory"))
712 return PreservedAnalyses::all();
713 bool Modified = false;
714 if (!Options.Kernel) {
715 insertModuleCtor(M);
716 Modified = true;
717 }
718
719 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
720 for (Function &F : M) {
721 if (F.empty())
722 continue;
723 MemorySanitizer Msan(*F.getParent(), Options);
724 Modified |=
725 Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
726 }
727
728 if (!Modified)
729 return PreservedAnalyses::all();
730
732 // GlobalsAA is considered stateless and does not get invalidated unless
733 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
734 // make changes that require GlobalsAA to be invalidated.
735 PA.abandon<GlobalsAA>();
736 return PA;
737}
738
740 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
742 OS, MapClassName2PassName);
743 OS << '<';
744 if (Options.Recover)
745 OS << "recover;";
746 if (Options.Kernel)
747 OS << "kernel;";
748 if (Options.EagerChecks)
749 OS << "eager-checks;";
750 OS << "track-origins=" << Options.TrackOrigins;
751 OS << '>';
752}
753
754/// Create a non-const global initialized with the given string.
755///
756/// Creates a writable global for Str so that we can pass it to the
757/// run-time lib. Runtime uses first 4 bytes of the string to store the
758/// frame ID, so the string needs to be mutable.
760 StringRef Str) {
761 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
762 return new GlobalVariable(M, StrConst->getType(), /*isConstant=*/true,
763 GlobalValue::PrivateLinkage, StrConst, "");
764}
765
766template <typename... ArgsTy>
768MemorySanitizer::getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
769 ArgsTy... Args) {
770 if (TargetTriple.getArch() == Triple::systemz) {
771 // SystemZ ABI: shadow/origin pair is returned via a hidden parameter.
772 return M.getOrInsertFunction(Name, Type::getVoidTy(*C),
773 PointerType::get(MsanMetadata, 0),
774 std::forward<ArgsTy>(Args)...);
775 }
776
777 return M.getOrInsertFunction(Name, MsanMetadata,
778 std::forward<ArgsTy>(Args)...);
779}
780
781/// Create KMSAN API callbacks.
782void MemorySanitizer::createKernelApi(Module &M, const TargetLibraryInfo &TLI) {
783 IRBuilder<> IRB(*C);
784
785 // These will be initialized in insertKmsanPrologue().
786 RetvalTLS = nullptr;
787 RetvalOriginTLS = nullptr;
788 ParamTLS = nullptr;
789 ParamOriginTLS = nullptr;
790 VAArgTLS = nullptr;
791 VAArgOriginTLS = nullptr;
792 VAArgOverflowSizeTLS = nullptr;
793
794 WarningFn = M.getOrInsertFunction("__msan_warning",
795 TLI.getAttrList(C, {0}, /*Signed=*/false),
796 IRB.getVoidTy(), IRB.getInt32Ty());
797
798 // Requests the per-task context state (kmsan_context_state*) from the
799 // runtime library.
800 MsanContextStateTy = StructType::get(
801 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
802 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8),
803 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
804 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), /* va_arg_origin */
805 IRB.getInt64Ty(), ArrayType::get(OriginTy, kParamTLSSize / 4), OriginTy,
806 OriginTy);
807 MsanGetContextStateFn = M.getOrInsertFunction(
808 "__msan_get_context_state", PointerType::get(MsanContextStateTy, 0));
809
810 MsanMetadata = StructType::get(PointerType::get(IRB.getInt8Ty(), 0),
811 PointerType::get(IRB.getInt32Ty(), 0));
812
813 for (int ind = 0, size = 1; ind < 4; ind++, size <<= 1) {
814 std::string name_load =
815 "__msan_metadata_ptr_for_load_" + std::to_string(size);
816 std::string name_store =
817 "__msan_metadata_ptr_for_store_" + std::to_string(size);
818 MsanMetadataPtrForLoad_1_8[ind] = getOrInsertMsanMetadataFunction(
819 M, name_load, PointerType::get(IRB.getInt8Ty(), 0));
820 MsanMetadataPtrForStore_1_8[ind] = getOrInsertMsanMetadataFunction(
821 M, name_store, PointerType::get(IRB.getInt8Ty(), 0));
822 }
823
824 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
825 M, "__msan_metadata_ptr_for_load_n", PointerType::get(IRB.getInt8Ty(), 0),
826 IRB.getInt64Ty());
827 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
828 M, "__msan_metadata_ptr_for_store_n",
829 PointerType::get(IRB.getInt8Ty(), 0), IRB.getInt64Ty());
830
831 // Functions for poisoning and unpoisoning memory.
832 MsanPoisonAllocaFn = M.getOrInsertFunction(
833 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
834 MsanUnpoisonAllocaFn = M.getOrInsertFunction(
835 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
836}
837
839 return M.getOrInsertGlobal(Name, Ty, [&] {
840 return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
841 nullptr, Name, nullptr,
843 });
844}
845
846/// Insert declarations for userspace-specific functions and globals.
847void MemorySanitizer::createUserspaceApi(Module &M, const TargetLibraryInfo &TLI) {
848 IRBuilder<> IRB(*C);
849
850 // Create the callback.
851 // FIXME: this function should have "Cold" calling conv,
852 // which is not yet implemented.
853 if (TrackOrigins) {
854 StringRef WarningFnName = Recover ? "__msan_warning_with_origin"
855 : "__msan_warning_with_origin_noreturn";
856 WarningFn = M.getOrInsertFunction(WarningFnName,
857 TLI.getAttrList(C, {0}, /*Signed=*/false),
858 IRB.getVoidTy(), IRB.getInt32Ty());
859 } else {
860 StringRef WarningFnName =
861 Recover ? "__msan_warning" : "__msan_warning_noreturn";
862 WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
863 }
864
865 // Create the global TLS variables.
866 RetvalTLS =
867 getOrInsertGlobal(M, "__msan_retval_tls",
868 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8));
869
870 RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy);
871
872 ParamTLS =
873 getOrInsertGlobal(M, "__msan_param_tls",
874 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
875
876 ParamOriginTLS =
877 getOrInsertGlobal(M, "__msan_param_origin_tls",
878 ArrayType::get(OriginTy, kParamTLSSize / 4));
879
880 VAArgTLS =
881 getOrInsertGlobal(M, "__msan_va_arg_tls",
882 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
883
884 VAArgOriginTLS =
885 getOrInsertGlobal(M, "__msan_va_arg_origin_tls",
886 ArrayType::get(OriginTy, kParamTLSSize / 4));
887
888 VAArgOverflowSizeTLS =
889 getOrInsertGlobal(M, "__msan_va_arg_overflow_size_tls", IRB.getInt64Ty());
890
891 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
892 AccessSizeIndex++) {
893 unsigned AccessSize = 1 << AccessSizeIndex;
894 std::string FunctionName = "__msan_maybe_warning_" + itostr(AccessSize);
895 MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction(
896 FunctionName, TLI.getAttrList(C, {0, 1}, /*Signed=*/false),
897 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
898
899 FunctionName = "__msan_maybe_store_origin_" + itostr(AccessSize);
900 MaybeStoreOriginFn[AccessSizeIndex] = M.getOrInsertFunction(
901 FunctionName, TLI.getAttrList(C, {0, 2}, /*Signed=*/false),
902 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
903 IRB.getInt32Ty());
904 }
905
906 MsanSetAllocaOriginWithDescriptionFn =
907 M.getOrInsertFunction("__msan_set_alloca_origin_with_descr",
908 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
909 MsanSetAllocaOriginNoDescriptionFn =
910 M.getOrInsertFunction("__msan_set_alloca_origin_no_descr",
911 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
912 MsanPoisonStackFn = M.getOrInsertFunction("__msan_poison_stack",
913 IRB.getVoidTy(), PtrTy, IntptrTy);
914}
915
916/// Insert extern declaration of runtime-provided functions and globals.
917void MemorySanitizer::initializeCallbacks(Module &M, const TargetLibraryInfo &TLI) {
918 // Only do this once.
919 if (CallbacksInitialized)
920 return;
921
922 IRBuilder<> IRB(*C);
923 // Initialize callbacks that are common for kernel and userspace
924 // instrumentation.
925 MsanChainOriginFn = M.getOrInsertFunction(
926 "__msan_chain_origin",
927 TLI.getAttrList(C, {0}, /*Signed=*/false, /*Ret=*/true), IRB.getInt32Ty(),
928 IRB.getInt32Ty());
929 MsanSetOriginFn = M.getOrInsertFunction(
930 "__msan_set_origin", TLI.getAttrList(C, {2}, /*Signed=*/false),
931 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
932 MemmoveFn =
933 M.getOrInsertFunction("__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
934 MemcpyFn =
935 M.getOrInsertFunction("__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
936 MemsetFn = M.getOrInsertFunction("__msan_memset",
937 TLI.getAttrList(C, {1}, /*Signed=*/true),
938 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
939
940 MsanInstrumentAsmStoreFn =
941 M.getOrInsertFunction("__msan_instrument_asm_store", IRB.getVoidTy(),
942 PointerType::get(IRB.getInt8Ty(), 0), IntptrTy);
943
944 if (CompileKernel) {
945 createKernelApi(M, TLI);
946 } else {
947 createUserspaceApi(M, TLI);
948 }
949 CallbacksInitialized = true;
950}
951
952FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore,
953 int size) {
954 FunctionCallee *Fns =
955 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
956 switch (size) {
957 case 1:
958 return Fns[0];
959 case 2:
960 return Fns[1];
961 case 4:
962 return Fns[2];
963 case 8:
964 return Fns[3];
965 default:
966 return nullptr;
967 }
968}
969
970/// Module-level initialization.
971///
972/// inserts a call to __msan_init to the module's constructor list.
973void MemorySanitizer::initializeModule(Module &M) {
974 auto &DL = M.getDataLayout();
975
976 TargetTriple = Triple(M.getTargetTriple());
977
978 bool ShadowPassed = ClShadowBase.getNumOccurrences() > 0;
979 bool OriginPassed = ClOriginBase.getNumOccurrences() > 0;
980 // Check the overrides first
981 if (ShadowPassed || OriginPassed) {
982 CustomMapParams.AndMask = ClAndMask;
983 CustomMapParams.XorMask = ClXorMask;
984 CustomMapParams.ShadowBase = ClShadowBase;
985 CustomMapParams.OriginBase = ClOriginBase;
986 MapParams = &CustomMapParams;
987 } else {
988 switch (TargetTriple.getOS()) {
989 case Triple::FreeBSD:
990 switch (TargetTriple.getArch()) {
991 case Triple::aarch64:
992 MapParams = FreeBSD_ARM_MemoryMapParams.bits64;
993 break;
994 case Triple::x86_64:
995 MapParams = FreeBSD_X86_MemoryMapParams.bits64;
996 break;
997 case Triple::x86:
998 MapParams = FreeBSD_X86_MemoryMapParams.bits32;
999 break;
1000 default:
1001 report_fatal_error("unsupported architecture");
1002 }
1003 break;
1004 case Triple::NetBSD:
1005 switch (TargetTriple.getArch()) {
1006 case Triple::x86_64:
1007 MapParams = NetBSD_X86_MemoryMapParams.bits64;
1008 break;
1009 default:
1010 report_fatal_error("unsupported architecture");
1011 }
1012 break;
1013 case Triple::Linux:
1014 switch (TargetTriple.getArch()) {
1015 case Triple::x86_64:
1016 MapParams = Linux_X86_MemoryMapParams.bits64;
1017 break;
1018 case Triple::x86:
1019 MapParams = Linux_X86_MemoryMapParams.bits32;
1020 break;
1021 case Triple::mips64:
1022 case Triple::mips64el:
1023 MapParams = Linux_MIPS_MemoryMapParams.bits64;
1024 break;
1025 case Triple::ppc64:
1026 case Triple::ppc64le:
1027 MapParams = Linux_PowerPC_MemoryMapParams.bits64;
1028 break;
1029 case Triple::systemz:
1030 MapParams = Linux_S390_MemoryMapParams.bits64;
1031 break;
1032 case Triple::aarch64:
1033 case Triple::aarch64_be:
1034 MapParams = Linux_ARM_MemoryMapParams.bits64;
1035 break;
1037 MapParams = Linux_LoongArch_MemoryMapParams.bits64;
1038 break;
1039 default:
1040 report_fatal_error("unsupported architecture");
1041 }
1042 break;
1043 default:
1044 report_fatal_error("unsupported operating system");
1045 }
1046 }
1047
1048 C = &(M.getContext());
1049 IRBuilder<> IRB(*C);
1050 IntptrTy = IRB.getIntPtrTy(DL);
1051 OriginTy = IRB.getInt32Ty();
1052 PtrTy = IRB.getPtrTy();
1053
1054 ColdCallWeights = MDBuilder(*C).createUnlikelyBranchWeights();
1055 OriginStoreWeights = MDBuilder(*C).createUnlikelyBranchWeights();
1056
1057 if (!CompileKernel) {
1058 if (TrackOrigins)
1059 M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
1060 return new GlobalVariable(
1061 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
1062 IRB.getInt32(TrackOrigins), "__msan_track_origins");
1063 });
1064
1065 if (Recover)
1066 M.getOrInsertGlobal("__msan_keep_going", IRB.getInt32Ty(), [&] {
1067 return new GlobalVariable(M, IRB.getInt32Ty(), true,
1068 GlobalValue::WeakODRLinkage,
1069 IRB.getInt32(Recover), "__msan_keep_going");
1070 });
1071 }
1072}
1073
1074namespace {
1075
1076/// A helper class that handles instrumentation of VarArg
1077/// functions on a particular platform.
1078///
1079/// Implementations are expected to insert the instrumentation
1080/// necessary to propagate argument shadow through VarArg function
1081/// calls. Visit* methods are called during an InstVisitor pass over
1082/// the function, and should avoid creating new basic blocks. A new
1083/// instance of this class is created for each instrumented function.
1084struct VarArgHelper {
1085 virtual ~VarArgHelper() = default;
1086
1087 /// Visit a CallBase.
1088 virtual void visitCallBase(CallBase &CB, IRBuilder<> &IRB) = 0;
1089
1090 /// Visit a va_start call.
1091 virtual void visitVAStartInst(VAStartInst &I) = 0;
1092
1093 /// Visit a va_copy call.
1094 virtual void visitVACopyInst(VACopyInst &I) = 0;
1095
1096 /// Finalize function instrumentation.
1097 ///
1098 /// This method is called after visiting all interesting (see above)
1099 /// instructions in a function.
1100 virtual void finalizeInstrumentation() = 0;
1101};
1102
1103struct MemorySanitizerVisitor;
1104
1105} // end anonymous namespace
1106
1107static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
1108 MemorySanitizerVisitor &Visitor);
1109
1110static unsigned TypeSizeToSizeIndex(TypeSize TS) {
1111 if (TS.isScalable())
1112 // Scalable types unconditionally take slowpaths.
1113 return kNumberOfAccessSizes;
1114 unsigned TypeSizeFixed = TS.getFixedValue();
1115 if (TypeSizeFixed <= 8)
1116 return 0;
1117 return Log2_32_Ceil((TypeSizeFixed + 7) / 8);
1118}
1119
1120namespace {
1121
1122/// Helper class to attach debug information of the given instruction onto new
1123/// instructions inserted after.
1124class NextNodeIRBuilder : public IRBuilder<> {
1125public:
1126 explicit NextNodeIRBuilder(Instruction *IP) : IRBuilder<>(IP->getNextNode()) {
1127 SetCurrentDebugLocation(IP->getDebugLoc());
1128 }
1129};
1130
1131/// This class does all the work for a given function. Store and Load
1132/// instructions store and load corresponding shadow and origin
1133/// values. Most instructions propagate shadow from arguments to their
1134/// return values. Certain instructions (most importantly, BranchInst)
1135/// test their argument shadow and print reports (with a runtime call) if it's
1136/// non-zero.
1137struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1138 Function &F;
1139 MemorySanitizer &MS;
1140 SmallVector<PHINode *, 16> ShadowPHINodes, OriginPHINodes;
1141 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1142 std::unique_ptr<VarArgHelper> VAHelper;
1143 const TargetLibraryInfo *TLI;
1144 Instruction *FnPrologueEnd;
1146
1147 // The following flags disable parts of MSan instrumentation based on
1148 // exclusion list contents and command-line options.
1149 bool InsertChecks;
1150 bool PropagateShadow;
1151 bool PoisonStack;
1152 bool PoisonUndef;
1153
1154 struct ShadowOriginAndInsertPoint {
1155 Value *Shadow;
1156 Value *Origin;
1157 Instruction *OrigIns;
1158
1159 ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I)
1160 : Shadow(S), Origin(O), OrigIns(I) {}
1161 };
1163 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1164 bool InstrumentLifetimeStart = ClHandleLifetimeIntrinsics;
1168 int64_t SplittableBlocksCount = 0;
1169
1170 MemorySanitizerVisitor(Function &F, MemorySanitizer &MS,
1171 const TargetLibraryInfo &TLI)
1172 : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)), TLI(&TLI) {
1173 bool SanitizeFunction =
1174 F.hasFnAttribute(Attribute::SanitizeMemory) && !ClDisableChecks;
1175 InsertChecks = SanitizeFunction;
1176 PropagateShadow = SanitizeFunction;
1177 PoisonStack = SanitizeFunction && ClPoisonStack;
1178 PoisonUndef = SanitizeFunction && ClPoisonUndef;
1179
1180 // In the presence of unreachable blocks, we may see Phi nodes with
1181 // incoming nodes from such blocks. Since InstVisitor skips unreachable
1182 // blocks, such nodes will not have any shadow value associated with them.
1183 // It's easier to remove unreachable blocks than deal with missing shadow.
1185
1186 MS.initializeCallbacks(*F.getParent(), TLI);
1187 FnPrologueEnd = IRBuilder<>(F.getEntryBlock().getFirstNonPHI())
1188 .CreateIntrinsic(Intrinsic::donothing, {}, {});
1189
1190 if (MS.CompileKernel) {
1191 IRBuilder<> IRB(FnPrologueEnd);
1192 insertKmsanPrologue(IRB);
1193 }
1194
1195 LLVM_DEBUG(if (!InsertChecks) dbgs()
1196 << "MemorySanitizer is not inserting checks into '"
1197 << F.getName() << "'\n");
1198 }
1199
1200 bool instrumentWithCalls(Value *V) {
1201 // Constants likely will be eliminated by follow-up passes.
1202 if (isa<Constant>(V))
1203 return false;
1204
1205 ++SplittableBlocksCount;
1207 SplittableBlocksCount > ClInstrumentationWithCallThreshold;
1208 }
1209
1210 bool isInPrologue(Instruction &I) {
1211 return I.getParent() == FnPrologueEnd->getParent() &&
1212 (&I == FnPrologueEnd || I.comesBefore(FnPrologueEnd));
1213 }
1214
1215 // Creates a new origin and records the stack trace. In general we can call
1216 // this function for any origin manipulation we like. However it will cost
1217 // runtime resources. So use this wisely only if it can provide additional
1218 // information helpful to a user.
1219 Value *updateOrigin(Value *V, IRBuilder<> &IRB) {
1220 if (MS.TrackOrigins <= 1)
1221 return V;
1222 return IRB.CreateCall(MS.MsanChainOriginFn, V);
1223 }
1224
1225 Value *originToIntptr(IRBuilder<> &IRB, Value *Origin) {
1226 const DataLayout &DL = F.getDataLayout();
1227 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1228 if (IntptrSize == kOriginSize)
1229 return Origin;
1230 assert(IntptrSize == kOriginSize * 2);
1231 Origin = IRB.CreateIntCast(Origin, MS.IntptrTy, /* isSigned */ false);
1232 return IRB.CreateOr(Origin, IRB.CreateShl(Origin, kOriginSize * 8));
1233 }
1234
1235 /// Fill memory range with the given origin value.
1236 void paintOrigin(IRBuilder<> &IRB, Value *Origin, Value *OriginPtr,
1237 TypeSize TS, Align Alignment) {
1238 const DataLayout &DL = F.getDataLayout();
1239 const Align IntptrAlignment = DL.getABITypeAlign(MS.IntptrTy);
1240 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1241 assert(IntptrAlignment >= kMinOriginAlignment);
1242 assert(IntptrSize >= kOriginSize);
1243
1244 // Note: The loop based formation works for fixed length vectors too,
1245 // however we prefer to unroll and specialize alignment below.
1246 if (TS.isScalable()) {
1247 Value *Size = IRB.CreateTypeSize(MS.IntptrTy, TS);
1248 Value *RoundUp =
1249 IRB.CreateAdd(Size, ConstantInt::get(MS.IntptrTy, kOriginSize - 1));
1250 Value *End =
1251 IRB.CreateUDiv(RoundUp, ConstantInt::get(MS.IntptrTy, kOriginSize));
1252 auto [InsertPt, Index] =
1254 IRB.SetInsertPoint(InsertPt);
1255
1256 Value *GEP = IRB.CreateGEP(MS.OriginTy, OriginPtr, Index);
1258 return;
1259 }
1260
1261 unsigned Size = TS.getFixedValue();
1262
1263 unsigned Ofs = 0;
1264 Align CurrentAlignment = Alignment;
1265 if (Alignment >= IntptrAlignment && IntptrSize > kOriginSize) {
1266 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1267 Value *IntptrOriginPtr =
1268 IRB.CreatePointerCast(OriginPtr, PointerType::get(MS.IntptrTy, 0));
1269 for (unsigned i = 0; i < Size / IntptrSize; ++i) {
1270 Value *Ptr = i ? IRB.CreateConstGEP1_32(MS.IntptrTy, IntptrOriginPtr, i)
1271 : IntptrOriginPtr;
1272 IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
1273 Ofs += IntptrSize / kOriginSize;
1274 CurrentAlignment = IntptrAlignment;
1275 }
1276 }
1277
1278 for (unsigned i = Ofs; i < (Size + kOriginSize - 1) / kOriginSize; ++i) {
1279 Value *GEP =
1280 i ? IRB.CreateConstGEP1_32(MS.OriginTy, OriginPtr, i) : OriginPtr;
1281 IRB.CreateAlignedStore(Origin, GEP, CurrentAlignment);
1282 CurrentAlignment = kMinOriginAlignment;
1283 }
1284 }
1285
1286 void storeOrigin(IRBuilder<> &IRB, Value *Addr, Value *Shadow, Value *Origin,
1287 Value *OriginPtr, Align Alignment) {
1288 const DataLayout &DL = F.getDataLayout();
1289 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1290 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
1291 // ZExt cannot convert between vector and scalar
1292 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1293 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1294 if (!ClCheckConstantShadow || ConstantShadow->isZeroValue()) {
1295 // Origin is not needed: value is initialized or const shadow is
1296 // ignored.
1297 return;
1298 }
1299 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1300 // Copy origin as the value is definitely uninitialized.
1301 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1302 OriginAlignment);
1303 return;
1304 }
1305 // Fallback to runtime check, which still can be optimized out later.
1306 }
1307
1308 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1309 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1310 if (instrumentWithCalls(ConvertedShadow) &&
1311 SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
1312 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1313 Value *ConvertedShadow2 =
1314 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1315 CallBase *CB = IRB.CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1316 CB->addParamAttr(0, Attribute::ZExt);
1317 CB->addParamAttr(2, Attribute::ZExt);
1318 } else {
1319 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1321 Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
1322 IRBuilder<> IRBNew(CheckTerm);
1323 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1324 OriginAlignment);
1325 }
1326 }
1327
1328 void materializeStores() {
1329 for (StoreInst *SI : StoreList) {
1330 IRBuilder<> IRB(SI);
1331 Value *Val = SI->getValueOperand();
1332 Value *Addr = SI->getPointerOperand();
1333 Value *Shadow = SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1334 Value *ShadowPtr, *OriginPtr;
1335 Type *ShadowTy = Shadow->getType();
1336 const Align Alignment = SI->getAlign();
1337 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1338 std::tie(ShadowPtr, OriginPtr) =
1339 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ true);
1340
1341 StoreInst *NewSI = IRB.CreateAlignedStore(Shadow, ShadowPtr, Alignment);
1342 LLVM_DEBUG(dbgs() << " STORE: " << *NewSI << "\n");
1343 (void)NewSI;
1344
1345 if (SI->isAtomic())
1346 SI->setOrdering(addReleaseOrdering(SI->getOrdering()));
1347
1348 if (MS.TrackOrigins && !SI->isAtomic())
1349 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1350 OriginAlignment);
1351 }
1352 }
1353
1354 // Returns true if Debug Location corresponds to multiple warnings.
1355 bool shouldDisambiguateWarningLocation(const DebugLoc &DebugLoc) {
1356 if (MS.TrackOrigins < 2)
1357 return false;
1358
1359 if (LazyWarningDebugLocationCount.empty())
1360 for (const auto &I : InstrumentationList)
1361 ++LazyWarningDebugLocationCount[I.OrigIns->getDebugLoc()];
1362
1363 return LazyWarningDebugLocationCount[DebugLoc] >= ClDisambiguateWarning;
1364 }
1365
1366 /// Helper function to insert a warning at IRB's current insert point.
1367 void insertWarningFn(IRBuilder<> &IRB, Value *Origin) {
1368 if (!Origin)
1369 Origin = (Value *)IRB.getInt32(0);
1370 assert(Origin->getType()->isIntegerTy());
1371
1372 if (shouldDisambiguateWarningLocation(IRB.getCurrentDebugLocation())) {
1373 // Try to create additional origin with debug info of the last origin
1374 // instruction. It may provide additional information to the user.
1375 if (Instruction *OI = dyn_cast_or_null<Instruction>(Origin)) {
1376 assert(MS.TrackOrigins);
1377 auto NewDebugLoc = OI->getDebugLoc();
1378 // Origin update with missing or the same debug location provides no
1379 // additional value.
1380 if (NewDebugLoc && NewDebugLoc != IRB.getCurrentDebugLocation()) {
1381 // Insert update just before the check, so we call runtime only just
1382 // before the report.
1383 IRBuilder<> IRBOrigin(&*IRB.GetInsertPoint());
1384 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1385 Origin = updateOrigin(Origin, IRBOrigin);
1386 }
1387 }
1388 }
1389
1390 if (MS.CompileKernel || MS.TrackOrigins)
1391 IRB.CreateCall(MS.WarningFn, Origin)->setCannotMerge();
1392 else
1393 IRB.CreateCall(MS.WarningFn)->setCannotMerge();
1394 // FIXME: Insert UnreachableInst if !MS.Recover?
1395 // This may invalidate some of the following checks and needs to be done
1396 // at the very end.
1397 }
1398
1399 void materializeOneCheck(IRBuilder<> &IRB, Value *ConvertedShadow,
1400 Value *Origin) {
1401 const DataLayout &DL = F.getDataLayout();
1402 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1403 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1404 if (instrumentWithCalls(ConvertedShadow) &&
1405 SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
1406 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1407 // ZExt cannot convert between vector and scalar
1408 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1409 Value *ConvertedShadow2 =
1410 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1411 CallBase *CB = IRB.CreateCall(
1412 Fn, {ConvertedShadow2,
1413 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1414 CB->addParamAttr(0, Attribute::ZExt);
1415 CB->addParamAttr(1, Attribute::ZExt);
1416 } else {
1417 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1419 Cmp, &*IRB.GetInsertPoint(),
1420 /* Unreachable */ !MS.Recover, MS.ColdCallWeights);
1421
1422 IRB.SetInsertPoint(CheckTerm);
1423 insertWarningFn(IRB, Origin);
1424 LLVM_DEBUG(dbgs() << " CHECK: " << *Cmp << "\n");
1425 }
1426 }
1427
1428 void materializeInstructionChecks(
1429 ArrayRef<ShadowOriginAndInsertPoint> InstructionChecks) {
1430 const DataLayout &DL = F.getDataLayout();
1431 // Disable combining in some cases. TrackOrigins checks each shadow to pick
1432 // correct origin.
1433 bool Combine = !MS.TrackOrigins;
1434 Instruction *Instruction = InstructionChecks.front().OrigIns;
1435 Value *Shadow = nullptr;
1436 for (const auto &ShadowData : InstructionChecks) {
1437 assert(ShadowData.OrigIns == Instruction);
1439
1440 Value *ConvertedShadow = ShadowData.Shadow;
1441
1442 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1443 if (!ClCheckConstantShadow || ConstantShadow->isZeroValue()) {
1444 // Skip, value is initialized or const shadow is ignored.
1445 continue;
1446 }
1447 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1448 // Report as the value is definitely uninitialized.
1449 insertWarningFn(IRB, ShadowData.Origin);
1450 if (!MS.Recover)
1451 return; // Always fail and stop here, not need to check the rest.
1452 // Skip entire instruction,
1453 continue;
1454 }
1455 // Fallback to runtime check, which still can be optimized out later.
1456 }
1457
1458 if (!Combine) {
1459 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1460 continue;
1461 }
1462
1463 if (!Shadow) {
1464 Shadow = ConvertedShadow;
1465 continue;
1466 }
1467
1468 Shadow = convertToBool(Shadow, IRB, "_mscmp");
1469 ConvertedShadow = convertToBool(ConvertedShadow, IRB, "_mscmp");
1470 Shadow = IRB.CreateOr(Shadow, ConvertedShadow, "_msor");
1471 }
1472
1473 if (Shadow) {
1474 assert(Combine);
1476 materializeOneCheck(IRB, Shadow, nullptr);
1477 }
1478 }
1479
1480 void materializeChecks() {
1481#ifndef NDEBUG
1482 // For assert below.
1484#endif
1485
1486 for (auto I = InstrumentationList.begin();
1487 I != InstrumentationList.end();) {
1488 auto OrigIns = I->OrigIns;
1489 // Checks are grouped by the original instruction. We call all
1490 // `insertShadowCheck` for an instruction at once.
1491 assert(Done.insert(OrigIns).second);
1492 auto J = std::find_if(I + 1, InstrumentationList.end(),
1493 [OrigIns](const ShadowOriginAndInsertPoint &R) {
1494 return OrigIns != R.OrigIns;
1495 });
1496 // Process all checks of instruction at once.
1497 materializeInstructionChecks(ArrayRef<ShadowOriginAndInsertPoint>(I, J));
1498 I = J;
1499 }
1500
1501 LLVM_DEBUG(dbgs() << "DONE:\n" << F);
1502 }
1503
1504 // Returns the last instruction in the new prologue
1505 void insertKmsanPrologue(IRBuilder<> &IRB) {
1506 Value *ContextState = IRB.CreateCall(MS.MsanGetContextStateFn, {});
1507 Constant *Zero = IRB.getInt32(0);
1508 MS.ParamTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1509 {Zero, IRB.getInt32(0)}, "param_shadow");
1510 MS.RetvalTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1511 {Zero, IRB.getInt32(1)}, "retval_shadow");
1512 MS.VAArgTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1513 {Zero, IRB.getInt32(2)}, "va_arg_shadow");
1514 MS.VAArgOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1515 {Zero, IRB.getInt32(3)}, "va_arg_origin");
1516 MS.VAArgOverflowSizeTLS =
1517 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1518 {Zero, IRB.getInt32(4)}, "va_arg_overflow_size");
1519 MS.ParamOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1520 {Zero, IRB.getInt32(5)}, "param_origin");
1521 MS.RetvalOriginTLS =
1522 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1523 {Zero, IRB.getInt32(6)}, "retval_origin");
1524 if (MS.TargetTriple.getArch() == Triple::systemz)
1525 MS.MsanMetadataAlloca = IRB.CreateAlloca(MS.MsanMetadata, 0u);
1526 }
1527
1528 /// Add MemorySanitizer instrumentation to a function.
1529 bool runOnFunction() {
1530 // Iterate all BBs in depth-first order and create shadow instructions
1531 // for all instructions (where applicable).
1532 // For PHI nodes we create dummy shadow PHIs which will be finalized later.
1533 for (BasicBlock *BB : depth_first(FnPrologueEnd->getParent()))
1534 visit(*BB);
1535
1536 // `visit` above only collects instructions. Process them after iterating
1537 // CFG to avoid requirement on CFG transformations.
1538 for (Instruction *I : Instructions)
1540
1541 // Finalize PHI nodes.
1542 for (PHINode *PN : ShadowPHINodes) {
1543 PHINode *PNS = cast<PHINode>(getShadow(PN));
1544 PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
1545 size_t NumValues = PN->getNumIncomingValues();
1546 for (size_t v = 0; v < NumValues; v++) {
1547 PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1548 if (PNO)
1549 PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1550 }
1551 }
1552
1553 VAHelper->finalizeInstrumentation();
1554
1555 // Poison llvm.lifetime.start intrinsics, if we haven't fallen back to
1556 // instrumenting only allocas.
1557 if (InstrumentLifetimeStart) {
1558 for (auto Item : LifetimeStartList) {
1559 instrumentAlloca(*Item.second, Item.first);
1560 AllocaSet.remove(Item.second);
1561 }
1562 }
1563 // Poison the allocas for which we didn't instrument the corresponding
1564 // lifetime intrinsics.
1565 for (AllocaInst *AI : AllocaSet)
1566 instrumentAlloca(*AI);
1567
1568 // Insert shadow value checks.
1569 materializeChecks();
1570
1571 // Delayed instrumentation of StoreInst.
1572 // This may not add new address checks.
1573 materializeStores();
1574
1575 return true;
1576 }
1577
1578 /// Compute the shadow type that corresponds to a given Value.
1579 Type *getShadowTy(Value *V) { return getShadowTy(V->getType()); }
1580
1581 /// Compute the shadow type that corresponds to a given Type.
1582 Type *getShadowTy(Type *OrigTy) {
1583 if (!OrigTy->isSized()) {
1584 return nullptr;
1585 }
1586 // For integer type, shadow is the same as the original type.
1587 // This may return weird-sized types like i1.
1588 if (IntegerType *IT = dyn_cast<IntegerType>(OrigTy))
1589 return IT;
1590 const DataLayout &DL = F.getDataLayout();
1591 if (VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
1592 uint32_t EltSize = DL.getTypeSizeInBits(VT->getElementType());
1593 return VectorType::get(IntegerType::get(*MS.C, EltSize),
1594 VT->getElementCount());
1595 }
1596 if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) {
1597 return ArrayType::get(getShadowTy(AT->getElementType()),
1598 AT->getNumElements());
1599 }
1600 if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
1602 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1603 Elements.push_back(getShadowTy(ST->getElementType(i)));
1604 StructType *Res = StructType::get(*MS.C, Elements, ST->isPacked());
1605 LLVM_DEBUG(dbgs() << "getShadowTy: " << *ST << " ===> " << *Res << "\n");
1606 return Res;
1607 }
1608 uint32_t TypeSize = DL.getTypeSizeInBits(OrigTy);
1609 return IntegerType::get(*MS.C, TypeSize);
1610 }
1611
1612 /// Extract combined shadow of struct elements as a bool
1613 Value *collapseStructShadow(StructType *Struct, Value *Shadow,
1614 IRBuilder<> &IRB) {
1615 Value *FalseVal = IRB.getIntN(/* width */ 1, /* value */ 0);
1616 Value *Aggregator = FalseVal;
1617
1618 for (unsigned Idx = 0; Idx < Struct->getNumElements(); Idx++) {
1619 // Combine by ORing together each element's bool shadow
1620 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1621 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1622
1623 if (Aggregator != FalseVal)
1624 Aggregator = IRB.CreateOr(Aggregator, ShadowBool);
1625 else
1626 Aggregator = ShadowBool;
1627 }
1628
1629 return Aggregator;
1630 }
1631
1632 // Extract combined shadow of array elements
1633 Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
1634 IRBuilder<> &IRB) {
1635 if (!Array->getNumElements())
1636 return IRB.getIntN(/* width */ 1, /* value */ 0);
1637
1638 Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
1639 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1640
1641 for (unsigned Idx = 1; Idx < Array->getNumElements(); Idx++) {
1642 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1643 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1644 Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
1645 }
1646 return Aggregator;
1647 }
1648
1649 /// Convert a shadow value to it's flattened variant. The resulting
1650 /// shadow may not necessarily have the same bit width as the input
1651 /// value, but it will always be comparable to zero.
1652 Value *convertShadowToScalar(Value *V, IRBuilder<> &IRB) {
1653 if (StructType *Struct = dyn_cast<StructType>(V->getType()))
1654 return collapseStructShadow(Struct, V, IRB);
1655 if (ArrayType *Array = dyn_cast<ArrayType>(V->getType()))
1656 return collapseArrayShadow(Array, V, IRB);
1657 if (isa<VectorType>(V->getType())) {
1658 if (isa<ScalableVectorType>(V->getType()))
1659 return convertShadowToScalar(IRB.CreateOrReduce(V), IRB);
1660 unsigned BitWidth =
1661 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1662 return IRB.CreateBitCast(V, IntegerType::get(*MS.C, BitWidth));
1663 }
1664 return V;
1665 }
1666
1667 // Convert a scalar value to an i1 by comparing with 0
1668 Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &name = "") {
1669 Type *VTy = V->getType();
1670 if (!VTy->isIntegerTy())
1671 return convertToBool(convertShadowToScalar(V, IRB), IRB, name);
1672 if (VTy->getIntegerBitWidth() == 1)
1673 // Just converting a bool to a bool, so do nothing.
1674 return V;
1675 return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), name);
1676 }
1677
1678 Type *ptrToIntPtrType(Type *PtrTy) const {
1679 if (VectorType *VectTy = dyn_cast<VectorType>(PtrTy)) {
1680 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1681 VectTy->getElementCount());
1682 }
1683 assert(PtrTy->isIntOrPtrTy());
1684 return MS.IntptrTy;
1685 }
1686
1687 Type *getPtrToShadowPtrType(Type *IntPtrTy, Type *ShadowTy) const {
1688 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1689 return VectorType::get(
1690 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1691 VectTy->getElementCount());
1692 }
1693 assert(IntPtrTy == MS.IntptrTy);
1694 return PointerType::get(*MS.C, 0);
1695 }
1696
1697 Constant *constToIntPtr(Type *IntPtrTy, uint64_t C) const {
1698 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1700 VectTy->getElementCount(), constToIntPtr(VectTy->getElementType(), C));
1701 }
1702 assert(IntPtrTy == MS.IntptrTy);
1703 return ConstantInt::get(MS.IntptrTy, C);
1704 }
1705
1706 /// Compute the integer shadow offset that corresponds to a given
1707 /// application address.
1708 ///
1709 /// Offset = (Addr & ~AndMask) ^ XorMask
1710 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1711 /// a single pointee.
1712 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1713 Value *getShadowPtrOffset(Value *Addr, IRBuilder<> &IRB) {
1714 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1715 Value *OffsetLong = IRB.CreatePointerCast(Addr, IntptrTy);
1716
1717 if (uint64_t AndMask = MS.MapParams->AndMask)
1718 OffsetLong = IRB.CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1719
1720 if (uint64_t XorMask = MS.MapParams->XorMask)
1721 OffsetLong = IRB.CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1722 return OffsetLong;
1723 }
1724
1725 /// Compute the shadow and origin addresses corresponding to a given
1726 /// application address.
1727 ///
1728 /// Shadow = ShadowBase + Offset
1729 /// Origin = (OriginBase + Offset) & ~3ULL
1730 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1731 /// a single pointee.
1732 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1733 std::pair<Value *, Value *>
1734 getShadowOriginPtrUserspace(Value *Addr, IRBuilder<> &IRB, Type *ShadowTy,
1735 MaybeAlign Alignment) {
1736 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1737 if (!VectTy) {
1738 assert(Addr->getType()->isPointerTy());
1739 } else {
1740 assert(VectTy->getElementType()->isPointerTy());
1741 }
1742 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1743 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1744 Value *ShadowLong = ShadowOffset;
1745 if (uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1746 ShadowLong =
1747 IRB.CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1748 }
1749 Value *ShadowPtr = IRB.CreateIntToPtr(
1750 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1751
1752 Value *OriginPtr = nullptr;
1753 if (MS.TrackOrigins) {
1754 Value *OriginLong = ShadowOffset;
1755 uint64_t OriginBase = MS.MapParams->OriginBase;
1756 if (OriginBase != 0)
1757 OriginLong =
1758 IRB.CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1759 if (!Alignment || *Alignment < kMinOriginAlignment) {
1761 OriginLong = IRB.CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1762 }
1763 OriginPtr = IRB.CreateIntToPtr(
1764 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1765 }
1766 return std::make_pair(ShadowPtr, OriginPtr);
1767 }
1768
1769 template <typename... ArgsTy>
1770 Value *createMetadataCall(IRBuilder<> &IRB, FunctionCallee Callee,
1771 ArgsTy... Args) {
1772 if (MS.TargetTriple.getArch() == Triple::systemz) {
1773 IRB.CreateCall(Callee,
1774 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1775 return IRB.CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1776 }
1777
1778 return IRB.CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1779 }
1780
1781 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(Value *Addr,
1782 IRBuilder<> &IRB,
1783 Type *ShadowTy,
1784 bool isStore) {
1785 Value *ShadowOriginPtrs;
1786 const DataLayout &DL = F.getDataLayout();
1787 TypeSize Size = DL.getTypeStoreSize(ShadowTy);
1788
1789 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size);
1790 Value *AddrCast =
1791 IRB.CreatePointerCast(Addr, PointerType::get(IRB.getInt8Ty(), 0));
1792 if (Getter) {
1793 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1794 } else {
1795 Value *SizeVal = ConstantInt::get(MS.IntptrTy, Size);
1796 ShadowOriginPtrs = createMetadataCall(
1797 IRB,
1798 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1799 AddrCast, SizeVal);
1800 }
1801 Value *ShadowPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 0);
1802 ShadowPtr = IRB.CreatePointerCast(ShadowPtr, PointerType::get(ShadowTy, 0));
1803 Value *OriginPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 1);
1804
1805 return std::make_pair(ShadowPtr, OriginPtr);
1806 }
1807
1808 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1809 /// a single pointee.
1810 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1811 std::pair<Value *, Value *> getShadowOriginPtrKernel(Value *Addr,
1812 IRBuilder<> &IRB,
1813 Type *ShadowTy,
1814 bool isStore) {
1815 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1816 if (!VectTy) {
1817 assert(Addr->getType()->isPointerTy());
1818 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy, isStore);
1819 }
1820
1821 // TODO: Support callbacs with vectors of addresses.
1822 unsigned NumElements = cast<FixedVectorType>(VectTy)->getNumElements();
1823 Value *ShadowPtrs = ConstantInt::getNullValue(
1824 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1825 Value *OriginPtrs = nullptr;
1826 if (MS.TrackOrigins)
1827 OriginPtrs = ConstantInt::getNullValue(
1828 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1829 for (unsigned i = 0; i < NumElements; ++i) {
1830 Value *OneAddr =
1831 IRB.CreateExtractElement(Addr, ConstantInt::get(IRB.getInt32Ty(), i));
1832 auto [ShadowPtr, OriginPtr] =
1833 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy, isStore);
1834
1835 ShadowPtrs = IRB.CreateInsertElement(
1836 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1837 if (MS.TrackOrigins)
1838 OriginPtrs = IRB.CreateInsertElement(
1839 OriginPtrs, OriginPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1840 }
1841 return {ShadowPtrs, OriginPtrs};
1842 }
1843
1844 std::pair<Value *, Value *> getShadowOriginPtr(Value *Addr, IRBuilder<> &IRB,
1845 Type *ShadowTy,
1846 MaybeAlign Alignment,
1847 bool isStore) {
1848 if (MS.CompileKernel)
1849 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy, isStore);
1850 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1851 }
1852
1853 /// Compute the shadow address for a given function argument.
1854 ///
1855 /// Shadow = ParamTLS+ArgOffset.
1856 Value *getShadowPtrForArgument(IRBuilder<> &IRB, int ArgOffset) {
1857 Value *Base = IRB.CreatePointerCast(MS.ParamTLS, MS.IntptrTy);
1858 if (ArgOffset)
1859 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
1860 return IRB.CreateIntToPtr(Base, IRB.getPtrTy(0), "_msarg");
1861 }
1862
1863 /// Compute the origin address for a given function argument.
1864 Value *getOriginPtrForArgument(IRBuilder<> &IRB, int ArgOffset) {
1865 if (!MS.TrackOrigins)
1866 return nullptr;
1867 Value *Base = IRB.CreatePointerCast(MS.ParamOriginTLS, MS.IntptrTy);
1868 if (ArgOffset)
1869 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
1870 return IRB.CreateIntToPtr(Base, IRB.getPtrTy(0), "_msarg_o");
1871 }
1872
1873 /// Compute the shadow address for a retval.
1874 Value *getShadowPtrForRetval(IRBuilder<> &IRB) {
1875 return IRB.CreatePointerCast(MS.RetvalTLS, IRB.getPtrTy(0), "_msret");
1876 }
1877
1878 /// Compute the origin address for a retval.
1879 Value *getOriginPtrForRetval() {
1880 // We keep a single origin for the entire retval. Might be too optimistic.
1881 return MS.RetvalOriginTLS;
1882 }
1883
1884 /// Set SV to be the shadow value for V.
1885 void setShadow(Value *V, Value *SV) {
1886 assert(!ShadowMap.count(V) && "Values may only have one shadow");
1887 ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
1888 }
1889
1890 /// Set Origin to be the origin value for V.
1891 void setOrigin(Value *V, Value *Origin) {
1892 if (!MS.TrackOrigins)
1893 return;
1894 assert(!OriginMap.count(V) && "Values may only have one origin");
1895 LLVM_DEBUG(dbgs() << "ORIGIN: " << *V << " ==> " << *Origin << "\n");
1896 OriginMap[V] = Origin;
1897 }
1898
1899 Constant *getCleanShadow(Type *OrigTy) {
1900 Type *ShadowTy = getShadowTy(OrigTy);
1901 if (!ShadowTy)
1902 return nullptr;
1903 return Constant::getNullValue(ShadowTy);
1904 }
1905
1906 /// Create a clean shadow value for a given value.
1907 ///
1908 /// Clean shadow (all zeroes) means all bits of the value are defined
1909 /// (initialized).
1910 Constant *getCleanShadow(Value *V) { return getCleanShadow(V->getType()); }
1911
1912 /// Create a dirty shadow of a given shadow type.
1913 Constant *getPoisonedShadow(Type *ShadowTy) {
1914 assert(ShadowTy);
1915 if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
1916 return Constant::getAllOnesValue(ShadowTy);
1917 if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) {
1918 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
1919 getPoisonedShadow(AT->getElementType()));
1920 return ConstantArray::get(AT, Vals);
1921 }
1922 if (StructType *ST = dyn_cast<StructType>(ShadowTy)) {
1924 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1925 Vals.push_back(getPoisonedShadow(ST->getElementType(i)));
1926 return ConstantStruct::get(ST, Vals);
1927 }
1928 llvm_unreachable("Unexpected shadow type");
1929 }
1930
1931 /// Create a dirty shadow for a given value.
1932 Constant *getPoisonedShadow(Value *V) {
1933 Type *ShadowTy = getShadowTy(V);
1934 if (!ShadowTy)
1935 return nullptr;
1936 return getPoisonedShadow(ShadowTy);
1937 }
1938
1939 /// Create a clean (zero) origin.
1940 Value *getCleanOrigin() { return Constant::getNullValue(MS.OriginTy); }
1941
1942 /// Get the shadow value for a given Value.
1943 ///
1944 /// This function either returns the value set earlier with setShadow,
1945 /// or extracts if from ParamTLS (for function arguments).
1946 Value *getShadow(Value *V) {
1947 if (Instruction *I = dyn_cast<Instruction>(V)) {
1948 if (!PropagateShadow || I->getMetadata(LLVMContext::MD_nosanitize))
1949 return getCleanShadow(V);
1950 // For instructions the shadow is already stored in the map.
1951 Value *Shadow = ShadowMap[V];
1952 if (!Shadow) {
1953 LLVM_DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent()));
1954 (void)I;
1955 assert(Shadow && "No shadow for a value");
1956 }
1957 return Shadow;
1958 }
1959 if (UndefValue *U = dyn_cast<UndefValue>(V)) {
1960 Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
1961 : getCleanShadow(V);
1962 LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n");
1963 (void)U;
1964 return AllOnes;
1965 }
1966 if (Argument *A = dyn_cast<Argument>(V)) {
1967 // For arguments we compute the shadow on demand and store it in the map.
1968 Value *&ShadowPtr = ShadowMap[V];
1969 if (ShadowPtr)
1970 return ShadowPtr;
1971 Function *F = A->getParent();
1972 IRBuilder<> EntryIRB(FnPrologueEnd);
1973 unsigned ArgOffset = 0;
1974 const DataLayout &DL = F->getDataLayout();
1975 for (auto &FArg : F->args()) {
1976 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
1977 LLVM_DEBUG(dbgs() << (FArg.getType()->isScalableTy()
1978 ? "vscale not fully supported\n"
1979 : "Arg is not sized\n"));
1980 if (A == &FArg) {
1981 ShadowPtr = getCleanShadow(V);
1982 setOrigin(A, getCleanOrigin());
1983 break;
1984 }
1985 continue;
1986 }
1987
1988 unsigned Size = FArg.hasByValAttr()
1989 ? DL.getTypeAllocSize(FArg.getParamByValType())
1990 : DL.getTypeAllocSize(FArg.getType());
1991
1992 if (A == &FArg) {
1993 bool Overflow = ArgOffset + Size > kParamTLSSize;
1994 if (FArg.hasByValAttr()) {
1995 // ByVal pointer itself has clean shadow. We copy the actual
1996 // argument shadow to the underlying memory.
1997 // Figure out maximal valid memcpy alignment.
1998 const Align ArgAlign = DL.getValueOrABITypeAlignment(
1999 FArg.getParamAlign(), FArg.getParamByValType());
2000 Value *CpShadowPtr, *CpOriginPtr;
2001 std::tie(CpShadowPtr, CpOriginPtr) =
2002 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
2003 /*isStore*/ true);
2004 if (!PropagateShadow || Overflow) {
2005 // ParamTLS overflow.
2006 EntryIRB.CreateMemSet(
2007 CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()),
2008 Size, ArgAlign);
2009 } else {
2010 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2011 const Align CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
2012 Value *Cpy = EntryIRB.CreateMemCpy(CpShadowPtr, CopyAlign, Base,
2013 CopyAlign, Size);
2014 LLVM_DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n");
2015 (void)Cpy;
2016
2017 if (MS.TrackOrigins) {
2018 Value *OriginPtr =
2019 getOriginPtrForArgument(EntryIRB, ArgOffset);
2020 // FIXME: OriginSize should be:
2021 // alignTo(V % kMinOriginAlignment + Size, kMinOriginAlignment)
2022 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
2023 EntryIRB.CreateMemCpy(
2024 CpOriginPtr,
2025 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginPtr,
2026 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
2027 OriginSize);
2028 }
2029 }
2030 }
2031
2032 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
2033 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
2034 ShadowPtr = getCleanShadow(V);
2035 setOrigin(A, getCleanOrigin());
2036 } else {
2037 // Shadow over TLS
2038 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2039 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg), Base,
2041 if (MS.TrackOrigins) {
2042 Value *OriginPtr =
2043 getOriginPtrForArgument(EntryIRB, ArgOffset);
2044 setOrigin(A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2045 }
2046 }
2048 << " ARG: " << FArg << " ==> " << *ShadowPtr << "\n");
2049 break;
2050 }
2051
2052 ArgOffset += alignTo(Size, kShadowTLSAlignment);
2053 }
2054 assert(ShadowPtr && "Could not find shadow for an argument");
2055 return ShadowPtr;
2056 }
2057 // For everything else the shadow is zero.
2058 return getCleanShadow(V);
2059 }
2060
2061 /// Get the shadow for i-th argument of the instruction I.
2062 Value *getShadow(Instruction *I, int i) {
2063 return getShadow(I->getOperand(i));
2064 }
2065
2066 /// Get the origin for a value.
2067 Value *getOrigin(Value *V) {
2068 if (!MS.TrackOrigins)
2069 return nullptr;
2070 if (!PropagateShadow || isa<Constant>(V) || isa<InlineAsm>(V))
2071 return getCleanOrigin();
2072 assert((isa<Instruction>(V) || isa<Argument>(V)) &&
2073 "Unexpected value type in getOrigin()");
2074 if (Instruction *I = dyn_cast<Instruction>(V)) {
2075 if (I->getMetadata(LLVMContext::MD_nosanitize))
2076 return getCleanOrigin();
2077 }
2078 Value *Origin = OriginMap[V];
2079 assert(Origin && "Missing origin");
2080 return Origin;
2081 }
2082
2083 /// Get the origin for i-th argument of the instruction I.
2084 Value *getOrigin(Instruction *I, int i) {
2085 return getOrigin(I->getOperand(i));
2086 }
2087
2088 /// Remember the place where a shadow check should be inserted.
2089 ///
2090 /// This location will be later instrumented with a check that will print a
2091 /// UMR warning in runtime if the shadow value is not 0.
2092 void insertShadowCheck(Value *Shadow, Value *Origin, Instruction *OrigIns) {
2093 assert(Shadow);
2094 if (!InsertChecks)
2095 return;
2096
2097 if (!DebugCounter::shouldExecute(DebugInsertCheck)) {
2098 LLVM_DEBUG(dbgs() << "Skipping check of " << *Shadow << " before "
2099 << *OrigIns << "\n");
2100 return;
2101 }
2102#ifndef NDEBUG
2103 Type *ShadowTy = Shadow->getType();
2104 assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
2105 isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
2106 "Can only insert checks for integer, vector, and aggregate shadow "
2107 "types");
2108#endif
2109 InstrumentationList.push_back(
2110 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2111 }
2112
2113 /// Remember the place where a shadow check should be inserted.
2114 ///
2115 /// This location will be later instrumented with a check that will print a
2116 /// UMR warning in runtime if the value is not fully defined.
2117 void insertShadowCheck(Value *Val, Instruction *OrigIns) {
2118 assert(Val);
2119 Value *Shadow, *Origin;
2121 Shadow = getShadow(Val);
2122 if (!Shadow)
2123 return;
2124 Origin = getOrigin(Val);
2125 } else {
2126 Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
2127 if (!Shadow)
2128 return;
2129 Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
2130 }
2131 insertShadowCheck(Shadow, Origin, OrigIns);
2132 }
2133
2135 switch (a) {
2136 case AtomicOrdering::NotAtomic:
2137 return AtomicOrdering::NotAtomic;
2138 case AtomicOrdering::Unordered:
2139 case AtomicOrdering::Monotonic:
2140 case AtomicOrdering::Release:
2141 return AtomicOrdering::Release;
2142 case AtomicOrdering::Acquire:
2143 case AtomicOrdering::AcquireRelease:
2144 return AtomicOrdering::AcquireRelease;
2145 case AtomicOrdering::SequentiallyConsistent:
2146 return AtomicOrdering::SequentiallyConsistent;
2147 }
2148 llvm_unreachable("Unknown ordering");
2149 }
2150
2151 Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
2152 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2153 uint32_t OrderingTable[NumOrderings] = {};
2154
2155 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2156 OrderingTable[(int)AtomicOrderingCABI::release] =
2157 (int)AtomicOrderingCABI::release;
2158 OrderingTable[(int)AtomicOrderingCABI::consume] =
2159 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2160 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2161 (int)AtomicOrderingCABI::acq_rel;
2162 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2163 (int)AtomicOrderingCABI::seq_cst;
2164
2165 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2166 }
2167
2169 switch (a) {
2170 case AtomicOrdering::NotAtomic:
2171 return AtomicOrdering::NotAtomic;
2172 case AtomicOrdering::Unordered:
2173 case AtomicOrdering::Monotonic:
2174 case AtomicOrdering::Acquire:
2175 return AtomicOrdering::Acquire;
2176 case AtomicOrdering::Release:
2177 case AtomicOrdering::AcquireRelease:
2178 return AtomicOrdering::AcquireRelease;
2179 case AtomicOrdering::SequentiallyConsistent:
2180 return AtomicOrdering::SequentiallyConsistent;
2181 }
2182 llvm_unreachable("Unknown ordering");
2183 }
2184
2185 Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
2186 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2187 uint32_t OrderingTable[NumOrderings] = {};
2188
2189 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2190 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2191 OrderingTable[(int)AtomicOrderingCABI::consume] =
2192 (int)AtomicOrderingCABI::acquire;
2193 OrderingTable[(int)AtomicOrderingCABI::release] =
2194 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2195 (int)AtomicOrderingCABI::acq_rel;
2196 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2197 (int)AtomicOrderingCABI::seq_cst;
2198
2199 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2200 }
2201
2202 // ------------------- Visitors.
2203 using InstVisitor<MemorySanitizerVisitor>::visit;
2204 void visit(Instruction &I) {
2205 if (I.getMetadata(LLVMContext::MD_nosanitize))
2206 return;
2207 // Don't want to visit if we're in the prologue
2208 if (isInPrologue(I))
2209 return;
2210 if (!DebugCounter::shouldExecute(DebugInstrumentInstruction)) {
2211 LLVM_DEBUG(dbgs() << "Skipping instruction: " << I << "\n");
2212 // We still need to set the shadow and origin to clean values.
2213 setShadow(&I, getCleanShadow(&I));
2214 setOrigin(&I, getCleanOrigin());
2215 return;
2216 }
2217
2218 Instructions.push_back(&I);
2219 }
2220
2221 /// Instrument LoadInst
2222 ///
2223 /// Loads the corresponding shadow and (optionally) origin.
2224 /// Optionally, checks that the load address is fully defined.
2225 void visitLoadInst(LoadInst &I) {
2226 assert(I.getType()->isSized() && "Load type must have size");
2227 assert(!I.getMetadata(LLVMContext::MD_nosanitize));
2228 NextNodeIRBuilder IRB(&I);
2229 Type *ShadowTy = getShadowTy(&I);
2230 Value *Addr = I.getPointerOperand();
2231 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
2232 const Align Alignment = I.getAlign();
2233 if (PropagateShadow) {
2234 std::tie(ShadowPtr, OriginPtr) =
2235 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
2236 setShadow(&I,
2237 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2238 } else {
2239 setShadow(&I, getCleanShadow(&I));
2240 }
2241
2243 insertShadowCheck(I.getPointerOperand(), &I);
2244
2245 if (I.isAtomic())
2246 I.setOrdering(addAcquireOrdering(I.getOrdering()));
2247
2248 if (MS.TrackOrigins) {
2249 if (PropagateShadow) {
2250 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
2251 setOrigin(
2252 &I, IRB.CreateAlignedLoad(MS.OriginTy, OriginPtr, OriginAlignment));
2253 } else {
2254 setOrigin(&I, getCleanOrigin());
2255 }
2256 }
2257 }
2258
2259 /// Instrument StoreInst
2260 ///
2261 /// Stores the corresponding shadow and (optionally) origin.
2262 /// Optionally, checks that the store address is fully defined.
2263 void visitStoreInst(StoreInst &I) {
2264 StoreList.push_back(&I);
2266 insertShadowCheck(I.getPointerOperand(), &I);
2267 }
2268
2269 void handleCASOrRMW(Instruction &I) {
2270 assert(isa<AtomicRMWInst>(I) || isa<AtomicCmpXchgInst>(I));
2271
2272 IRBuilder<> IRB(&I);
2273 Value *Addr = I.getOperand(0);
2274 Value *Val = I.getOperand(1);
2275 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val), Align(1),
2276 /*isStore*/ true)
2277 .first;
2278
2280 insertShadowCheck(Addr, &I);
2281
2282 // Only test the conditional argument of cmpxchg instruction.
2283 // The other argument can potentially be uninitialized, but we can not
2284 // detect this situation reliably without possible false positives.
2285 if (isa<AtomicCmpXchgInst>(I))
2286 insertShadowCheck(Val, &I);
2287
2288 IRB.CreateStore(getCleanShadow(Val), ShadowPtr);
2289
2290 setShadow(&I, getCleanShadow(&I));
2291 setOrigin(&I, getCleanOrigin());
2292 }
2293
2294 void visitAtomicRMWInst(AtomicRMWInst &I) {
2295 handleCASOrRMW(I);
2296 I.setOrdering(addReleaseOrdering(I.getOrdering()));
2297 }
2298
2299 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
2300 handleCASOrRMW(I);
2301 I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
2302 }
2303
2304 // Vector manipulation.
2305 void visitExtractElementInst(ExtractElementInst &I) {
2306 insertShadowCheck(I.getOperand(1), &I);
2307 IRBuilder<> IRB(&I);
2308 setShadow(&I, IRB.CreateExtractElement(getShadow(&I, 0), I.getOperand(1),
2309 "_msprop"));
2310 setOrigin(&I, getOrigin(&I, 0));
2311 }
2312
2313 void visitInsertElementInst(InsertElementInst &I) {
2314 insertShadowCheck(I.getOperand(2), &I);
2315 IRBuilder<> IRB(&I);
2316 auto *Shadow0 = getShadow(&I, 0);
2317 auto *Shadow1 = getShadow(&I, 1);
2318 setShadow(&I, IRB.CreateInsertElement(Shadow0, Shadow1, I.getOperand(2),
2319 "_msprop"));
2320 setOriginForNaryOp(I);
2321 }
2322
2323 void visitShuffleVectorInst(ShuffleVectorInst &I) {
2324 IRBuilder<> IRB(&I);
2325 auto *Shadow0 = getShadow(&I, 0);
2326 auto *Shadow1 = getShadow(&I, 1);
2327 setShadow(&I, IRB.CreateShuffleVector(Shadow0, Shadow1, I.getShuffleMask(),
2328 "_msprop"));
2329 setOriginForNaryOp(I);
2330 }
2331
2332 // Casts.
2333 void visitSExtInst(SExtInst &I) {
2334 IRBuilder<> IRB(&I);
2335 setShadow(&I, IRB.CreateSExt(getShadow(&I, 0), I.getType(), "_msprop"));
2336 setOrigin(&I, getOrigin(&I, 0));
2337 }
2338
2339 void visitZExtInst(ZExtInst &I) {
2340 IRBuilder<> IRB(&I);
2341 setShadow(&I, IRB.CreateZExt(getShadow(&I, 0), I.getType(), "_msprop"));
2342 setOrigin(&I, getOrigin(&I, 0));
2343 }
2344
2345 void visitTruncInst(TruncInst &I) {
2346 IRBuilder<> IRB(&I);
2347 setShadow(&I, IRB.CreateTrunc(getShadow(&I, 0), I.getType(), "_msprop"));
2348 setOrigin(&I, getOrigin(&I, 0));
2349 }
2350
2351 void visitBitCastInst(BitCastInst &I) {
2352 // Special case: if this is the bitcast (there is exactly 1 allowed) between
2353 // a musttail call and a ret, don't instrument. New instructions are not
2354 // allowed after a musttail call.
2355 if (auto *CI = dyn_cast<CallInst>(I.getOperand(0)))
2356 if (CI->isMustTailCall())
2357 return;
2358 IRBuilder<> IRB(&I);
2359 setShadow(&I, IRB.CreateBitCast(getShadow(&I, 0), getShadowTy(&I)));
2360 setOrigin(&I, getOrigin(&I, 0));
2361 }
2362
2363 void visitPtrToIntInst(PtrToIntInst &I) {
2364 IRBuilder<> IRB(&I);
2365 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2366 "_msprop_ptrtoint"));
2367 setOrigin(&I, getOrigin(&I, 0));
2368 }
2369
2370 void visitIntToPtrInst(IntToPtrInst &I) {
2371 IRBuilder<> IRB(&I);
2372 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2373 "_msprop_inttoptr"));
2374 setOrigin(&I, getOrigin(&I, 0));
2375 }
2376
2377 void visitFPToSIInst(CastInst &I) { handleShadowOr(I); }
2378 void visitFPToUIInst(CastInst &I) { handleShadowOr(I); }
2379 void visitSIToFPInst(CastInst &I) { handleShadowOr(I); }
2380 void visitUIToFPInst(CastInst &I) { handleShadowOr(I); }
2381 void visitFPExtInst(CastInst &I) { handleShadowOr(I); }
2382 void visitFPTruncInst(CastInst &I) { handleShadowOr(I); }
2383
2384 /// Propagate shadow for bitwise AND.
2385 ///
2386 /// This code is exact, i.e. if, for example, a bit in the left argument
2387 /// is defined and 0, then neither the value not definedness of the
2388 /// corresponding bit in B don't affect the resulting shadow.
2389 void visitAnd(BinaryOperator &I) {
2390 IRBuilder<> IRB(&I);
2391 // "And" of 0 and a poisoned value results in unpoisoned value.
2392 // 1&1 => 1; 0&1 => 0; p&1 => p;
2393 // 1&0 => 0; 0&0 => 0; p&0 => 0;
2394 // 1&p => p; 0&p => 0; p&p => p;
2395 // S = (S1 & S2) | (V1 & S2) | (S1 & V2)
2396 Value *S1 = getShadow(&I, 0);
2397 Value *S2 = getShadow(&I, 1);
2398 Value *V1 = I.getOperand(0);
2399 Value *V2 = I.getOperand(1);
2400 if (V1->getType() != S1->getType()) {
2401 V1 = IRB.CreateIntCast(V1, S1->getType(), false);
2402 V2 = IRB.CreateIntCast(V2, S2->getType(), false);
2403 }
2404 Value *S1S2 = IRB.CreateAnd(S1, S2);
2405 Value *V1S2 = IRB.CreateAnd(V1, S2);
2406 Value *S1V2 = IRB.CreateAnd(S1, V2);
2407 setShadow(&I, IRB.CreateOr({S1S2, V1S2, S1V2}));
2408 setOriginForNaryOp(I);
2409 }
2410
2411 void visitOr(BinaryOperator &I) {
2412 IRBuilder<> IRB(&I);
2413 // "Or" of 1 and a poisoned value results in unpoisoned value.
2414 // 1|1 => 1; 0|1 => 1; p|1 => 1;
2415 // 1|0 => 1; 0|0 => 0; p|0 => p;
2416 // 1|p => 1; 0|p => p; p|p => p;
2417 // S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2)
2418 Value *S1 = getShadow(&I, 0);
2419 Value *S2 = getShadow(&I, 1);
2420 Value *V1 = IRB.CreateNot(I.getOperand(0));
2421 Value *V2 = IRB.CreateNot(I.getOperand(1));
2422 if (V1->getType() != S1->getType()) {
2423 V1 = IRB.CreateIntCast(V1, S1->getType(), false);
2424 V2 = IRB.CreateIntCast(V2, S2->getType(), false);
2425 }
2426 Value *S1S2 = IRB.CreateAnd(S1, S2);
2427 Value *V1S2 = IRB.CreateAnd(V1, S2);
2428 Value *S1V2 = IRB.CreateAnd(S1, V2);
2429 setShadow(&I, IRB.CreateOr({S1S2, V1S2, S1V2}));
2430 setOriginForNaryOp(I);
2431 }
2432
2433 /// Default propagation of shadow and/or origin.
2434 ///
2435 /// This class implements the general case of shadow propagation, used in all
2436 /// cases where we don't know and/or don't care about what the operation
2437 /// actually does. It converts all input shadow values to a common type
2438 /// (extending or truncating as necessary), and bitwise OR's them.
2439 ///
2440 /// This is much cheaper than inserting checks (i.e. requiring inputs to be
2441 /// fully initialized), and less prone to false positives.
2442 ///
2443 /// This class also implements the general case of origin propagation. For a
2444 /// Nary operation, result origin is set to the origin of an argument that is
2445 /// not entirely initialized. If there is more than one such arguments, the
2446 /// rightmost of them is picked. It does not matter which one is picked if all
2447 /// arguments are initialized.
2448 template <bool CombineShadow> class Combiner {
2449 Value *Shadow = nullptr;
2450 Value *Origin = nullptr;
2451 IRBuilder<> &IRB;
2452 MemorySanitizerVisitor *MSV;
2453
2454 public:
2455 Combiner(MemorySanitizerVisitor *MSV, IRBuilder<> &IRB)
2456 : IRB(IRB), MSV(MSV) {}
2457
2458 /// Add a pair of shadow and origin values to the mix.
2459 Combiner &Add(Value *OpShadow, Value *OpOrigin) {
2460 if (CombineShadow) {
2461 assert(OpShadow);
2462 if (!Shadow)
2463 Shadow = OpShadow;
2464 else {
2465 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2466 Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop");
2467 }
2468 }
2469
2470 if (MSV->MS.TrackOrigins) {
2471 assert(OpOrigin);
2472 if (!Origin) {
2473 Origin = OpOrigin;
2474 } else {
2475 Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
2476 // No point in adding something that might result in 0 origin value.
2477 if (!ConstOrigin || !ConstOrigin->isNullValue()) {
2478 Value *Cond = MSV->convertToBool(OpShadow, IRB);
2479 Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
2480 }
2481 }
2482 }
2483 return *this;
2484 }
2485
2486 /// Add an application value to the mix.
2487 Combiner &Add(Value *V) {
2488 Value *OpShadow = MSV->getShadow(V);
2489 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : nullptr;
2490 return Add(OpShadow, OpOrigin);
2491 }
2492
2493 /// Set the current combined values as the given instruction's shadow
2494 /// and origin.
2495 void Done(Instruction *I) {
2496 if (CombineShadow) {
2497 assert(Shadow);
2498 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
2499 MSV->setShadow(I, Shadow);
2500 }
2501 if (MSV->MS.TrackOrigins) {
2502 assert(Origin);
2503 MSV->setOrigin(I, Origin);
2504 }
2505 }
2506
2507 /// Store the current combined value at the specified origin
2508 /// location.
2509 void DoneAndStoreOrigin(TypeSize TS, Value *OriginPtr) {
2510 if (MSV->MS.TrackOrigins) {
2511 assert(Origin);
2512 MSV->paintOrigin(IRB, Origin, OriginPtr, TS, kMinOriginAlignment);
2513 }
2514 }
2515 };
2516
2517 using ShadowAndOriginCombiner = Combiner<true>;
2518 using OriginCombiner = Combiner<false>;
2519
2520 /// Propagate origin for arbitrary operation.
2521 void setOriginForNaryOp(Instruction &I) {
2522 if (!MS.TrackOrigins)
2523 return;
2524 IRBuilder<> IRB(&I);
2525 OriginCombiner OC(this, IRB);
2526 for (Use &Op : I.operands())
2527 OC.Add(Op.get());
2528 OC.Done(&I);
2529 }
2530
2531 size_t VectorOrPrimitiveTypeSizeInBits(Type *Ty) {
2532 assert(!(Ty->isVectorTy() && Ty->getScalarType()->isPointerTy()) &&
2533 "Vector of pointers is not a valid shadow type");
2534 return Ty->isVectorTy() ? cast<FixedVectorType>(Ty)->getNumElements() *
2536 : Ty->getPrimitiveSizeInBits();
2537 }
2538
2539 /// Cast between two shadow types, extending or truncating as
2540 /// necessary.
2541 Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
2542 bool Signed = false) {
2543 Type *srcTy = V->getType();
2544 if (srcTy == dstTy)
2545 return V;
2546 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2547 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2548 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2549 return IRB.CreateICmpNE(V, getCleanShadow(V));
2550
2551 if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
2552 return IRB.CreateIntCast(V, dstTy, Signed);
2553 if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
2554 cast<VectorType>(dstTy)->getElementCount() ==
2555 cast<VectorType>(srcTy)->getElementCount())
2556 return IRB.CreateIntCast(V, dstTy, Signed);
2557 Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
2558 Value *V2 =
2559 IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
2560 return IRB.CreateBitCast(V2, dstTy);
2561 // TODO: handle struct types.
2562 }
2563
2564 /// Cast an application value to the type of its own shadow.
2565 Value *CreateAppToShadowCast(IRBuilder<> &IRB, Value *V) {
2566 Type *ShadowTy = getShadowTy(V);
2567 if (V->getType() == ShadowTy)
2568 return V;
2569 if (V->getType()->isPtrOrPtrVectorTy())
2570 return IRB.CreatePtrToInt(V, ShadowTy);
2571 else
2572 return IRB.CreateBitCast(V, ShadowTy);
2573 }
2574
2575 /// Propagate shadow for arbitrary operation.
2576 void handleShadowOr(Instruction &I) {
2577 IRBuilder<> IRB(&I);
2578 ShadowAndOriginCombiner SC(this, IRB);
2579 for (Use &Op : I.operands())
2580 SC.Add(Op.get());
2581 SC.Done(&I);
2582 }
2583
2584 void visitFNeg(UnaryOperator &I) { handleShadowOr(I); }
2585
2586 // Handle multiplication by constant.
2587 //
2588 // Handle a special case of multiplication by constant that may have one or
2589 // more zeros in the lower bits. This makes corresponding number of lower bits
2590 // of the result zero as well. We model it by shifting the other operand
2591 // shadow left by the required number of bits. Effectively, we transform
2592 // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B).
2593 // We use multiplication by 2**N instead of shift to cover the case of
2594 // multiplication by 0, which may occur in some elements of a vector operand.
2595 void handleMulByConstant(BinaryOperator &I, Constant *ConstArg,
2596 Value *OtherArg) {
2597 Constant *ShadowMul;
2598 Type *Ty = ConstArg->getType();
2599 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
2600 unsigned NumElements = cast<FixedVectorType>(VTy)->getNumElements();
2601 Type *EltTy = VTy->getElementType();
2603 for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
2604 if (ConstantInt *Elt =
2605 dyn_cast<ConstantInt>(ConstArg->getAggregateElement(Idx))) {
2606 const APInt &V = Elt->getValue();
2607 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
2608 Elements.push_back(ConstantInt::get(EltTy, V2));
2609 } else {
2610 Elements.push_back(ConstantInt::get(EltTy, 1));
2611 }
2612 }
2613 ShadowMul = ConstantVector::get(Elements);
2614 } else {
2615 if (ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg)) {
2616 const APInt &V = Elt->getValue();
2617 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
2618 ShadowMul = ConstantInt::get(Ty, V2);
2619 } else {
2620 ShadowMul = ConstantInt::get(Ty, 1);
2621 }
2622 }
2623
2624 IRBuilder<> IRB(&I);
2625 setShadow(&I,
2626 IRB.CreateMul(getShadow(OtherArg), ShadowMul, "msprop_mul_cst"));
2627 setOrigin(&I, getOrigin(OtherArg));
2628 }
2629
2630 void visitMul(BinaryOperator &I) {
2631 Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
2632 Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
2633 if (constOp0 && !constOp1)
2634 handleMulByConstant(I, constOp0, I.getOperand(1));
2635 else if (constOp1 && !constOp0)
2636 handleMulByConstant(I, constOp1, I.getOperand(0));
2637 else
2638 handleShadowOr(I);
2639 }
2640
2641 void visitFAdd(BinaryOperator &I) { handleShadowOr(I); }
2642 void visitFSub(BinaryOperator &I) { handleShadowOr(I); }
2643 void visitFMul(BinaryOperator &I) { handleShadowOr(I); }
2644 void visitAdd(BinaryOperator &I) { handleShadowOr(I); }
2645 void visitSub(BinaryOperator &I) { handleShadowOr(I); }
2646 void visitXor(BinaryOperator &I) { handleShadowOr(I); }
2647
2648 void handleIntegerDiv(Instruction &I) {
2649 IRBuilder<> IRB(&I);
2650 // Strict on the second argument.
2651 insertShadowCheck(I.getOperand(1), &I);
2652 setShadow(&I, getShadow(&I, 0));
2653 setOrigin(&I, getOrigin(&I, 0));
2654 }
2655
2656 void visitUDiv(BinaryOperator &I) { handleIntegerDiv(I); }
2657 void visitSDiv(BinaryOperator &I) { handleIntegerDiv(I); }
2658 void visitURem(BinaryOperator &I) { handleIntegerDiv(I); }
2659 void visitSRem(BinaryOperator &I) { handleIntegerDiv(I); }
2660
2661 // Floating point division is side-effect free. We can not require that the
2662 // divisor is fully initialized and must propagate shadow. See PR37523.
2663 void visitFDiv(BinaryOperator &I) { handleShadowOr(I); }
2664 void visitFRem(BinaryOperator &I) { handleShadowOr(I); }
2665
2666 /// Instrument == and != comparisons.
2667 ///
2668 /// Sometimes the comparison result is known even if some of the bits of the
2669 /// arguments are not.
2670 void handleEqualityComparison(ICmpInst &I) {
2671 IRBuilder<> IRB(&I);
2672 Value *A = I.getOperand(0);
2673 Value *B = I.getOperand(1);
2674 Value *Sa = getShadow(A);
2675 Value *Sb = getShadow(B);
2676
2677 // Get rid of pointers and vectors of pointers.
2678 // For ints (and vectors of ints), types of A and Sa match,
2679 // and this is a no-op.
2680 A = IRB.CreatePointerCast(A, Sa->getType());
2681 B = IRB.CreatePointerCast(B, Sb->getType());
2682
2683 // A == B <==> (C = A^B) == 0
2684 // A != B <==> (C = A^B) != 0
2685 // Sc = Sa | Sb
2686 Value *C = IRB.CreateXor(A, B);
2687 Value *Sc = IRB.CreateOr(Sa, Sb);
2688 // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
2689 // Result is defined if one of the following is true
2690 // * there is a defined 1 bit in C
2691 // * C is fully defined
2692 // Si = !(C & ~Sc) && Sc
2694 Value *MinusOne = Constant::getAllOnesValue(Sc->getType());
2695 Value *LHS = IRB.CreateICmpNE(Sc, Zero);
2696 Value *RHS =
2697 IRB.CreateICmpEQ(IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero);
2698 Value *Si = IRB.CreateAnd(LHS, RHS);
2699 Si->setName("_msprop_icmp");
2700 setShadow(&I, Si);
2701 setOriginForNaryOp(I);
2702 }
2703
2704 /// Build the lowest possible value of V, taking into account V's
2705 /// uninitialized bits.
2706 Value *getLowestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
2707 bool isSigned) {
2708 if (isSigned) {
2709 // Split shadow into sign bit and other bits.
2710 Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
2711 Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
2712 // Maximise the undefined shadow bit, minimize other undefined bits.
2713 return IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaOtherBits)),
2714 SaSignBit);
2715 } else {
2716 // Minimize undefined bits.
2717 return IRB.CreateAnd(A, IRB.CreateNot(Sa));
2718 }
2719 }
2720
2721 /// Build the highest possible value of V, taking into account V's
2722 /// uninitialized bits.
2723 Value *getHighestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
2724 bool isSigned) {
2725 if (isSigned) {
2726 // Split shadow into sign bit and other bits.
2727 Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
2728 Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
2729 // Minimise the undefined shadow bit, maximise other undefined bits.
2730 return IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaSignBit)),
2731 SaOtherBits);
2732 } else {
2733 // Maximize undefined bits.
2734 return IRB.CreateOr(A, Sa);
2735 }
2736 }
2737
2738 /// Instrument relational comparisons.
2739 ///
2740 /// This function does exact shadow propagation for all relational
2741 /// comparisons of integers, pointers and vectors of those.
2742 /// FIXME: output seems suboptimal when one of the operands is a constant
2743 void handleRelationalComparisonExact(ICmpInst &I) {
2744 IRBuilder<> IRB(&I);
2745 Value *A = I.getOperand(0);
2746 Value *B = I.getOperand(1);
2747 Value *Sa = getShadow(A);
2748 Value *Sb = getShadow(B);
2749
2750 // Get rid of pointers and vectors of pointers.
2751 // For ints (and vectors of ints), types of A and Sa match,
2752 // and this is a no-op.
2753 A = IRB.CreatePointerCast(A, Sa->getType());
2754 B = IRB.CreatePointerCast(B, Sb->getType());
2755
2756 // Let [a0, a1] be the interval of possible values of A, taking into account
2757 // its undefined bits. Let [b0, b1] be the interval of possible values of B.
2758 // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
2759 bool IsSigned = I.isSigned();
2760 Value *S1 = IRB.CreateICmp(I.getPredicate(),
2761 getLowestPossibleValue(IRB, A, Sa, IsSigned),
2762 getHighestPossibleValue(IRB, B, Sb, IsSigned));
2763 Value *S2 = IRB.CreateICmp(I.getPredicate(),
2764 getHighestPossibleValue(IRB, A, Sa, IsSigned),
2765 getLowestPossibleValue(IRB, B, Sb, IsSigned));
2766 Value *Si = IRB.CreateXor(S1, S2);
2767 setShadow(&I, Si);
2768 setOriginForNaryOp(I);
2769 }
2770
2771 /// Instrument signed relational comparisons.
2772 ///
2773 /// Handle sign bit tests: x<0, x>=0, x<=-1, x>-1 by propagating the highest
2774 /// bit of the shadow. Everything else is delegated to handleShadowOr().
2775 void handleSignedRelationalComparison(ICmpInst &I) {
2776 Constant *constOp;
2777 Value *op = nullptr;
2779 if ((constOp = dyn_cast<Constant>(I.getOperand(1)))) {
2780 op = I.getOperand(0);
2781 pre = I.getPredicate();
2782 } else if ((constOp = dyn_cast<Constant>(I.getOperand(0)))) {
2783 op = I.getOperand(1);
2784 pre = I.getSwappedPredicate();
2785 } else {
2786 handleShadowOr(I);
2787 return;
2788 }
2789
2790 if ((constOp->isNullValue() &&
2791 (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) ||
2792 (constOp->isAllOnesValue() &&
2793 (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE))) {
2794 IRBuilder<> IRB(&I);
2795 Value *Shadow = IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op),
2796 "_msprop_icmp_s");
2797 setShadow(&I, Shadow);
2798 setOrigin(&I, getOrigin(op));
2799 } else {
2800 handleShadowOr(I);
2801 }
2802 }
2803
2804 void visitICmpInst(ICmpInst &I) {
2805 if (!ClHandleICmp) {
2806 handleShadowOr(I);
2807 return;
2808 }
2809 if (I.isEquality()) {
2810 handleEqualityComparison(I);
2811 return;
2812 }
2813
2814 assert(I.isRelational());
2815 if (ClHandleICmpExact) {
2816 handleRelationalComparisonExact(I);
2817 return;
2818 }
2819 if (I.isSigned()) {
2820 handleSignedRelationalComparison(I);
2821 return;
2822 }
2823
2824 assert(I.isUnsigned());
2825 if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
2826 handleRelationalComparisonExact(I);
2827 return;
2828 }
2829
2830 handleShadowOr(I);
2831 }
2832
2833 void visitFCmpInst(FCmpInst &I) { handleShadowOr(I); }
2834
2835 void handleShift(BinaryOperator &I) {
2836 IRBuilder<> IRB(&I);
2837 // If any of the S2 bits are poisoned, the whole thing is poisoned.
2838 // Otherwise perform the same shift on S1.
2839 Value *S1 = getShadow(&I, 0);
2840 Value *S2 = getShadow(&I, 1);
2841 Value *S2Conv =
2842 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
2843 Value *V2 = I.getOperand(1);
2844 Value *Shift = IRB.CreateBinOp(I.getOpcode(), S1, V2);
2845 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
2846 setOriginForNaryOp(I);
2847 }
2848
2849 void visitShl(BinaryOperator &I) { handleShift(I); }
2850 void visitAShr(BinaryOperator &I) { handleShift(I); }
2851 void visitLShr(BinaryOperator &I) { handleShift(I); }
2852
2853 void handleFunnelShift(IntrinsicInst &I) {
2854 IRBuilder<> IRB(&I);
2855 // If any of the S2 bits are poisoned, the whole thing is poisoned.
2856 // Otherwise perform the same shift on S0 and S1.
2857 Value *S0 = getShadow(&I, 0);
2858 Value *S1 = getShadow(&I, 1);
2859 Value *S2 = getShadow(&I, 2);
2860 Value *S2Conv =
2861 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
2862 Value *V2 = I.getOperand(2);
2864 I.getModule(), I.getIntrinsicID(), S2Conv->getType());
2865 Value *Shift = IRB.CreateCall(Intrin, {S0, S1, V2});
2866 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
2867 setOriginForNaryOp(I);
2868 }
2869
2870 /// Instrument llvm.memmove
2871 ///
2872 /// At this point we don't know if llvm.memmove will be inlined or not.
2873 /// If we don't instrument it and it gets inlined,
2874 /// our interceptor will not kick in and we will lose the memmove.
2875 /// If we instrument the call here, but it does not get inlined,
2876 /// we will memove the shadow twice: which is bad in case
2877 /// of overlapping regions. So, we simply lower the intrinsic to a call.
2878 ///
2879 /// Similar situation exists for memcpy and memset.
2880 void visitMemMoveInst(MemMoveInst &I) {
2881 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
2882 IRBuilder<> IRB(&I);
2883 IRB.CreateCall(MS.MemmoveFn,
2884 {I.getArgOperand(0), I.getArgOperand(1),
2885 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2886 I.eraseFromParent();
2887 }
2888
2889 /// Instrument memcpy
2890 ///
2891 /// Similar to memmove: avoid copying shadow twice. This is somewhat
2892 /// unfortunate as it may slowdown small constant memcpys.
2893 /// FIXME: consider doing manual inline for small constant sizes and proper
2894 /// alignment.
2895 ///
2896 /// Note: This also handles memcpy.inline, which promises no calls to external
2897 /// functions as an optimization. However, with instrumentation enabled this
2898 /// is difficult to promise; additionally, we know that the MSan runtime
2899 /// exists and provides __msan_memcpy(). Therefore, we assume that with
2900 /// instrumentation it's safe to turn memcpy.inline into a call to
2901 /// __msan_memcpy(). Should this be wrong, such as when implementing memcpy()
2902 /// itself, instrumentation should be disabled with the no_sanitize attribute.
2903 void visitMemCpyInst(MemCpyInst &I) {
2904 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
2905 IRBuilder<> IRB(&I);
2906 IRB.CreateCall(MS.MemcpyFn,
2907 {I.getArgOperand(0), I.getArgOperand(1),
2908 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2909 I.eraseFromParent();
2910 }
2911
2912 // Same as memcpy.
2913 void visitMemSetInst(MemSetInst &I) {
2914 IRBuilder<> IRB(&I);
2915 IRB.CreateCall(
2916 MS.MemsetFn,
2917 {I.getArgOperand(0),
2918 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
2919 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2920 I.eraseFromParent();
2921 }
2922
2923 void visitVAStartInst(VAStartInst &I) { VAHelper->visitVAStartInst(I); }
2924
2925 void visitVACopyInst(VACopyInst &I) { VAHelper->visitVACopyInst(I); }
2926
2927 /// Handle vector store-like intrinsics.
2928 ///
2929 /// Instrument intrinsics that look like a simple SIMD store: writes memory,
2930 /// has 1 pointer argument and 1 vector argument, returns void.
2931 bool handleVectorStoreIntrinsic(IntrinsicInst &I) {
2932 IRBuilder<> IRB(&I);
2933 Value *Addr = I.getArgOperand(0);
2934 Value *Shadow = getShadow(&I, 1);
2935 Value *ShadowPtr, *OriginPtr;
2936
2937 // We don't know the pointer alignment (could be unaligned SSE store!).
2938 // Have to assume to worst case.
2939 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
2940 Addr, IRB, Shadow->getType(), Align(1), /*isStore*/ true);
2941 IRB.CreateAlignedStore(Shadow, ShadowPtr, Align(1));
2942
2944 insertShadowCheck(Addr, &I);
2945
2946 // FIXME: factor out common code from materializeStores
2947 if (MS.TrackOrigins)
2948 IRB.CreateStore(getOrigin(&I, 1), OriginPtr);
2949 return true;
2950 }
2951
2952 /// Handle vector load-like intrinsics.
2953 ///
2954 /// Instrument intrinsics that look like a simple SIMD load: reads memory,
2955 /// has 1 pointer argument, returns a vector.
2956 bool handleVectorLoadIntrinsic(IntrinsicInst &I) {
2957 IRBuilder<> IRB(&I);
2958 Value *Addr = I.getArgOperand(0);
2959
2960 Type *ShadowTy = getShadowTy(&I);
2961 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
2962 if (PropagateShadow) {
2963 // We don't know the pointer alignment (could be unaligned SSE load!).
2964 // Have to assume to worst case.
2965 const Align Alignment = Align(1);
2966 std::tie(ShadowPtr, OriginPtr) =
2967 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
2968 setShadow(&I,
2969 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2970 } else {
2971 setShadow(&I, getCleanShadow(&I));
2972 }
2973
2975 insertShadowCheck(Addr, &I);
2976
2977 if (MS.TrackOrigins) {
2978 if (PropagateShadow)
2979 setOrigin(&I, IRB.CreateLoad(MS.OriginTy, OriginPtr));
2980 else
2981 setOrigin(&I, getCleanOrigin());
2982 }
2983 return true;
2984 }
2985
2986 /// Handle (SIMD arithmetic)-like intrinsics.
2987 ///
2988 /// Instrument intrinsics with any number of arguments of the same type,
2989 /// equal to the return type. The type should be simple (no aggregates or
2990 /// pointers; vectors are fine).
2991 /// Caller guarantees that this intrinsic does not access memory.
2992 bool maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I) {
2993 Type *RetTy = I.getType();
2994 if (!(RetTy->isIntOrIntVectorTy() || RetTy->isFPOrFPVectorTy()))
2995 return false;
2996
2997 unsigned NumArgOperands = I.arg_size();
2998 for (unsigned i = 0; i < NumArgOperands; ++i) {
2999 Type *Ty = I.getArgOperand(i)->getType();
3000 if (Ty != RetTy)
3001 return false;
3002 }
3003
3004 IRBuilder<> IRB(&I);
3005 ShadowAndOriginCombiner SC(this, IRB);
3006 for (unsigned i = 0; i < NumArgOperands; ++i)
3007 SC.Add(I.getArgOperand(i));
3008 SC.Done(&I);
3009
3010 return true;
3011 }
3012
3013 /// Heuristically instrument unknown intrinsics.
3014 ///
3015 /// The main purpose of this code is to do something reasonable with all
3016 /// random intrinsics we might encounter, most importantly - SIMD intrinsics.
3017 /// We recognize several classes of intrinsics by their argument types and
3018 /// ModRefBehaviour and apply special instrumentation when we are reasonably
3019 /// sure that we know what the intrinsic does.
3020 ///
3021 /// We special-case intrinsics where this approach fails. See llvm.bswap
3022 /// handling as an example of that.
3023 bool handleUnknownIntrinsic(IntrinsicInst &I) {
3024 unsigned NumArgOperands = I.arg_size();
3025 if (NumArgOperands == 0)
3026 return false;
3027
3028 if (NumArgOperands == 2 && I.getArgOperand(0)->getType()->isPointerTy() &&
3029 I.getArgOperand(1)->getType()->isVectorTy() &&
3030 I.getType()->isVoidTy() && !I.onlyReadsMemory()) {
3031 // This looks like a vector store.
3032 return handleVectorStoreIntrinsic(I);
3033 }
3034
3035 if (NumArgOperands == 1 && I.getArgOperand(0)->getType()->isPointerTy() &&
3036 I.getType()->isVectorTy() && I.onlyReadsMemory()) {
3037 // This looks like a vector load.
3038 return handleVectorLoadIntrinsic(I);
3039 }
3040
3041 if (I.doesNotAccessMemory())
3042 if (maybeHandleSimpleNomemIntrinsic(I))
3043 return true;
3044
3045 // FIXME: detect and handle SSE maskstore/maskload
3046 return false;
3047 }
3048
3049 void handleInvariantGroup(IntrinsicInst &I) {
3050 setShadow(&I, getShadow(&I, 0));
3051 setOrigin(&I, getOrigin(&I, 0));
3052 }
3053
3054 void handleLifetimeStart(IntrinsicInst &I) {
3055 if (!PoisonStack)
3056 return;
3057 AllocaInst *AI = llvm::findAllocaForValue(I.getArgOperand(1));
3058 if (!AI)
3059 InstrumentLifetimeStart = false;
3060 LifetimeStartList.push_back(std::make_pair(&I, AI));
3061 }
3062
3063 void handleBswap(IntrinsicInst &I) {
3064 IRBuilder<> IRB(&I);
3065 Value *Op = I.getArgOperand(0);
3066 Type *OpType = Op->getType();
3068 F.getParent(), Intrinsic::bswap, ArrayRef(&OpType, 1));
3069 setShadow(&I, IRB.CreateCall(BswapFunc, getShadow(Op)));
3070 setOrigin(&I, getOrigin(Op));
3071 }
3072
3073 void handleCountZeroes(IntrinsicInst &I) {
3074 IRBuilder<> IRB(&I);
3075 Value *Src = I.getArgOperand(0);
3076
3077 // Set the Output shadow based on input Shadow
3078 Value *BoolShadow = IRB.CreateIsNotNull(getShadow(Src), "_mscz_bs");
3079
3080 // If zero poison is requested, mix in with the shadow
3081 Constant *IsZeroPoison = cast<Constant>(I.getOperand(1));
3082 if (!IsZeroPoison->isZeroValue()) {
3083 Value *BoolZeroPoison = IRB.CreateIsNull(Src, "_mscz_bzp");
3084 BoolShadow = IRB.CreateOr(BoolShadow, BoolZeroPoison, "_mscz_bs");
3085 }
3086
3087 Value *OutputShadow =
3088 IRB.CreateSExt(BoolShadow, getShadowTy(Src), "_mscz_os");
3089
3090 setShadow(&I, OutputShadow);
3091 setOriginForNaryOp(I);
3092 }
3093
3094 // Instrument vector convert intrinsic.
3095 //
3096 // This function instruments intrinsics like cvtsi2ss:
3097 // %Out = int_xxx_cvtyyy(%ConvertOp)
3098 // or
3099 // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp)
3100 // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same
3101 // number \p Out elements, and (if has 2 arguments) copies the rest of the
3102 // elements from \p CopyOp.
3103 // In most cases conversion involves floating-point value which may trigger a
3104 // hardware exception when not fully initialized. For this reason we require
3105 // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise.
3106 // We copy the shadow of \p CopyOp[NumUsedElements:] to \p
3107 // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
3108 // return a fully initialized value.
3109 void handleVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
3110 bool HasRoundingMode = false) {
3111 IRBuilder<> IRB(&I);
3112 Value *CopyOp, *ConvertOp;
3113
3114 assert((!HasRoundingMode ||
3115 isa<ConstantInt>(I.getArgOperand(I.arg_size() - 1))) &&
3116 "Invalid rounding mode");
3117
3118 switch (I.arg_size() - HasRoundingMode) {
3119 case 2:
3120 CopyOp = I.getArgOperand(0);
3121 ConvertOp = I.getArgOperand(1);
3122 break;
3123 case 1:
3124 ConvertOp = I.getArgOperand(0);
3125 CopyOp = nullptr;
3126 break;
3127 default:
3128 llvm_unreachable("Cvt intrinsic with unsupported number of arguments.");
3129 }
3130
3131 // The first *NumUsedElements* elements of ConvertOp are converted to the
3132 // same number of output elements. The rest of the output is copied from
3133 // CopyOp, or (if not available) filled with zeroes.
3134 // Combine shadow for elements of ConvertOp that are used in this operation,
3135 // and insert a check.
3136 // FIXME: consider propagating shadow of ConvertOp, at least in the case of
3137 // int->any conversion.
3138 Value *ConvertShadow = getShadow(ConvertOp);
3139 Value *AggShadow = nullptr;
3140 if (ConvertOp->getType()->isVectorTy()) {
3141 AggShadow = IRB.CreateExtractElement(
3142 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
3143 for (int i = 1; i < NumUsedElements; ++i) {
3144 Value *MoreShadow = IRB.CreateExtractElement(
3145 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), i));
3146 AggShadow = IRB.CreateOr(AggShadow, MoreShadow);
3147 }
3148 } else {
3149 AggShadow = ConvertShadow;
3150 }
3151 assert(AggShadow->getType()->isIntegerTy());
3152 insertShadowCheck(AggShadow, getOrigin(ConvertOp), &I);
3153
3154 // Build result shadow by zero-filling parts of CopyOp shadow that come from
3155 // ConvertOp.
3156 if (CopyOp) {
3157 assert(CopyOp->getType() == I.getType());
3158 assert(CopyOp->getType()->isVectorTy());
3159 Value *ResultShadow = getShadow(CopyOp);
3160 Type *EltTy = cast<VectorType>(ResultShadow->getType())->getElementType();
3161 for (int i = 0; i < NumUsedElements; ++i) {
3162 ResultShadow = IRB.CreateInsertElement(
3163 ResultShadow, ConstantInt::getNullValue(EltTy),
3164 ConstantInt::get(IRB.getInt32Ty(), i));
3165 }
3166 setShadow(&I, ResultShadow);
3167 setOrigin(&I, getOrigin(CopyOp));
3168 } else {
3169 setShadow(&I, getCleanShadow(&I));
3170 setOrigin(&I, getCleanOrigin());
3171 }
3172 }
3173
3174 // Given a scalar or vector, extract lower 64 bits (or less), and return all
3175 // zeroes if it is zero, and all ones otherwise.
3176 Value *Lower64ShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3177 if (S->getType()->isVectorTy())
3178 S = CreateShadowCast(IRB, S, IRB.getInt64Ty(), /* Signed */ true);
3179 assert(S->getType()->getPrimitiveSizeInBits() <= 64);
3180 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3181 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3182 }
3183
3184 // Given a vector, extract its first element, and return all
3185 // zeroes if it is zero, and all ones otherwise.
3186 Value *LowerElementShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3187 Value *S1 = IRB.CreateExtractElement(S, (uint64_t)0);
3188 Value *S2 = IRB.CreateICmpNE(S1, getCleanShadow(S1));
3189 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3190 }
3191
3192 Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) {
3193 Type *T = S->getType();
3194 assert(T->isVectorTy());
3195 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3196 return IRB.CreateSExt(S2, T);
3197 }
3198
3199 // Instrument vector shift intrinsic.
3200 //
3201 // This function instruments intrinsics like int_x86_avx2_psll_w.
3202 // Intrinsic shifts %In by %ShiftSize bits.
3203 // %ShiftSize may be a vector. In that case the lower 64 bits determine shift
3204 // size, and the rest is ignored. Behavior is defined even if shift size is
3205 // greater than register (or field) width.
3206 void handleVectorShiftIntrinsic(IntrinsicInst &I, bool Variable) {
3207 assert(I.arg_size() == 2);
3208 IRBuilder<> IRB(&I);
3209 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3210 // Otherwise perform the same shift on S1.
3211 Value *S1 = getShadow(&I, 0);
3212 Value *S2 = getShadow(&I, 1);
3213 Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
3214 : Lower64ShadowExtend(IRB, S2, getShadowTy(&I));
3215 Value *V1 = I.getOperand(0);
3216 Value *V2 = I.getOperand(1);
3217 Value *Shift = IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(),
3218 {IRB.CreateBitCast(S1, V1->getType()), V2});
3219 Shift = IRB.CreateBitCast(Shift, getShadowTy(&I));
3220 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3221 setOriginForNaryOp(I);
3222 }
3223
3224 // Get an MMX-sized vector type.
3225 Type *getMMXVectorTy(unsigned EltSizeInBits) {
3226 const unsigned X86_MMXSizeInBits = 64;
3227 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3228 "Illegal MMX vector element size");
3229 return FixedVectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
3230 X86_MMXSizeInBits / EltSizeInBits);
3231 }
3232
3233 // Returns a signed counterpart for an (un)signed-saturate-and-pack
3234 // intrinsic.
3235 Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
3236 switch (id) {
3237 case Intrinsic::x86_sse2_packsswb_128:
3238 case Intrinsic::x86_sse2_packuswb_128:
3239 return Intrinsic::x86_sse2_packsswb_128;
3240
3241 case Intrinsic::x86_sse2_packssdw_128:
3242 case Intrinsic::x86_sse41_packusdw:
3243 return Intrinsic::x86_sse2_packssdw_128;
3244
3245 case Intrinsic::x86_avx2_packsswb:
3246 case Intrinsic::x86_avx2_packuswb:
3247 return Intrinsic::x86_avx2_packsswb;
3248
3249 case Intrinsic::x86_avx2_packssdw:
3250 case Intrinsic::x86_avx2_packusdw:
3251 return Intrinsic::x86_avx2_packssdw;
3252
3253 case Intrinsic::x86_mmx_packsswb:
3254 case Intrinsic::x86_mmx_packuswb:
3255 return Intrinsic::x86_mmx_packsswb;
3256
3257 case Intrinsic::x86_mmx_packssdw:
3258 return Intrinsic::x86_mmx_packssdw;
3259 default:
3260 llvm_unreachable("unexpected intrinsic id");
3261 }
3262 }
3263
3264 // Instrument vector pack intrinsic.
3265 //
3266 // This function instruments intrinsics like x86_mmx_packsswb, that
3267 // packs elements of 2 input vectors into half as many bits with saturation.
3268 // Shadow is propagated with the signed variant of the same intrinsic applied
3269 // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
3270 // MMXEltSizeInBits is used only for x86mmx arguments.
3271 void handleVectorPackIntrinsic(IntrinsicInst &I,
3272 unsigned MMXEltSizeInBits = 0) {
3273 assert(I.arg_size() == 2);
3274 IRBuilder<> IRB(&I);
3275 Value *S1 = getShadow(&I, 0);
3276 Value *S2 = getShadow(&I, 1);
3277 assert(S1->getType()->isVectorTy());
3278
3279 // SExt and ICmpNE below must apply to individual elements of input vectors.
3280 // In case of x86mmx arguments, cast them to appropriate vector types and
3281 // back.
3282 Type *T =
3283 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) : S1->getType();
3284 if (MMXEltSizeInBits) {
3285 S1 = IRB.CreateBitCast(S1, T);
3286 S2 = IRB.CreateBitCast(S2, T);
3287 }
3288 Value *S1_ext =
3290 Value *S2_ext =
3292 if (MMXEltSizeInBits) {
3293 S1_ext = IRB.CreateBitCast(S1_ext, getMMXVectorTy(64));
3294 S2_ext = IRB.CreateBitCast(S2_ext, getMMXVectorTy(64));
3295 }
3296
3298 F.getParent(), getSignedPackIntrinsic(I.getIntrinsicID()));
3299
3300 Value *S =
3301 IRB.CreateCall(ShadowFn, {S1_ext, S2_ext}, "_msprop_vector_pack");
3302 if (MMXEltSizeInBits)
3303 S = IRB.CreateBitCast(S, getShadowTy(&I));
3304 setShadow(&I, S);
3305 setOriginForNaryOp(I);
3306 }
3307
3308 // Convert `Mask` into `<n x i1>`.
3309 Constant *createDppMask(unsigned Width, unsigned Mask) {
3311 for (auto &M : R) {
3312 M = ConstantInt::getBool(F.getContext(), Mask & 1);
3313 Mask >>= 1;
3314 }
3315 return ConstantVector::get(R);
3316 }
3317
3318 // Calculate output shadow as array of booleans `<n x i1>`, assuming if any
3319 // arg is poisoned, entire dot product is poisoned.
3320 Value *findDppPoisonedOutput(IRBuilder<> &IRB, Value *S, unsigned SrcMask,
3321 unsigned DstMask) {
3322 const unsigned Width =
3323 cast<FixedVectorType>(S->getType())->getNumElements();
3324
3325 S = IRB.CreateSelect(createDppMask(Width, SrcMask), S,
3327 Value *SElem = IRB.CreateOrReduce(S);
3328 Value *IsClean = IRB.CreateIsNull(SElem, "_msdpp");
3329 Value *DstMaskV = createDppMask(Width, DstMask);
3330
3331 return IRB.CreateSelect(
3332 IsClean, Constant::getNullValue(DstMaskV->getType()), DstMaskV);
3333 }
3334
3335 // See `Intel Intrinsics Guide` for `_dp_p*` instructions.
3336 //
3337 // 2 and 4 element versions produce single scalar of dot product, and then
3338 // puts it into elements of output vector, selected by 4 lowest bits of the
3339 // mask. Top 4 bits of the mask control which elements of input to use for dot
3340 // product.
3341 //
3342 // 8 element version mask still has only 4 bit for input, and 4 bit for output
3343 // mask. According to the spec it just operates as 4 element version on first
3344 // 4 elements of inputs and output, and then on last 4 elements of inputs and
3345 // output.
3346 void handleDppIntrinsic(IntrinsicInst &I) {
3347 IRBuilder<> IRB(&I);
3348
3349 Value *S0 = getShadow(&I, 0);
3350 Value *S1 = getShadow(&I, 1);
3351 Value *S = IRB.CreateOr(S0, S1);
3352
3353 const unsigned Width =
3354 cast<FixedVectorType>(S->getType())->getNumElements();
3355 assert(Width == 2 || Width == 4 || Width == 8);
3356
3357 const unsigned Mask = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
3358 const unsigned SrcMask = Mask >> 4;
3359 const unsigned DstMask = Mask & 0xf;
3360
3361 // Calculate shadow as `<n x i1>`.
3362 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3363 if (Width == 8) {
3364 // First 4 elements of shadow are already calculated. `makeDppShadow`
3365 // operats on 32 bit masks, so we can just shift masks, and repeat.
3366 SI1 = IRB.CreateOr(
3367 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3368 }
3369 // Extend to real size of shadow, poisoning either all or none bits of an
3370 // element.
3371 S = IRB.CreateSExt(SI1, S->getType(), "_msdpp");
3372
3373 setShadow(&I, S);
3374 setOriginForNaryOp(I);
3375 }
3376
3377 Value *convertBlendvToSelectMask(IRBuilder<> &IRB, Value *C) {
3378 C = CreateAppToShadowCast(IRB, C);
3379 FixedVectorType *FVT = cast<FixedVectorType>(C->getType());
3380 unsigned ElSize = FVT->getElementType()->getPrimitiveSizeInBits();
3381 C = IRB.CreateAShr(C, ElSize - 1);
3382 FVT = FixedVectorType::get(IRB.getInt1Ty(), FVT->getNumElements());
3383 return IRB.CreateTrunc(C, FVT);
3384 }
3385
3386 // `blendv(f, t, c)` is effectively `select(c[top_bit], t, f)`.
3387 void handleBlendvIntrinsic(IntrinsicInst &I) {
3388 Value *C = I.getOperand(2);
3389 Value *T = I.getOperand(1);
3390 Value *F = I.getOperand(0);
3391
3392 Value *Sc = getShadow(&I, 2);
3393 Value *Oc = MS.TrackOrigins ? getOrigin(C) : nullptr;
3394
3395 {
3396 IRBuilder<> IRB(&I);
3397 // Extract top bit from condition and its shadow.
3398 C = convertBlendvToSelectMask(IRB, C);
3399 Sc = convertBlendvToSelectMask(IRB, Sc);
3400
3401 setShadow(C, Sc);
3402 setOrigin(C, Oc);
3403 }
3404
3405 handleSelectLikeInst(I, C, T, F);
3406 }
3407
3408 // Instrument sum-of-absolute-differences intrinsic.
3409 void handleVectorSadIntrinsic(IntrinsicInst &I, bool IsMMX = false) {
3410 const unsigned SignificantBitsPerResultElement = 16;
3411 Type *ResTy = IsMMX ? IntegerType::get(*MS.C, 64) : I.getType();
3412 unsigned ZeroBitsPerResultElement =
3413 ResTy->getScalarSizeInBits() - SignificantBitsPerResultElement;
3414
3415 IRBuilder<> IRB(&I);
3416 auto *Shadow0 = getShadow(&I, 0);
3417 auto *Shadow1 = getShadow(&I, 1);
3418 Value *S = IRB.CreateOr(Shadow0, Shadow1);
3419 S = IRB.CreateBitCast(S, ResTy);
3420 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
3421 ResTy);
3422 S = IRB.CreateLShr(S, ZeroBitsPerResultElement);
3423 S = IRB.CreateBitCast(S, getShadowTy(&I));
3424 setShadow(&I, S);
3425 setOriginForNaryOp(I);
3426 }
3427
3428 // Instrument multiply-add intrinsic.
3429 void handleVectorPmaddIntrinsic(IntrinsicInst &I,
3430 unsigned MMXEltSizeInBits = 0) {
3431 Type *ResTy =
3432 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits * 2) : I.getType();
3433 IRBuilder<> IRB(&I);
3434 auto *Shadow0 = getShadow(&I, 0);
3435 auto *Shadow1 = getShadow(&I, 1);
3436 Value *S = IRB.CreateOr(Shadow0, Shadow1);
3437 S = IRB.CreateBitCast(S, ResTy);
3438 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
3439 ResTy);
3440 S = IRB.CreateBitCast(S, getShadowTy(&I));
3441 setShadow(&I, S);
3442 setOriginForNaryOp(I);
3443 }
3444
3445 // Instrument compare-packed intrinsic.
3446 // Basically, an or followed by sext(icmp ne 0) to end up with all-zeros or
3447 // all-ones shadow.
3448 void handleVectorComparePackedIntrinsic(IntrinsicInst &I) {
3449 IRBuilder<> IRB(&I);
3450 Type *ResTy = getShadowTy(&I);
3451 auto *Shadow0 = getShadow(&I, 0);
3452 auto *Shadow1 = getShadow(&I, 1);
3453 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
3454 Value *S = IRB.CreateSExt(
3455 IRB.CreateICmpNE(S0, Constant::getNullValue(ResTy)), ResTy);
3456 setShadow(&I, S);
3457 setOriginForNaryOp(I);
3458 }
3459
3460 // Instrument compare-scalar intrinsic.
3461 // This handles both cmp* intrinsics which return the result in the first
3462 // element of a vector, and comi* which return the result as i32.
3463 void handleVectorCompareScalarIntrinsic(IntrinsicInst &I) {
3464 IRBuilder<> IRB(&I);
3465 auto *Shadow0 = getShadow(&I, 0);
3466 auto *Shadow1 = getShadow(&I, 1);
3467 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
3468 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&I));
3469 setShadow(&I, S);
3470 setOriginForNaryOp(I);
3471 }
3472
3473 // Instrument generic vector reduction intrinsics
3474 // by ORing together all their fields.
3475 void handleVectorReduceIntrinsic(IntrinsicInst &I) {
3476 IRBuilder<> IRB(&I);
3477 Value *S = IRB.CreateOrReduce(getShadow(&I, 0));
3478 setShadow(&I, S);
3479 setOrigin(&I, getOrigin(&I, 0));
3480 }
3481
3482 // Instrument vector.reduce.or intrinsic.
3483 // Valid (non-poisoned) set bits in the operand pull low the
3484 // corresponding shadow bits.
3485 void handleVectorReduceOrIntrinsic(IntrinsicInst &I) {
3486 IRBuilder<> IRB(&I);
3487 Value *OperandShadow = getShadow(&I, 0);
3488 Value *OperandUnsetBits = IRB.CreateNot(I.getOperand(0));
3489 Value *OperandUnsetOrPoison = IRB.CreateOr(OperandUnsetBits, OperandShadow);
3490 // Bit N is clean if any field's bit N is 1 and unpoison
3491 Value *OutShadowMask = IRB.CreateAndReduce(OperandUnsetOrPoison);
3492 // Otherwise, it is clean if every field's bit N is unpoison
3493 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
3494 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
3495
3496 setShadow(&I, S);
3497 setOrigin(&I, getOrigin(&I, 0));
3498 }
3499
3500 // Instrument vector.reduce.and intrinsic.
3501 // Valid (non-poisoned) unset bits in the operand pull down the
3502 // corresponding shadow bits.
3503 void handleVectorReduceAndIntrinsic(IntrinsicInst &I) {
3504 IRBuilder<> IRB(&I);
3505 Value *OperandShadow = getShadow(&I, 0);
3506 Value *OperandSetOrPoison = IRB.CreateOr(I.getOperand(0), OperandShadow);
3507 // Bit N is clean if any field's bit N is 0 and unpoison
3508 Value *OutShadowMask = IRB.CreateAndReduce(OperandSetOrPoison);
3509 // Otherwise, it is clean if every field's bit N is unpoison
3510 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
3511 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
3512
3513 setShadow(&I, S);
3514 setOrigin(&I, getOrigin(&I, 0));
3515 }
3516
3517 void handleStmxcsr(IntrinsicInst &I) {
3518 IRBuilder<> IRB(&I);
3519 Value *Addr = I.getArgOperand(0);
3520 Type *Ty = IRB.getInt32Ty();
3521 Value *ShadowPtr =
3522 getShadowOriginPtr(Addr, IRB, Ty, Align(1), /*isStore*/ true).first;
3523
3524 IRB.CreateStore(getCleanShadow(Ty), ShadowPtr);
3525
3527 insertShadowCheck(Addr, &I);
3528 }
3529
3530 void handleLdmxcsr(IntrinsicInst &I) {
3531 if (!InsertChecks)
3532 return;
3533
3534 IRBuilder<> IRB(&I);
3535 Value *Addr = I.getArgOperand(0);
3536 Type *Ty = IRB.getInt32Ty();
3537 const Align Alignment = Align(1);
3538 Value *ShadowPtr, *OriginPtr;
3539 std::tie(ShadowPtr, OriginPtr) =
3540 getShadowOriginPtr(Addr, IRB, Ty, Alignment, /*isStore*/ false);
3541
3543 insertShadowCheck(Addr, &I);
3544
3545 Value *Shadow = IRB.CreateAlignedLoad(Ty, ShadowPtr, Alignment, "_ldmxcsr");
3546 Value *Origin = MS.TrackOrigins ? IRB.CreateLoad(MS.OriginTy, OriginPtr)
3547 : getCleanOrigin();
3548 insertShadowCheck(Shadow, Origin, &I);
3549 }
3550
3551 void handleMaskedExpandLoad(IntrinsicInst &I) {
3552 IRBuilder<> IRB(&I);
3553 Value *Ptr = I.getArgOperand(0);
3554 Value *Mask = I.getArgOperand(1);
3555 Value *PassThru = I.getArgOperand(2);
3556
3558 insertShadowCheck(Ptr, &I);
3559 insertShadowCheck(Mask, &I);
3560 }
3561
3562 if (!PropagateShadow) {
3563 setShadow(&I, getCleanShadow(&I));
3564 setOrigin(&I, getCleanOrigin());
3565 return;
3566 }
3567
3568 Type *ShadowTy = getShadowTy(&I);
3569 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
3570 auto [ShadowPtr, OriginPtr] =
3571 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, {}, /*isStore*/ false);
3572
3573 Value *Shadow = IRB.CreateMaskedExpandLoad(
3574 ShadowTy, ShadowPtr, Mask, getShadow(PassThru), "_msmaskedexpload");
3575
3576 setShadow(&I, Shadow);
3577
3578 // TODO: Store origins.
3579 setOrigin(&I, getCleanOrigin());
3580 }
3581
3582 void handleMaskedCompressStore(IntrinsicInst &I) {
3583 IRBuilder<> IRB(&I);
3584 Value *Values = I.getArgOperand(0);
3585 Value *Ptr = I.getArgOperand(1);
3586 Value *Mask = I.getArgOperand(2);
3587
3589 insertShadowCheck(Ptr, &I);
3590 insertShadowCheck(Mask, &I);
3591 }
3592
3593 Value *Shadow = getShadow(Values);
3594 Type *ElementShadowTy =
3595 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
3596 auto [ShadowPtr, OriginPtrs] =
3597 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, {}, /*isStore*/ true);
3598
3599 IRB.CreateMaskedCompressStore(Shadow, ShadowPtr, Mask);
3600
3601 // TODO: Store origins.
3602 }
3603
3604 void handleMaskedGather(IntrinsicInst &I) {
3605 IRBuilder<> IRB(&I);
3606 Value *Ptrs = I.getArgOperand(0);
3607 const Align Alignment(
3608 cast<ConstantInt>(I.getArgOperand(1))->getZExtValue());
3609 Value *Mask = I.getArgOperand(2);
3610 Value *PassThru = I.getArgOperand(3);
3611
3612 Type *PtrsShadowTy = getShadowTy(Ptrs);
3614 insertShadowCheck(Mask, &I);
3615 Value *MaskedPtrShadow = IRB.CreateSelect(
3616 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
3617 "_msmaskedptrs");
3618 insertShadowCheck(MaskedPtrShadow, getOrigin(Ptrs), &I);
3619 }
3620
3621 if (!PropagateShadow) {
3622 setShadow(&I, getCleanShadow(&I));
3623 setOrigin(&I, getCleanOrigin());
3624 return;
3625 }
3626
3627 Type *ShadowTy = getShadowTy(&I);
3628 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
3629 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
3630 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ false);
3631
3632 Value *Shadow =
3633 IRB.CreateMaskedGather(ShadowTy, ShadowPtrs, Alignment, Mask,
3634 getShadow(PassThru), "_msmaskedgather");
3635
3636 setShadow(&I, Shadow);
3637
3638 // TODO: Store origins.
3639 setOrigin(&I, getCleanOrigin());
3640 }
3641
3642 void handleMaskedScatter(IntrinsicInst &I) {
3643 IRBuilder<> IRB(&I);
3644 Value *Values = I.getArgOperand(0);
3645 Value *Ptrs = I.getArgOperand(1);
3646 const Align Alignment(
3647 cast<ConstantInt>(I.getArgOperand(2))->getZExtValue());
3648 Value *Mask = I.getArgOperand(3);
3649
3650 Type *PtrsShadowTy = getShadowTy(Ptrs);
3652 insertShadowCheck(Mask, &I);
3653 Value *MaskedPtrShadow = IRB.CreateSelect(
3654 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
3655 "_msmaskedptrs");
3656 insertShadowCheck(MaskedPtrShadow, getOrigin(Ptrs), &I);
3657 }
3658
3659 Value *Shadow = getShadow(Values);
3660 Type *ElementShadowTy =
3661 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
3662 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
3663 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ true);
3664
3665 IRB.CreateMaskedScatter(Shadow, ShadowPtrs, Alignment, Mask);
3666
3667 // TODO: Store origin.
3668 }
3669
3670 void handleMaskedStore(IntrinsicInst &I) {
3671 IRBuilder<> IRB(&I);
3672 Value *V = I.getArgOperand(0);
3673 Value *Ptr = I.getArgOperand(1);
3674 const Align Alignment(
3675 cast<ConstantInt>(I.getArgOperand(2))->getZExtValue());
3676 Value *Mask = I.getArgOperand(3);
3677 Value *Shadow = getShadow(V);
3678
3680 insertShadowCheck(Ptr, &I);
3681 insertShadowCheck(Mask, &I);
3682 }
3683
3684 Value *ShadowPtr;
3685 Value *OriginPtr;
3686 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3687 Ptr, IRB, Shadow->getType(), Alignment, /*isStore*/ true);
3688
3689 IRB.CreateMaskedStore(Shadow, ShadowPtr, Alignment, Mask);
3690
3691 if (!MS.TrackOrigins)
3692 return;
3693
3694 auto &DL = F.getDataLayout();
3695 paintOrigin(IRB, getOrigin(V), OriginPtr,
3696 DL.getTypeStoreSize(Shadow->getType()),
3697 std::max(Alignment, kMinOriginAlignment));
3698 }
3699
3700 void handleMaskedLoad(IntrinsicInst &I) {
3701 IRBuilder<> IRB(&I);
3702 Value *Ptr = I.getArgOperand(0);
3703 const Align Alignment(
3704 cast<ConstantInt>(I.getArgOperand(1))->getZExtValue());
3705 Value *Mask = I.getArgOperand(2);
3706 Value *PassThru = I.getArgOperand(3);
3707
3709 insertShadowCheck(Ptr, &I);
3710 insertShadowCheck(Mask, &I);
3711 }
3712
3713 if (!PropagateShadow) {
3714 setShadow(&I, getCleanShadow(&I));
3715 setOrigin(&I, getCleanOrigin());
3716 return;
3717 }
3718
3719 Type *ShadowTy = getShadowTy(&I);
3720 Value *ShadowPtr, *OriginPtr;
3721 std::tie(ShadowPtr, OriginPtr) =
3722 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment, /*isStore*/ false);
3723 setShadow(&I, IRB.CreateMaskedLoad(ShadowTy, ShadowPtr, Alignment, Mask,
3724 getShadow(PassThru), "_msmaskedld"));
3725
3726 if (!MS.TrackOrigins)
3727 return;
3728
3729 // Choose between PassThru's and the loaded value's origins.
3730 Value *MaskedPassThruShadow = IRB.CreateAnd(
3731 getShadow(PassThru), IRB.CreateSExt(IRB.CreateNeg(Mask), ShadowTy));
3732
3733 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB, "_mscmp");
3734
3735 Value *PtrOrigin = IRB.CreateLoad(MS.OriginTy, OriginPtr);
3736 Value *Origin = IRB.CreateSelect(NotNull, getOrigin(PassThru), PtrOrigin);
3737
3738 setOrigin(&I, Origin);
3739 }
3740
3741 // Instrument BMI / BMI2 intrinsics.
3742 // All of these intrinsics are Z = I(X, Y)
3743 // where the types of all operands and the result match, and are either i32 or
3744 // i64. The following instrumentation happens to work for all of them:
3745 // Sz = I(Sx, Y) | (sext (Sy != 0))
3746 void handleBmiIntrinsic(IntrinsicInst &I) {
3747 IRBuilder<> IRB(&I);
3748 Type *ShadowTy = getShadowTy(&I);
3749
3750 // If any bit of the mask operand is poisoned, then the whole thing is.
3751 Value *SMask = getShadow(&I, 1);
3752 SMask = IRB.CreateSExt(IRB.CreateICmpNE(SMask, getCleanShadow(ShadowTy)),
3753 ShadowTy);
3754 // Apply the same intrinsic to the shadow of the first operand.
3755 Value *S = IRB.CreateCall(I.getCalledFunction(),
3756 {getShadow(&I, 0), I.getOperand(1)});
3757 S = IRB.CreateOr(SMask, S);
3758 setShadow(&I, S);
3759 setOriginForNaryOp(I);
3760 }
3761
3762 static SmallVector<int, 8> getPclmulMask(unsigned Width, bool OddElements) {
3764 for (unsigned X = OddElements ? 1 : 0; X < Width; X += 2) {
3765 Mask.append(2, X);
3766 }
3767 return Mask;
3768 }
3769
3770 // Instrument pclmul intrinsics.
3771 // These intrinsics operate either on odd or on even elements of the input
3772 // vectors, depending on the constant in the 3rd argument, ignoring the rest.
3773 // Replace the unused elements with copies of the used ones, ex:
3774 // (0, 1, 2, 3) -> (0, 0, 2, 2) (even case)
3775 // or
3776 // (0, 1, 2, 3) -> (1, 1, 3, 3) (odd case)
3777 // and then apply the usual shadow combining logic.
3778 void handlePclmulIntrinsic(IntrinsicInst &I) {
3779 IRBuilder<> IRB(&I);
3780 unsigned Width =
3781 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
3782 assert(isa<ConstantInt>(I.getArgOperand(2)) &&
3783 "pclmul 3rd operand must be a constant");
3784 unsigned Imm = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
3785 Value *Shuf0 = IRB.CreateShuffleVector(getShadow(&I, 0),
3786 getPclmulMask(Width, Imm & 0x01));
3787 Value *Shuf1 = IRB.CreateShuffleVector(getShadow(&I, 1),
3788 getPclmulMask(Width, Imm & 0x10));
3789 ShadowAndOriginCombiner SOC(this, IRB);
3790 SOC.Add(Shuf0, getOrigin(&I, 0));
3791 SOC.Add(Shuf1, getOrigin(&I, 1));
3792 SOC.Done(&I);
3793 }
3794
3795 // Instrument _mm_*_sd|ss intrinsics
3796 void handleUnarySdSsIntrinsic(IntrinsicInst &I) {
3797 IRBuilder<> IRB(&I);
3798 unsigned Width =
3799 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
3800 Value *First = getShadow(&I, 0);
3801 Value *Second = getShadow(&I, 1);
3802 // First element of second operand, remaining elements of first operand
3804 Mask.push_back(Width);
3805 for (unsigned i = 1; i < Width; i++)
3806 Mask.push_back(i);
3807 Value *Shadow = IRB.CreateShuffleVector(First, Second, Mask);
3808
3809 setShadow(&I, Shadow);
3810 setOriginForNaryOp(I);
3811 }
3812
3813 void handleVtestIntrinsic(IntrinsicInst &I) {
3814 IRBuilder<> IRB(&I);
3815 Value *Shadow0 = getShadow(&I, 0);
3816 Value *Shadow1 = getShadow(&I, 1);
3817 Value *Or = IRB.CreateOr(Shadow0, Shadow1);
3818 Value *NZ = IRB.CreateICmpNE(Or, Constant::getNullValue(Or->getType()));
3819 Value *Scalar = convertShadowToScalar(NZ, IRB);
3820 Value *Shadow = IRB.CreateZExt(Scalar, getShadowTy(&I));
3821
3822 setShadow(&I, Shadow);
3823 setOriginForNaryOp(I);
3824 }
3825
3826 void handleBinarySdSsIntrinsic(IntrinsicInst &I) {
3827 IRBuilder<> IRB(&I);
3828 unsigned Width =
3829 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
3830 Value *First = getShadow(&I, 0);
3831 Value *Second = getShadow(&I, 1);
3832 Value *OrShadow = IRB.CreateOr(First, Second);
3833 // First element of both OR'd together, remaining elements of first operand
3835 Mask.push_back(Width);
3836 for (unsigned i = 1; i < Width; i++)
3837 Mask.push_back(i);
3838 Value *Shadow = IRB.CreateShuffleVector(First, OrShadow, Mask);
3839
3840 setShadow(&I, Shadow);
3841 setOriginForNaryOp(I);
3842 }
3843
3844 // Instrument abs intrinsic.
3845 // handleUnknownIntrinsic can't handle it because of the last
3846 // is_int_min_poison argument which does not match the result type.
3847 void handleAbsIntrinsic(IntrinsicInst &I) {
3848 assert(I.getType()->isIntOrIntVectorTy());
3849 assert(I.getArgOperand(0)->getType() == I.getType());
3850
3851 // FIXME: Handle is_int_min_poison.
3852 IRBuilder<> IRB(&I);
3853 setShadow(&I, getShadow(&I, 0));
3854 setOrigin(&I, getOrigin(&I, 0));
3855 }
3856
3857 void handleIsFpClass(IntrinsicInst &I) {
3858 IRBuilder<> IRB(&I);
3859 Value *Shadow = getShadow(&I, 0);
3860 setShadow(&I, IRB.CreateICmpNE(Shadow, getCleanShadow(Shadow)));
3861 setOrigin(&I, getOrigin(&I, 0));
3862 }
3863
3864 void handleArithmeticWithOverflow(IntrinsicInst &I) {
3865 IRBuilder<> IRB(&I);
3866 Value *Shadow0 = getShadow(&I, 0);
3867 Value *Shadow1 = getShadow(&I, 1);
3868 Value *ShadowElt0 = IRB.CreateOr(Shadow0, Shadow1);
3869 Value *ShadowElt1 =
3870 IRB.CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
3871
3872 Value *Shadow = PoisonValue::get(getShadowTy(&I));
3873 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt0, 0);
3874 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt1, 1);
3875
3876 setShadow(&I, Shadow);
3877 setOriginForNaryOp(I);
3878 }
3879
3880 /// Handle Arm NEON vector store intrinsics (vst{2,3,4}, vst1x_{2,3,4},
3881 /// and vst{2,3,4}lane).
3882 ///
3883 /// Arm NEON vector store intrinsics have the output address (pointer) as the
3884 /// last argument, with the initial arguments being the inputs (and lane
3885 /// number for vst{2,3,4}lane). They return void.
3886 ///
3887 /// - st4 interleaves the output e.g., st4 (inA, inB, inC, inD, outP) writes
3888 /// abcdabcdabcdabcd... into *outP
3889 /// - st1_x4 is non-interleaved e.g., st1_x4 (inA, inB, inC, inD, outP)
3890 /// writes aaaa...bbbb...cccc...dddd... into *outP
3891 /// - st4lane has arguments of (inA, inB, inC, inD, lane, outP)
3892 /// These instructions can all be instrumented with essentially the same
3893 /// MSan logic, simply by applying the corresponding intrinsic to the shadow.
3894 void handleNEONVectorStoreIntrinsic(IntrinsicInst &I, bool useLane) {
3895 IRBuilder<> IRB(&I);
3896
3897 // Don't use getNumOperands() because it includes the callee
3898 int numArgOperands = I.arg_size();
3899
3900 // The last arg operand is the output (pointer)
3901 assert(numArgOperands >= 1);
3902 Value *Addr = I.getArgOperand(numArgOperands - 1);
3903 assert(Addr->getType()->isPointerTy());
3904 int skipTrailingOperands = 1;
3905
3907 insertShadowCheck(Addr, &I);
3908
3909 // Second-last operand is the lane number (for vst{2,3,4}lane)
3910 if (useLane) {
3911 skipTrailingOperands++;
3912 assert(numArgOperands >= static_cast<int>(skipTrailingOperands));
3913 assert(isa<IntegerType>(
3914 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
3915 }
3916
3917 SmallVector<Value *, 8> ShadowArgs;
3918 // All the initial operands are the inputs
3919 for (int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
3920 assert(isa<FixedVectorType>(I.getArgOperand(i)->getType()));
3921 Value *Shadow = getShadow(&I, i);
3922 ShadowArgs.append(1, Shadow);
3923 }
3924
3925 // MSan's GetShadowTy assumes the LHS is the type we want the shadow for
3926 // e.g., for:
3927 // [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to i128
3928 // we know the type of the output (and its shadow) is <16 x i8>.
3929 //
3930 // Arm NEON VST is unusual because the last argument is the output address:
3931 // define void @st2_16b(<16 x i8> %A, <16 x i8> %B, ptr %P) {
3932 // call void @llvm.aarch64.neon.st2.v16i8.p0
3933 // (<16 x i8> [[A]], <16 x i8> [[B]], ptr [[P]])
3934 // and we have no type information about P's operand. We must manually
3935 // compute the type (<16 x i8> x 2).
3936 FixedVectorType *OutputVectorTy = FixedVectorType::get(
3937 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getElementType(),
3938 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements() *
3939 (numArgOperands - skipTrailingOperands));
3940 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
3941
3942 if (useLane)
3943 ShadowArgs.append(1,
3944 I.getArgOperand(numArgOperands - skipTrailingOperands));
3945
3946 Value *OutputShadowPtr, *OutputOriginPtr;
3947 // AArch64 NEON does not need alignment (unless OS requires it)
3948 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
3949 Addr, IRB, OutputShadowTy, Align(1), /*isStore*/ true);
3950 ShadowArgs.append(1, OutputShadowPtr);
3951
3952 CallInst *CI =
3953 IRB.CreateIntrinsic(IRB.getVoidTy(), I.getIntrinsicID(), ShadowArgs);
3954 setShadow(&I, CI);
3955
3956 if (MS.TrackOrigins) {
3957 // TODO: if we modelled the vst* instruction more precisely, we could
3958 // more accurately track the origins (e.g., if both inputs are
3959 // uninitialized for vst2, we currently blame the second input, even
3960 // though part of the output depends only on the first input).
3961 //
3962 // This is particularly imprecise for vst{2,3,4}lane, since only one
3963 // lane of each input is actually copied to the output.
3964 OriginCombiner OC(this, IRB);
3965 for (int i = 0; i < numArgOperands - skipTrailingOperands; i++)
3966 OC.Add(I.getArgOperand(i));
3967
3968 const DataLayout &DL = F.getDataLayout();
3969 OC.DoneAndStoreOrigin(DL.getTypeStoreSize(OutputVectorTy),
3970 OutputOriginPtr);
3971 }
3972 }
3973
3974 void visitIntrinsicInst(IntrinsicInst &I) {
3975 switch (I.getIntrinsicID()) {
3976 case Intrinsic::uadd_with_overflow:
3977 case Intrinsic::sadd_with_overflow:
3978 case Intrinsic::usub_with_overflow:
3979 case Intrinsic::ssub_with_overflow:
3980 case Intrinsic::umul_with_overflow:
3981 case Intrinsic::smul_with_overflow:
3982 handleArithmeticWithOverflow(I);
3983 break;
3984 case Intrinsic::abs:
3985 handleAbsIntrinsic(I);
3986 break;
3987 case Intrinsic::is_fpclass:
3988 handleIsFpClass(I);
3989 break;
3990 case Intrinsic::lifetime_start:
3991 handleLifetimeStart(I);
3992 break;
3993 case Intrinsic::launder_invariant_group:
3994 case Intrinsic::strip_invariant_group:
3995 handleInvariantGroup(I);
3996 break;
3997 case Intrinsic::bswap:
3998 handleBswap(I);
3999 break;
4000 case Intrinsic::ctlz:
4001 case Intrinsic::cttz:
4002 handleCountZeroes(I);
4003 break;
4004 case Intrinsic::masked_compressstore:
4005 handleMaskedCompressStore(I);
4006 break;
4007 case Intrinsic::masked_expandload:
4008 handleMaskedExpandLoad(I);
4009 break;
4010 case Intrinsic::masked_gather:
4011 handleMaskedGather(I);
4012 break;
4013 case Intrinsic::masked_scatter:
4014 handleMaskedScatter(I);
4015 break;
4016 case Intrinsic::masked_store:
4017 handleMaskedStore(I);
4018 break;
4019 case Intrinsic::masked_load:
4020 handleMaskedLoad(I);
4021 break;
4022 case Intrinsic::vector_reduce_and:
4023 handleVectorReduceAndIntrinsic(I);
4024 break;
4025 case Intrinsic::vector_reduce_or:
4026 handleVectorReduceOrIntrinsic(I);
4027 break;
4028 case Intrinsic::vector_reduce_add:
4029 case Intrinsic::vector_reduce_xor:
4030 case Intrinsic::vector_reduce_mul:
4031 handleVectorReduceIntrinsic(I);
4032 break;
4033 case Intrinsic::x86_sse_stmxcsr:
4034 handleStmxcsr(I);
4035 break;
4036 case Intrinsic::x86_sse_ldmxcsr:
4037 handleLdmxcsr(I);
4038 break;
4039 case Intrinsic::x86_avx512_vcvtsd2usi64:
4040 case Intrinsic::x86_avx512_vcvtsd2usi32:
4041 case Intrinsic::x86_avx512_vcvtss2usi64:
4042 case Intrinsic::x86_avx512_vcvtss2usi32:
4043 case Intrinsic::x86_avx512_cvttss2usi64:
4044 case Intrinsic::x86_avx512_cvttss2usi:
4045 case Intrinsic::x86_avx512_cvttsd2usi64:
4046 case Intrinsic::x86_avx512_cvttsd2usi:
4047 case Intrinsic::x86_avx512_cvtusi2ss:
4048 case Intrinsic::x86_avx512_cvtusi642sd:
4049 case Intrinsic::x86_avx512_cvtusi642ss:
4050 handleVectorConvertIntrinsic(I, 1, true);
4051 break;
4052 case Intrinsic::x86_sse2_cvtsd2si64:
4053 case Intrinsic::x86_sse2_cvtsd2si:
4054 case Intrinsic::x86_sse2_cvtsd2ss:
4055 case Intrinsic::x86_sse2_cvttsd2si64:
4056 case Intrinsic::x86_sse2_cvttsd2si:
4057 case Intrinsic::x86_sse_cvtss2si64:
4058 case Intrinsic::x86_sse_cvtss2si:
4059 case Intrinsic::x86_sse_cvttss2si64:
4060 case Intrinsic::x86_sse_cvttss2si:
4061 handleVectorConvertIntrinsic(I, 1);
4062 break;
4063 case Intrinsic::x86_sse_cvtps2pi:
4064 case Intrinsic::x86_sse_cvttps2pi:
4065 handleVectorConvertIntrinsic(I, 2);
4066 break;
4067
4068 case Intrinsic::x86_avx512_psll_w_512:
4069 case Intrinsic::x86_avx512_psll_d_512:
4070 case Intrinsic::x86_avx512_psll_q_512:
4071 case Intrinsic::x86_avx512_pslli_w_512:
4072 case Intrinsic::x86_avx512_pslli_d_512:
4073 case Intrinsic::x86_avx512_pslli_q_512:
4074 case Intrinsic::x86_avx512_psrl_w_512:
4075 case Intrinsic::x86_avx512_psrl_d_512:
4076 case Intrinsic::x86_avx512_psrl_q_512:
4077 case Intrinsic::x86_avx512_psra_w_512:
4078 case Intrinsic::x86_avx512_psra_d_512:
4079 case Intrinsic::x86_avx512_psra_q_512:
4080 case Intrinsic::x86_avx512_psrli_w_512:
4081 case Intrinsic::x86_avx512_psrli_d_512:
4082 case Intrinsic::x86_avx512_psrli_q_512:
4083 case Intrinsic::x86_avx512_psrai_w_512:
4084 case Intrinsic::x86_avx512_psrai_d_512:
4085 case Intrinsic::x86_avx512_psrai_q_512:
4086 case Intrinsic::x86_avx512_psra_q_256:
4087 case Intrinsic::x86_avx512_psra_q_128:
4088 case Intrinsic::x86_avx512_psrai_q_256:
4089 case Intrinsic::x86_avx512_psrai_q_128:
4090 case Intrinsic::x86_avx2_psll_w:
4091 case Intrinsic::x86_avx2_psll_d:
4092 case Intrinsic::x86_avx2_psll_q:
4093 case Intrinsic::x86_avx2_pslli_w:
4094 case Intrinsic::x86_avx2_pslli_d:
4095 case Intrinsic::x86_avx2_pslli_q:
4096 case Intrinsic::x86_avx2_psrl_w:
4097 case Intrinsic::x86_avx2_psrl_d:
4098 case Intrinsic::x86_avx2_psrl_q:
4099 case Intrinsic::x86_avx2_psra_w:
4100 case Intrinsic::x86_avx2_psra_d:
4101 case Intrinsic::x86_avx2_psrli_w:
4102 case Intrinsic::x86_avx2_psrli_d:
4103 case Intrinsic::x86_avx2_psrli_q:
4104 case Intrinsic::x86_avx2_psrai_w:
4105 case Intrinsic::x86_avx2_psrai_d:
4106 case Intrinsic::x86_sse2_psll_w:
4107 case Intrinsic::x86_sse2_psll_d:
4108 case Intrinsic::x86_sse2_psll_q:
4109 case Intrinsic::x86_sse2_pslli_w:
4110 case Intrinsic::x86_sse2_pslli_d:
4111 case Intrinsic::x86_sse2_pslli_q:
4112 case Intrinsic::x86_sse2_psrl_w:
4113 case Intrinsic::x86_sse2_psrl_d:
4114 case Intrinsic::x86_sse2_psrl_q:
4115 case Intrinsic::x86_sse2_psra_w:
4116 case Intrinsic::x86_sse2_psra_d:
4117 case Intrinsic::x86_sse2_psrli_w:
4118 case Intrinsic::x86_sse2_psrli_d:
4119 case Intrinsic::x86_sse2_psrli_q:
4120 case Intrinsic::x86_sse2_psrai_w:
4121 case Intrinsic::x86_sse2_psrai_d:
4122 case Intrinsic::x86_mmx_psll_w:
4123 case Intrinsic::x86_mmx_psll_d:
4124 case Intrinsic::x86_mmx_psll_q:
4125 case Intrinsic::x86_mmx_pslli_w:
4126 case Intrinsic::x86_mmx_pslli_d:
4127 case Intrinsic::x86_mmx_pslli_q:
4128 case Intrinsic::x86_mmx_psrl_w:
4129 case Intrinsic::x86_mmx_psrl_d:
4130 case Intrinsic::x86_mmx_psrl_q:
4131 case Intrinsic::x86_mmx_psra_w:
4132 case Intrinsic::x86_mmx_psra_d:
4133 case Intrinsic::x86_mmx_psrli_w:
4134 case Intrinsic::x86_mmx_psrli_d:
4135 case Intrinsic::x86_mmx_psrli_q:
4136 case Intrinsic::x86_mmx_psrai_w:
4137 case Intrinsic::x86_mmx_psrai_d:
4138 case Intrinsic::aarch64_neon_rshrn:
4139 case Intrinsic::aarch64_neon_sqrshl:
4140 case Intrinsic::aarch64_neon_sqrshrn:
4141 case Intrinsic::aarch64_neon_sqrshrun:
4142 case Intrinsic::aarch64_neon_sqshl:
4143 case Intrinsic::aarch64_neon_sqshlu:
4144 case Intrinsic::aarch64_neon_sqshrn:
4145 case Intrinsic::aarch64_neon_sqshrun:
4146 case Intrinsic::aarch64_neon_srshl:
4147 case Intrinsic::aarch64_neon_sshl:
4148 case Intrinsic::aarch64_neon_uqrshl:
4149 case Intrinsic::aarch64_neon_uqrshrn:
4150 case Intrinsic::aarch64_neon_uqshl:
4151 case Intrinsic::aarch64_neon_uqshrn:
4152 case Intrinsic::aarch64_neon_urshl:
4153 case Intrinsic::aarch64_neon_ushl:
4154 // Not handled here: aarch64_neon_vsli (vector shift left and insert)
4155 handleVectorShiftIntrinsic(I, /* Variable */ false);
4156 break;
4157 case Intrinsic::x86_avx2_psllv_d:
4158 case Intrinsic::x86_avx2_psllv_d_256:
4159 case Intrinsic::x86_avx512_psllv_d_512:
4160 case Intrinsic::x86_avx2_psllv_q:
4161 case Intrinsic::x86_avx2_psllv_q_256:
4162 case Intrinsic::x86_avx512_psllv_q_512:
4163 case Intrinsic::x86_avx2_psrlv_d:
4164 case Intrinsic::x86_avx2_psrlv_d_256:
4165 case Intrinsic::x86_avx512_psrlv_d_512:
4166 case Intrinsic::x86_avx2_psrlv_q:
4167 case Intrinsic::x86_avx2_psrlv_q_256:
4168 case Intrinsic::x86_avx512_psrlv_q_512:
4169 case Intrinsic::x86_avx2_psrav_d:
4170 case Intrinsic::x86_avx2_psrav_d_256:
4171 case Intrinsic::x86_avx512_psrav_d_512:
4172 case Intrinsic::x86_avx512_psrav_q_128:
4173 case Intrinsic::x86_avx512_psrav_q_256:
4174 case Intrinsic::x86_avx512_psrav_q_512:
4175 handleVectorShiftIntrinsic(I, /* Variable */ true);
4176 break;
4177
4178 case Intrinsic::x86_sse2_packsswb_128:
4179 case Intrinsic::x86_sse2_packssdw_128:
4180 case Intrinsic::x86_sse2_packuswb_128:
4181 case Intrinsic::x86_sse41_packusdw:
4182 case Intrinsic::x86_avx2_packsswb:
4183 case Intrinsic::x86_avx2_packssdw:
4184 case Intrinsic::x86_avx2_packuswb:
4185 case Intrinsic::x86_avx2_packusdw:
4186 handleVectorPackIntrinsic(I);
4187 break;
4188
4189 case Intrinsic::x86_sse41_pblendvb:
4190 case Intrinsic::x86_sse41_blendvpd:
4191 case Intrinsic::x86_sse41_blendvps:
4192 case Intrinsic::x86_avx_blendv_pd_256:
4193 case Intrinsic::x86_avx_blendv_ps_256:
4194 case Intrinsic::x86_avx2_pblendvb:
4195 handleBlendvIntrinsic(I);
4196 break;
4197
4198 case Intrinsic::x86_avx_dp_ps_256:
4199 case Intrinsic::x86_sse41_dppd:
4200 case Intrinsic::x86_sse41_dpps:
4201 handleDppIntrinsic(I);
4202 break;
4203
4204 case Intrinsic::x86_mmx_packsswb:
4205 case Intrinsic::x86_mmx_packuswb:
4206 handleVectorPackIntrinsic(I, 16);
4207 break;
4208
4209 case Intrinsic::x86_mmx_packssdw:
4210 handleVectorPackIntrinsic(I, 32);
4211 break;
4212
4213 case Intrinsic::x86_mmx_psad_bw:
4214 handleVectorSadIntrinsic(I, true);
4215 break;
4216 case Intrinsic::x86_sse2_psad_bw:
4217 case Intrinsic::x86_avx2_psad_bw:
4218 handleVectorSadIntrinsic(I);
4219 break;
4220
4221 case Intrinsic::x86_sse2_pmadd_wd:
4222 case Intrinsic::x86_avx2_pmadd_wd:
4223 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
4224 case Intrinsic::x86_avx2_pmadd_ub_sw:
4225 handleVectorPmaddIntrinsic(I);
4226 break;
4227
4228 case Intrinsic::x86_ssse3_pmadd_ub_sw:
4229 handleVectorPmaddIntrinsic(I, 8);
4230 break;
4231
4232 case Intrinsic::x86_mmx_pmadd_wd:
4233 handleVectorPmaddIntrinsic(I, 16);
4234 break;
4235
4236 case Intrinsic::x86_sse_cmp_ss:
4237 case Intrinsic::x86_sse2_cmp_sd:
4238 case Intrinsic::x86_sse_comieq_ss:
4239 case Intrinsic::x86_sse_comilt_ss:
4240 case Intrinsic::x86_sse_comile_ss:
4241 case Intrinsic::x86_sse_comigt_ss:
4242 case Intrinsic::x86_sse_comige_ss:
4243 case Intrinsic::x86_sse_comineq_ss:
4244 case Intrinsic::x86_sse_ucomieq_ss:
4245 case Intrinsic::x86_sse_ucomilt_ss:
4246 case Intrinsic::x86_sse_ucomile_ss:
4247 case Intrinsic::x86_sse_ucomigt_ss:
4248 case Intrinsic::x86_sse_ucomige_ss:
4249 case Intrinsic::x86_sse_ucomineq_ss:
4250 case Intrinsic::x86_sse2_comieq_sd:
4251 case Intrinsic::x86_sse2_comilt_sd:
4252 case Intrinsic::x86_sse2_comile_sd:
4253 case Intrinsic::x86_sse2_comigt_sd:
4254 case Intrinsic::x86_sse2_comige_sd:
4255 case Intrinsic::x86_sse2_comineq_sd:
4256 case Intrinsic::x86_sse2_ucomieq_sd:
4257 case Intrinsic::x86_sse2_ucomilt_sd:
4258 case Intrinsic::x86_sse2_ucomile_sd:
4259 case Intrinsic::x86_sse2_ucomigt_sd:
4260 case Intrinsic::x86_sse2_ucomige_sd:
4261 case Intrinsic::x86_sse2_ucomineq_sd:
4262 handleVectorCompareScalarIntrinsic(I);
4263 break;
4264
4265 case Intrinsic::x86_avx_cmp_pd_256:
4266 case Intrinsic::x86_avx_cmp_ps_256:
4267 case Intrinsic::x86_sse2_cmp_pd:
4268 case Intrinsic::x86_sse_cmp_ps:
4269 handleVectorComparePackedIntrinsic(I);
4270 break;
4271
4272 case Intrinsic::x86_bmi_bextr_32:
4273 case Intrinsic::x86_bmi_bextr_64:
4274 case Intrinsic::x86_bmi_bzhi_32:
4275 case Intrinsic::x86_bmi_bzhi_64:
4276 case Intrinsic::x86_bmi_pdep_32:
4277 case Intrinsic::x86_bmi_pdep_64:
4278 case Intrinsic::x86_bmi_pext_32:
4279 case Intrinsic::x86_bmi_pext_64:
4280 handleBmiIntrinsic(I);
4281 break;
4282
4283 case Intrinsic::x86_pclmulqdq:
4284 case Intrinsic::x86_pclmulqdq_256:
4285 case Intrinsic::x86_pclmulqdq_512:
4286 handlePclmulIntrinsic(I);
4287 break;
4288
4289 case Intrinsic::x86_sse41_round_sd:
4290 case Intrinsic::x86_sse41_round_ss:
4291 handleUnarySdSsIntrinsic(I);
4292 break;
4293 case Intrinsic::x86_sse2_max_sd:
4294 case Intrinsic::x86_sse_max_ss:
4295 case Intrinsic::x86_sse2_min_sd:
4296 case Intrinsic::x86_sse_min_ss:
4297 handleBinarySdSsIntrinsic(I);
4298 break;
4299
4300 case Intrinsic::x86_avx_vtestc_pd:
4301 case Intrinsic::x86_avx_vtestc_pd_256:
4302 case Intrinsic::x86_avx_vtestc_ps:
4303 case Intrinsic::x86_avx_vtestc_ps_256:
4304 case Intrinsic::x86_avx_vtestnzc_pd:
4305 case Intrinsic::x86_avx_vtestnzc_pd_256:
4306 case Intrinsic::x86_avx_vtestnzc_ps:
4307 case Intrinsic::x86_avx_vtestnzc_ps_256:
4308 case Intrinsic::x86_avx_vtestz_pd:
4309 case Intrinsic::x86_avx_vtestz_pd_256:
4310 case Intrinsic::x86_avx_vtestz_ps:
4311 case Intrinsic::x86_avx_vtestz_ps_256:
4312 case Intrinsic::x86_avx_ptestc_256:
4313 case Intrinsic::x86_avx_ptestnzc_256:
4314 case Intrinsic::x86_avx_ptestz_256:
4315 case Intrinsic::x86_sse41_ptestc:
4316 case Intrinsic::x86_sse41_ptestnzc:
4317 case Intrinsic::x86_sse41_ptestz:
4318 handleVtestIntrinsic(I);
4319 break;
4320
4321 case Intrinsic::fshl:
4322 case Intrinsic::fshr:
4323 handleFunnelShift(I);
4324 break;
4325
4326 case Intrinsic::is_constant:
4327 // The result of llvm.is.constant() is always defined.
4328 setShadow(&I, getCleanShadow(&I));
4329 setOrigin(&I, getCleanOrigin());
4330 break;
4331
4332 case Intrinsic::aarch64_neon_st1x2:
4333 case Intrinsic::aarch64_neon_st1x3:
4334 case Intrinsic::aarch64_neon_st1x4:
4335 case Intrinsic::aarch64_neon_st2:
4336 case Intrinsic::aarch64_neon_st3:
4337 case Intrinsic::aarch64_neon_st4: {
4338 handleNEONVectorStoreIntrinsic(I, false);
4339 break;
4340 }
4341
4342 case Intrinsic::aarch64_neon_st2lane:
4343 case Intrinsic::aarch64_neon_st3lane:
4344 case Intrinsic::aarch64_neon_st4lane: {
4345 handleNEONVectorStoreIntrinsic(I, true);
4346 break;
4347 }
4348
4349 default:
4350 if (!handleUnknownIntrinsic(I))
4351 visitInstruction(I);
4352 break;
4353 }
4354 }
4355
4356 void visitLibAtomicLoad(CallBase &CB) {
4357 // Since we use getNextNode here, we can't have CB terminate the BB.
4358 assert(isa<CallInst>(CB));
4359
4360 IRBuilder<> IRB(&CB);
4361 Value *Size = CB.getArgOperand(0);
4362 Value *SrcPtr = CB.getArgOperand(1);
4363 Value *DstPtr = CB.getArgOperand(2);
4364 Value *Ordering = CB.getArgOperand(3);
4365 // Convert the call to have at least Acquire ordering to make sure
4366 // the shadow operations aren't reordered before it.
4367 Value *NewOrdering =
4368 IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
4369 CB.setArgOperand(3, NewOrdering);
4370
4371 NextNodeIRBuilder NextIRB(&CB);
4372 Value *SrcShadowPtr, *SrcOriginPtr;
4373 std::tie(SrcShadowPtr, SrcOriginPtr) =
4374 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
4375 /*isStore*/ false);
4376 Value *DstShadowPtr =
4377 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
4378 /*isStore*/ true)
4379 .first;
4380
4381 NextIRB.CreateMemCpy(DstShadowPtr, Align(1), SrcShadowPtr, Align(1), Size);
4382 if (MS.TrackOrigins) {
4383 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
4385 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
4386 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
4387 }
4388 }
4389
4390 void visitLibAtomicStore(CallBase &CB) {
4391 IRBuilder<> IRB(&CB);
4392 Value *Size = CB.getArgOperand(0);
4393 Value *DstPtr = CB.getArgOperand(2);
4394 Value *Ordering = CB.getArgOperand(3);
4395 // Convert the call to have at least Release ordering to make sure
4396 // the shadow operations aren't reordered after it.
4397 Value *NewOrdering =
4398 IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
4399 CB.setArgOperand(3, NewOrdering);
4400
4401 Value *DstShadowPtr =
4402 getShadowOriginPtr(DstPtr, IRB, IRB.getInt8Ty(), Align(1),
4403 /*isStore*/ true)
4404 .first;
4405
4406 // Atomic store always paints clean shadow/origin. See file header.
4407 IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
4408 Align(1));
4409 }
4410
4411 void visitCallBase(CallBase &CB) {
4412 assert(!CB.getMetadata(LLVMContext::MD_nosanitize));
4413 if (CB.isInlineAsm()) {
4414 // For inline asm (either a call to asm function, or callbr instruction),
4415 // do the usual thing: check argument shadow and mark all outputs as
4416 // clean. Note that any side effects of the inline asm that are not
4417 // immediately visible in its constraints are not handled.
4419 visitAsmInstruction(CB);
4420 else
4421 visitInstruction(CB);
4422 return;
4423 }
4424 LibFunc LF;
4425 if (TLI->getLibFunc(CB, LF)) {
4426 // libatomic.a functions need to have special handling because there isn't
4427 // a good way to intercept them or compile the library with
4428 // instrumentation.
4429 switch (LF) {
4430 case LibFunc_atomic_load:
4431 if (!isa<CallInst>(CB)) {
4432 llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
4433 "Ignoring!\n";
4434 break;
4435 }
4436 visitLibAtomicLoad(CB);
4437 return;
4438 case LibFunc_atomic_store:
4439 visitLibAtomicStore(CB);
4440 return;
4441 default:
4442 break;
4443 }
4444 }
4445
4446 if (auto *Call = dyn_cast<CallInst>(&CB)) {
4447 assert(!isa<IntrinsicInst>(Call) && "intrinsics are handled elsewhere");
4448
4449 // We are going to insert code that relies on the fact that the callee
4450 // will become a non-readonly function after it is instrumented by us. To
4451 // prevent this code from being optimized out, mark that function
4452 // non-readonly in advance.
4453 // TODO: We can likely do better than dropping memory() completely here.
4455 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
4456
4457 Call->removeFnAttrs(B);
4458 if (Function *Func = Call->getCalledFunction()) {
4459 Func->removeFnAttrs(B);
4460 }
4461
4463 }
4464 IRBuilder<> IRB(&CB);
4465 bool MayCheckCall = MS.EagerChecks;
4466 if (Function *Func = CB.getCalledFunction()) {
4467 // __sanitizer_unaligned_{load,store} functions may be called by users
4468 // and always expects shadows in the TLS. So don't check them.
4469 MayCheckCall &= !Func->getName().starts_with("__sanitizer_unaligned_");
4470 }
4471
4472 unsigned ArgOffset = 0;
4473 LLVM_DEBUG(dbgs() << " CallSite: " << CB << "\n");
4474 for (const auto &[i, A] : llvm::enumerate(CB.args())) {
4475 if (!A->getType()->isSized()) {
4476 LLVM_DEBUG(dbgs() << "Arg " << i << " is not sized: " << CB << "\n");
4477 continue;
4478 }
4479
4480 if (A->getType()->isScalableTy()) {
4481 LLVM_DEBUG(dbgs() << "Arg " << i << " is vscale: " << CB << "\n");
4482 // Handle as noundef, but don't reserve tls slots.
4483 insertShadowCheck(A, &CB);
4484 continue;
4485 }
4486
4487 unsigned Size = 0;
4488 const DataLayout &DL = F.getDataLayout();
4489
4490 bool ByVal = CB.paramHasAttr(i, Attribute::ByVal);
4491 bool NoUndef = CB.paramHasAttr(i, Attribute::NoUndef);
4492 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
4493
4494 if (EagerCheck) {
4495 insertShadowCheck(A, &CB);
4496 Size = DL.getTypeAllocSize(A->getType());
4497 } else {
4498 Value *Store = nullptr;
4499 // Compute the Shadow for arg even if it is ByVal, because
4500 // in that case getShadow() will copy the actual arg shadow to
4501 // __msan_param_tls.
4502 Value *ArgShadow = getShadow(A);
4503 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
4504 LLVM_DEBUG(dbgs() << " Arg#" << i << ": " << *A
4505 << " Shadow: " << *ArgShadow << "\n");
4506 if (ByVal) {
4507 // ByVal requires some special handling as it's too big for a single
4508 // load
4509 assert(A->getType()->isPointerTy() &&
4510 "ByVal argument is not a pointer!");
4511 Size = DL.getTypeAllocSize(CB.getParamByValType(i));
4512 if (ArgOffset + Size > kParamTLSSize)
4513 break;
4514 const MaybeAlign ParamAlignment(CB.getParamAlign(i));
4515 MaybeAlign Alignment = std::nullopt;
4516 if (ParamAlignment)
4517 Alignment = std::min(*ParamAlignment, kShadowTLSAlignment);
4518 Value *AShadowPtr, *AOriginPtr;
4519 std::tie(AShadowPtr, AOriginPtr) =
4520 getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
4521 /*isStore*/ false);
4522 if (!PropagateShadow) {
4523 Store = IRB.CreateMemSet(ArgShadowBase,
4525 Size, Alignment);
4526 } else {
4527 Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr,
4528 Alignment, Size);
4529 if (MS.TrackOrigins) {
4530 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
4531 // FIXME: OriginSize should be:
4532 // alignTo(A % kMinOriginAlignment + Size, kMinOriginAlignment)
4533 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
4534 IRB.CreateMemCpy(
4535 ArgOriginBase,
4536 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
4537 AOriginPtr,
4538 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginSize);
4539 }
4540 }
4541 } else {
4542 // Any other parameters mean we need bit-grained tracking of uninit
4543 // data
4544 Size = DL.getTypeAllocSize(A->getType());
4545 if (ArgOffset + Size > kParamTLSSize)
4546 break;
4547 Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
4549 Constant *Cst = dyn_cast<Constant>(ArgShadow);
4550 if (MS.TrackOrigins && !(Cst && Cst->isNullValue())) {
4551 IRB.CreateStore(getOrigin(A),
4552 getOriginPtrForArgument(IRB, ArgOffset));
4553 }
4554 }
4555 (void)Store;
4556 assert(Store != nullptr);
4557 LLVM_DEBUG(dbgs() << " Param:" << *Store << "\n");
4558 }
4559 assert(Size != 0);
4560 ArgOffset += alignTo(Size, kShadowTLSAlignment);
4561 }
4562 LLVM_DEBUG(dbgs() << " done with call args\n");
4563
4564 FunctionType *FT = CB.getFunctionType();
4565 if (FT->isVarArg()) {
4566 VAHelper->visitCallBase(CB, IRB);
4567 }
4568
4569 // Now, get the shadow for the RetVal.
4570 if (!CB.getType()->isSized())
4571 return;
4572 // Don't emit the epilogue for musttail call returns.
4573 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
4574 return;
4575
4576 if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
4577 setShadow(&CB, getCleanShadow(&CB));
4578 setOrigin(&CB, getCleanOrigin());
4579 return;
4580 }
4581
4582 IRBuilder<> IRBBefore(&CB);
4583 // Until we have full dynamic coverage, make sure the retval shadow is 0.
4584 Value *Base = getShadowPtrForRetval(IRBBefore);
4585 IRBBefore.CreateAlignedStore(getCleanShadow(&CB), Base,
4587 BasicBlock::iterator NextInsn;
4588 if (isa<CallInst>(CB)) {
4589 NextInsn = ++CB.getIterator();
4590 assert(NextInsn != CB.getParent()->end());
4591 } else {
4592 BasicBlock *NormalDest = cast<InvokeInst>(CB).getNormalDest();
4593 if (!NormalDest->getSinglePredecessor()) {
4594 // FIXME: this case is tricky, so we are just conservative here.
4595 // Perhaps we need to split the edge between this BB and NormalDest,
4596 // but a naive attempt to use SplitEdge leads to a crash.
4597 setShadow(&CB, getCleanShadow(&CB));
4598 setOrigin(&CB, getCleanOrigin());
4599 return;
4600 }
4601 // FIXME: NextInsn is likely in a basic block that has not been visited
4602 // yet. Anything inserted there will be instrumented by MSan later!
4603 NextInsn = NormalDest->getFirstInsertionPt();
4604 assert(NextInsn != NormalDest->end() &&
4605 "Could not find insertion point for retval shadow load");
4606 }
4607 IRBuilder<> IRBAfter(&*NextInsn);
4608 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
4609 getShadowTy(&CB), getShadowPtrForRetval(IRBAfter),
4610 kShadowTLSAlignment, "_msret");
4611 setShadow(&CB, RetvalShadow);
4612 if (MS.TrackOrigins)
4613 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy,
4614 getOriginPtrForRetval()));
4615 }
4616
4617 bool isAMustTailRetVal(Value *RetVal) {
4618 if (auto *I = dyn_cast<BitCastInst>(RetVal)) {
4619 RetVal = I->getOperand(0);
4620 }
4621 if (auto *I = dyn_cast<CallInst>(RetVal)) {
4622 return I->isMustTailCall();
4623 }
4624 return false;
4625 }
4626
4627 void visitReturnInst(ReturnInst &I) {
4628 IRBuilder<> IRB(&I);
4629 Value *RetVal = I.getReturnValue();
4630 if (!RetVal)
4631 return;
4632 // Don't emit the epilogue for musttail call returns.
4633 if (isAMustTailRetVal(RetVal))
4634 return;
4635 Value *ShadowPtr = getShadowPtrForRetval(IRB);
4636 bool HasNoUndef = F.hasRetAttribute(Attribute::NoUndef);
4637 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
4638 // FIXME: Consider using SpecialCaseList to specify a list of functions that
4639 // must always return fully initialized values. For now, we hardcode "main".
4640 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (F.getName() == "main");
4641
4642 Value *Shadow = getShadow(RetVal);
4643 bool StoreOrigin = true;
4644 if (EagerCheck) {
4645 insertShadowCheck(RetVal, &I);
4646 Shadow = getCleanShadow(RetVal);
4647 StoreOrigin = false;
4648 }
4649
4650 // The caller may still expect information passed over TLS if we pass our
4651 // check
4652 if (StoreShadow) {
4653 IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
4654 if (MS.TrackOrigins && StoreOrigin)
4655 IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
4656 }
4657 }
4658
4659 void visitPHINode(PHINode &I) {
4660 IRBuilder<> IRB(&I);
4661 if (!PropagateShadow) {
4662 setShadow(&I, getCleanShadow(&I));
4663 setOrigin(&I, getCleanOrigin());
4664 return;
4665 }
4666
4667 ShadowPHINodes.push_back(&I);
4668 setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
4669 "_msphi_s"));
4670 if (MS.TrackOrigins)
4671 setOrigin(
4672 &I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(), "_msphi_o"));
4673 }
4674
4675 Value *getLocalVarIdptr(AllocaInst &I) {
4676 ConstantInt *IntConst =
4677 ConstantInt::get(Type::getInt32Ty((*F.getParent()).getContext()), 0);
4678 return new GlobalVariable(*F.getParent(), IntConst->getType(),
4679 /*isConstant=*/false, GlobalValue::PrivateLinkage,
4680 IntConst);
4681 }
4682
4683 Value *getLocalVarDescription(AllocaInst &I) {
4684 return createPrivateConstGlobalForString(*F.getParent(), I.getName());
4685 }
4686
4687 void poisonAllocaUserspace(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
4688 if (PoisonStack && ClPoisonStackWithCall) {
4689 IRB.CreateCall(MS.MsanPoisonStackFn, {&I, Len});
4690 } else {
4691 Value *ShadowBase, *OriginBase;
4692 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
4693 &I, IRB, IRB.getInt8Ty(), Align(1), /*isStore*/ true);
4694
4695 Value *PoisonValue = IRB.getInt8(PoisonStack ? ClPoisonStackPattern : 0);
4696 IRB.CreateMemSet(ShadowBase, PoisonValue, Len, I.getAlign());
4697 }
4698
4699 if (PoisonStack && MS.TrackOrigins) {
4700 Value *Idptr = getLocalVarIdptr(I);
4701 if (ClPrintStackNames) {
4702 Value *Descr = getLocalVarDescription(I);
4703 IRB.CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
4704 {&I, Len, Idptr, Descr});
4705 } else {
4706 IRB.CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
4707 }
4708 }
4709 }
4710
4711 void poisonAllocaKmsan(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
4712 Value *Descr = getLocalVarDescription(I);
4713 if (PoisonStack) {
4714 IRB.CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
4715 } else {
4716 IRB.CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
4717 }
4718 }
4719
4720 void instrumentAlloca(AllocaInst &I, Instruction *InsPoint = nullptr) {
4721 if (!InsPoint)
4722 InsPoint = &I;
4723 NextNodeIRBuilder IRB(InsPoint);
4724 const DataLayout &DL = F.getDataLayout();
4725 TypeSize TS = DL.getTypeAllocSize(I.getAllocatedType());
4726 Value *Len = IRB.CreateTypeSize(MS.IntptrTy, TS);
4727 if (I.isArrayAllocation())
4728 Len = IRB.CreateMul(Len,
4729 IRB.CreateZExtOrTrunc(I.getArraySize(), MS.IntptrTy));
4730
4731 if (MS.CompileKernel)
4732 poisonAllocaKmsan(I, IRB, Len);
4733 else
4734 poisonAllocaUserspace(I, IRB, Len);
4735 }
4736
4737 void visitAllocaInst(AllocaInst &I) {
4738 setShadow(&I, getCleanShadow(&I));
4739 setOrigin(&I, getCleanOrigin());
4740 // We'll get to this alloca later unless it's poisoned at the corresponding
4741 // llvm.lifetime.start.
4742 AllocaSet.insert(&I);
4743 }
4744
4745 void visitSelectInst(SelectInst &I) {
4746 // a = select b, c, d
4747 Value *B = I.getCondition();
4748 Value *C = I.getTrueValue();
4749 Value *D = I.getFalseValue();
4750
4751 handleSelectLikeInst(I, B, C, D);
4752 }
4753
4754 void handleSelectLikeInst(Instruction &I, Value *B, Value *C, Value *D) {
4755 IRBuilder<> IRB(&I);
4756
4757 Value *Sb = getShadow(B);
4758 Value *Sc = getShadow(C);
4759 Value *Sd = getShadow(D);
4760
4761 Value *Ob = MS.TrackOrigins ? getOrigin(B) : nullptr;
4762 Value *Oc = MS.TrackOrigins ? getOrigin(C) : nullptr;
4763 Value *Od = MS.TrackOrigins ? getOrigin(D) : nullptr;
4764
4765 // Result shadow if condition shadow is 0.
4766 Value *Sa0 = IRB.CreateSelect(B, Sc, Sd);
4767 Value *Sa1;
4768 if (I.getType()->isAggregateType()) {
4769 // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do
4770 // an extra "select". This results in much more compact IR.
4771 // Sa = select Sb, poisoned, (select b, Sc, Sd)
4772 Sa1 = getPoisonedShadow(getShadowTy(I.getType()));
4773 } else {
4774 // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ]
4775 // If Sb (condition is poisoned), look for bits in c and d that are equal
4776 // and both unpoisoned.
4777 // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd.
4778
4779 // Cast arguments to shadow-compatible type.
4780 C = CreateAppToShadowCast(IRB, C);
4781 D = CreateAppToShadowCast(IRB, D);
4782
4783 // Result shadow if condition shadow is 1.
4784 Sa1 = IRB.CreateOr({IRB.CreateXor(C, D), Sc, Sd});
4785 }
4786 Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
4787 setShadow(&I, Sa);
4788 if (MS.TrackOrigins) {
4789 // Origins are always i32, so any vector conditions must be flattened.
4790 // FIXME: consider tracking vector origins for app vectors?
4791 if (B->getType()->isVectorTy()) {
4792 B = convertToBool(B, IRB);
4793 Sb = convertToBool(Sb, IRB);
4794 }
4795 // a = select b, c, d
4796 // Oa = Sb ? Ob : (b ? Oc : Od)
4797 setOrigin(&I, IRB.CreateSelect(Sb, Ob, IRB.CreateSelect(B, Oc, Od)));
4798 }
4799 }
4800
4801 void visitLandingPadInst(LandingPadInst &I) {
4802 // Do nothing.
4803 // See https://github.com/google/sanitizers/issues/504
4804 setShadow(&I, getCleanShadow(&I));
4805 setOrigin(&I, getCleanOrigin());
4806 }
4807
4808 void visitCatchSwitchInst(CatchSwitchInst &I) {
4809 setShadow(&I, getCleanShadow(&I));
4810 setOrigin(&I, getCleanOrigin());
4811 }
4812
4813 void visitFuncletPadInst(FuncletPadInst &I) {
4814 setShadow(&I, getCleanShadow(&I));
4815 setOrigin(&I, getCleanOrigin());
4816 }
4817
4818 void visitGetElementPtrInst(GetElementPtrInst &I) { handleShadowOr(I); }
4819
4820 void visitExtractValueInst(ExtractValueInst &I) {
4821 IRBuilder<> IRB(&I);
4822 Value *Agg = I.getAggregateOperand();
4823 LLVM_DEBUG(dbgs() << "ExtractValue: " << I << "\n");
4824 Value *AggShadow = getShadow(Agg);
4825 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
4826 Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
4827 LLVM_DEBUG(dbgs() << " ResShadow: " << *ResShadow << "\n");
4828 setShadow(&I, ResShadow);
4829 setOriginForNaryOp(I);
4830 }
4831
4832 void visitInsertValueInst(InsertValueInst &I) {
4833 IRBuilder<> IRB(&I);
4834 LLVM_DEBUG(dbgs() << "InsertValue: " << I << "\n");
4835 Value *AggShadow = getShadow(I.getAggregateOperand());
4836 Value *InsShadow = getShadow(I.getInsertedValueOperand());
4837 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
4838 LLVM_DEBUG(dbgs() << " InsShadow: " << *InsShadow << "\n");
4839 Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
4840 LLVM_DEBUG(dbgs() << " Res: " << *Res << "\n");
4841 setShadow(&I, Res);
4842 setOriginForNaryOp(I);
4843 }
4844
4845 void dumpInst(Instruction &I) {
4846 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
4847 errs() << "ZZZ call " << CI->getCalledFunction()->getName() << "\n";
4848 } else {
4849 errs() << "ZZZ " << I.getOpcodeName() << "\n";
4850 }
4851 errs() << "QQQ " << I << "\n";
4852 }
4853
4854 void visitResumeInst(ResumeInst &I) {
4855 LLVM_DEBUG(dbgs() << "Resume: " << I << "\n");
4856 // Nothing to do here.
4857 }
4858
4859 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
4860 LLVM_DEBUG(dbgs() << "CleanupReturn: " << CRI << "\n");
4861 // Nothing to do here.
4862 }
4863
4864 void visitCatchReturnInst(CatchReturnInst &CRI) {
4865 LLVM_DEBUG(dbgs() << "CatchReturn: " << CRI << "\n");
4866 // Nothing to do here.
4867 }
4868
4869 void instrumentAsmArgument(Value *Operand, Type *ElemTy, Instruction &I,
4870 IRBuilder<> &IRB, const DataLayout &DL,
4871 bool isOutput) {
4872 // For each assembly argument, we check its value for being initialized.
4873 // If the argument is a pointer, we assume it points to a single element
4874 // of the corresponding type (or to a 8-byte word, if the type is unsized).
4875 // Each such pointer is instrumented with a call to the runtime library.
4876 Type *OpType = Operand->getType();
4877 // Check the operand value itself.
4878 insertShadowCheck(Operand, &I);
4879 if (!OpType->isPointerTy() || !isOutput) {
4880 assert(!isOutput);
4881 return;
4882 }
4883 if (!ElemTy->isSized())
4884 return;
4885 auto Size = DL.getTypeStoreSize(ElemTy);
4886 Value *SizeVal = IRB.CreateTypeSize(MS.IntptrTy, Size);
4887 if (MS.CompileKernel) {
4888 IRB.CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
4889 } else {
4890 // ElemTy, derived from elementtype(), does not encode the alignment of
4891 // the pointer. Conservatively assume that the shadow memory is unaligned.
4892 // When Size is large, avoid StoreInst as it would expand to many
4893 // instructions.
4894 auto [ShadowPtr, _] =
4895 getShadowOriginPtrUserspace(Operand, IRB, IRB.getInt8Ty(), Align(1));
4896 if (Size <= 32)
4897 IRB.CreateAlignedStore(getCleanShadow(ElemTy), ShadowPtr, Align(1));
4898 else
4899 IRB.CreateMemSet(ShadowPtr, ConstantInt::getNullValue(IRB.getInt8Ty()),
4900 SizeVal, Align(1));
4901 }
4902 }
4903
4904 /// Get the number of output arguments returned by pointers.
4905 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
4906 int NumRetOutputs = 0;
4907 int NumOutputs = 0;
4908 Type *RetTy = cast<Value>(CB)->getType();
4909 if (!RetTy->isVoidTy()) {
4910 // Register outputs are returned via the CallInst return value.
4911 auto *ST = dyn_cast<StructType>(RetTy);
4912 if (ST)
4913 NumRetOutputs = ST->getNumElements();
4914 else
4915 NumRetOutputs = 1;
4916 }
4917 InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
4918 for (const InlineAsm::ConstraintInfo &Info : Constraints) {
4919 switch (Info.Type) {
4921 NumOutputs++;
4922 break;
4923 default:
4924 break;
4925 }
4926 }
4927 return NumOutputs - NumRetOutputs;
4928 }
4929
4930 void visitAsmInstruction(Instruction &I) {
4931 // Conservative inline assembly handling: check for poisoned shadow of
4932 // asm() arguments, then unpoison the result and all the memory locations
4933 // pointed to by those arguments.
4934 // An inline asm() statement in C++ contains lists of input and output
4935 // arguments used by the assembly code. These are mapped to operands of the
4936 // CallInst as follows:
4937 // - nR register outputs ("=r) are returned by value in a single structure
4938 // (SSA value of the CallInst);
4939 // - nO other outputs ("=m" and others) are returned by pointer as first
4940 // nO operands of the CallInst;
4941 // - nI inputs ("r", "m" and others) are passed to CallInst as the
4942 // remaining nI operands.
4943 // The total number of asm() arguments in the source is nR+nO+nI, and the
4944 // corresponding CallInst has nO+nI+1 operands (the last operand is the
4945 // function to be called).
4946 const DataLayout &DL = F.getDataLayout();
4947 CallBase *CB = cast<CallBase>(&I);
4948 IRBuilder<> IRB(&I);
4949 InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
4950 int OutputArgs = getNumOutputArgs(IA, CB);
4951 // The last operand of a CallInst is the function itself.
4952 int NumOperands = CB->getNumOperands() - 1;
4953
4954 // Check input arguments. Doing so before unpoisoning output arguments, so
4955 // that we won't overwrite uninit values before checking them.
4956 for (int i = OutputArgs; i < NumOperands; i++) {
4957 Value *Operand = CB->getOperand(i);
4958 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
4959 /*isOutput*/ false);
4960 }
4961 // Unpoison output arguments. This must happen before the actual InlineAsm
4962 // call, so that the shadow for memory published in the asm() statement
4963 // remains valid.
4964 for (int i = 0; i < OutputArgs; i++) {
4965 Value *Operand = CB->getOperand(i);
4966 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
4967 /*isOutput*/ true);
4968 }
4969
4970 setShadow(&I, getCleanShadow(&I));
4971 setOrigin(&I, getCleanOrigin());
4972 }
4973
4974 void visitFreezeInst(FreezeInst &I) {
4975 // Freeze always returns a fully defined value.
4976 setShadow(&I, getCleanShadow(&I));
4977 setOrigin(&I, getCleanOrigin());
4978 }
4979
4980 void visitInstruction(Instruction &I) {
4981 // Everything else: stop propagating and check for poisoned shadow.
4983 dumpInst(I);
4984 LLVM_DEBUG(dbgs() << "DEFAULT: " << I << "\n");
4985 for (size_t i = 0, n = I.getNumOperands(); i < n; i++) {
4986 Value *Operand = I.getOperand(i);
4987 if (Operand->getType()->isSized())
4988 insertShadowCheck(Operand, &I);
4989 }
4990 setShadow(&I, getCleanShadow(&I));
4991 setOrigin(&I, getCleanOrigin());
4992 }
4993};
4994
4995struct VarArgHelperBase : public VarArgHelper {
4996 Function &F;
4997 MemorySanitizer &MS;
4998 MemorySanitizerVisitor &MSV;
4999 SmallVector<CallInst *, 16> VAStartInstrumentationList;
5000 const unsigned VAListTagSize;
5001
5002 VarArgHelperBase(Function &F, MemorySanitizer &MS,
5003 MemorySanitizerVisitor &MSV, unsigned VAListTagSize)
5004 : F(F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
5005
5006 Value *getShadowAddrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
5007 Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
5008 return IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
5009 }
5010
5011 /// Compute the shadow address for a given va_arg.
5012 Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
5013 unsigned ArgOffset) {
5014 Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
5015 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
5016 return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
5017 "_msarg_va_s");
5018 }
5019
5020 /// Compute the shadow address for a given va_arg.
5021 Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
5022 unsigned ArgOffset, unsigned ArgSize) {
5023 // Make sure we don't overflow __msan_va_arg_tls.
5024 if (ArgOffset + ArgSize > kParamTLSSize)
5025 return nullptr;
5026 return getShadowPtrForVAArgument(Ty, IRB, ArgOffset);
5027 }
5028
5029 /// Compute the origin address for a given va_arg.
5030 Value *getOriginPtrForVAArgument(IRBuilder<> &IRB, int ArgOffset) {
5031 Value *Base = IRB.CreatePointerCast(MS.VAArgOriginTLS, MS.IntptrTy);
5032 // getOriginPtrForVAArgument() is always called after
5033 // getShadowPtrForVAArgument(), so __msan_va_arg_origin_tls can never
5034 // overflow.
5035 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
5036 return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0),
5037 "_msarg_va_o");
5038 }
5039
5040 void CleanUnusedTLS(IRBuilder<> &IRB, Value *ShadowBase,
5041 unsigned BaseOffset) {
5042 // The tails of __msan_va_arg_tls is not large enough to fit full
5043 // value shadow, but it will be copied to backup anyway. Make it
5044 // clean.
5045 if (BaseOffset >= kParamTLSSize)
5046 return;
5047 Value *TailSize =
5048 ConstantInt::getSigned(IRB.getInt32Ty(), kParamTLSSize - BaseOffset);
5049 IRB.CreateMemSet(ShadowBase, ConstantInt::getNullValue(IRB.getInt8Ty()),
5050 TailSize, Align(8));
5051 }
5052
5053 void unpoisonVAListTagForInst(IntrinsicInst &I) {
5054 IRBuilder<> IRB(&I);
5055 Value *VAListTag = I.getArgOperand(0);
5056 const Align Alignment = Align(8);
5057 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
5058 VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
5059 // Unpoison the whole __va_list_tag.
5060 IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
5061 VAListTagSize, Alignment, false);
5062 }
5063
5064 void visitVAStartInst(VAStartInst &I) override {
5065 if (F.getCallingConv() == CallingConv::Win64)
5066 return;
5067 VAStartInstrumentationList.push_back(&I);
5068 unpoisonVAListTagForInst(I);
5069 }
5070
5071 void visitVACopyInst(VACopyInst &I) override {
5072 if (F.getCallingConv() == CallingConv::Win64)
5073 return;
5074 unpoisonVAListTagForInst(I);
5075 }
5076};
5077
5078/// AMD64-specific implementation of VarArgHelper.
5079struct VarArgAMD64Helper : public VarArgHelperBase {
5080 // An unfortunate workaround for asymmetric lowering of va_arg stuff.
5081 // See a comment in visitCallBase for more details.
5082 static const unsigned AMD64GpEndOffset = 48; // AMD64 ABI Draft 0.99.6 p3.5.7
5083 static const unsigned AMD64FpEndOffsetSSE = 176;
5084 // If SSE is disabled, fp_offset in va_list is zero.
5085 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
5086
5087 unsigned AMD64FpEndOffset;
5088 AllocaInst *VAArgTLSCopy = nullptr;
5089 AllocaInst *VAArgTLSOriginCopy = nullptr;
5090 Value *VAArgOverflowSize = nullptr;
5091
5092 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
5093
5094 VarArgAMD64Helper(Function &F, MemorySanitizer &MS,
5095 MemorySanitizerVisitor &MSV)
5096 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/24) {
5097 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
5098 for (const auto &Attr : F.getAttributes().getFnAttrs()) {
5099 if (Attr.isStringAttribute() &&
5100 (Attr.getKindAsString() == "target-features")) {
5101 if (Attr.getValueAsString().contains("-sse"))
5102 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
5103 break;
5104 }
5105 }
5106 }
5107
5108 ArgKind classifyArgument(Value *arg) {
5109 // A very rough approximation of X86_64 argument classification rules.
5110 Type *T = arg->getType();
5111 if (T->isX86_FP80Ty())
5112 return AK_Memory;
5113 if (T->isFPOrFPVectorTy())
5114 return AK_FloatingPoint;
5115 if (T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64)
5116 return AK_GeneralPurpose;
5117 if (T->isPointerTy())
5118 return AK_GeneralPurpose;
5119 return AK_Memory;
5120 }
5121
5122 // For VarArg functions, store the argument shadow in an ABI-specific format
5123 // that corresponds to va_list layout.
5124 // We do this because Clang lowers va_arg in the frontend, and this pass
5125 // only sees the low level code that deals with va_list internals.
5126 // A much easier alternative (provided that Clang emits va_arg instructions)
5127 // would have been to associate each live instance of va_list with a copy of
5128 // MSanParamTLS, and extract shadow on va_arg() call in the argument list
5129 // order.
5130 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5131 unsigned GpOffset = 0;
5132 unsigned FpOffset = AMD64GpEndOffset;
5133 unsigned OverflowOffset = AMD64FpEndOffset;
5134 const DataLayout &DL = F.getDataLayout();
5135
5136 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
5137 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
5138 bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal);
5139 if (IsByVal) {
5140 // ByVal arguments always go to the overflow area.
5141 // Fixed arguments passed through the overflow area will be stepped
5142 // over by va_start, so don't count them towards the offset.
5143 if (IsFixed)
5144 continue;
5145 assert(A->getType()->isPointerTy());
5146 Type *RealTy = CB.getParamByValType(ArgNo);
5147 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
5148 uint64_t AlignedSize = alignTo(ArgSize, 8);
5149 unsigned BaseOffset = OverflowOffset;
5150 Value *ShadowBase =
5151 getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset);
5152 Value *OriginBase = nullptr;
5153 if (MS.TrackOrigins)
5154 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
5155 OverflowOffset += AlignedSize;
5156
5157 if (OverflowOffset > kParamTLSSize) {
5158 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
5159 continue; // We have no space to copy shadow there.
5160 }
5161
5162 Value *ShadowPtr, *OriginPtr;
5163 std::tie(ShadowPtr, OriginPtr) =
5164 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), kShadowTLSAlignment,
5165 /*isStore*/ false);
5166 IRB.CreateMemCpy(ShadowBase, kShadowTLSAlignment, ShadowPtr,
5167 kShadowTLSAlignment, ArgSize);
5168 if (MS.TrackOrigins)
5169 IRB.CreateMemCpy(OriginBase, kShadowTLSAlignment, OriginPtr,
5170 kShadowTLSAlignment, ArgSize);
5171 } else {
5172 ArgKind AK = classifyArgument(A);
5173 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
5174 AK = AK_Memory;
5175 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
5176 AK = AK_Memory;
5177 Value *ShadowBase, *OriginBase = nullptr;
5178 switch (AK) {
5179 case AK_GeneralPurpose:
5180 ShadowBase = getShadowPtrForVAArgument(A->getType(), IRB, GpOffset);
5181 if (MS.TrackOrigins)
5182 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
5183 GpOffset += 8;
5184 assert(GpOffset <= kParamTLSSize);
5185 break;
5186 case AK_FloatingPoint:
5187 ShadowBase = getShadowPtrForVAArgument(A->getType(), IRB, FpOffset);
5188 if (MS.TrackOrigins)
5189 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
5190 FpOffset += 16;
5191 assert(FpOffset <= kParamTLSSize);
5192 break;
5193 case AK_Memory:
5194 if (IsFixed)
5195 continue;
5196 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
5197 uint64_t AlignedSize = alignTo(ArgSize, 8);
5198 unsigned BaseOffset = OverflowOffset;
5199 ShadowBase =
5200 getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset);
5201 if (MS.TrackOrigins) {
5202 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
5203 }
5204 OverflowOffset += AlignedSize;
5205 if (OverflowOffset > kParamTLSSize) {
5206 // We have no space to copy shadow there.
5207 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
5208 continue;
5209 }
5210 }
5211 // Take fixed arguments into account for GpOffset and FpOffset,
5212 // but don't actually store shadows for them.
5213 // TODO(glider): don't call get*PtrForVAArgument() for them.
5214 if (IsFixed)
5215 continue;
5216 Value *Shadow = MSV.getShadow(A);
5217 IRB.CreateAlignedStore(Shadow, ShadowBase, kShadowTLSAlignment);
5218 if (MS.TrackOrigins) {
5219 Value *Origin = MSV.getOrigin(A);
5220 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
5221 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
5223 }
5224 }
5225 }
5226 Constant *OverflowSize =
5227 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
5228 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5229 }
5230
5231 void finalizeInstrumentation() override {
5232 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
5233 "finalizeInstrumentation called twice");
5234 if (!VAStartInstrumentationList.empty()) {
5235 // If there is a va_start in this function, make a backup copy of
5236 // va_arg_tls somewhere in the function entry block.
5237 IRBuilder<> IRB(MSV.FnPrologueEnd);
5238 VAArgOverflowSize =
5239 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5240 Value *CopySize = IRB.CreateAdd(
5241 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
5242 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5243 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
5244 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
5245 CopySize, kShadowTLSAlignment, false);
5246
5247 Value *SrcSize = IRB.CreateBinaryIntrinsic(
5248 Intrinsic::umin, CopySize,
5249 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
5250 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
5251 kShadowTLSAlignment, SrcSize);
5252 if (MS.TrackOrigins) {
5253 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5254 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
5255 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
5256 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
5257 }
5258 }
5259
5260 // Instrument va_start.
5261 // Copy va_list shadow from the backup copy of the TLS contents.
5262 for (CallInst *OrigInst : VAStartInstrumentationList) {
5263 NextNodeIRBuilder IRB(OrigInst);
5264 Value *VAListTag = OrigInst->getArgOperand(0);
5265
5266 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5267 Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
5268 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5269 ConstantInt::get(MS.IntptrTy, 16)),
5270 PointerType::get(RegSaveAreaPtrTy, 0));
5271 Value *RegSaveAreaPtr =
5272 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5273 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5274 const Align Alignment = Align(16);
5275 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5276 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5277 Alignment, /*isStore*/ true);
5278 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5279 AMD64FpEndOffset);
5280 if (MS.TrackOrigins)
5281 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
5282 Alignment, AMD64FpEndOffset);
5283 Type *OverflowArgAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5284 Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
5285 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5286 ConstantInt::get(MS.IntptrTy, 8)),
5287 PointerType::get(OverflowArgAreaPtrTy, 0));
5288 Value *OverflowArgAreaPtr =
5289 IRB.CreateLoad(OverflowArgAreaPtrTy, OverflowArgAreaPtrPtr);
5290 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
5291 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
5292 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
5293 Alignment, /*isStore*/ true);
5294 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
5295 AMD64FpEndOffset);
5296 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
5297 VAArgOverflowSize);
5298 if (MS.TrackOrigins) {
5299 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
5300 AMD64FpEndOffset);
5301 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
5302 VAArgOverflowSize);
5303 }
5304 }
5305 }
5306};
5307
5308/// MIPS64-specific implementation of VarArgHelper.
5309/// NOTE: This is also used for LoongArch64.
5310struct VarArgMIPS64Helper : public VarArgHelperBase {
5311 AllocaInst *VAArgTLSCopy = nullptr;
5312 Value *VAArgSize = nullptr;
5313
5314 VarArgMIPS64Helper(Function &F, MemorySanitizer &MS,
5315 MemorySanitizerVisitor &MSV)
5316 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/8) {}
5317
5318 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5319 unsigned VAArgOffset = 0;
5320 const DataLayout &DL = F.getDataLayout();
5321 for (Value *A :
5323 Triple TargetTriple(F.getParent()->getTargetTriple());
5324 Value *Base;
5325 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
5326 if (TargetTriple.getArch() == Triple::mips64) {
5327 // Adjusting the shadow for argument with size < 8 to match the
5328 // placement of bits in big endian system
5329 if (ArgSize < 8)
5330 VAArgOffset += (8 - ArgSize);
5331 }
5332 Base = getShadowPtrForVAArgument(A->getType(), IRB, VAArgOffset, ArgSize);
5333 VAArgOffset += ArgSize;
5334 VAArgOffset = alignTo(VAArgOffset, 8);
5335 if (!Base)
5336 continue;
5337 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
5338 }
5339
5340 Constant *TotalVAArgSize = ConstantInt::get(IRB.getInt64Ty(), VAArgOffset);
5341 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
5342 // a new class member i.e. it is the total size of all VarArgs.
5343 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
5344 }
5345
5346 void finalizeInstrumentation() override {
5347 assert(!VAArgSize && !VAArgTLSCopy &&
5348 "finalizeInstrumentation called twice");
5349 IRBuilder<> IRB(MSV.FnPrologueEnd);
5350 VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5351 Value *CopySize =
5352 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize);
5353
5354 if (!VAStartInstrumentationList.empty()) {
5355 // If there is a va_start in this function, make a backup copy of
5356 // va_arg_tls somewhere in the function entry block.
5357 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5358 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
5359 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
5360 CopySize, kShadowTLSAlignment, false);
5361
5362 Value *SrcSize = IRB.CreateBinaryIntrinsic(
5363 Intrinsic::umin, CopySize,
5364 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
5365 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
5366 kShadowTLSAlignment, SrcSize);
5367 }
5368
5369 // Instrument va_start.
5370 // Copy va_list shadow from the backup copy of the TLS contents.
5371 for (CallInst *OrigInst : VAStartInstrumentationList) {
5372 NextNodeIRBuilder IRB(OrigInst);
5373 Value *VAListTag = OrigInst->getArgOperand(0);
5374 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5375 Value *RegSaveAreaPtrPtr =
5376 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5377 PointerType::get(RegSaveAreaPtrTy, 0));
5378 Value *RegSaveAreaPtr =
5379 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5380 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5381 const Align Alignment = Align(8);
5382 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5383 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5384 Alignment, /*isStore*/ true);
5385 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5386 CopySize);
5387 }
5388 }
5389};
5390
5391/// AArch64-specific implementation of VarArgHelper.
5392struct VarArgAArch64Helper : public VarArgHelperBase {
5393 static const unsigned kAArch64GrArgSize = 64;
5394 static const unsigned kAArch64VrArgSize = 128;
5395
5396 static const unsigned AArch64GrBegOffset = 0;
5397 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
5398 // Make VR space aligned to 16 bytes.
5399 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
5400 static const unsigned AArch64VrEndOffset =
5401 AArch64VrBegOffset + kAArch64VrArgSize;
5402 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
5403
5404 AllocaInst *VAArgTLSCopy = nullptr;
5405 Value *VAArgOverflowSize = nullptr;
5406
5407 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
5408
5409 VarArgAArch64Helper(Function &F, MemorySanitizer &MS,
5410 MemorySanitizerVisitor &MSV)
5411 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/32) {}
5412
5413 // A very rough approximation of aarch64 argument classification rules.
5414 std::pair<ArgKind, uint64_t> classifyArgument(Type *T) {
5415 if (T->isIntOrPtrTy() && T->getPrimitiveSizeInBits() <= 64)
5416 return {AK_GeneralPurpose, 1};
5417 if (T->isFloatingPointTy() && T->getPrimitiveSizeInBits() <= 128)
5418 return {AK_FloatingPoint, 1};
5419
5420 if (T->isArrayTy()) {
5421 auto R = classifyArgument(T->getArrayElementType());
5422 R.second *= T->getScalarType()->getArrayNumElements();
5423 return R;
5424 }
5425
5426 if (const FixedVectorType *FV = dyn_cast<FixedVectorType>(T)) {
5427 auto R = classifyArgument(FV->getScalarType());
5428 R.second *= FV->getNumElements();
5429 return R;
5430 }
5431
5432 LLVM_DEBUG(errs() << "Unknown vararg type: " << *T << "\n");
5433 return {AK_Memory, 0};
5434 }
5435
5436 // The instrumentation stores the argument shadow in a non ABI-specific
5437 // format because it does not know which argument is named (since Clang,
5438 // like x86_64 case, lowers the va_args in the frontend and this pass only
5439 // sees the low level code that deals with va_list internals).
5440 // The first seven GR registers are saved in the first 56 bytes of the
5441 // va_arg tls arra, followed by the first 8 FP/SIMD registers, and then
5442 // the remaining arguments.
5443 // Using constant offset within the va_arg TLS array allows fast copy
5444 // in the finalize instrumentation.
5445 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5446 unsigned GrOffset = AArch64GrBegOffset;
5447 unsigned VrOffset = AArch64VrBegOffset;
5448 unsigned OverflowOffset = AArch64VAEndOffset;
5449
5450 const DataLayout &DL = F.getDataLayout();
5451 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
5452 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
5453 auto [AK, RegNum] = classifyArgument(A->getType());
5454 if (AK == AK_GeneralPurpose &&
5455 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
5456 AK = AK_Memory;
5457 if (AK == AK_FloatingPoint &&
5458 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
5459 AK = AK_Memory;
5460 Value *Base;
5461 switch (AK) {
5462 case AK_GeneralPurpose:
5463 Base = getShadowPtrForVAArgument(A->getType(), IRB, GrOffset);
5464 GrOffset += 8 * RegNum;
5465 break;
5466 case AK_FloatingPoint:
5467 Base = getShadowPtrForVAArgument(A->getType(), IRB, VrOffset);
5468 VrOffset += 16 * RegNum;
5469 break;
5470 case AK_Memory:
5471 // Don't count fixed arguments in the overflow area - va_start will
5472 // skip right over them.
5473 if (IsFixed)
5474 continue;
5475 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
5476 uint64_t AlignedSize = alignTo(ArgSize, 8);
5477 unsigned BaseOffset = OverflowOffset;
5478 Base = getShadowPtrForVAArgument(A->getType(), IRB, BaseOffset);
5479 OverflowOffset += AlignedSize;
5480 if (OverflowOffset > kParamTLSSize) {
5481 // We have no space to copy shadow there.
5482 CleanUnusedTLS(IRB, Base, BaseOffset);
5483 continue;
5484 }
5485 break;
5486 }
5487 // Count Gp/Vr fixed arguments to their respective offsets, but don't
5488 // bother to actually store a shadow.
5489 if (IsFixed)
5490 continue;
5491 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
5492 }
5493 Constant *OverflowSize =
5494 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
5495 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5496 }
5497
5498 // Retrieve a va_list field of 'void*' size.
5499 Value *getVAField64(IRBuilder<> &IRB, Value *VAListTag, int offset) {
5500 Value *SaveAreaPtrPtr = IRB.CreateIntToPtr(
5501 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5502 ConstantInt::get(MS.IntptrTy, offset)),
5503 PointerType::get(*MS.C, 0));
5504 return IRB.CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
5505 }
5506
5507 // Retrieve a va_list field of 'int' size.
5508 Value *getVAField32(IRBuilder<> &IRB, Value *VAListTag, int offset) {
5509 Value *SaveAreaPtr = IRB.CreateIntToPtr(
5510 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5511 ConstantInt::get(MS.IntptrTy, offset)),
5512 PointerType::get(*MS.C, 0));
5513 Value *SaveArea32 = IRB.CreateLoad(IRB.getInt32Ty(), SaveAreaPtr);
5514 return IRB.CreateSExt(SaveArea32, MS.IntptrTy);
5515 }
5516
5517 void finalizeInstrumentation() override {
5518 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
5519 "finalizeInstrumentation called twice");
5520 if (!VAStartInstrumentationList.empty()) {
5521 // If there is a va_start in this function, make a backup copy of
5522 // va_arg_tls somewhere in the function entry block.
5523 IRBuilder<> IRB(MSV.FnPrologueEnd);
5524 VAArgOverflowSize =
5525 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5526 Value *CopySize = IRB.CreateAdd(
5527 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
5528 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5529 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
5530 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
5531 CopySize, kShadowTLSAlignment, false);
5532
5533 Value *SrcSize = IRB.CreateBinaryIntrinsic(
5534 Intrinsic::umin, CopySize,
5535 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
5536 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
5537 kShadowTLSAlignment, SrcSize);
5538 }
5539
5540 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
5541 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
5542
5543 // Instrument va_start, copy va_list shadow from the backup copy of
5544 // the TLS contents.
5545 for (CallInst *OrigInst : VAStartInstrumentationList) {
5546 NextNodeIRBuilder IRB(OrigInst);
5547
5548 Value *VAListTag = OrigInst->getArgOperand(0);
5549
5550 // The variadic ABI for AArch64 creates two areas to save the incoming
5551 // argument registers (one for 64-bit general register xn-x7 and another
5552 // for 128-bit FP/SIMD vn-v7).
5553 // We need then to propagate the shadow arguments on both regions
5554 // 'va::__gr_top + va::__gr_offs' and 'va::__vr_top + va::__vr_offs'.
5555 // The remaining arguments are saved on shadow for 'va::stack'.
5556 // One caveat is it requires only to propagate the non-named arguments,
5557 // however on the call site instrumentation 'all' the arguments are
5558 // saved. So to copy the shadow values from the va_arg TLS array
5559 // we need to adjust the offset for both GR and VR fields based on
5560 // the __{gr,vr}_offs value (since they are stores based on incoming
5561 // named arguments).
5562 Type *RegSaveAreaPtrTy = IRB.getPtrTy();
5563
5564 // Read the stack pointer from the va_list.
5565 Value *StackSaveAreaPtr =
5566 IRB.CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
5567
5568 // Read both the __gr_top and __gr_off and add them up.
5569 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
5570 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
5571
5572 Value *GrRegSaveAreaPtr = IRB.CreateIntToPtr(
5573 IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
5574
5575 // Read both the __vr_top and __vr_off and add them up.
5576 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
5577 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
5578
5579 Value *VrRegSaveAreaPtr = IRB.CreateIntToPtr(
5580 IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
5581
5582 // It does not know how many named arguments is being used and, on the
5583 // callsite all the arguments were saved. Since __gr_off is defined as
5584 // '0 - ((8 - named_gr) * 8)', the idea is to just propagate the variadic
5585 // argument by ignoring the bytes of shadow from named arguments.
5586 Value *GrRegSaveAreaShadowPtrOff =
5587 IRB.CreateAdd(GrArgSize, GrOffSaveArea);
5588
5589 Value *GrRegSaveAreaShadowPtr =
5590 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5591 Align(8), /*isStore*/ true)
5592 .first;
5593
5594 Value *GrSrcPtr =
5595 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy, GrRegSaveAreaShadowPtrOff);
5596 Value *GrCopySize = IRB.CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
5597
5598 IRB.CreateMemCpy(GrRegSaveAreaShadowPtr, Align(8), GrSrcPtr, Align(8),
5599 GrCopySize);
5600
5601 // Again, but for FP/SIMD values.
5602 Value *VrRegSaveAreaShadowPtrOff =
5603 IRB.CreateAdd(VrArgSize, VrOffSaveArea);
5604
5605 Value *VrRegSaveAreaShadowPtr =
5606 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5607 Align(8), /*isStore*/ true)
5608 .first;
5609
5610 Value *VrSrcPtr = IRB.CreateInBoundsPtrAdd(
5611 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy,
5612 IRB.getInt32(AArch64VrBegOffset)),
5613 VrRegSaveAreaShadowPtrOff);
5614 Value *VrCopySize = IRB.CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
5615
5616 IRB.CreateMemCpy(VrRegSaveAreaShadowPtr, Align(8), VrSrcPtr, Align(8),
5617 VrCopySize);
5618
5619 // And finally for remaining arguments.
5620 Value *StackSaveAreaShadowPtr =
5621 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.getInt8Ty(),
5622 Align(16), /*isStore*/ true)
5623 .first;
5624
5625 Value *StackSrcPtr = IRB.CreateInBoundsPtrAdd(
5626 VAArgTLSCopy, IRB.getInt32(AArch64VAEndOffset));
5627
5628 IRB.CreateMemCpy(StackSaveAreaShadowPtr, Align(16), StackSrcPtr,
5629 Align(16), VAArgOverflowSize);
5630 }
5631 }
5632};
5633
5634/// PowerPC64-specific implementation of VarArgHelper.
5635struct VarArgPowerPC64Helper : public VarArgHelperBase {
5636 AllocaInst *VAArgTLSCopy = nullptr;
5637 Value *VAArgSize = nullptr;
5638
5639 VarArgPowerPC64Helper(Function &F, MemorySanitizer &MS,
5640 MemorySanitizerVisitor &MSV)
5641 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/8) {}
5642
5643 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5644 // For PowerPC, we need to deal with alignment of stack arguments -
5645 // they are mostly aligned to 8 bytes, but vectors and i128 arrays
5646 // are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
5647 // For that reason, we compute current offset from stack pointer (which is
5648 // always properly aligned), and offset for the first vararg, then subtract
5649 // them.
5650 unsigned VAArgBase;
5651 Triple TargetTriple(F.getParent()->getTargetTriple());
5652 // Parameter save area starts at 48 bytes from frame pointer for ABIv1,
5653 // and 32 bytes for ABIv2. This is usually determined by target
5654 // endianness, but in theory could be overridden by function attribute.
5655 if (TargetTriple.getArch() == Triple::ppc64)
5656 VAArgBase = 48;
5657 else
5658 VAArgBase = 32;
5659 unsigned VAArgOffset = VAArgBase;
5660 const DataLayout &DL = F.getDataLayout();
5661 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
5662 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
5663 bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal);
5664 if (IsByVal) {
5665 assert(A->getType()->isPointerTy());
5666 Type *RealTy = CB.getParamByValType(ArgNo);
5667 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
5668 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(8));
5669 if (ArgAlign < 8)
5670 ArgAlign = Align(8);
5671 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
5672 if (!IsFixed) {
5673 Value *Base = getShadowPtrForVAArgument(
5674 RealTy, IRB, VAArgOffset - VAArgBase, ArgSize);
5675 if (Base) {
5676 Value *AShadowPtr, *AOriginPtr;
5677 std::tie(AShadowPtr, AOriginPtr) =
5678 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
5679 kShadowTLSAlignment, /*isStore*/ false);
5680
5681 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
5682 kShadowTLSAlignment, ArgSize);
5683 }
5684 }
5685 VAArgOffset += alignTo(ArgSize, Align(8));
5686 } else {
5687 Value *Base;
5688 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
5689 Align ArgAlign = Align(8);
5690 if (A->getType()->isArrayTy()) {
5691 // Arrays are aligned to element size, except for long double
5692 // arrays, which are aligned to 8 bytes.
5693 Type *ElementTy = A->getType()->getArrayElementType();
5694 if (!ElementTy->isPPC_FP128Ty())
5695 ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
5696 } else if (A->getType()->isVectorTy()) {
5697 // Vectors are naturally aligned.
5698 ArgAlign = Align(ArgSize);
5699 }
5700 if (ArgAlign < 8)
5701 ArgAlign = Align(8);
5702 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
5703 if (DL.isBigEndian()) {
5704 // Adjusting the shadow for argument with size < 8 to match the
5705 // placement of bits in big endian system
5706 if (ArgSize < 8)
5707 VAArgOffset += (8 - ArgSize);
5708 }
5709 if (!IsFixed) {
5710 Base = getShadowPtrForVAArgument(A->getType(), IRB,
5711 VAArgOffset - VAArgBase, ArgSize);
5712 if (Base)
5713 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
5714 }
5715 VAArgOffset += ArgSize;
5716 VAArgOffset = alignTo(VAArgOffset, Align(8));
5717 }
5718 if (IsFixed)
5719 VAArgBase = VAArgOffset;
5720 }
5721
5722 Constant *TotalVAArgSize =
5723 ConstantInt::get(IRB.getInt64Ty(), VAArgOffset - VAArgBase);
5724 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
5725 // a new class member i.e. it is the total size of all VarArgs.
5726 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
5727 }
5728
5729 void finalizeInstrumentation() override {
5730 assert(!VAArgSize && !VAArgTLSCopy &&
5731 "finalizeInstrumentation called twice");
5732 IRBuilder<> IRB(MSV.FnPrologueEnd);
5733 VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5734 Value *CopySize =
5735 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize);
5736
5737 if (!VAStartInstrumentationList.empty()) {
5738 // If there is a va_start in this function, make a backup copy of
5739 // va_arg_tls somewhere in the function entry block.
5740
5741 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5742 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
5743 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
5744 CopySize, kShadowTLSAlignment, false);
5745
5746 Value *SrcSize = IRB.CreateBinaryIntrinsic(
5747 Intrinsic::umin, CopySize,
5748 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
5749 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
5750 kShadowTLSAlignment, SrcSize);
5751 }
5752
5753 // Instrument va_start.
5754 // Copy va_list shadow from the backup copy of the TLS contents.
5755 for (CallInst *OrigInst : VAStartInstrumentationList) {
5756 NextNodeIRBuilder IRB(OrigInst);
5757 Value *VAListTag = OrigInst->getArgOperand(0);
5758 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5759 Value *RegSaveAreaPtrPtr =
5760 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5761 PointerType::get(RegSaveAreaPtrTy, 0));
5762 Value *RegSaveAreaPtr =
5763 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5764 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5765 const Align Alignment = Align(8);
5766 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5767 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5768 Alignment, /*isStore*/ true);
5769 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5770 CopySize);
5771 }
5772 }
5773};
5774
5775/// SystemZ-specific implementation of VarArgHelper.
5776struct VarArgSystemZHelper : public VarArgHelperBase {
5777 static const unsigned SystemZGpOffset = 16;
5778 static const unsigned SystemZGpEndOffset = 56;
5779 static const unsigned SystemZFpOffset = 128;
5780 static const unsigned SystemZFpEndOffset = 160;
5781 static const unsigned SystemZMaxVrArgs = 8;
5782 static const unsigned SystemZRegSaveAreaSize = 160;
5783 static const unsigned SystemZOverflowOffset = 160;
5784 static const unsigned SystemZVAListTagSize = 32;
5785 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
5786 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
5787
5788 bool IsSoftFloatABI;
5789 AllocaInst *VAArgTLSCopy = nullptr;
5790 AllocaInst *VAArgTLSOriginCopy = nullptr;
5791 Value *VAArgOverflowSize = nullptr;
5792
5793 enum class ArgKind {
5794 GeneralPurpose,
5795 FloatingPoint,
5796 Vector,
5797 Memory,
5798 Indirect,
5799 };
5800
5801 enum class ShadowExtension { None, Zero, Sign };
5802
5803 VarArgSystemZHelper(Function &F, MemorySanitizer &MS,
5804 MemorySanitizerVisitor &MSV)
5805 : VarArgHelperBase(F, MS, MSV, SystemZVAListTagSize),
5806 IsSoftFloatABI(F.getFnAttribute("use-soft-float").getValueAsBool()) {}
5807
5808 ArgKind classifyArgument(Type *T) {
5809 // T is a SystemZABIInfo::classifyArgumentType() output, and there are
5810 // only a few possibilities of what it can be. In particular, enums, single
5811 // element structs and large types have already been taken care of.
5812
5813 // Some i128 and fp128 arguments are converted to pointers only in the
5814 // back end.
5815 if (T->isIntegerTy(128) || T->isFP128Ty())
5816 return ArgKind::Indirect;
5817 if (T->isFloatingPointTy())
5818 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
5819 if (T->isIntegerTy() || T->isPointerTy())
5820 return ArgKind::GeneralPurpose;
5821 if (T->isVectorTy())
5822 return ArgKind::Vector;
5823 return ArgKind::Memory;
5824 }
5825
5826 ShadowExtension getShadowExtension(const CallBase &CB, unsigned ArgNo) {
5827 // ABI says: "One of the simple integer types no more than 64 bits wide.
5828 // ... If such an argument is shorter than 64 bits, replace it by a full
5829 // 64-bit integer representing the same number, using sign or zero
5830 // extension". Shadow for an integer argument has the same type as the
5831 // argument itself, so it can be sign or zero extended as well.
5832 bool ZExt = CB.paramHasAttr(ArgNo, Attribute::ZExt);
5833 bool SExt = CB.paramHasAttr(ArgNo, Attribute::SExt);
5834 if (ZExt) {
5835 assert(!SExt);
5836 return ShadowExtension::Zero;
5837 }
5838 if (SExt) {
5839 assert(!ZExt);
5840 return ShadowExtension::Sign;
5841 }
5842 return ShadowExtension::None;
5843 }
5844
5845 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5846 unsigned GpOffset = SystemZGpOffset;
5847 unsigned FpOffset = SystemZFpOffset;
5848 unsigned VrIndex = 0;
5849 unsigned OverflowOffset = SystemZOverflowOffset;
5850 const DataLayout &DL = F.getDataLayout();
5851 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
5852 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
5853 // SystemZABIInfo does not produce ByVal parameters.
5854 assert(!CB.paramHasAttr(ArgNo, Attribute::ByVal));
5855 Type *T = A->getType();
5856 ArgKind AK = classifyArgument(T);
5857 if (AK == ArgKind::Indirect) {
5858 T = PointerType::get(T, 0);
5859 AK = ArgKind::GeneralPurpose;
5860 }
5861 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
5862 AK = ArgKind::Memory;
5863 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
5864 AK = ArgKind::Memory;
5865 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
5866 AK = ArgKind::Memory;
5867 Value *ShadowBase = nullptr;
5868 Value *OriginBase = nullptr;
5869 ShadowExtension SE = ShadowExtension::None;
5870 switch (AK) {
5871 case ArgKind::GeneralPurpose: {
5872 // Always keep track of GpOffset, but store shadow only for varargs.
5873 uint64_t ArgSize = 8;
5874 if (GpOffset + ArgSize <= kParamTLSSize) {
5875 if (!IsFixed) {
5876 SE = getShadowExtension(CB, ArgNo);
5877 uint64_t GapSize = 0;
5878 if (SE == ShadowExtension::None) {
5879 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
5880 assert(ArgAllocSize <= ArgSize);
5881 GapSize = ArgSize - ArgAllocSize;
5882 }
5883 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
5884 if (MS.TrackOrigins)
5885 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
5886 }
5887 GpOffset += ArgSize;
5888 } else {
5889 GpOffset = kParamTLSSize;
5890 }
5891 break;
5892 }
5893 case ArgKind::FloatingPoint: {
5894 // Always keep track of FpOffset, but store shadow only for varargs.
5895 uint64_t ArgSize = 8;
5896 if (FpOffset + ArgSize <= kParamTLSSize) {
5897 if (!IsFixed) {
5898 // PoP says: "A short floating-point datum requires only the
5899 // left-most 32 bit positions of a floating-point register".
5900 // Therefore, in contrast to AK_GeneralPurpose and AK_Memory,
5901 // don't extend shadow and don't mind the gap.
5902 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
5903 if (MS.TrackOrigins)
5904 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
5905 }
5906 FpOffset += ArgSize;
5907 } else {
5908 FpOffset = kParamTLSSize;
5909 }
5910 break;
5911 }
5912 case ArgKind::Vector: {
5913 // Keep track of VrIndex. No need to store shadow, since vector varargs
5914 // go through AK_Memory.
5915 assert(IsFixed);
5916 VrIndex++;
5917 break;
5918 }
5919 case ArgKind::Memory: {
5920 // Keep track of OverflowOffset and store shadow only for varargs.
5921 // Ignore fixed args, since we need to copy only the vararg portion of
5922 // the overflow area shadow.
5923 if (!IsFixed) {
5924 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
5925 uint64_t ArgSize = alignTo(ArgAllocSize, 8);
5926 if (OverflowOffset + ArgSize <= kParamTLSSize) {
5927 SE = getShadowExtension(CB, ArgNo);
5928 uint64_t GapSize =
5929 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
5930 ShadowBase =
5931 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
5932 if (MS.TrackOrigins)
5933 OriginBase =
5934 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
5935 OverflowOffset += ArgSize;
5936 } else {
5937 OverflowOffset = kParamTLSSize;
5938 }
5939 }
5940 break;
5941 }
5942 case ArgKind::Indirect:
5943 llvm_unreachable("Indirect must be converted to GeneralPurpose");
5944 }
5945 if (ShadowBase == nullptr)
5946 continue;
5947 Value *Shadow = MSV.getShadow(A);
5948 if (SE != ShadowExtension::None)
5949 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.getInt64Ty(),
5950 /*Signed*/ SE == ShadowExtension::Sign);
5951 ShadowBase = IRB.CreateIntToPtr(
5952 ShadowBase, PointerType::get(Shadow->getType(), 0), "_msarg_va_s");
5953 IRB.CreateStore(Shadow, ShadowBase);
5954 if (MS.TrackOrigins) {
5955 Value *Origin = MSV.getOrigin(A);
5956 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
5957 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
5959 }
5960 }
5961 Constant *OverflowSize = ConstantInt::get(
5962 IRB.getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
5963 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5964 }
5965
5966 void copyRegSaveArea(IRBuilder<> &IRB, Value *VAListTag) {
5967 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5968 Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
5969 IRB.CreateAdd(
5970 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5971 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
5972 PointerType::get(RegSaveAreaPtrTy, 0));
5973 Value *RegSaveAreaPtr = IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5974 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5975 const Align Alignment = Align(8);
5976 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5977 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), Alignment,
5978 /*isStore*/ true);
5979 // TODO(iii): copy only fragments filled by visitCallBase()
5980 // TODO(iii): support packed-stack && !use-soft-float
5981 // For use-soft-float functions, it is enough to copy just the GPRs.
5982 unsigned RegSaveAreaSize =
5983 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
5984 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5985 RegSaveAreaSize);
5986 if (MS.TrackOrigins)
5987 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
5988 Alignment, RegSaveAreaSize);
5989 }
5990
5991 // FIXME: This implementation limits OverflowOffset to kParamTLSSize, so we
5992 // don't know real overflow size and can't clear shadow beyond kParamTLSSize.
5993 void copyOverflowArea(IRBuilder<> &IRB, Value *VAListTag) {
5994 Type *OverflowArgAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5995 Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
5996 IRB.CreateAdd(
5997 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5998 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
5999 PointerType::get(OverflowArgAreaPtrTy, 0));
6000 Value *OverflowArgAreaPtr =
6001 IRB.CreateLoad(OverflowArgAreaPtrTy, OverflowArgAreaPtrPtr);
6002 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
6003 const Align Alignment = Align(8);
6004 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
6005 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
6006 Alignment, /*isStore*/ true);
6007 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
6008 SystemZOverflowOffset);
6009 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
6010 VAArgOverflowSize);
6011 if (MS.TrackOrigins) {
6012 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
6013 SystemZOverflowOffset);
6014 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
6015 VAArgOverflowSize);
6016 }
6017 }
6018
6019 void finalizeInstrumentation() override {
6020 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
6021 "finalizeInstrumentation called twice");
6022 if (!VAStartInstrumentationList.empty()) {
6023 // If there is a va_start in this function, make a backup copy of
6024 // va_arg_tls somewhere in the function entry block.
6025 IRBuilder<> IRB(MSV.FnPrologueEnd);
6026 VAArgOverflowSize =
6027 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
6028 Value *CopySize =
6029 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
6030 VAArgOverflowSize);
6031 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
6032 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
6033 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
6034 CopySize, kShadowTLSAlignment, false);
6035
6036 Value *SrcSize = IRB.CreateBinaryIntrinsic(
6037 Intrinsic::umin, CopySize,
6038 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
6039 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
6040 kShadowTLSAlignment, SrcSize);
6041 if (MS.TrackOrigins) {
6042 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
6043 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
6044 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
6045 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
6046 }
6047 }
6048
6049 // Instrument va_start.
6050 // Copy va_list shadow from the backup copy of the TLS contents.
6051 for (CallInst *OrigInst : VAStartInstrumentationList) {
6052 NextNodeIRBuilder IRB(OrigInst);
6053 Value *VAListTag = OrigInst->getArgOperand(0);
6054 copyRegSaveArea(IRB, VAListTag);
6055 copyOverflowArea(IRB, VAListTag);
6056 }
6057 }
6058};
6059
6060// Loongarch64 is not a MIPS, but the current vargs calling convention matches
6061// the MIPS.
6062using VarArgLoongArch64Helper = VarArgMIPS64Helper;
6063
6064/// A no-op implementation of VarArgHelper.
6065struct VarArgNoOpHelper : public VarArgHelper {
6066 VarArgNoOpHelper(Function &F, MemorySanitizer &MS,
6067 MemorySanitizerVisitor &MSV) {}
6068
6069 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {}
6070
6071 void visitVAStartInst(VAStartInst &I) override {}
6072
6073 void visitVACopyInst(VACopyInst &I) override {}
6074
6075 void finalizeInstrumentation() override {}
6076};
6077
6078} // end anonymous namespace
6079
6080static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
6081 MemorySanitizerVisitor &Visitor) {
6082 // VarArg handling is only implemented on AMD64. False positives are possible
6083 // on other platforms.
6084 Triple TargetTriple(Func.getParent()->getTargetTriple());
6085 if (TargetTriple.getArch() == Triple::x86_64)
6086 return new VarArgAMD64Helper(Func, Msan, Visitor);
6087 else if (TargetTriple.isMIPS64())
6088 return new VarArgMIPS64Helper(Func, Msan, Visitor);
6089 else if (TargetTriple.getArch() == Triple::aarch64)
6090 return new VarArgAArch64Helper(Func, Msan, Visitor);
6091 else if (TargetTriple.getArch() == Triple::ppc64 ||
6092 TargetTriple.getArch() == Triple::ppc64le)
6093 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
6094 else if (TargetTriple.getArch() == Triple::systemz)
6095 return new VarArgSystemZHelper(Func, Msan, Visitor);
6096 else if (TargetTriple.isLoongArch64())
6097 return new VarArgLoongArch64Helper(Func, Msan, Visitor);
6098 else
6099 return new VarArgNoOpHelper(Func, Msan, Visitor);
6100}
6101
6102bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
6103 if (!CompileKernel && F.getName() == kMsanModuleCtorName)
6104 return false;
6105
6106 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
6107 return false;
6108
6109 MemorySanitizerVisitor Visitor(F, *this, TLI);
6110
6111 // Clear out memory attributes.
6113 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
6114 F.removeFnAttrs(B);
6115
6116 return Visitor.runOnFunction();
6117}
static const LLT S1
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...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
static bool isAMustTailRetVal(Value *RetVal)
return RetTy
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
Definition: DebugCounter.h:190
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
@ Default
Definition: DwarfDebug.cpp:87
uint64_t Addr
std::string Name
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
static bool runOnFunction(Function &F, bool PostInlining)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
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 _
Hexagon Vector Combine
static LVOptions Options
Definition: LVOptions.cpp:25
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static const MemoryMapParams Linux_LoongArch64_MemoryMapParams
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< uint64_t > ClShadowBase("msan-shadow-base", cl::desc("Define custom MSan ShadowBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClDumpStrictInstructions("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClHandleICmpExact("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(false))
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static cl::opt< uint64_t > ClOriginBase("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClCheckConstantShadow("msan-check-constant-shadow", cl::desc("Insert checks for constant shadow values"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static cl::opt< bool > ClWithComdat("msan-with-comdat", cl::desc("Place MSan constructors in comdat sections"), cl::Hidden, cl::init(false))
static cl::opt< int > ClTrackOrigins("msan-track-origins", cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden, cl::init(0))
Track origins of uninitialized values.
static cl::opt< int > ClInstrumentationWithCallThreshold("msan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of checks and origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< int > ClPoisonStackPattern("msan-poison-stack-pattern", cl::desc("poison uninitialized stack variables with the given pattern"), cl::Hidden, cl::init(0xff))
static const Align kShadowTLSAlignment
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static const MemoryMapParams Linux_S390X_MemoryMapParams
static cl::opt< bool > ClPoisonUndef("msan-poison-undef", cl::desc("poison undef temps"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClPoisonStack("msan-poison-stack", cl::desc("poison uninitialized stack variables"), cl::Hidden, cl::init(true))
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
static cl::opt< bool > ClPrintStackNames("msan-print-stack-names", cl::desc("Print name of local stack variable"), cl::Hidden, cl::init(true))
static const MemoryMapParams Linux_AArch64_MemoryMapParams
static cl::opt< uint64_t > ClAndMask("msan-and-mask", cl::desc("Define custom MSan AndMask"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClHandleLifetimeIntrinsics("msan-handle-lifetime-intrinsics", cl::desc("when possible, poison scoped variables at the beginning of the scope " "(slower, but more precise)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKeepGoing("msan-keep-going", cl::desc("keep going after reporting a UMR"), cl::Hidden, cl::init(false))
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 cl::opt< bool > ClEagerChecks("msan-eager-checks", cl::desc("check arguments and return values at function call boundaries"), cl::Hidden, cl::init(false))
static cl::opt< int > ClDisambiguateWarning("msan-disambiguate-warning-threshold", cl::desc("Define threshold for number of checks per " "debug location to force origin update."), cl::Hidden, cl::init(3))
static VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static cl::opt< uint64_t > ClXorMask("msan-xor-mask", cl::desc("Define custom MSan XorMask"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClHandleAsmConservative("msan-handle-asm-conservative", cl::desc("conservative handling of inline assembly"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static cl::opt< bool > ClHandleICmp("msan-handle-icmp", cl::desc("propagate shadow through ICmpEQ and ICmpNE"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClEnableKmsan("msan-kernel", cl::desc("Enable KernelMemorySanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClPoisonStackWithCall("msan-poison-stack-with-call", cl::desc("poison uninitialized stack variables with a call"), cl::Hidden, cl::init(false))
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
static cl::opt< bool > ClCheckAccessAddress("msan-check-access-address", cl::desc("report accesses through a pointer which has poisoned shadow"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDisableChecks("msan-disable-checks", cl::desc("Apply no_sanitize to the whole file"), cl::Hidden, cl::init(false))
Module.h This file contains the declarations for the Module class.
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:50
raw_pwrite_stream & OS
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.
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:40
@ Struct
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:78
an instruction to allocate memory on the stack
Definition: Instructions.h:61
void setAlignment(Align Align)
Definition: Instructions.h:126
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:405
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:168
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:635
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:495
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:696
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
iterator end()
Definition: BasicBlock.h:461
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:416
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
Definition: BasicBlock.cpp:459
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:177
This class represents a no-op cast from one type to another.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1236
bool isInlineAsm() const
Check if this call is an inline asm statement.
Definition: InstrTypes.h:1532
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1465
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
Definition: InstrTypes.h:1673
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
void setCannotMerge()
Definition: InstrTypes.h:2024
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Definition: InstrTypes.h:1838
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Definition: InstrTypes.h:1856
Value * getCalledOperand() const
Definition: InstrTypes.h:1458
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Definition: InstrTypes.h:1894
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1410
void setArgOperand(unsigned i, Value *v)
Definition: InstrTypes.h:1415
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1323
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1401
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Definition: InstrTypes.h:1594
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:530
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:757
@ ICMP_SLT
signed less than
Definition: InstrTypes.h:786
@ ICMP_SLE
signed less or equal
Definition: InstrTypes.h:787
@ ICMP_SGT
signed greater than
Definition: InstrTypes.h:784
@ ICMP_SGE
signed greater or equal
Definition: InstrTypes.h:785
Combiner implementation.
Definition: Combiner.h:34
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1292
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
Definition: Constants.cpp:2950
static Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
Definition: Constants.cpp:2966
This is the shared class of boolean and integer constants.
Definition: Constants.h:81
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
Definition: Constants.h:124
static ConstantInt * getBool(LLVMContext &Context, bool V)
Definition: Constants.cpp:864
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1357
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
Definition: Constants.cpp:1450
static Constant * get(ArrayRef< Constant * > V)
Definition: Constants.cpp:1399
This is an important base class in LLVM.
Definition: Constant.h:42
static Constant * getAllOnesValue(Type *Ty)
Definition: Constants.cpp:417
bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
Definition: Constants.cpp:107
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:370
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
Definition: Constants.cpp:432
bool isZeroValue() const
Return true if the value is negative zero or null value.
Definition: Constants.cpp:76
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition: Constants.cpp:90
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
static bool shouldExecute(unsigned CounterName)
Definition: DebugCounter.h:87
A debug info location.
Definition: DebugLoc.h:33
bool empty() const
Definition: DenseMap.h:98
This instruction extracts a single (scalar) element from a VectorType value.
This instruction extracts a struct member or array element value from an aggregate value.
This instruction compares its operands according to the predicate given to the constructor.
Class to represent fixed width SIMD vectors.
Definition: DerivedTypes.h:539
unsigned getNumElements() const
Definition: DerivedTypes.h:582
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:680
This class represents a freeze function that returns random concrete value if an operand is either a ...
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:168
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:142
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:915
void setComdat(Comdat *C)
Definition: Globals.cpp:206
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:60
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:52
Analysis pass providing a never-invalidated alias analysis result.
This instruction compares its operands according to the predicate given to the constructor.
CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Definition: IRBuilder.cpp:705
CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Definition: IRBuilder.cpp:687
Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
Definition: IRBuilder.cpp:922
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2492
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition: IRBuilder.h:1896
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition: IRBuilder.h:1790
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition: IRBuilder.h:508
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2543
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2480
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition: IRBuilder.h:536
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition: IRBuilder.h:1824
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Definition: IRBuilder.h:2059
CallInst * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Definition: IRBuilder.cpp:442
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2190
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2536
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Definition: IRBuilder.cpp:933
CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
Definition: IRBuilder.cpp:579
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
Definition: IRBuilder.h:592
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Definition: IRBuilder.cpp:1091
BasicBlock::iterator GetInsertPoint() const
Definition: IRBuilder.h:172
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2053
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2142
Value * CreateTypeSize(Type *DstType, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Definition: IRBuilder.cpp:105
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1454
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:523
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Definition: IRBuilder.h:473
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition: IRBuilder.h:528
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1395
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2265
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition: IRBuilder.h:1883
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Definition: IRBuilder.h:1738
CallInst * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
Definition: IRBuilder.cpp:446
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:483
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition: IRBuilder.h:2417
Value * CreateNot(Value *V, const Twine &Name="")
Definition: IRBuilder.h:1766
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2261
DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Definition: IRBuilder.cpp:64
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1361
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2147
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended or truncated from a 64-bit value.
Definition: IRBuilder.h:494
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:1807
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1433
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition: IRBuilder.h:2041
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition: IRBuilder.h:2514
LLVMContext & getContext() const
Definition: IRBuilder.h:173
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1492
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1820
CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Definition: IRBuilder.cpp:599
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1344
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2137
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Definition: IRBuilder.h:2569
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition: IRBuilder.h:2027
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1514
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition: IRBuilder.h:566
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1683
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2293
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition: IRBuilder.h:2216
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
Definition: IRBuilder.h:2564
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:177
Type * getVoidTy()
Fetch the type representing void.
Definition: IRBuilder.h:561
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition: IRBuilder.h:1843
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2432
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Definition: IRBuilder.h:2001
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1473
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1536
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2371
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition: IRBuilder.h:513
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *TBAAStructTag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memcpy between the specified pointers.
Definition: IRBuilder.h:656
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1378
CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
Definition: IRBuilder.cpp:662
CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
Definition: IRBuilder.cpp:631
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2686
std::vector< ConstraintInfo > ConstraintInfoVector
Definition: InlineAsm.h:121
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:563
This instruction inserts a single (scalar) element into a VectorType value.
This instruction inserts a struct field of array element value into an aggregate value.
Base class for instruction visitors.
Definition: InstVisitor.h:78
void visit(Iterator Start, Iterator End)
Definition: InstVisitor.h:87
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:466
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:381
This class represents a cast from an integer to a pointer.
Class to represent integer types.
Definition: DerivedTypes.h:40
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:266
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:48
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
The landingpad instruction holds all of the information necessary to generate correct exception handl...
An instruction for reading from memory.
Definition: Instructions.h:174
MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition: MDBuilder.cpp:47
Metadata node.
Definition: Metadata.h:1069
This class wraps the llvm.memcpy intrinsic.
This class wraps the llvm.memmove intrinsic.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
Definition: Constants.h:1446
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1852
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:114
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
void abandon()
Mark an analysis as abandoned.
Definition: Analysis.h:164
This class represents a cast from a pointer to an integer.
Resume the propagation of an exception.
Return a value (possibly void), from a function.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
bool remove(const value_type &X)
Remove an item from the set vector.
Definition: SetVector.h:188
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
This instruction constructs a fixed permutation of two input vectors.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:502
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:370
bool empty() const
Definition: SmallVector.h:94
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:696
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
An instruction for storing to memory.
Definition: Instructions.h:290
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Class to represent struct types.
Definition: DerivedTypes.h:216
static 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:361
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
Definition: Triple.h:943
@ aarch64_be
Definition: Triple.h:52
@ loongarch64
Definition: Triple.h:62
@ mips64el
Definition: Triple.h:67
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:373
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
Definition: Triple.h:932
This class represents a truncation of integer types.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:261
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:251
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
Definition: Type.h:165
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:298
static IntegerType * getInt8Ty(LLVMContext &C)
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
Definition: Type.h:239
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:224
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition: Type.h:343
'undef' values are things that do not have specified contents.
Definition: Constants.h:1398
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
Value * getOperand(unsigned i) const
Definition: User.h:169
unsigned getNumOperands() const
Definition: User.h:191
This represents the llvm.va_copy intrinsic.
This represents the llvm.va_start intrinsic.
See the file comment.
Definition: ValueMap.h:84
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: ValueMap.h:151
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:377
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
Type * getElementType() const
Definition: DerivedTypes.h:436
This class represents zero extension of integer types.
int getNumOccurrences() const
Definition: CommandLine.h:399
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:202
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition: ilist_node.h:32
self_iterator getIterator()
Definition: ilist_node.h:132
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This class provides various memory handling functions that manipulate MemoryBlock instances.
Definition: Memory.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
Definition: BitmaskEnum.h:121
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
Definition: CallingConv.h:159
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1539
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
Function * Kernel
Summary of a kernel (=entry point for target offloading).
Definition: OpenMPOpt.h:21
NodeAddr< FuncNode * > Func
Definition: RDFGraph.h:393
@ FalseVal
Definition: TGLexer.h:59
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
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:353
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:1680
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:2431
AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
@ Done
Definition: Threading.h:61
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.
@ None
Definition: CodeGenData.h:101
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
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.
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.
@ Or
Bitwise or logical OR of integers.
@ Add
Sum of integers.
std::pair< Instruction *, Value * > SplitBlockAndInsertSimpleForLoop(Value *End, Instruction *SplitBefore)
Insert a for (int i = 0; i < End; i++) loop structure (with the exception that End is assumed > 0,...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:191
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.
Definition: ModuleUtils.cpp:74
iterator_range< df_iterator< T > > depth_first(const T &G)
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 ...
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:4103
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition: Local.cpp:3202
bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:69