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