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