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