LLVM 24.0.0git
MemorySanitizer.cpp
Go to the documentation of this file.
1//===- MemorySanitizer.cpp - detector of uninitialized reads --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// This file is a part of MemorySanitizer, a detector of uninitialized
11/// reads.
12///
13/// The algorithm of the tool is similar to Memcheck
14/// (https://static.usenix.org/event/usenix05/tech/general/full_papers/seward/seward_html/usenix2005.html)
15/// We associate a few shadow bits with every byte of the application memory,
16/// poison the shadow of the malloc-ed or alloca-ed memory, load the shadow,
17/// bits on every memory read, propagate the shadow bits through some of the
18/// arithmetic instruction (including MOV), store the shadow bits on every
19/// memory write, report a bug on some other instructions (e.g. JMP) if the
20/// associated shadow is poisoned.
21///
22/// But there are differences too. The first and the major one:
23/// compiler instrumentation instead of binary instrumentation. This
24/// gives us much better register allocation, possible compiler
25/// optimizations and a fast start-up. But this brings the major issue
26/// as well: msan needs to see all program events, including system
27/// calls and reads/writes in system libraries, so we either need to
28/// compile *everything* with msan or use a binary translation
29/// component (e.g. DynamoRIO) to instrument pre-built libraries.
30/// Another difference from Memcheck is that we use 8 shadow bits per
31/// byte of application memory and use a direct shadow mapping. This
32/// greatly simplifies the instrumentation code and avoids races on
33/// shadow updates (Memcheck is single-threaded so races are not a
34/// concern there. Memcheck uses 2 shadow bits per byte with a slow
35/// path storage that uses 8 bits per byte).
36///
37/// The default value of shadow is 0, which means "clean" (not poisoned).
38///
39/// Every module initializer should call __msan_init to ensure that the
40/// shadow memory is ready. On error, __msan_warning is called. Since
41/// parameters and return values may be passed via registers, we have a
42/// specialized thread-local shadow for return values
43/// (__msan_retval_tls) and parameters (__msan_param_tls).
44///
45/// Origin tracking.
46///
47/// MemorySanitizer can track origins (allocation points) of all uninitialized
48/// values. This behavior is controlled with a flag (msan-track-origins) and is
49/// disabled by default.
50///
51/// Origins are 4-byte values created and interpreted by the runtime library.
52/// They are stored in a second shadow mapping, one 4-byte value for 4 bytes
53/// of application memory. Propagation of origins is basically a bunch of
54/// "select" instructions that pick the origin of a dirty argument, if an
55/// instruction has one.
56///
57/// Every 4 aligned, consecutive bytes of application memory have one origin
58/// value associated with them. If these bytes contain uninitialized data
59/// coming from 2 different allocations, the last store wins. Because of this,
60/// MemorySanitizer reports can show unrelated origins, but this is unlikely in
61/// practice.
62///
63/// Origins are meaningless for fully initialized values, so MemorySanitizer
64/// avoids storing origin to memory when a fully initialized value is stored.
65/// This way it avoids needless overwriting origin of the 4-byte region on
66/// a short (i.e. 1 byte) clean store, and it is also good for performance.
67///
68/// Atomic handling.
69///
70/// Ideally, every atomic store of application value should update the
71/// corresponding shadow location in an atomic way. Unfortunately, atomic store
72/// of two disjoint locations can not be done without severe slowdown.
73///
74/// Therefore, we implement an approximation that may err on the safe side.
75/// In this implementation, every atomically accessed location in the program
76/// may only change from (partially) uninitialized to fully initialized, but
77/// not the other way around. We load the shadow _after_ the application load,
78/// and we store the shadow _before_ the app store. Also, we always store clean
79/// shadow (if the application store is atomic). This way, if the store-load
80/// pair constitutes a happens-before arc, shadow store and load are correctly
81/// ordered such that the load will get either the value that was stored, or
82/// some later value (which is always clean).
83///
84/// This does not work very well with Compare-And-Swap (CAS) and
85/// Read-Modify-Write (RMW) operations. To follow the above logic, CAS and RMW
86/// must store the new shadow before the app operation, and load the shadow
87/// after the app operation. Computers don't work this way. Current
88/// implementation ignores the load aspect of CAS/RMW, always returning a clean
89/// value. It implements the store part as a simple atomic store by storing a
90/// clean shadow.
91///
92/// Instrumenting inline assembly.
93///
94/// For inline assembly code LLVM has little idea about which memory locations
95/// become initialized depending on the arguments. It can be possible to figure
96/// out which arguments are meant to point to inputs and outputs, but the
97/// actual semantics can be only visible at runtime. In the Linux kernel it's
98/// also possible that the arguments only indicate the offset for a base taken
99/// from a segment register, so it's dangerous to treat any asm() arguments as
100/// pointers. We take a conservative approach generating calls to
101/// __msan_instrument_asm_store(ptr, size)
102/// , which defer the memory unpoisoning to the runtime library.
103/// The latter can perform more complex address checks to figure out whether
104/// it's safe to touch the shadow memory.
105/// Like with atomic operations, we call __msan_instrument_asm_store() before
106/// the assembly call, so that changes to the shadow memory will be seen by
107/// other threads together with main memory initialization.
108///
109/// KernelMemorySanitizer (KMSAN) implementation.
110///
111/// The major differences between KMSAN and MSan instrumentation are:
112/// - KMSAN always tracks the origins and implies msan-keep-going=true;
113/// - KMSAN allocates shadow and origin memory for each page separately, so
114/// there are no explicit accesses to shadow and origin in the
115/// instrumentation.
116/// Shadow and origin values for a particular X-byte memory location
117/// (X=1,2,4,8) are accessed through pointers obtained via the
118/// __msan_metadata_ptr_for_load_X(ptr)
119/// __msan_metadata_ptr_for_store_X(ptr)
120/// functions. The corresponding functions check that the X-byte accesses
121/// are possible and returns the pointers to shadow and origin memory.
122/// Arbitrary sized accesses are handled with:
123/// __msan_metadata_ptr_for_load_n(ptr, size)
124/// __msan_metadata_ptr_for_store_n(ptr, size);
125/// Note that the sanitizer code has to deal with how shadow/origin pairs
126/// returned by the these functions are represented in different ABIs. In
127/// the X86_64 ABI they are returned in RDX:RAX, in PowerPC64 they are
128/// returned in r3 and r4, and in the SystemZ ABI they are written to memory
129/// pointed to by a hidden parameter.
130/// - TLS variables are stored in a single per-task struct. A call to a
131/// function __msan_get_context_state() returning a pointer to that struct
132/// is inserted into every instrumented function before the entry block;
133/// - __msan_warning() takes a 32-bit origin parameter;
134/// - local variables are poisoned with __msan_poison_alloca() upon function
135/// entry and unpoisoned with __msan_unpoison_alloca() before leaving the
136/// function;
137/// - the pass doesn't declare any global variables or add global constructors
138/// to the translation unit.
139///
140/// Also, KMSAN currently ignores uninitialized memory passed into inline asm
141/// calls, making sure we're on the safe side wrt. possible false positives.
142///
143/// KernelMemorySanitizer only supports X86_64, SystemZ and PowerPC64 at the
144/// moment.
145///
146//
147// FIXME: This sanitizer does not yet handle scalable vectors
148//
149//===----------------------------------------------------------------------===//
150
152#include "llvm/ADT/APInt.h"
153#include "llvm/ADT/ArrayRef.h"
154#include "llvm/ADT/DenseMap.h"
156#include "llvm/ADT/SetVector.h"
157#include "llvm/ADT/SmallPtrSet.h"
158#include "llvm/ADT/SmallVector.h"
160#include "llvm/ADT/StringRef.h"
164#include "llvm/IR/Argument.h"
166#include "llvm/IR/Attributes.h"
167#include "llvm/IR/BasicBlock.h"
168#include "llvm/IR/CallingConv.h"
169#include "llvm/IR/Constant.h"
170#include "llvm/IR/Constants.h"
171#include "llvm/IR/DataLayout.h"
172#include "llvm/IR/DerivedTypes.h"
173#include "llvm/IR/Function.h"
174#include "llvm/IR/GlobalValue.h"
176#include "llvm/IR/IRBuilder.h"
177#include "llvm/IR/InlineAsm.h"
178#include "llvm/IR/InstVisitor.h"
179#include "llvm/IR/InstrTypes.h"
180#include "llvm/IR/Instruction.h"
181#include "llvm/IR/Instructions.h"
183#include "llvm/IR/Intrinsics.h"
184#include "llvm/IR/IntrinsicsAArch64.h"
185#include "llvm/IR/IntrinsicsX86.h"
186#include "llvm/IR/MDBuilder.h"
187#include "llvm/IR/Module.h"
188#include "llvm/IR/Type.h"
189#include "llvm/IR/Value.h"
190#include "llvm/IR/ValueMap.h"
193#include "llvm/Support/Casting.h"
195#include "llvm/Support/Debug.h"
205#include <algorithm>
206#include <cassert>
207#include <cstddef>
208#include <cstdint>
209#include <memory>
210#include <numeric>
211#include <string>
212#include <tuple>
213
214using namespace llvm;
215
216#define DEBUG_TYPE "msan"
217
218DEBUG_COUNTER(DebugInsertCheck, "msan-insert-check",
219 "Controls which checks to insert");
220
221DEBUG_COUNTER(DebugInstrumentInstruction, "msan-instrument-instruction",
222 "Controls which instruction to instrument");
223
224static const unsigned kOriginSize = 4;
227
228// These constants must be kept in sync with the ones in msan.h.
229// TODO: increase size to match SVE/SVE2/SME/SME2 limits
230static const unsigned kParamTLSSize = 800;
231static const unsigned kRetvalTLSSize = 800;
232
233// Accesses sizes are powers of two: 1, 2, 4, 8.
234static const size_t kNumberOfAccessSizes = 4;
235
236/// Track origins of uninitialized values.
237///
238/// Adds a section to MemorySanitizer report that points to the allocation
239/// (stack or heap) the uninitialized bits came from originally.
241 "msan-track-origins",
242 cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden,
243 cl::init(0));
244
245static cl::opt<bool> ClKeepGoing("msan-keep-going",
246 cl::desc("keep going after reporting a UMR"),
247 cl::Hidden, cl::init(false));
248
249static cl::opt<bool>
250 ClPoisonStack("msan-poison-stack",
251 cl::desc("poison uninitialized stack variables"), cl::Hidden,
252 cl::init(true));
253
255 "msan-poison-stack-with-call",
256 cl::desc("poison uninitialized stack variables with a call"), cl::Hidden,
257 cl::init(false));
258
260 "msan-poison-stack-pattern",
261 cl::desc("poison uninitialized stack variables with the given pattern"),
262 cl::Hidden, cl::init(0xff));
263
264static cl::opt<bool>
265 ClPrintStackNames("msan-print-stack-names",
266 cl::desc("Print name of local stack variable"),
267 cl::Hidden, cl::init(true));
268
269static cl::opt<bool>
270 ClPoisonUndef("msan-poison-undef",
271 cl::desc("Poison fully undef temporary values. "
272 "Partially undefined constant vectors "
273 "are unaffected by this flag (see "
274 "-msan-poison-undef-vectors)."),
275 cl::Hidden, cl::init(true));
276
278 "msan-poison-undef-vectors",
279 cl::desc("Precisely poison partially undefined constant vectors. "
280 "If false (legacy behavior), the entire vector is "
281 "considered fully initialized, which may lead to false "
282 "negatives. Fully undefined constant vectors are "
283 "unaffected by this flag (see -msan-poison-undef)."),
284 cl::Hidden, cl::init(false));
285
287 "msan-precise-disjoint-or",
288 cl::desc("Precisely poison disjoint OR. If false (legacy behavior), "
289 "disjointedness is ignored (i.e., 1|1 is initialized)."),
290 cl::Hidden, cl::init(false));
291
292static cl::opt<bool>
293 ClHandleICmp("msan-handle-icmp",
294 cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
295 cl::Hidden, cl::init(true));
296
297static cl::opt<bool>
298 ClHandleICmpExact("msan-handle-icmp-exact",
299 cl::desc("exact handling of relational integer ICmp"),
300 cl::Hidden, cl::init(true));
301
303 "msan-switch-precision",
304 cl::desc("Controls the number of cases considered by MSan for LLVM switch "
305 "instructions. 0 means no UUMs detected. Higher values lead to "
306 "fewer false negatives but may impact compiler and/or "
307 "application performance. N.B. LLVM switch instructions do not "
308 "correspond exactly to C++ switch statements."),
309 cl::Hidden, cl::init(99));
310
312 "msan-handle-lifetime-intrinsics",
313 cl::desc(
314 "when possible, poison scoped variables at the beginning of the scope "
315 "(slower, but more precise)"),
316 cl::Hidden, cl::init(true));
317
318// When compiling the Linux kernel, we sometimes see false positives related to
319// MSan being unable to understand that inline assembly calls may initialize
320// local variables.
321// This flag makes the compiler conservatively unpoison every memory location
322// passed into an assembly call. Note that this may cause false positives.
323// Because it's impossible to figure out the array sizes, we can only unpoison
324// the first sizeof(type) bytes for each type* pointer.
326 "msan-handle-asm-conservative",
327 cl::desc("conservative handling of inline assembly"), cl::Hidden,
328 cl::init(true));
329
330// This flag controls whether we check the shadow of the address
331// operand of load or store. Such bugs are very rare, since load from
332// a garbage address typically results in SEGV, but still happen
333// (e.g. only lower bits of address are garbage, or the access happens
334// early at program startup where malloc-ed memory is more likely to
335// be zeroed. As of 2012-08-28 this flag adds 20% slowdown.
337 "msan-check-access-address",
338 cl::desc("report accesses through a pointer which has poisoned shadow"),
339 cl::Hidden, cl::init(true));
340
342 "msan-eager-checks",
343 cl::desc("check arguments and return values at function call boundaries"),
344 cl::Hidden, cl::init(false));
345
347 "msan-dump-strict-instructions",
348 cl::desc("print out instructions with default strict semantics i.e.,"
349 "check that all the inputs are fully initialized, and mark "
350 "the output as fully initialized. These semantics are applied "
351 "to instructions that could not be handled explicitly nor "
352 "heuristically."),
353 cl::Hidden, cl::init(false));
354
355// Currently, all the heuristically handled instructions are specifically
356// IntrinsicInst. However, we use the broader "HeuristicInstructions" name
357// to parallel 'msan-dump-strict-instructions', and to keep the door open to
358// handling non-intrinsic instructions heuristically.
360 "msan-dump-heuristic-instructions",
361 cl::desc("Prints 'unknown' instructions that were handled heuristically. "
362 "Use -msan-dump-strict-instructions to print instructions that "
363 "could not be handled explicitly nor heuristically."),
364 cl::Hidden, cl::init(false));
365
367 "msan-instrumentation-with-call-threshold",
368 cl::desc(
369 "If the function being instrumented requires more than "
370 "this number of checks and origin stores, use callbacks instead of "
371 "inline checks (-1 means never use callbacks)."),
372 cl::Hidden, cl::init(3500));
373
374static cl::opt<bool>
375 ClEnableKmsan("msan-kernel",
376 cl::desc("Enable KernelMemorySanitizer instrumentation"),
377 cl::Hidden, cl::init(false));
378
379static cl::opt<bool>
380 ClDisableChecks("msan-disable-checks",
381 cl::desc("Apply no_sanitize to the whole file"), cl::Hidden,
382 cl::init(false));
383
384static cl::opt<bool>
385 ClCheckConstantShadow("msan-check-constant-shadow",
386 cl::desc("Insert checks for constant shadow values"),
387 cl::Hidden, cl::init(true));
388
389// This is off by default because of a bug in gold:
390// https://sourceware.org/bugzilla/show_bug.cgi?id=19002
391static cl::opt<bool>
392 ClWithComdat("msan-with-comdat",
393 cl::desc("Place MSan constructors in comdat sections"),
394 cl::Hidden, cl::init(false));
395
396// These options allow to specify custom memory map parameters
397// See MemoryMapParams for details.
398static cl::opt<uint64_t> ClAndMask("msan-and-mask",
399 cl::desc("Define custom MSan AndMask"),
400 cl::Hidden, cl::init(0));
401
402static cl::opt<uint64_t> ClXorMask("msan-xor-mask",
403 cl::desc("Define custom MSan XorMask"),
404 cl::Hidden, cl::init(0));
405
406static cl::opt<uint64_t> ClShadowBase("msan-shadow-base",
407 cl::desc("Define custom MSan ShadowBase"),
408 cl::Hidden, cl::init(0));
409
410static cl::opt<uint64_t> ClOriginBase("msan-origin-base",
411 cl::desc("Define custom MSan OriginBase"),
412 cl::Hidden, cl::init(0));
413
414static cl::opt<int>
415 ClDisambiguateWarning("msan-disambiguate-warning-threshold",
416 cl::desc("Define threshold for number of checks per "
417 "debug location to force origin update."),
418 cl::Hidden, cl::init(3));
419
420const char kMsanModuleCtorName[] = "msan.module_ctor";
421const char kMsanInitName[] = "__msan_init";
422
423namespace {
424
425// Memory map parameters used in application-to-shadow address calculation.
426// Offset = (Addr & ~AndMask) ^ XorMask
427// Shadow = ShadowBase + Offset
428// Origin = OriginBase + Offset
429struct MemoryMapParams {
430 uint64_t AndMask;
431 uint64_t XorMask;
432 uint64_t ShadowBase;
433 uint64_t OriginBase;
434};
435
436struct PlatformMemoryMapParams {
437 const MemoryMapParams *bits32;
438 const MemoryMapParams *bits64;
439};
440
441} // end anonymous namespace
442
443// i386 Linux
444static const MemoryMapParams Linux_I386_MemoryMapParams = {
445 0x000080000000, // AndMask
446 0, // XorMask (not used)
447 0, // ShadowBase (not used)
448 0x000040000000, // OriginBase
449};
450
451// x86_64 Linux
452static const MemoryMapParams Linux_X86_64_MemoryMapParams = {
453 0, // AndMask (not used)
454 0x500000000000, // XorMask
455 0, // ShadowBase (not used)
456 0x100000000000, // OriginBase
457};
458
459// mips32 Linux
460// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
461// after picking good constants
462
463// mips64 Linux
464static const MemoryMapParams Linux_MIPS64_MemoryMapParams = {
465 0, // AndMask (not used)
466 0x008000000000, // XorMask
467 0, // ShadowBase (not used)
468 0x002000000000, // OriginBase
469};
470
471// ppc32 Linux
472// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
473// after picking good constants
474
475// ppc64 Linux
476static const MemoryMapParams Linux_PowerPC64_MemoryMapParams = {
477 0xE00000000000, // AndMask
478 0x100000000000, // XorMask
479 0x080000000000, // ShadowBase
480 0x1C0000000000, // OriginBase
481};
482
483// s390x Linux
484static const MemoryMapParams Linux_S390X_MemoryMapParams = {
485 0xC00000000000, // AndMask
486 0, // XorMask (not used)
487 0x080000000000, // ShadowBase
488 0x1C0000000000, // OriginBase
489};
490
491// arm32 Linux
492// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
493// after picking good constants
494
495// aarch64 Linux
496static const MemoryMapParams Linux_AArch64_MemoryMapParams = {
497 0, // AndMask (not used)
498 0x0B00000000000, // XorMask
499 0, // ShadowBase (not used)
500 0x0200000000000, // OriginBase
501};
502
503// loongarch64 Linux
504static const MemoryMapParams Linux_LoongArch64_MemoryMapParams = {
505 0, // AndMask (not used)
506 0x500000000000, // XorMask
507 0, // ShadowBase (not used)
508 0x100000000000, // OriginBase
509};
510
511// hexagon Linux
512static const MemoryMapParams Linux_Hexagon_MemoryMapParams = {
513 0, // AndMask (not used)
514 0x20000000, // XorMask
515 0, // ShadowBase (not used)
516 0x50000000, // OriginBase
517};
518
519// riscv32 Linux
520// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
521// after picking good constants
522
523// aarch64 FreeBSD
524static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams = {
525 0x1800000000000, // AndMask
526 0x0400000000000, // XorMask
527 0x0200000000000, // ShadowBase
528 0x0700000000000, // OriginBase
529};
530
531// i386 FreeBSD
532static const MemoryMapParams FreeBSD_I386_MemoryMapParams = {
533 0x000180000000, // AndMask
534 0x000040000000, // XorMask
535 0x000020000000, // ShadowBase
536 0x000700000000, // OriginBase
537};
538
539// x86_64 FreeBSD
540static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams = {
541 0xc00000000000, // AndMask
542 0x200000000000, // XorMask
543 0x100000000000, // ShadowBase
544 0x380000000000, // OriginBase
545};
546
547// x86_64 NetBSD
548static const MemoryMapParams NetBSD_X86_64_MemoryMapParams = {
549 0, // AndMask
550 0x500000000000, // XorMask
551 0, // ShadowBase
552 0x100000000000, // OriginBase
553};
554
555static const PlatformMemoryMapParams Linux_X86_MemoryMapParams = {
558};
559
560static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams = {
561 nullptr,
563};
564
565static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams = {
566 nullptr,
568};
569
570static const PlatformMemoryMapParams Linux_S390_MemoryMapParams = {
571 nullptr,
573};
574
575static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams = {
576 nullptr,
578};
579
580static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams = {
581 nullptr,
583};
584
585static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P = {
587 nullptr,
588};
589
590static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams = {
591 nullptr,
593};
594
595static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams = {
598};
599
600static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams = {
601 nullptr,
603};
604
606
607namespace {
608
609/// Instrument functions of a module to detect uninitialized reads.
610///
611/// Instantiating MemorySanitizer inserts the msan runtime library API function
612/// declarations into the module if they don't exist already. Instantiating
613/// ensures the __msan_init function is in the list of global constructors for
614/// the module.
615class MemorySanitizer {
616public:
617 MemorySanitizer(Module &M, MemorySanitizerOptions Options)
618 : CompileKernel(Options.Kernel), TrackOrigins(Options.TrackOrigins),
619 Recover(Options.Recover), EagerChecks(Options.EagerChecks) {
620 initializeModule(M);
621 }
622
623 // MSan cannot be moved or copied because of MapParams.
624 MemorySanitizer(MemorySanitizer &&) = delete;
625 MemorySanitizer &operator=(MemorySanitizer &&) = delete;
626 MemorySanitizer(const MemorySanitizer &) = delete;
627 MemorySanitizer &operator=(const MemorySanitizer &) = delete;
628
629 bool sanitizeFunction(Function &F, TargetLibraryInfo &TLI);
630
631private:
632 friend struct MemorySanitizerVisitor;
633 friend struct VarArgHelperBase;
634 friend struct VarArgAMD64Helper;
635 friend struct VarArgAArch64Helper;
636 friend struct VarArgPowerPC64Helper;
637 friend struct VarArgPowerPC32Helper;
638 friend struct VarArgSystemZHelper;
639 friend struct VarArgI386Helper;
640 friend struct VarArgGenericHelper;
641
642 void initializeModule(Module &M);
643 void initializeCallbacks(Module &M, const TargetLibraryInfo &TLI);
644 void createKernelApi(Module &M, const TargetLibraryInfo &TLI);
645 void createUserspaceApi(Module &M, const TargetLibraryInfo &TLI);
646
647 template <typename... ArgsTy>
648 FunctionCallee getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
649 ArgsTy... Args);
650
651 /// True if we're compiling the Linux kernel.
652 bool CompileKernel;
653 /// Track origins (allocation points) of uninitialized values.
654 int TrackOrigins;
655 bool Recover;
656 bool EagerChecks;
657
658 Triple TargetTriple;
659 LLVMContext *C;
660 Type *IntptrTy; ///< Integer type with the size of a ptr in default AS.
661 Type *OriginTy;
662 PointerType *PtrTy; ///< Integer type with the size of a ptr in default AS.
663
664 // XxxTLS variables represent the per-thread state in MSan and per-task state
665 // in KMSAN.
666 // For the userspace these point to thread-local globals. In the kernel land
667 // they point to the members of a per-task struct obtained via a call to
668 // __msan_get_context_state().
669
670 /// Thread-local shadow storage for function parameters.
671 Value *ParamTLS;
672
673 /// Thread-local origin storage for function parameters.
674 Value *ParamOriginTLS;
675
676 /// Thread-local shadow storage for function return value.
677 Value *RetvalTLS;
678
679 /// Thread-local origin storage for function return value.
680 Value *RetvalOriginTLS;
681
682 /// Thread-local shadow storage for in-register va_arg function.
683 Value *VAArgTLS;
684
685 /// Thread-local shadow storage for in-register va_arg function.
686 Value *VAArgOriginTLS;
687
688 /// Thread-local shadow storage for va_arg overflow area.
689 Value *VAArgOverflowSizeTLS;
690
691 /// Are the instrumentation callbacks set up?
692 bool CallbacksInitialized = false;
693
694 /// The run-time callback to print a warning.
695 FunctionCallee WarningFn;
696
697 // These arrays are indexed by log2(AccessSize).
698 FunctionCallee MaybeWarningFn[kNumberOfAccessSizes];
699 FunctionCallee MaybeWarningVarSizeFn;
700 FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes];
701
702 /// Run-time helper that generates a new origin value for a stack
703 /// allocation.
704 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
705 // No description version
706 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
707
708 /// Run-time helper that poisons stack on function entry.
709 FunctionCallee MsanPoisonStackFn;
710
711 /// Run-time helper that records a store (or any event) of an
712 /// uninitialized value and returns an updated origin id encoding this info.
713 FunctionCallee MsanChainOriginFn;
714
715 /// Run-time helper that paints an origin over a region.
716 FunctionCallee MsanSetOriginFn;
717
718 /// MSan runtime replacements for memmove, memcpy and memset.
719 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
720
721 /// KMSAN callback for task-local function argument shadow.
722 StructType *MsanContextStateTy;
723 FunctionCallee MsanGetContextStateFn;
724
725 /// Functions for poisoning/unpoisoning local variables
726 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
727
728 /// Pair of shadow/origin pointers.
729 Type *MsanMetadata;
730
731 /// Each of the MsanMetadataPtrXxx functions returns a MsanMetadata.
732 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
733 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
734 FunctionCallee MsanMetadataPtrForStore_1_8[4];
735 FunctionCallee MsanInstrumentAsmStoreFn;
736
737 /// Storage for return values of the MsanMetadataPtrXxx functions.
738 Value *MsanMetadataAlloca;
739
740 /// Helper to choose between different MsanMetadataPtrXxx().
741 FunctionCallee getKmsanShadowOriginAccessFn(bool isStore, int size);
742
743 /// Memory map parameters used in application-to-shadow calculation.
744 const MemoryMapParams *MapParams;
745
746 /// Custom memory map parameters used when -msan-shadow-base or
747 // -msan-origin-base is provided.
748 MemoryMapParams CustomMapParams;
749
750 MDNode *ColdCallWeights;
751
752 /// Branch weights for origin store.
753 MDNode *OriginStoreWeights;
754};
755
756void insertModuleCtor(Module &M) {
759 /*InitArgTypes=*/{},
760 /*InitArgs=*/{},
761 // This callback is invoked when the functions are created the first
762 // time. Hook them into the global ctors list in that case:
763 [&](Function *Ctor, FunctionCallee) {
764 if (!ClWithComdat) {
765 appendToGlobalCtors(M, Ctor, 0);
766 return;
767 }
768 Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
769 Ctor->setComdat(MsanCtorComdat);
770 appendToGlobalCtors(M, Ctor, 0, Ctor);
771 });
772}
773
774template <class T> T getOptOrDefault(const cl::opt<T> &Opt, T Default) {
775 return (Opt.getNumOccurrences() > 0) ? Opt : Default;
776}
777
778} // end anonymous namespace
779
781 bool EagerChecks)
782 : Kernel(getOptOrDefault(ClEnableKmsan, K)),
783 TrackOrigins(getOptOrDefault(ClTrackOrigins, Kernel ? 2 : TO)),
784 Recover(getOptOrDefault(ClKeepGoing, Kernel || R)),
785 EagerChecks(getOptOrDefault(ClEagerChecks, EagerChecks)) {}
786
789 // Return early if nosanitize_memory module flag is present for the module.
790 if (checkIfAlreadyInstrumented(M, "nosanitize_memory"))
791 return PreservedAnalyses::all();
792 bool Modified = false;
793 if (!Options.Kernel) {
795 Modified = true;
796 }
797
798 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
799 for (Function &F : M) {
800 if (F.empty())
801 continue;
802 MemorySanitizer Msan(*F.getParent(), Options);
803 Modified |=
804 Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
805 }
806
807 if (!Modified)
808 return PreservedAnalyses::all();
809
811 // GlobalsAA is considered stateless and does not get invalidated unless
812 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
813 // make changes that require GlobalsAA to be invalidated.
814 PA.abandon<GlobalsAA>();
815 return PA;
816}
817
819 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
820 static_cast<PassInfoMixin<MemorySanitizerPass> *>(this)->printPipeline(
821 OS, MapClassName2PassName);
822 OS << '<';
823 if (Options.Recover)
824 OS << "recover;";
825 if (Options.Kernel)
826 OS << "kernel;";
827 if (Options.EagerChecks)
828 OS << "eager-checks;";
829 OS << "track-origins=" << Options.TrackOrigins;
830 OS << '>';
831}
832
833/// Create a non-const global initialized with the given string.
834///
835/// Creates a writable global for Str so that we can pass it to the
836/// run-time lib. Runtime uses first 4 bytes of the string to store the
837/// frame ID, so the string needs to be mutable.
839 StringRef Str) {
840 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
841 return new GlobalVariable(M, StrConst->getType(), /*isConstant=*/true,
842 GlobalValue::PrivateLinkage, StrConst, "");
843}
844
845template <typename... ArgsTy>
847MemorySanitizer::getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
848 ArgsTy... Args) {
849 if (TargetTriple.getArch() == Triple::systemz) {
850 // SystemZ ABI: shadow/origin pair is returned via a hidden parameter.
851 return M.getOrInsertFunction(Name, Type::getVoidTy(*C), PtrTy,
852 std::forward<ArgsTy>(Args)...);
853 }
854
855 return M.getOrInsertFunction(Name, MsanMetadata,
856 std::forward<ArgsTy>(Args)...);
857}
858
859/// Create KMSAN API callbacks.
860void MemorySanitizer::createKernelApi(Module &M, const TargetLibraryInfo &TLI) {
861 IRBuilder<> IRB(*C);
862
863 // These will be initialized in insertKmsanPrologue().
864 RetvalTLS = nullptr;
865 RetvalOriginTLS = nullptr;
866 ParamTLS = nullptr;
867 ParamOriginTLS = nullptr;
868 VAArgTLS = nullptr;
869 VAArgOriginTLS = nullptr;
870 VAArgOverflowSizeTLS = nullptr;
871
872 WarningFn = M.getOrInsertFunction("__msan_warning",
873 TLI.getAttrList(C, {0}, /*Signed=*/false),
874 IRB.getVoidTy(), IRB.getInt32Ty());
875
876 // Requests the per-task context state (kmsan_context_state*) from the
877 // runtime library.
878 MsanContextStateTy = StructType::get(
879 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
880 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8),
881 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
882 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), /* va_arg_origin */
883 IRB.getInt64Ty(), ArrayType::get(OriginTy, kParamTLSSize / 4), OriginTy,
884 OriginTy);
885 MsanGetContextStateFn =
886 M.getOrInsertFunction("__msan_get_context_state", PtrTy);
887
888 MsanMetadata = StructType::get(PtrTy, PtrTy);
889
890 for (int ind = 0, size = 1; ind < 4; ind++, size <<= 1) {
891 std::string name_load =
892 "__msan_metadata_ptr_for_load_" + std::to_string(size);
893 std::string name_store =
894 "__msan_metadata_ptr_for_store_" + std::to_string(size);
895 MsanMetadataPtrForLoad_1_8[ind] =
896 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
897 MsanMetadataPtrForStore_1_8[ind] =
898 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
899 }
900
901 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
902 M, "__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
903 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
904 M, "__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
905
906 // Functions for poisoning and unpoisoning memory.
907 MsanPoisonAllocaFn = M.getOrInsertFunction(
908 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
909 MsanUnpoisonAllocaFn = M.getOrInsertFunction(
910 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
911}
912
914 return M.getOrInsertGlobal(Name, Ty, [&] {
915 return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
916 nullptr, Name, nullptr,
918 });
919}
920
921/// Insert declarations for userspace-specific functions and globals.
922void MemorySanitizer::createUserspaceApi(Module &M,
923 const TargetLibraryInfo &TLI) {
924 IRBuilder<> IRB(*C);
925
926 // Create the callback.
927 // FIXME: this function should have "Cold" calling conv,
928 // which is not yet implemented.
929 if (TrackOrigins) {
930 StringRef WarningFnName = Recover ? "__msan_warning_with_origin"
931 : "__msan_warning_with_origin_noreturn";
932 WarningFn = M.getOrInsertFunction(WarningFnName,
933 TLI.getAttrList(C, {0}, /*Signed=*/false),
934 IRB.getVoidTy(), IRB.getInt32Ty());
935 } else {
936 StringRef WarningFnName =
937 Recover ? "__msan_warning" : "__msan_warning_noreturn";
938 WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
939 }
940
941 // Create the global TLS variables.
942 RetvalTLS =
943 getOrInsertGlobal(M, "__msan_retval_tls",
944 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8));
945
946 RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy);
947
948 ParamTLS =
949 getOrInsertGlobal(M, "__msan_param_tls",
950 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
951
952 ParamOriginTLS =
953 getOrInsertGlobal(M, "__msan_param_origin_tls",
954 ArrayType::get(OriginTy, kParamTLSSize / 4));
955
956 VAArgTLS =
957 getOrInsertGlobal(M, "__msan_va_arg_tls",
958 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
959
960 VAArgOriginTLS =
961 getOrInsertGlobal(M, "__msan_va_arg_origin_tls",
962 ArrayType::get(OriginTy, kParamTLSSize / 4));
963
964 VAArgOverflowSizeTLS = getOrInsertGlobal(M, "__msan_va_arg_overflow_size_tls",
965 IRB.getIntPtrTy(M.getDataLayout()));
966
967 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
968 AccessSizeIndex++) {
969 unsigned AccessSize = 1 << AccessSizeIndex;
970 std::string FunctionName = "__msan_maybe_warning_" + itostr(AccessSize);
971 MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction(
972 FunctionName, TLI.getAttrList(C, {0, 1}, /*Signed=*/false),
973 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
974 MaybeWarningVarSizeFn = M.getOrInsertFunction(
975 "__msan_maybe_warning_N", TLI.getAttrList(C, {}, /*Signed=*/false),
976 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
977 FunctionName = "__msan_maybe_store_origin_" + itostr(AccessSize);
978 MaybeStoreOriginFn[AccessSizeIndex] = M.getOrInsertFunction(
979 FunctionName, TLI.getAttrList(C, {0, 2}, /*Signed=*/false),
980 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
981 IRB.getInt32Ty());
982 }
983
984 MsanSetAllocaOriginWithDescriptionFn =
985 M.getOrInsertFunction("__msan_set_alloca_origin_with_descr",
986 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
987 MsanSetAllocaOriginNoDescriptionFn =
988 M.getOrInsertFunction("__msan_set_alloca_origin_no_descr",
989 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
990 MsanPoisonStackFn = M.getOrInsertFunction("__msan_poison_stack",
991 IRB.getVoidTy(), PtrTy, IntptrTy);
992}
993
994/// Insert extern declaration of runtime-provided functions and globals.
995void MemorySanitizer::initializeCallbacks(Module &M,
996 const TargetLibraryInfo &TLI) {
997 // Only do this once.
998 if (CallbacksInitialized)
999 return;
1000
1001 IRBuilder<> IRB(*C);
1002 // Initialize callbacks that are common for kernel and userspace
1003 // instrumentation.
1004 MsanChainOriginFn = M.getOrInsertFunction(
1005 "__msan_chain_origin",
1006 TLI.getAttrList(C, {0}, /*Signed=*/false, /*Ret=*/true), IRB.getInt32Ty(),
1007 IRB.getInt32Ty());
1008 MsanSetOriginFn = M.getOrInsertFunction(
1009 "__msan_set_origin", TLI.getAttrList(C, {2}, /*Signed=*/false),
1010 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
1011 MemmoveFn =
1012 M.getOrInsertFunction("__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
1013 MemcpyFn =
1014 M.getOrInsertFunction("__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
1015 MemsetFn = M.getOrInsertFunction("__msan_memset",
1016 TLI.getAttrList(C, {1}, /*Signed=*/true),
1017 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
1018
1019 MsanInstrumentAsmStoreFn = M.getOrInsertFunction(
1020 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
1021
1022 if (CompileKernel) {
1023 createKernelApi(M, TLI);
1024 } else {
1025 createUserspaceApi(M, TLI);
1026 }
1027 CallbacksInitialized = true;
1028}
1029
1030FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore,
1031 int size) {
1032 FunctionCallee *Fns =
1033 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
1034 switch (size) {
1035 case 1:
1036 return Fns[0];
1037 case 2:
1038 return Fns[1];
1039 case 4:
1040 return Fns[2];
1041 case 8:
1042 return Fns[3];
1043 default:
1044 return nullptr;
1045 }
1046}
1047
1048/// Module-level initialization.
1049///
1050/// inserts a call to __msan_init to the module's constructor list.
1051void MemorySanitizer::initializeModule(Module &M) {
1052 auto &DL = M.getDataLayout();
1053
1054 TargetTriple = M.getTargetTriple();
1055
1056 bool ShadowPassed = ClShadowBase.getNumOccurrences() > 0;
1057 bool OriginPassed = ClOriginBase.getNumOccurrences() > 0;
1058 // Check the overrides first
1059 if (ShadowPassed || OriginPassed) {
1060 CustomMapParams.AndMask = ClAndMask;
1061 CustomMapParams.XorMask = ClXorMask;
1062 CustomMapParams.ShadowBase = ClShadowBase;
1063 CustomMapParams.OriginBase = ClOriginBase;
1064 MapParams = &CustomMapParams;
1065 } else {
1066 switch (TargetTriple.getOS()) {
1067 case Triple::FreeBSD:
1068 switch (TargetTriple.getArch()) {
1069 case Triple::aarch64:
1070 MapParams = FreeBSD_ARM_MemoryMapParams.bits64;
1071 break;
1072 case Triple::x86_64:
1073 MapParams = FreeBSD_X86_MemoryMapParams.bits64;
1074 break;
1075 case Triple::x86:
1076 MapParams = FreeBSD_X86_MemoryMapParams.bits32;
1077 break;
1078 default:
1079 report_fatal_error("unsupported architecture");
1080 }
1081 break;
1082 case Triple::NetBSD:
1083 switch (TargetTriple.getArch()) {
1084 case Triple::x86_64:
1085 MapParams = NetBSD_X86_MemoryMapParams.bits64;
1086 break;
1087 default:
1088 report_fatal_error("unsupported architecture");
1089 }
1090 break;
1091 case Triple::Linux:
1092 switch (TargetTriple.getArch()) {
1093 case Triple::x86_64:
1094 MapParams = Linux_X86_MemoryMapParams.bits64;
1095 break;
1096 case Triple::x86:
1097 MapParams = Linux_X86_MemoryMapParams.bits32;
1098 break;
1099 case Triple::mips64:
1100 case Triple::mips64el:
1101 MapParams = Linux_MIPS_MemoryMapParams.bits64;
1102 break;
1103 case Triple::ppc64:
1104 case Triple::ppc64le:
1105 MapParams = Linux_PowerPC_MemoryMapParams.bits64;
1106 break;
1107 case Triple::systemz:
1108 MapParams = Linux_S390_MemoryMapParams.bits64;
1109 break;
1110 case Triple::aarch64:
1111 case Triple::aarch64_be:
1112 MapParams = Linux_ARM_MemoryMapParams.bits64;
1113 break;
1115 MapParams = Linux_LoongArch_MemoryMapParams.bits64;
1116 break;
1117 case Triple::hexagon:
1118 MapParams = Linux_Hexagon_MemoryMapParams_P.bits32;
1119 break;
1120 default:
1121 report_fatal_error("unsupported architecture");
1122 }
1123 break;
1124 default:
1125 report_fatal_error("unsupported operating system");
1126 }
1127 }
1128
1129 C = &(M.getContext());
1130 IRBuilder<> IRB(*C);
1131 IntptrTy = IRB.getIntPtrTy(DL);
1132 OriginTy = IRB.getInt32Ty();
1133 PtrTy = IRB.getPtrTy();
1134
1135 ColdCallWeights = MDBuilder(*C).createUnlikelyBranchWeights();
1136 OriginStoreWeights = MDBuilder(*C).createUnlikelyBranchWeights();
1137
1138 if (!CompileKernel) {
1139 if (TrackOrigins)
1140 M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
1141 return new GlobalVariable(
1142 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
1143 IRB.getInt32(TrackOrigins), "__msan_track_origins");
1144 });
1145
1146 if (Recover)
1147 M.getOrInsertGlobal("__msan_keep_going", IRB.getInt32Ty(), [&] {
1148 return new GlobalVariable(M, IRB.getInt32Ty(), true,
1149 GlobalValue::WeakODRLinkage,
1150 IRB.getInt32(Recover), "__msan_keep_going");
1151 });
1152 }
1153}
1154
1155namespace {
1156
1157/// A helper class that handles instrumentation of VarArg
1158/// functions on a particular platform.
1159///
1160/// Implementations are expected to insert the instrumentation
1161/// necessary to propagate argument shadow through VarArg function
1162/// calls. Visit* methods are called during an InstVisitor pass over
1163/// the function, and should avoid creating new basic blocks. A new
1164/// instance of this class is created for each instrumented function.
1165struct VarArgHelper {
1166 virtual ~VarArgHelper() = default;
1167
1168 /// Visit a CallBase.
1169 virtual void visitCallBase(CallBase &CB, IRBuilder<> &IRB) = 0;
1170
1171 /// Visit a va_start call.
1172 virtual void visitVAStartInst(VAStartInst &I) = 0;
1173
1174 /// Visit a va_copy call.
1175 virtual void visitVACopyInst(VACopyInst &I) = 0;
1176
1177 /// Finalize function instrumentation.
1178 ///
1179 /// This method is called after visiting all interesting (see above)
1180 /// instructions in a function.
1181 virtual void finalizeInstrumentation() = 0;
1182};
1183
1184struct MemorySanitizerVisitor;
1185
1186} // end anonymous namespace
1187
1188static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
1189 MemorySanitizerVisitor &Visitor);
1190
1191static unsigned TypeSizeToSizeIndex(TypeSize TS) {
1192 if (TS.isScalable())
1193 // Scalable types unconditionally take slowpaths.
1194 return kNumberOfAccessSizes;
1195 unsigned TypeSizeFixed = TS.getFixedValue();
1196 if (TypeSizeFixed <= 8)
1197 return 0;
1198 return Log2_32_Ceil((TypeSizeFixed + 7) / 8);
1199}
1200
1201namespace {
1202
1203/// Helper class to attach debug information of the given instruction onto new
1204/// instructions inserted after.
1205class NextNodeIRBuilder : public IRBuilder<> {
1206public:
1207 explicit NextNodeIRBuilder(Instruction *IP) : IRBuilder<>(IP->getNextNode()) {
1208 SetCurrentDebugLocation(IP->getDebugLoc());
1209 }
1210};
1211
1212/// This class does all the work for a given function. Store and Load
1213/// instructions store and load corresponding shadow and origin
1214/// values. Most instructions propagate shadow from arguments to their
1215/// return values. Certain instructions (most importantly, BranchInst)
1216/// test their argument shadow and print reports (with a runtime call) if it's
1217/// non-zero.
1218struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1219 Function &F;
1220 MemorySanitizer &MS;
1221 SmallVector<PHINode *, 16> ShadowPHINodes, OriginPHINodes;
1222 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1223 std::unique_ptr<VarArgHelper> VAHelper;
1224 const TargetLibraryInfo *TLI;
1225 Instruction *FnPrologueEnd;
1226 SmallVector<Instruction *, 16> Instructions;
1227
1228 // The following flags disable parts of MSan instrumentation based on
1229 // exclusion list contents and command-line options.
1230 bool InsertChecks;
1231 bool PropagateShadow;
1232 bool PoisonStack;
1233 bool PoisonUndef;
1234 bool PoisonUndefVectors;
1235
1236 struct ShadowOriginAndInsertPoint {
1237 Value *Shadow;
1238 Value *Origin;
1239 Instruction *OrigIns;
1240
1241 ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I)
1242 : Shadow(S), Origin(O), OrigIns(I) {}
1243 };
1245 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1246 SmallSetVector<AllocaInst *, 16> AllocaSet;
1249 int64_t SplittableBlocksCount = 0;
1250
1251 MemorySanitizerVisitor(Function &F, MemorySanitizer &MS,
1252 const TargetLibraryInfo &TLI)
1253 : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)), TLI(&TLI) {
1254 bool SanitizeFunction =
1255 F.hasFnAttribute(Attribute::SanitizeMemory) && !ClDisableChecks;
1256 InsertChecks = SanitizeFunction;
1257 PropagateShadow = SanitizeFunction;
1258 PoisonStack = SanitizeFunction && ClPoisonStack;
1259 PoisonUndef = SanitizeFunction && ClPoisonUndef;
1260 PoisonUndefVectors = SanitizeFunction && ClPoisonUndefVectors;
1261
1262 // In the presence of unreachable blocks, we may see Phi nodes with
1263 // incoming nodes from such blocks. Since InstVisitor skips unreachable
1264 // blocks, such nodes will not have any shadow value associated with them.
1265 // It's easier to remove unreachable blocks than deal with missing shadow.
1267
1268 MS.initializeCallbacks(*F.getParent(), TLI);
1269 FnPrologueEnd =
1270 IRBuilder<>(F.getEntryBlock().getFirstNonPHIIt())
1271 .CreateIntrinsicWithoutFolding(Intrinsic::donothing, {});
1272
1273 if (MS.CompileKernel) {
1274 IRBuilder<> IRB(FnPrologueEnd);
1275 insertKmsanPrologue(IRB);
1276 }
1277
1278 LLVM_DEBUG(if (!InsertChecks) dbgs()
1279 << "MemorySanitizer is not inserting checks into '"
1280 << F.getName() << "'\n");
1281 }
1282
1283 bool instrumentWithCalls(Value *V) {
1284 // Constants likely will be eliminated by follow-up passes.
1285 if (isa<Constant>(V))
1286 return false;
1287 ++SplittableBlocksCount;
1289 SplittableBlocksCount > ClInstrumentationWithCallThreshold;
1290 }
1291
1292 bool isInPrologue(Instruction &I) {
1293 return I.getParent() == FnPrologueEnd->getParent() &&
1294 (&I == FnPrologueEnd || I.comesBefore(FnPrologueEnd));
1295 }
1296
1297 // Creates a new origin and records the stack trace. In general we can call
1298 // this function for any origin manipulation we like. However it will cost
1299 // runtime resources. So use this wisely only if it can provide additional
1300 // information helpful to a user.
1301 Value *updateOrigin(Value *V, IRBuilder<> &IRB) {
1302 if (MS.TrackOrigins <= 1)
1303 return V;
1304 return IRB.CreateCall(MS.MsanChainOriginFn, V);
1305 }
1306
1307 Value *originToIntptr(IRBuilder<> &IRB, Value *Origin) {
1308 const DataLayout &DL = F.getDataLayout();
1309 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1310 if (IntptrSize == kOriginSize)
1311 return Origin;
1312 assert(IntptrSize == kOriginSize * 2);
1313 Origin = IRB.CreateIntCast(Origin, MS.IntptrTy, /* isSigned */ false);
1314 return IRB.CreateOr(Origin, IRB.CreateShl(Origin, kOriginSize * 8));
1315 }
1316
1317 /// Fill memory range with the given origin value.
1318 void paintOrigin(IRBuilder<> &IRB, Value *Origin, Value *OriginPtr,
1319 TypeSize TS, Align Alignment) {
1320 const DataLayout &DL = F.getDataLayout();
1321 const Align IntptrAlignment = DL.getABITypeAlign(MS.IntptrTy);
1322 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1323 assert(IntptrAlignment >= kMinOriginAlignment);
1324 assert(IntptrSize >= kOriginSize);
1325
1326 // Note: The loop based formation works for fixed length vectors too,
1327 // however we prefer to unroll and specialize alignment below.
1328 if (TS.isScalable()) {
1329 Value *Size = IRB.CreateTypeSize(MS.IntptrTy, TS);
1330 Value *RoundUp =
1331 IRB.CreateAdd(Size, ConstantInt::get(MS.IntptrTy, kOriginSize - 1));
1332 Value *End =
1333 IRB.CreateUDiv(RoundUp, ConstantInt::get(MS.IntptrTy, kOriginSize));
1334 auto [InsertPt, Index] =
1336 IRB.SetInsertPoint(InsertPt);
1337
1338 Value *GEP = IRB.CreateGEP(MS.OriginTy, OriginPtr, Index);
1340 return;
1341 }
1342
1343 unsigned Size = TS.getFixedValue();
1344
1345 unsigned Ofs = 0;
1346 Align CurrentAlignment = Alignment;
1347 if (Alignment >= IntptrAlignment && IntptrSize > kOriginSize) {
1348 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1349 Value *IntptrOriginPtr = IRB.CreatePointerCast(OriginPtr, MS.PtrTy);
1350 for (unsigned i = 0; i < Size / IntptrSize; ++i) {
1351 Value *Ptr = i ? IRB.CreateConstGEP1_32(MS.IntptrTy, IntptrOriginPtr, i)
1352 : IntptrOriginPtr;
1353 IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
1354 Ofs += IntptrSize / kOriginSize;
1355 CurrentAlignment = IntptrAlignment;
1356 }
1357 }
1358
1359 for (unsigned i = Ofs; i < (Size + kOriginSize - 1) / kOriginSize; ++i) {
1360 Value *GEP =
1361 i ? IRB.CreateConstGEP1_32(MS.OriginTy, OriginPtr, i) : OriginPtr;
1362 IRB.CreateAlignedStore(Origin, GEP, CurrentAlignment);
1363 CurrentAlignment = kMinOriginAlignment;
1364 }
1365 }
1366
1367 void storeOrigin(IRBuilder<> &IRB, Value *Addr, Value *Shadow, Value *Origin,
1368 Value *OriginPtr, Align Alignment) {
1369 const DataLayout &DL = F.getDataLayout();
1370 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1371 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
1372 // ZExt cannot convert between vector and scalar
1373 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1374 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1375 if (!ClCheckConstantShadow || ConstantShadow->isNullValue()) {
1376 // Origin is not needed: value is initialized or const shadow is
1377 // ignored.
1378 return;
1379 }
1380 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1381 // Copy origin as the value is definitely uninitialized.
1382 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1383 OriginAlignment);
1384 return;
1385 }
1386 // Fallback to runtime check, which still can be optimized out later.
1387 }
1388
1389 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1390 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1391 if (instrumentWithCalls(ConvertedShadow) &&
1392 SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
1393 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1394 Value *ConvertedShadow2 =
1395 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1396 CallBase *CB = IRB.CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1397 CB->addParamAttr(0, Attribute::ZExt);
1398 CB->addParamAttr(2, Attribute::ZExt);
1399 } else {
1400 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1402 Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
1403 IRBuilder<> IRBNew(CheckTerm);
1404 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1405 OriginAlignment);
1406 }
1407 }
1408
1409 void materializeStores() {
1410 for (StoreInst *SI : StoreList) {
1411 IRBuilder<> IRB(SI);
1412 Value *Val = SI->getValueOperand();
1413 Value *Addr = SI->getPointerOperand();
1414 Value *Shadow = SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1415 Value *ShadowPtr, *OriginPtr;
1416 Type *ShadowTy = Shadow->getType();
1417 const Align Alignment = SI->getAlign();
1418 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1419 std::tie(ShadowPtr, OriginPtr) =
1420 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ true);
1421
1422 [[maybe_unused]] StoreInst *NewSI =
1423 IRB.CreateAlignedStore(Shadow, ShadowPtr, Alignment);
1424 LLVM_DEBUG(dbgs() << " STORE: " << *NewSI << "\n");
1425
1426 if (SI->isAtomic())
1427 SI->setOrdering(addReleaseOrdering(SI->getOrdering()));
1428
1429 if (MS.TrackOrigins && !SI->isAtomic())
1430 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1431 OriginAlignment);
1432 }
1433 }
1434
1435 // Returns true if Debug Location corresponds to multiple warnings.
1436 bool shouldDisambiguateWarningLocation(const DebugLoc &DebugLoc) {
1437 if (MS.TrackOrigins < 2)
1438 return false;
1439
1440 if (LazyWarningDebugLocationCount.empty())
1441 for (const auto &I : InstrumentationList)
1442 ++LazyWarningDebugLocationCount[I.OrigIns->getDebugLoc()];
1443
1444 return LazyWarningDebugLocationCount[DebugLoc] >= ClDisambiguateWarning;
1445 }
1446
1447 /// Helper function to insert a warning at IRB's current insert point.
1448 void insertWarningFn(IRBuilder<> &IRB, Value *Origin) {
1449 if (!Origin)
1450 Origin = (Value *)IRB.getInt32(0);
1451 assert(Origin->getType()->isIntegerTy());
1452
1453 if (shouldDisambiguateWarningLocation(IRB.getCurrentDebugLocation())) {
1454 // Try to create additional origin with debug info of the last origin
1455 // instruction. It may provide additional information to the user.
1456 if (Instruction *OI = dyn_cast_or_null<Instruction>(Origin)) {
1457 assert(MS.TrackOrigins);
1458 auto NewDebugLoc = OI->getDebugLoc();
1459 // Origin update with missing or the same debug location provides no
1460 // additional value.
1461 if (NewDebugLoc && NewDebugLoc != IRB.getCurrentDebugLocation()) {
1462 // Insert update just before the check, so we call runtime only just
1463 // before the report.
1464 IRBuilder<> IRBOrigin(&*IRB.GetInsertPoint());
1465 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1466 Origin = updateOrigin(Origin, IRBOrigin);
1467 }
1468 }
1469 }
1470
1471 if (MS.CompileKernel || MS.TrackOrigins)
1472 IRB.CreateCall(MS.WarningFn, Origin)->setCannotMerge();
1473 else
1474 IRB.CreateCall(MS.WarningFn)->setCannotMerge();
1475 // FIXME: Insert UnreachableInst if !MS.Recover?
1476 // This may invalidate some of the following checks and needs to be done
1477 // at the very end.
1478 }
1479
1480 void materializeOneCheck(IRBuilder<> &IRB, Value *ConvertedShadow,
1481 Value *Origin) {
1482 const DataLayout &DL = F.getDataLayout();
1483 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1484 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1485 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1486 // ZExt cannot convert between vector and scalar
1487 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1488 Value *ConvertedShadow2 =
1489 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1490
1491 if (SizeIndex < kNumberOfAccessSizes) {
1492 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1493 CallBase *CB = IRB.CreateCall(
1494 Fn,
1495 {ConvertedShadow2,
1496 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1497 CB->addParamAttr(0, Attribute::ZExt);
1498 CB->addParamAttr(1, Attribute::ZExt);
1499 } else {
1500 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1501 Value *ShadowAlloca = IRB.CreateAlloca(ConvertedShadow2->getType(), 0u);
1502 IRB.CreateStore(ConvertedShadow2, ShadowAlloca);
1503 unsigned ShadowSize = DL.getTypeAllocSize(ConvertedShadow2->getType());
1504 CallBase *CB = IRB.CreateCall(
1505 Fn,
1506 {ShadowAlloca, ConstantInt::get(IRB.getInt64Ty(), ShadowSize),
1507 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1508 CB->addParamAttr(1, Attribute::ZExt);
1509 CB->addParamAttr(2, Attribute::ZExt);
1510 }
1511 } else {
1512 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1514 Cmp, &*IRB.GetInsertPoint(),
1515 /* Unreachable */ !MS.Recover, MS.ColdCallWeights);
1516
1517 IRB.SetInsertPoint(CheckTerm);
1518 insertWarningFn(IRB, Origin);
1519 LLVM_DEBUG(dbgs() << " CHECK: " << *Cmp << "\n");
1520 }
1521 }
1522
1523 void materializeInstructionChecks(
1524 ArrayRef<ShadowOriginAndInsertPoint> InstructionChecks) {
1525 const DataLayout &DL = F.getDataLayout();
1526 // Disable combining in some cases. TrackOrigins checks each shadow to pick
1527 // correct origin.
1528 bool Combine = !MS.TrackOrigins;
1529 Instruction *Instruction = InstructionChecks.front().OrigIns;
1530 Value *Shadow = nullptr;
1531 for (const auto &ShadowData : InstructionChecks) {
1532 assert(ShadowData.OrigIns == Instruction);
1533 IRBuilder<> IRB(Instruction);
1534
1535 Value *ConvertedShadow = ShadowData.Shadow;
1536
1537 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1538 if (!ClCheckConstantShadow || ConstantShadow->isNullValue()) {
1539 // Skip, value is initialized or const shadow is ignored.
1540 continue;
1541 }
1542 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1543 // Report as the value is definitely uninitialized.
1544 insertWarningFn(IRB, ShadowData.Origin);
1545 if (!MS.Recover)
1546 return; // Always fail and stop here, not need to check the rest.
1547 // Skip entire instruction,
1548 continue;
1549 }
1550 // Fallback to runtime check, which still can be optimized out later.
1551 }
1552
1553 if (!Combine) {
1554 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1555 continue;
1556 }
1557
1558 if (!Shadow) {
1559 Shadow = ConvertedShadow;
1560 continue;
1561 }
1562
1563 Shadow = convertToBool(Shadow, IRB, "_mscmp");
1564 ConvertedShadow = convertToBool(ConvertedShadow, IRB, "_mscmp");
1565 Shadow = IRB.CreateOr(Shadow, ConvertedShadow, "_msor");
1566 }
1567
1568 if (Shadow) {
1569 assert(Combine);
1570 IRBuilder<> IRB(Instruction);
1571 materializeOneCheck(IRB, Shadow, nullptr);
1572 }
1573 }
1574
1575 static bool isAArch64SVCount(Type *Ty) {
1576 if (TargetExtType *TTy = dyn_cast<TargetExtType>(Ty))
1577 return TTy->getName() == "aarch64.svcount";
1578 return false;
1579 }
1580
1581 // This is intended to match the "AArch64 Predicate-as-Counter Type" (aka
1582 // 'target("aarch64.svcount")', but not e.g., <vscale x 4 x i32>.
1583 static bool isScalableNonVectorType(Type *Ty) {
1584 if (!isAArch64SVCount(Ty))
1585 LLVM_DEBUG(dbgs() << "isScalableNonVectorType: Unexpected type " << *Ty
1586 << "\n");
1587
1588 return Ty->isScalableTy() && !isa<VectorType>(Ty);
1589 }
1590
1591 void materializeChecks() {
1592#ifndef NDEBUG
1593 // For assert below.
1594 SmallPtrSet<Instruction *, 16> Done;
1595#endif
1596
1597 for (auto I = InstrumentationList.begin();
1598 I != InstrumentationList.end();) {
1599 auto OrigIns = I->OrigIns;
1600 // Checks are grouped by the original instruction. We call all
1601 // `insertShadowCheck` for an instruction at once.
1602 assert(Done.insert(OrigIns).second);
1603 auto J = std::find_if(I + 1, InstrumentationList.end(),
1604 [OrigIns](const ShadowOriginAndInsertPoint &R) {
1605 return OrigIns != R.OrigIns;
1606 });
1607 // Process all checks of instruction at once.
1608 materializeInstructionChecks(ArrayRef<ShadowOriginAndInsertPoint>(I, J));
1609 I = J;
1610 }
1611
1612 LLVM_DEBUG(dbgs() << "DONE:\n" << F);
1613 }
1614
1615 // Returns the last instruction in the new prologue
1616 void insertKmsanPrologue(IRBuilder<> &IRB) {
1617 Value *ContextState = IRB.CreateCall(MS.MsanGetContextStateFn, {});
1618 Constant *Zero = IRB.getInt32(0);
1619 MS.ParamTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1620 {Zero, IRB.getInt32(0)}, "param_shadow");
1621 MS.RetvalTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1622 {Zero, IRB.getInt32(1)}, "retval_shadow");
1623 MS.VAArgTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1624 {Zero, IRB.getInt32(2)}, "va_arg_shadow");
1625 MS.VAArgOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1626 {Zero, IRB.getInt32(3)}, "va_arg_origin");
1627 MS.VAArgOverflowSizeTLS =
1628 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1629 {Zero, IRB.getInt32(4)}, "va_arg_overflow_size");
1630 MS.ParamOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1631 {Zero, IRB.getInt32(5)}, "param_origin");
1632 MS.RetvalOriginTLS =
1633 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1634 {Zero, IRB.getInt32(6)}, "retval_origin");
1635 if (MS.TargetTriple.getArch() == Triple::systemz)
1636 MS.MsanMetadataAlloca = IRB.CreateAlloca(MS.MsanMetadata, 0u);
1637 }
1638
1639 /// Add MemorySanitizer instrumentation to a function.
1640 bool runOnFunction() {
1641 // Iterate all BBs in depth-first order and create shadow instructions
1642 // for all instructions (where applicable).
1643 // For PHI nodes we create dummy shadow PHIs which will be finalized later.
1644 for (BasicBlock *BB : depth_first(FnPrologueEnd->getParent()))
1645 visit(*BB);
1646
1647 // `visit` above only collects instructions. Process them after iterating
1648 // CFG to avoid requirement on CFG transformations.
1649 for (Instruction *I : Instructions)
1651
1652 // Finalize PHI nodes.
1653 for (PHINode *PN : ShadowPHINodes) {
1654 PHINode *PNS = cast<PHINode>(getShadow(PN));
1655 PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
1656 size_t NumValues = PN->getNumIncomingValues();
1657 for (size_t v = 0; v < NumValues; v++) {
1658 PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1659 if (PNO)
1660 PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1661 }
1662 }
1663
1664 VAHelper->finalizeInstrumentation();
1665
1666 // Poison llvm.lifetime.start intrinsics, if we haven't fallen back to
1667 // instrumenting only allocas.
1669 for (auto Item : LifetimeStartList) {
1670 instrumentAlloca(*Item.second, Item.first);
1671 AllocaSet.remove(Item.second);
1672 }
1673 }
1674 // Poison the allocas for which we didn't instrument the corresponding
1675 // lifetime intrinsics.
1676 for (AllocaInst *AI : AllocaSet)
1677 instrumentAlloca(*AI);
1678
1679 // Insert shadow value checks.
1680 materializeChecks();
1681
1682 // Delayed instrumentation of StoreInst.
1683 // This may not add new address checks.
1684 materializeStores();
1685
1686 return true;
1687 }
1688
1689 /// Compute the shadow type that corresponds to a given Value.
1690 Type *getShadowTy(Value *V) { return getShadowTy(V->getType()); }
1691
1692 /// Compute the shadow type that corresponds to a given Type.
1693 Type *getShadowTy(Type *OrigTy) {
1694 if (!OrigTy->isSized()) {
1695 return nullptr;
1696 }
1697 // For integer type, shadow is the same as the original type.
1698 // This may return weird-sized types like i1.
1699 if (IntegerType *IT = dyn_cast<IntegerType>(OrigTy))
1700 return IT;
1701 const DataLayout &DL = F.getDataLayout();
1702 if (VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
1703 uint32_t EltSize = DL.getTypeSizeInBits(VT->getElementType());
1704 return VectorType::get(IntegerType::get(*MS.C, EltSize),
1705 VT->getElementCount());
1706 }
1707 if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) {
1708 return ArrayType::get(getShadowTy(AT->getElementType()),
1709 AT->getNumElements());
1710 }
1711 if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
1713 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1714 Elements.push_back(getShadowTy(ST->getElementType(i)));
1715 StructType *Res = StructType::get(*MS.C, Elements, ST->isPacked());
1716 LLVM_DEBUG(dbgs() << "getShadowTy: " << *ST << " ===> " << *Res << "\n");
1717 return Res;
1718 }
1719 if (isScalableNonVectorType(OrigTy)) {
1720 LLVM_DEBUG(dbgs() << "getShadowTy: Scalable non-vector type: " << *OrigTy
1721 << "\n");
1722 return OrigTy;
1723 }
1724
1725 uint32_t TypeSize = DL.getTypeSizeInBits(OrigTy);
1726 return IntegerType::get(*MS.C, TypeSize);
1727 }
1728
1729 /// Extract combined shadow of struct elements as a bool
1730 Value *collapseStructShadow(StructType *Struct, Value *Shadow,
1731 IRBuilder<> &IRB) {
1732 Value *FalseVal = IRB.getIntN(/* width */ 1, /* value */ 0);
1733 Value *Aggregator = FalseVal;
1734
1735 for (unsigned Idx = 0; Idx < Struct->getNumElements(); Idx++) {
1736 // Combine by ORing together each element's bool shadow
1737 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1738 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1739
1740 if (Aggregator != FalseVal)
1741 Aggregator = IRB.CreateOr(Aggregator, ShadowBool);
1742 else
1743 Aggregator = ShadowBool;
1744 }
1745
1746 return Aggregator;
1747 }
1748
1749 // Extract combined shadow of array elements
1750 Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
1751 IRBuilder<> &IRB) {
1752 if (!Array->getNumElements())
1753 return IRB.getIntN(/* width */ 1, /* value */ 0);
1754
1755 Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
1756 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1757
1758 for (unsigned Idx = 1; Idx < Array->getNumElements(); Idx++) {
1759 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1760 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1761 Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
1762 }
1763 return Aggregator;
1764 }
1765
1766 /// Convert a shadow value to it's flattened variant. The resulting
1767 /// shadow may not necessarily have the same bit width as the input
1768 /// value, but it will always be comparable to zero.
1769 Value *convertShadowToScalar(Value *V, IRBuilder<> &IRB) {
1770 if (StructType *Struct = dyn_cast<StructType>(V->getType()))
1771 return collapseStructShadow(Struct, V, IRB);
1772 if (ArrayType *Array = dyn_cast<ArrayType>(V->getType()))
1773 return collapseArrayShadow(Array, V, IRB);
1774 if (isa<VectorType>(V->getType())) {
1775 if (isa<ScalableVectorType>(V->getType()))
1776 return convertShadowToScalar(IRB.CreateOrReduce(V), IRB);
1777 unsigned BitWidth =
1778 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1779 return IRB.CreateBitCast(V, IntegerType::get(*MS.C, BitWidth));
1780 }
1781 return V;
1782 }
1783
1784 // Convert a scalar value to an i1 by comparing with 0
1785 Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &name = "") {
1786 Type *VTy = V->getType();
1787 if (!VTy->isIntegerTy())
1788 return convertToBool(convertShadowToScalar(V, IRB), IRB, name);
1789 if (VTy->getIntegerBitWidth() == 1)
1790 // Just converting a bool to a bool, so do nothing.
1791 return V;
1792 return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), name);
1793 }
1794
1795 Type *ptrToIntPtrType(Type *PtrTy) const {
1796 if (VectorType *VectTy = dyn_cast<VectorType>(PtrTy)) {
1797 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1798 VectTy->getElementCount());
1799 }
1800 assert(PtrTy->isIntOrPtrTy());
1801 return MS.IntptrTy;
1802 }
1803
1804 Type *getPtrToShadowPtrType(Type *IntPtrTy, Type *ShadowTy) const {
1805 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1806 return VectorType::get(
1807 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1808 VectTy->getElementCount());
1809 }
1810 assert(IntPtrTy == MS.IntptrTy);
1811 return MS.PtrTy;
1812 }
1813
1814 Constant *constToIntPtr(Type *IntPtrTy, uint64_t C) const {
1815 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1817 VectTy->getElementCount(),
1818 constToIntPtr(VectTy->getElementType(), C));
1819 }
1820 assert(IntPtrTy == MS.IntptrTy);
1821 // TODO: Avoid implicit trunc?
1822 // See https://github.com/llvm/llvm-project/issues/112510.
1823 return ConstantInt::get(MS.IntptrTy, C, /*IsSigned=*/false,
1824 /*ImplicitTrunc=*/true);
1825 }
1826
1827 /// Returns the integer shadow offset that corresponds to a given
1828 /// application address, whereby:
1829 ///
1830 /// Offset = (Addr & ~AndMask) ^ XorMask
1831 /// Shadow = ShadowBase + Offset
1832 /// Origin = (OriginBase + Offset) & ~Alignment
1833 ///
1834 /// Note: for efficiency, many shadow mappings only require use the XorMask
1835 /// and OriginBase; the AndMask and ShadowBase are often zero.
1836 Value *getShadowPtrOffset(Value *Addr, IRBuilder<> &IRB) {
1837 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1838 Value *OffsetLong = IRB.CreatePointerCast(Addr, IntptrTy);
1839
1840 if (uint64_t AndMask = MS.MapParams->AndMask)
1841 OffsetLong = IRB.CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1842
1843 if (uint64_t XorMask = MS.MapParams->XorMask)
1844 OffsetLong = IRB.CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1845 return OffsetLong;
1846 }
1847
1848 /// Compute the shadow and origin addresses corresponding to a given
1849 /// application address.
1850 ///
1851 /// Shadow = ShadowBase + Offset
1852 /// Origin = (OriginBase + Offset) & ~3ULL
1853 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1854 /// a single pointee.
1855 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1856 std::pair<Value *, Value *>
1857 getShadowOriginPtrUserspace(Value *Addr, IRBuilder<> &IRB, Type *ShadowTy,
1858 MaybeAlign Alignment) {
1859 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1860 if (!VectTy) {
1861 assert(Addr->getType()->isPointerTy());
1862 } else {
1863 assert(VectTy->getElementType()->isPointerTy());
1864 }
1865 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1866 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1867 Value *ShadowLong = ShadowOffset;
1868 if (uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1869 ShadowLong =
1870 IRB.CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1871 }
1872 Value *ShadowPtr = IRB.CreateIntToPtr(
1873 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1874
1875 Value *OriginPtr = nullptr;
1876 if (MS.TrackOrigins) {
1877 Value *OriginLong = ShadowOffset;
1878 uint64_t OriginBase = MS.MapParams->OriginBase;
1879 if (OriginBase != 0)
1880 OriginLong =
1881 IRB.CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1882 if (!Alignment || *Alignment < kMinOriginAlignment) {
1884 OriginLong = IRB.CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1885 }
1886 OriginPtr = IRB.CreateIntToPtr(
1887 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1888 }
1889 return std::make_pair(ShadowPtr, OriginPtr);
1890 }
1891
1892 template <typename... ArgsTy>
1893 Value *createMetadataCall(IRBuilder<> &IRB, FunctionCallee Callee,
1894 ArgsTy... Args) {
1895 if (MS.TargetTriple.getArch() == Triple::systemz) {
1896 IRB.CreateCall(Callee,
1897 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1898 return IRB.CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1899 }
1900
1901 return IRB.CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1902 }
1903
1904 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(Value *Addr,
1905 IRBuilder<> &IRB,
1906 Type *ShadowTy,
1907 bool isStore) {
1908 Value *ShadowOriginPtrs;
1909 const DataLayout &DL = F.getDataLayout();
1910 TypeSize Size = DL.getTypeStoreSize(ShadowTy);
1911
1912 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size);
1913 Value *AddrCast = IRB.CreatePointerCast(Addr, MS.PtrTy);
1914 if (Getter) {
1915 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1916 } else {
1917 Value *SizeVal = ConstantInt::get(MS.IntptrTy, Size);
1918 ShadowOriginPtrs = createMetadataCall(
1919 IRB,
1920 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1921 AddrCast, SizeVal);
1922 }
1923 Value *ShadowPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 0);
1924 ShadowPtr = IRB.CreatePointerCast(ShadowPtr, MS.PtrTy);
1925 Value *OriginPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 1);
1926
1927 return std::make_pair(ShadowPtr, OriginPtr);
1928 }
1929
1930 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1931 /// a single pointee.
1932 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1933 std::pair<Value *, Value *> getShadowOriginPtrKernel(Value *Addr,
1934 IRBuilder<> &IRB,
1935 Type *ShadowTy,
1936 bool isStore) {
1937 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1938 if (!VectTy) {
1939 assert(Addr->getType()->isPointerTy());
1940 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy, isStore);
1941 }
1942
1943 // TODO: Support callbacs with vectors of addresses.
1944 unsigned NumElements = cast<FixedVectorType>(VectTy)->getNumElements();
1945 Value *ShadowPtrs = ConstantInt::getNullValue(
1946 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1947 Value *OriginPtrs = nullptr;
1948 if (MS.TrackOrigins)
1949 OriginPtrs = ConstantInt::getNullValue(
1950 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1951 for (unsigned i = 0; i < NumElements; ++i) {
1952 Value *OneAddr =
1953 IRB.CreateExtractElement(Addr, ConstantInt::get(IRB.getInt32Ty(), i));
1954 auto [ShadowPtr, OriginPtr] =
1955 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy, isStore);
1956
1957 ShadowPtrs = IRB.CreateInsertElement(
1958 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1959 if (MS.TrackOrigins)
1960 OriginPtrs = IRB.CreateInsertElement(
1961 OriginPtrs, OriginPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1962 }
1963 return {ShadowPtrs, OriginPtrs};
1964 }
1965
1966 std::pair<Value *, Value *> getShadowOriginPtr(Value *Addr, IRBuilder<> &IRB,
1967 Type *ShadowTy,
1968 MaybeAlign Alignment,
1969 bool isStore) {
1970 if (MS.CompileKernel)
1971 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy, isStore);
1972 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1973 }
1974
1975 /// Compute the shadow address for a given function argument.
1976 ///
1977 /// Shadow = ParamTLS+ArgOffset.
1978 Value *getShadowPtrForArgument(IRBuilder<> &IRB, int ArgOffset) {
1979 return IRB.CreatePtrAdd(MS.ParamTLS,
1980 ConstantInt::get(MS.IntptrTy, ArgOffset), "_msarg");
1981 }
1982
1983 /// Compute the origin address for a given function argument.
1984 Value *getOriginPtrForArgument(IRBuilder<> &IRB, int ArgOffset) {
1985 if (!MS.TrackOrigins)
1986 return nullptr;
1987 return IRB.CreatePtrAdd(MS.ParamOriginTLS,
1988 ConstantInt::get(MS.IntptrTy, ArgOffset),
1989 "_msarg_o");
1990 }
1991
1992 /// Compute the shadow address for a retval.
1993 Value *getShadowPtrForRetval(IRBuilder<> &IRB) {
1994 return IRB.CreatePointerCast(MS.RetvalTLS, IRB.getPtrTy(0), "_msret");
1995 }
1996
1997 /// Compute the origin address for a retval.
1998 Value *getOriginPtrForRetval() {
1999 // We keep a single origin for the entire retval. Might be too optimistic.
2000 return MS.RetvalOriginTLS;
2001 }
2002
2003 /// Set SV to be the shadow value for V.
2004 void setShadow(Value *V, Value *SV) {
2005 assert(!ShadowMap.count(V) && "Values may only have one shadow");
2006 ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
2007 }
2008
2009 /// Set Origin to be the origin value for V.
2010 void setOrigin(Value *V, Value *Origin) {
2011 if (!MS.TrackOrigins)
2012 return;
2013 assert(!OriginMap.count(V) && "Values may only have one origin");
2014 LLVM_DEBUG(dbgs() << "ORIGIN: " << *V << " ==> " << *Origin << "\n");
2015 OriginMap[V] = Origin;
2016 }
2017
2018 Constant *getCleanShadow(Type *OrigTy) {
2019 Type *ShadowTy = getShadowTy(OrigTy);
2020 if (!ShadowTy)
2021 return nullptr;
2022 return Constant::getNullValue(ShadowTy);
2023 }
2024
2025 /// Create a clean shadow value for a given value.
2026 ///
2027 /// Clean shadow (all zeroes) means all bits of the value are defined
2028 /// (initialized).
2029 Constant *getCleanShadow(Value *V) { return getCleanShadow(V->getType()); }
2030
2031 /// Create a dirty shadow of a given shadow type.
2032 Constant *getPoisonedShadow(Type *ShadowTy) {
2033 assert(ShadowTy);
2034 if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
2035 return Constant::getAllOnesValue(ShadowTy);
2036 if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) {
2037 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
2038 getPoisonedShadow(AT->getElementType()));
2039 return ConstantArray::get(AT, Vals);
2040 }
2041 if (StructType *ST = dyn_cast<StructType>(ShadowTy)) {
2042 SmallVector<Constant *, 4> Vals;
2043 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
2044 Vals.push_back(getPoisonedShadow(ST->getElementType(i)));
2045 return ConstantStruct::get(ST, Vals);
2046 }
2047 llvm_unreachable("Unexpected shadow type");
2048 }
2049
2050 /// Create a dirty shadow for a given value.
2051 Constant *getPoisonedShadow(Value *V) {
2052 Type *ShadowTy = getShadowTy(V);
2053 if (!ShadowTy)
2054 return nullptr;
2055 return getPoisonedShadow(ShadowTy);
2056 }
2057
2058 /// Create a clean (zero) origin.
2059 Value *getCleanOrigin() { return Constant::getNullValue(MS.OriginTy); }
2060
2061 /// Get the shadow value for a given Value.
2062 ///
2063 /// This function either returns the value set earlier with setShadow,
2064 /// or extracts if from ParamTLS (for function arguments).
2065 Value *getShadow(Value *V) {
2066 if (Instruction *I = dyn_cast<Instruction>(V)) {
2067 if (!PropagateShadow || I->getMetadata(LLVMContext::MD_nosanitize))
2068 return getCleanShadow(V);
2069 // For instructions the shadow is already stored in the map.
2070 Value *Shadow = ShadowMap[V];
2071 if (!Shadow) {
2072 LLVM_DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent()));
2073 assert(Shadow && "No shadow for a value");
2074 }
2075 return Shadow;
2076 }
2077 // Handle fully undefined values
2078 // (partially undefined constant vectors are handled later)
2079 if ([[maybe_unused]] UndefValue *U = dyn_cast<UndefValue>(V)) {
2080 Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
2081 : getCleanShadow(V);
2082 LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n");
2083 return AllOnes;
2084 }
2085 if (Argument *A = dyn_cast<Argument>(V)) {
2086 // For arguments we compute the shadow on demand and store it in the map.
2087 Value *&ShadowPtr = ShadowMap[V];
2088 if (ShadowPtr)
2089 return ShadowPtr;
2090 Function *F = A->getParent();
2091 IRBuilder<> EntryIRB(FnPrologueEnd);
2092 unsigned ArgOffset = 0;
2093 const DataLayout &DL = F->getDataLayout();
2094 for (auto &FArg : F->args()) {
2095 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
2096 LLVM_DEBUG(dbgs() << (FArg.getType()->isScalableTy()
2097 ? "vscale not fully supported\n"
2098 : "Arg is not sized\n"));
2099 if (A == &FArg) {
2100 ShadowPtr = getCleanShadow(V);
2101 setOrigin(A, getCleanOrigin());
2102 break;
2103 }
2104 continue;
2105 }
2106
2107 unsigned Size = FArg.hasByValAttr()
2108 ? DL.getTypeAllocSize(FArg.getParamByValType())
2109 : DL.getTypeAllocSize(FArg.getType());
2110
2111 if (A == &FArg) {
2112 bool Overflow = ArgOffset + Size > kParamTLSSize;
2113 if (FArg.hasByValAttr()) {
2114 // ByVal pointer itself has clean shadow. We copy the actual
2115 // argument shadow to the underlying memory.
2116 // Figure out maximal valid memcpy alignment.
2117 const Align ArgAlign = DL.getValueOrABITypeAlignment(
2118 FArg.getParamAlign(), FArg.getParamByValType());
2119 Value *CpShadowPtr, *CpOriginPtr;
2120 std::tie(CpShadowPtr, CpOriginPtr) =
2121 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
2122 /*isStore*/ true);
2123 if (!PropagateShadow || Overflow) {
2124 // ParamTLS overflow.
2125 EntryIRB.CreateMemSet(
2126 CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()),
2127 Size, ArgAlign);
2128 } else {
2129 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2130 const Align CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
2131 [[maybe_unused]] Value *Cpy = EntryIRB.CreateMemCpy(
2132 CpShadowPtr, CopyAlign, Base, CopyAlign, Size);
2133 LLVM_DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n");
2134
2135 if (MS.TrackOrigins) {
2136 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
2137 // FIXME: OriginSize should be:
2138 // alignTo(V % kMinOriginAlignment + Size, kMinOriginAlignment)
2139 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
2140 EntryIRB.CreateMemCpy(
2141 CpOriginPtr,
2142 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginPtr,
2143 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
2144 OriginSize);
2145 }
2146 }
2147 }
2148
2149 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
2150 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
2151 ShadowPtr = getCleanShadow(V);
2152 setOrigin(A, getCleanOrigin());
2153 } else {
2154 // Shadow over TLS
2155 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2156 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg), Base,
2158 if (MS.TrackOrigins) {
2159 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
2160 setOrigin(A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2161 }
2162 }
2164 << " ARG: " << FArg << " ==> " << *ShadowPtr << "\n");
2165 break;
2166 }
2167
2168 ArgOffset += alignTo(Size, kShadowTLSAlignment);
2169 }
2170 assert(ShadowPtr && "Could not find shadow for an argument");
2171 return ShadowPtr;
2172 }
2173
2174 // Check for partially-undefined constant vectors
2175 // TODO: scalable vectors (this is hard because we do not have IRBuilder)
2176 if (isa<FixedVectorType>(V->getType()) && isa<Constant>(V) &&
2177 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2178 PoisonUndefVectors) {
2179 unsigned NumElems = cast<FixedVectorType>(V->getType())->getNumElements();
2180 SmallVector<Constant *, 32> ShadowVector(NumElems);
2181 for (unsigned i = 0; i != NumElems; ++i) {
2182 Constant *Elem = cast<Constant>(V)->getAggregateElement(i);
2183 ShadowVector[i] = isa<UndefValue>(Elem) ? getPoisonedShadow(Elem)
2184 : getCleanShadow(Elem);
2185 }
2186
2187 Value *ShadowConstant = ConstantVector::get(ShadowVector);
2188 LLVM_DEBUG(dbgs() << "Partial undef constant vector: " << *V << " ==> "
2189 << *ShadowConstant << "\n");
2190
2191 return ShadowConstant;
2192 }
2193
2194 // TODO: partially-undefined constant arrays, structures, and nested types
2195
2196 // For everything else the shadow is zero.
2197 return getCleanShadow(V);
2198 }
2199
2200 /// Get the shadow for i-th argument of the instruction I.
2201 Value *getShadow(Instruction *I, int i) {
2202 return getShadow(I->getOperand(i));
2203 }
2204
2205 /// Get the origin for a value.
2206 Value *getOrigin(Value *V) {
2207 if (!MS.TrackOrigins)
2208 return nullptr;
2209 if (!PropagateShadow || isa<Constant>(V) || isa<InlineAsm>(V))
2210 return getCleanOrigin();
2212 "Unexpected value type in getOrigin()");
2213 if (Instruction *I = dyn_cast<Instruction>(V)) {
2214 if (I->getMetadata(LLVMContext::MD_nosanitize))
2215 return getCleanOrigin();
2216 }
2217 Value *Origin = OriginMap[V];
2218 assert(Origin && "Missing origin");
2219 return Origin;
2220 }
2221
2222 /// Get the origin for i-th argument of the instruction I.
2223 Value *getOrigin(Instruction *I, int i) {
2224 return getOrigin(I->getOperand(i));
2225 }
2226
2227 /// Remember the place where a shadow check should be inserted.
2228 ///
2229 /// This location will be later instrumented with a check that will print a
2230 /// UMR warning in runtime if the shadow value is not 0.
2231 void insertCheckShadow(Value *Shadow, Value *Origin, Instruction *OrigIns) {
2232 assert(Shadow);
2233 if (!InsertChecks)
2234 return;
2235
2236 if (!DebugCounter::shouldExecute(DebugInsertCheck)) {
2237 LLVM_DEBUG(dbgs() << "Skipping check of " << *Shadow << " before "
2238 << *OrigIns << "\n");
2239 return;
2240 }
2241
2242 Type *ShadowTy = Shadow->getType();
2243 if (isScalableNonVectorType(ShadowTy)) {
2244 LLVM_DEBUG(dbgs() << "Skipping check of scalable non-vector " << *Shadow
2245 << " before " << *OrigIns << "\n");
2246 return;
2247 }
2248#ifndef NDEBUG
2249 assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
2250 isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
2251 "Can only insert checks for integer, vector, and aggregate shadow "
2252 "types");
2253#endif
2254 InstrumentationList.push_back(
2255 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2256 }
2257
2258 /// Get shadow for value, and remember the place where a shadow check should
2259 /// be inserted.
2260 ///
2261 /// This location will be later instrumented with a check that will print a
2262 /// UMR warning in runtime if the value is not fully defined.
2263 void insertCheckShadowOf(Value *Val, Instruction *OrigIns) {
2264 assert(Val);
2265 Value *Shadow, *Origin;
2267 Shadow = getShadow(Val);
2268 if (!Shadow)
2269 return;
2270 Origin = getOrigin(Val);
2271 } else {
2272 Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
2273 if (!Shadow)
2274 return;
2275 Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
2276 }
2277 insertCheckShadow(Shadow, Origin, OrigIns);
2278 }
2279
2281 switch (a) {
2282 case AtomicOrdering::NotAtomic:
2283 return AtomicOrdering::NotAtomic;
2284 case AtomicOrdering::Unordered:
2285 case AtomicOrdering::Monotonic:
2286 case AtomicOrdering::Release:
2287 return AtomicOrdering::Release;
2288 case AtomicOrdering::Acquire:
2289 case AtomicOrdering::AcquireRelease:
2290 return AtomicOrdering::AcquireRelease;
2291 case AtomicOrdering::SequentiallyConsistent:
2292 return AtomicOrdering::SequentiallyConsistent;
2293 }
2294 llvm_unreachable("Unknown ordering");
2295 }
2296
2297 Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
2298 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2299 uint32_t OrderingTable[NumOrderings] = {};
2300
2301 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2302 OrderingTable[(int)AtomicOrderingCABI::release] =
2303 (int)AtomicOrderingCABI::release;
2304 OrderingTable[(int)AtomicOrderingCABI::consume] =
2305 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2306 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2307 (int)AtomicOrderingCABI::acq_rel;
2308 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2309 (int)AtomicOrderingCABI::seq_cst;
2310
2311 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2312 }
2313
2315 switch (a) {
2316 case AtomicOrdering::NotAtomic:
2317 return AtomicOrdering::NotAtomic;
2318 case AtomicOrdering::Unordered:
2319 case AtomicOrdering::Monotonic:
2320 case AtomicOrdering::Acquire:
2321 return AtomicOrdering::Acquire;
2322 case AtomicOrdering::Release:
2323 case AtomicOrdering::AcquireRelease:
2324 return AtomicOrdering::AcquireRelease;
2325 case AtomicOrdering::SequentiallyConsistent:
2326 return AtomicOrdering::SequentiallyConsistent;
2327 }
2328 llvm_unreachable("Unknown ordering");
2329 }
2330
2331 Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
2332 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2333 uint32_t OrderingTable[NumOrderings] = {};
2334
2335 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2336 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2337 OrderingTable[(int)AtomicOrderingCABI::consume] =
2338 (int)AtomicOrderingCABI::acquire;
2339 OrderingTable[(int)AtomicOrderingCABI::release] =
2340 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2341 (int)AtomicOrderingCABI::acq_rel;
2342 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2343 (int)AtomicOrderingCABI::seq_cst;
2344
2345 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2346 }
2347
2348 // ------------------- Visitors.
2349 using InstVisitor<MemorySanitizerVisitor>::visit;
2350 void visit(Instruction &I) {
2351 if (I.getMetadata(LLVMContext::MD_nosanitize))
2352 return;
2353 // Don't want to visit if we're in the prologue
2354 if (isInPrologue(I))
2355 return;
2356 if (!DebugCounter::shouldExecute(DebugInstrumentInstruction)) {
2357 LLVM_DEBUG(dbgs() << "Skipping instruction: " << I << "\n");
2358 // We still need to set the shadow and origin to clean values.
2359 setShadow(&I, getCleanShadow(&I));
2360 setOrigin(&I, getCleanOrigin());
2361 return;
2362 }
2363
2364 Instructions.push_back(&I);
2365 }
2366
2367 /// Instrument LoadInst
2368 ///
2369 /// Loads the corresponding shadow and (optionally) origin.
2370 /// Optionally, checks that the load address is fully defined.
2371 void visitLoadInst(LoadInst &I) {
2372 assert(I.getType()->isSized() && "Load type must have size");
2373 assert(!I.getMetadata(LLVMContext::MD_nosanitize));
2374 NextNodeIRBuilder IRB(&I);
2375 Type *ShadowTy = getShadowTy(&I);
2376 Value *Addr = I.getPointerOperand();
2377 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
2378 const Align Alignment = I.getAlign();
2379 if (PropagateShadow) {
2380 std::tie(ShadowPtr, OriginPtr) =
2381 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
2382 setShadow(&I,
2383 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2384 } else {
2385 setShadow(&I, getCleanShadow(&I));
2386 }
2387
2389 insertCheckShadowOf(I.getPointerOperand(), &I);
2390
2391 if (I.isAtomic())
2392 I.setOrdering(addAcquireOrdering(I.getOrdering()));
2393
2394 if (MS.TrackOrigins) {
2395 if (PropagateShadow) {
2396 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
2397 setOrigin(
2398 &I, IRB.CreateAlignedLoad(MS.OriginTy, OriginPtr, OriginAlignment));
2399 } else {
2400 setOrigin(&I, getCleanOrigin());
2401 }
2402 }
2403 }
2404
2405 /// Instrument StoreInst
2406 ///
2407 /// Stores the corresponding shadow and (optionally) origin.
2408 /// Optionally, checks that the store address is fully defined.
2409 void visitStoreInst(StoreInst &I) {
2410 StoreList.push_back(&I);
2412 insertCheckShadowOf(I.getPointerOperand(), &I);
2413 }
2414
2415 void handleCASOrRMW(Instruction &I) {
2417
2418 IRBuilder<> IRB(&I);
2419 Value *Addr = I.getOperand(0);
2420 Value *Val = I.getOperand(1);
2421 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val), Align(1),
2422 /*isStore*/ true)
2423 .first;
2424
2426 insertCheckShadowOf(Addr, &I);
2427
2428 // Only test the conditional argument of cmpxchg instruction.
2429 // The other argument can potentially be uninitialized, but we can not
2430 // detect this situation reliably without possible false positives.
2432 insertCheckShadowOf(Val, &I);
2433
2434 IRB.CreateStore(getCleanShadow(Val), ShadowPtr);
2435
2436 setShadow(&I, getCleanShadow(&I));
2437 setOrigin(&I, getCleanOrigin());
2438 }
2439
2440 void visitAtomicRMWInst(AtomicRMWInst &I) {
2441 handleCASOrRMW(I);
2442 I.setOrdering(addReleaseOrdering(I.getOrdering()));
2443 }
2444
2445 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
2446 handleCASOrRMW(I);
2447 I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
2448 }
2449
2450 /// Generic handler to compute shadow for == and != comparisons.
2451 ///
2452 /// This function is used by handleEqualityComparison and visitSwitchInst.
2453 ///
2454 /// Sometimes the comparison result is known even if some of the bits of the
2455 /// arguments are not.
2456 Value *propagateEqualityComparison(IRBuilder<> &IRB, Value *A, Value *B,
2457 Value *Sa, Value *Sb) {
2458 assert(getShadowTy(A) == Sa->getType());
2459 assert(getShadowTy(B) == Sb->getType());
2460
2461 // Get rid of pointers and vectors of pointers.
2462 // For ints (and vectors of ints), types of A and Sa match,
2463 // and this is a no-op.
2464 A = IRB.CreatePointerCast(A, Sa->getType());
2465 B = IRB.CreatePointerCast(B, Sb->getType());
2466
2467 // A == B <==> (C = A^B) == 0
2468 // A != B <==> (C = A^B) != 0
2469 // Sc = Sa | Sb
2470 Value *C = IRB.CreateXor(A, B);
2471 Value *Sc = IRB.CreateOr(Sa, Sb);
2472 // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
2473 // Result is defined if one of the following is true
2474 // * there is a defined 1 bit in C
2475 // * C is fully defined
2476 // Si = !(C & ~Sc) && Sc
2478 Value *MinusOne = Constant::getAllOnesValue(Sc->getType());
2479 Value *LHS = IRB.CreateICmpNE(Sc, Zero);
2480 Value *RHS =
2481 IRB.CreateICmpEQ(IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero);
2482 Value *Si = IRB.CreateAnd(LHS, RHS);
2483 Si->setName("_msprop_icmp");
2484
2485 return Si;
2486 }
2487
2488 // Instrument:
2489 // switch i32 %Val, label %else [ i32 0, label %A
2490 // i32 1, label %B
2491 // i32 2, label %C ]
2492 //
2493 // Typically, the switch input value (%Val) is fully initialized.
2494 //
2495 // Sometimes the compiler may convert (icmp + br) into a switch statement.
2496 // MSan allows icmp eq/ne with partly initialized inputs to still result in a
2497 // fully initialized output, if there exists a bit that is initialized in
2498 // both inputs with a differing value. For compatibility, we support this in
2499 // the switch instrumentation as well. Note that this edge case only applies
2500 // if the switch input value does not match *any* of the cases (matching any
2501 // of the cases requires an exact, fully initialized match).
2502 //
2503 // ShadowCases = 0
2504 // | propagateEqualityComparison(Val, 0)
2505 // | propagateEqualityComparison(Val, 1)
2506 // | propagateEqualityComparison(Val, 2))
2507 void visitSwitchInst(SwitchInst &SI) {
2508 IRBuilder<> IRB(&SI);
2509
2510 Value *Val = SI.getCondition();
2511 Value *ShadowVal = getShadow(Val);
2512 // TODO: add fast path - if the condition is fully initialized, we know
2513 // there is no UUM, without needing to consider the case values below.
2514
2515 // Some code (e.g., AMDGPUGenMCCodeEmitter.inc) has tens of thousands of
2516 // cases. This results in an extremely long chained expression for MSan's
2517 // switch instrumentation, which can cause the JumpThreadingPass to have a
2518 // stack overflow or excessive runtime. We limit the number of cases
2519 // considered, with the tradeoff of niche false negatives.
2520 // TODO: figure out a better solution.
2521 int casesToConsider = ClSwitchPrecision;
2522
2523 Value *ShadowCases = nullptr;
2524 for (auto Case : SI.cases()) {
2525 if (casesToConsider <= 0)
2526 break;
2527
2528 Value *Comparator = Case.getCaseValue();
2529 // TODO: some simplification is possible when comparing multiple cases
2530 // simultaneously.
2531 Value *ComparisonShadow = propagateEqualityComparison(
2532 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2533
2534 if (ShadowCases)
2535 ShadowCases = IRB.CreateOr(ShadowCases, ComparisonShadow);
2536 else
2537 ShadowCases = ComparisonShadow;
2538
2539 casesToConsider--;
2540 }
2541
2542 if (ShadowCases)
2543 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2544 }
2545
2546 // Vector manipulation.
2547 void visitExtractElementInst(ExtractElementInst &I) {
2548 insertCheckShadowOf(I.getOperand(1), &I);
2549 IRBuilder<> IRB(&I);
2550 setShadow(&I, IRB.CreateExtractElement(getShadow(&I, 0), I.getOperand(1),
2551 "_msprop"));
2552 setOrigin(&I, getOrigin(&I, 0));
2553 }
2554
2555 void visitInsertElementInst(InsertElementInst &I) {
2556 insertCheckShadowOf(I.getOperand(2), &I);
2557 IRBuilder<> IRB(&I);
2558 auto *Shadow0 = getShadow(&I, 0);
2559 auto *Shadow1 = getShadow(&I, 1);
2560 setShadow(&I, IRB.CreateInsertElement(Shadow0, Shadow1, I.getOperand(2),
2561 "_msprop"));
2562 setOriginForNaryOp(I);
2563 }
2564
2565 void visitShuffleVectorInst(ShuffleVectorInst &I) {
2566 IRBuilder<> IRB(&I);
2567 auto *Shadow0 = getShadow(&I, 0);
2568 auto *Shadow1 = getShadow(&I, 1);
2569 setShadow(&I, IRB.CreateShuffleVector(Shadow0, Shadow1, I.getShuffleMask(),
2570 "_msprop"));
2571 setOriginForNaryOp(I);
2572 }
2573
2574 // Casts.
2575 void visitSExtInst(SExtInst &I) {
2576 IRBuilder<> IRB(&I);
2577 setShadow(&I, IRB.CreateSExt(getShadow(&I, 0), I.getType(), "_msprop"));
2578 setOrigin(&I, getOrigin(&I, 0));
2579 }
2580
2581 void visitZExtInst(ZExtInst &I) {
2582 IRBuilder<> IRB(&I);
2583 setShadow(&I, IRB.CreateZExt(getShadow(&I, 0), I.getType(), "_msprop"));
2584 setOrigin(&I, getOrigin(&I, 0));
2585 }
2586
2587 void visitTruncInst(TruncInst &I) {
2588 IRBuilder<> IRB(&I);
2589 setShadow(&I, IRB.CreateTrunc(getShadow(&I, 0), I.getType(), "_msprop"));
2590 setOrigin(&I, getOrigin(&I, 0));
2591 }
2592
2593 void visitBitCastInst(BitCastInst &I) {
2594 // Special case: if this is the bitcast (there is exactly 1 allowed) between
2595 // a musttail call and a ret, don't instrument. New instructions are not
2596 // allowed after a musttail call.
2597 if (auto *CI = dyn_cast<CallInst>(I.getOperand(0)))
2598 if (CI->isMustTailCall())
2599 return;
2600 IRBuilder<> IRB(&I);
2601 setShadow(&I, IRB.CreateBitCast(getShadow(&I, 0), getShadowTy(&I)));
2602 setOrigin(&I, getOrigin(&I, 0));
2603 }
2604
2605 void visitPtrToIntInst(PtrToIntInst &I) {
2606 IRBuilder<> IRB(&I);
2607 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2608 "_msprop_ptrtoint"));
2609 setOrigin(&I, getOrigin(&I, 0));
2610 }
2611
2612 void visitPtrToAddrInst(PtrToAddrInst &I) {
2613 IRBuilder<> IRB(&I);
2614 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2615 "_msprop_ptrtoaddr"));
2616 setOrigin(&I, getOrigin(&I, 0));
2617 }
2618
2619 void visitIntToPtrInst(IntToPtrInst &I) {
2620 IRBuilder<> IRB(&I);
2621 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2622 "_msprop_inttoptr"));
2623 setOrigin(&I, getOrigin(&I, 0));
2624 }
2625
2626 /// Handle LLVM and NEON vector convert intrinsics.
2627 ///
2628 /// e.g., <4 x i32> @llvm.aarch64.neon.fcvtpu.v4i32.v4f32(<4 x float>)
2629 /// i32 @llvm.aarch64.neon.fcvtms.i32.f64 (double)
2630 /// <2 x i32> @fptoui (<2 x float>)
2631 /// i64 @llvm.fptosi.sat.i64.f64(double)
2632 ///
2633 /// Note that the size of input/output elements can differ e.g.,
2634 /// double @sitofp(i32)
2635 /// but the number of elements must be the same.
2636 ///
2637 /// For conversions to or from fixed-point, there is a trailing argument to
2638 /// indicate the fixed-point precision:
2639 /// - <4 x float> llvm.aarch64.neon.vcvtfxs2fp.v4f32.v4i32(<4 x i32>, i32)
2640 /// - <4 x i32> llvm.aarch64.neon.vcvtfp2fxu.v4i32.v4f32(<4 x float>, i32)
2641 ///
2642 /// For x86 SSE vector convert intrinsics, see
2643 /// handleSSEVectorConvertIntrinsic().
2644 void handleGenericVectorConvertIntrinsic(Instruction &I, bool FixedPoint) {
2645 [[maybe_unused]] unsigned NumArgs = I.getNumOperands();
2646 if (auto *CI = dyn_cast<CallInst>(&I))
2647 NumArgs = CI->arg_size();
2648
2649 if (FixedPoint) {
2650 assert(NumArgs == 2);
2651 Value *Precision = I.getOperand(1);
2652 insertCheckShadowOf(Precision, &I);
2653 } else {
2654 assert(NumArgs == 1);
2655 }
2656
2657 IRBuilder<> IRB(&I);
2658 Value *S0 = getShadow(&I, 0);
2659
2660 /// For scalars:
2661 /// Since they are converting from floating-point to integer, or between
2662 /// different width floating-point values, the output is:
2663 /// - fully uninitialized if *any* bit of the input is uninitialized
2664 /// - fully ininitialized if all bits of the input are ininitialized
2665 /// We apply the same principle on a per-field basis for vectors.
2666 Value *OutShadow = IRB.CreateSExt(IRB.CreateICmpNE(S0, getCleanShadow(S0)),
2667 getShadowTy(&I));
2668 setShadow(&I, OutShadow);
2669 setOriginForNaryOp(I);
2670 }
2671
2672 void visitFPToSIInst(CastInst &I) {
2673 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2674 }
2675 void visitFPToUIInst(CastInst &I) {
2676 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2677 }
2678 void visitSIToFPInst(CastInst &I) {
2679 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2680 }
2681 void visitUIToFPInst(CastInst &I) {
2682 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2683 }
2684
2685 void visitFPExtInst(CastInst &I) {
2686 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2687 }
2688 void visitFPTruncInst(CastInst &I) {
2689 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2690 }
2691
2692 /// Generic handler to compute shadow for bitwise AND.
2693 ///
2694 /// This is used by 'visitAnd' but also as a primitive for other handlers.
2695 ///
2696 /// This code is precise: it implements the rule that "And" of an initialized
2697 /// zero bit always results in an initialized value:
2698 // 1&1 => 1; 0&1 => 0; p&1 => p;
2699 // 1&0 => 0; 0&0 => 0; p&0 => 0;
2700 // 1&p => p; 0&p => 0; p&p => p;
2701 //
2702 // S = (S1 & S2) | (V1 & S2) | (S1 & V2)
2703 Value *handleBitwiseAnd(IRBuilder<> &IRB, Value *V1, Value *V2, Value *S1,
2704 Value *S2) {
2705 // "The two arguments to the ‘and’ instruction must be integer or vector
2706 // of integer values. Both arguments must have identical types."
2707 //
2708 // We enforce this condition for all callers to handleBitwiseAnd(); callers
2709 // with non-integer types should call CreateAppToShadowCast() themselves.
2710 assert(V1->getType()->isIntOrIntVectorTy());
2711 assert(V1->getType() == V2->getType());
2712
2713 // Conveniently, getShadowTy() of Int/IntVector returns the original type.
2714 assert(V1->getType() == S1->getType());
2715 assert(V2->getType() == S2->getType());
2716
2717 Value *S1S2 = IRB.CreateAnd(S1, S2);
2718 Value *V1S2 = IRB.CreateAnd(V1, S2);
2719 Value *S1V2 = IRB.CreateAnd(S1, V2);
2720
2721 return IRB.CreateOr({S1S2, V1S2, S1V2});
2722 }
2723
2724 /// Handler for bitwise AND operator.
2725 void visitAnd(BinaryOperator &I) {
2726 IRBuilder<> IRB(&I);
2727 Value *V1 = I.getOperand(0);
2728 Value *V2 = I.getOperand(1);
2729 Value *S1 = getShadow(&I, 0);
2730 Value *S2 = getShadow(&I, 1);
2731
2732 Value *OutShadow = handleBitwiseAnd(IRB, V1, V2, S1, S2);
2733
2734 setShadow(&I, OutShadow);
2735 setOriginForNaryOp(I);
2736 }
2737
2738 void visitOr(BinaryOperator &I) {
2739 IRBuilder<> IRB(&I);
2740 // "Or" of 1 and a poisoned value results in unpoisoned value:
2741 // 1|1 => 1; 0|1 => 1; p|1 => 1;
2742 // 1|0 => 1; 0|0 => 0; p|0 => p;
2743 // 1|p => 1; 0|p => p; p|p => p;
2744 //
2745 // S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2)
2746 //
2747 // If the "disjoint OR" property is violated, the result is poison, and
2748 // hence the entire shadow is uninitialized:
2749 // S = S | SignExt(V1 & V2 != 0)
2750 Value *S1 = getShadow(&I, 0);
2751 Value *S2 = getShadow(&I, 1);
2752 Value *V1 = I.getOperand(0);
2753 Value *V2 = I.getOperand(1);
2754
2755 // "The two arguments to the ‘or’ instruction must be integer or vector
2756 // of integer values. Both arguments must have identical types."
2757 assert(V1->getType()->isIntOrIntVectorTy());
2758 assert(V1->getType() == V2->getType());
2759
2760 // Conveniently, getShadowTy() of Int/IntVector returns the original type.
2761 assert(V1->getType() == S1->getType());
2762 assert(V2->getType() == S2->getType());
2763
2764 Value *NotV1 = IRB.CreateNot(V1);
2765 Value *NotV2 = IRB.CreateNot(V2);
2766
2767 Value *S1S2 = IRB.CreateAnd(S1, S2);
2768 Value *S2NotV1 = IRB.CreateAnd(NotV1, S2);
2769 Value *S1NotV2 = IRB.CreateAnd(S1, NotV2);
2770
2771 Value *S = IRB.CreateOr({S1S2, S2NotV1, S1NotV2});
2772
2773 if (ClPreciseDisjointOr && cast<PossiblyDisjointInst>(&I)->isDisjoint()) {
2774 Value *V1V2 = IRB.CreateAnd(V1, V2);
2775 Value *DisjointOrShadow = IRB.CreateSExt(
2776 IRB.CreateICmpNE(V1V2, getCleanShadow(V1V2)), V1V2->getType());
2777 S = IRB.CreateOr(S, DisjointOrShadow, "_ms_disjoint");
2778 }
2779
2780 setShadow(&I, S);
2781 setOriginForNaryOp(I);
2782 }
2783
2784 /// Default propagation of shadow and/or origin.
2785 ///
2786 /// This class implements the general case of shadow propagation, used in all
2787 /// cases where we don't know and/or don't care about what the operation
2788 /// actually does. It converts all input shadow values to a common type
2789 /// (extending or truncating as necessary), and bitwise OR's them.
2790 ///
2791 /// This is much cheaper than inserting checks (i.e. requiring inputs to be
2792 /// fully initialized), and less prone to false positives.
2793 ///
2794 /// This class also implements the general case of origin propagation. For a
2795 /// Nary operation, result origin is set to the origin of an argument that is
2796 /// not entirely initialized. If there is more than one such arguments, the
2797 /// rightmost of them is picked. It does not matter which one is picked if all
2798 /// arguments are initialized.
2799 template <bool CombineShadow> class Combiner {
2800 Value *Shadow = nullptr;
2801 Value *Origin = nullptr;
2802 IRBuilder<> &IRB;
2803 MemorySanitizerVisitor *MSV;
2804
2805 public:
2806 Combiner(MemorySanitizerVisitor *MSV, IRBuilder<> &IRB)
2807 : IRB(IRB), MSV(MSV) {}
2808
2809 /// Add a pair of shadow and origin values to the mix.
2810 Combiner &Add(Value *OpShadow, Value *OpOrigin) {
2811 if (CombineShadow) {
2812 assert(OpShadow);
2813 if (!Shadow)
2814 Shadow = OpShadow;
2815 else {
2816 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2817 Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop");
2818 }
2819 }
2820
2821 if (MSV->MS.TrackOrigins) {
2822 assert(OpOrigin);
2823 if (!Origin) {
2824 Origin = OpOrigin;
2825 } else {
2826 Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
2827 // No point in adding something that might result in 0 origin value.
2828 if (!ConstOrigin || !ConstOrigin->isNullValue()) {
2829 Value *Cond = MSV->convertToBool(OpShadow, IRB);
2830 Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
2831 }
2832 }
2833 }
2834 return *this;
2835 }
2836
2837 /// Add an application value to the mix.
2838 Combiner &Add(Value *V) {
2839 Value *OpShadow = MSV->getShadow(V);
2840 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : nullptr;
2841 return Add(OpShadow, OpOrigin);
2842 }
2843
2844 /// Set the current combined values as the given instruction's shadow
2845 /// and origin.
2846 void Done(Instruction *I) {
2847 if (CombineShadow) {
2848 assert(Shadow);
2849 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
2850 MSV->setShadow(I, Shadow);
2851 }
2852 if (MSV->MS.TrackOrigins) {
2853 assert(Origin);
2854 MSV->setOrigin(I, Origin);
2855 }
2856 }
2857
2858 /// Store the current combined value at the specified origin
2859 /// location.
2860 void DoneAndStoreOrigin(TypeSize TS, Value *OriginPtr) {
2861 if (MSV->MS.TrackOrigins) {
2862 assert(Origin);
2863 MSV->paintOrigin(IRB, Origin, OriginPtr, TS, kMinOriginAlignment);
2864 }
2865 }
2866 };
2867
2868 using ShadowAndOriginCombiner = Combiner<true>;
2869 using OriginCombiner = Combiner<false>;
2870
2871 /// Propagate origin for arbitrary operation.
2872 void setOriginForNaryOp(Instruction &I) {
2873 if (!MS.TrackOrigins)
2874 return;
2875 IRBuilder<> IRB(&I);
2876 OriginCombiner OC(this, IRB);
2877 for (Use &Op : I.operands())
2878 OC.Add(Op.get());
2879 OC.Done(&I);
2880 }
2881
2882 size_t VectorOrPrimitiveTypeSizeInBits(Type *Ty) {
2883 assert(!(Ty->isVectorTy() && Ty->getScalarType()->isPointerTy()) &&
2884 "Vector of pointers is not a valid shadow type");
2885 return Ty->isVectorTy() ? cast<FixedVectorType>(Ty)->getNumElements() *
2887 : Ty->getPrimitiveSizeInBits();
2888 }
2889
2890 /// Cast between two shadow types, extending or truncating as
2891 /// necessary.
2892 Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
2893 bool Signed = false) {
2894 Type *srcTy = V->getType();
2895 if (srcTy == dstTy)
2896 return V;
2897 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2898 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2899 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2900 return IRB.CreateICmpNE(V, getCleanShadow(V));
2901
2902 if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
2903 return IRB.CreateIntCast(V, dstTy, Signed);
2904 if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
2905 cast<VectorType>(dstTy)->getElementCount() ==
2906 cast<VectorType>(srcTy)->getElementCount())
2907 return IRB.CreateIntCast(V, dstTy, Signed);
2908 Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
2909 Value *V2 =
2910 IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
2911 return IRB.CreateBitCast(V2, dstTy);
2912 // TODO: handle struct types.
2913 }
2914
2915 /// Cast an application value to the type of its own shadow.
2916 Value *CreateAppToShadowCast(IRBuilder<> &IRB, Value *V) {
2917 Type *ShadowTy = getShadowTy(V);
2918 if (V->getType() == ShadowTy)
2919 return V;
2920 if (V->getType()->isPtrOrPtrVectorTy())
2921 return IRB.CreatePtrToInt(V, ShadowTy);
2922 else
2923 return IRB.CreateBitCast(V, ShadowTy);
2924 }
2925
2926 /// Propagate shadow for arbitrary operation.
2927 void handleShadowOr(Instruction &I) {
2928 IRBuilder<> IRB(&I);
2929 ShadowAndOriginCombiner SC(this, IRB);
2930 for (Use &Op : I.operands())
2931 SC.Add(Op.get());
2932 SC.Done(&I);
2933 }
2934
2935 // Perform a bitwise OR on the horizontal pairs (or other specified grouping)
2936 // of elements.
2937 //
2938 // For example, suppose we have:
2939 // VectorA: <a0, a1, a2, a3, a4, a5>
2940 // VectorB: <b0, b1, b2, b3, b4, b5>
2941 // ReductionFactor: 3
2942 // Shards: 1
2943 // The output would be:
2944 // <a0|a1|a2, a3|a4|a5, b0|b1|b2, b3|b4|b5>
2945 //
2946 // If we have:
2947 // VectorA: <a0, a1, a2, a3, a4, a5, a6, a7>
2948 // VectorB: <b0, b1, b2, b3, b4, b5, b6, b7>
2949 // ReductionFactor: 2
2950 // Shards: 2
2951 // then a and be each have 2 "shards", resulting in the output being
2952 // interleaved:
2953 // <a0|a1, a2|a3, b0|b1, b2|b3, a4|a5, a6|a7, b4|b5, b6|b7>
2954 //
2955 // This is convenient for instrumenting horizontal add/sub.
2956 // For bitwise OR on "vertical" pairs, see maybeHandleSimpleNomemIntrinsic().
2957 Value *horizontalReduce(IntrinsicInst &I, unsigned ReductionFactor,
2958 unsigned Shards, Value *VectorA, Value *VectorB) {
2959 assert(isa<FixedVectorType>(VectorA->getType()));
2960 unsigned NumElems =
2961 cast<FixedVectorType>(VectorA->getType())->getNumElements();
2962
2963 [[maybe_unused]] unsigned TotalNumElems = NumElems;
2964 if (VectorB) {
2965 assert(VectorA->getType() == VectorB->getType());
2966 TotalNumElems *= 2;
2967 }
2968
2969 assert(NumElems % (ReductionFactor * Shards) == 0);
2970
2971 Value *Or = nullptr;
2972
2973 IRBuilder<> IRB(&I);
2974 for (unsigned i = 0; i < ReductionFactor; i++) {
2975 SmallVector<int, 16> Mask;
2976
2977 for (unsigned j = 0; j < Shards; j++) {
2978 unsigned Offset = NumElems / Shards * j;
2979
2980 for (unsigned X = 0; X < NumElems / Shards; X += ReductionFactor)
2981 Mask.push_back(Offset + X + i);
2982
2983 if (VectorB) {
2984 for (unsigned X = 0; X < NumElems / Shards; X += ReductionFactor)
2985 Mask.push_back(NumElems + Offset + X + i);
2986 }
2987 }
2988
2989 Value *Masked;
2990 if (VectorB)
2991 Masked = IRB.CreateShuffleVector(VectorA, VectorB, Mask);
2992 else
2993 Masked = IRB.CreateShuffleVector(VectorA, Mask);
2994
2995 if (Or)
2996 Or = IRB.CreateOr(Or, Masked);
2997 else
2998 Or = Masked;
2999 }
3000
3001 return Or;
3002 }
3003
3004 /// Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
3005 /// fields.
3006 ///
3007 /// e.g., <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16>)
3008 /// <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8>, <16 x i8>)
3009 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &I, unsigned Shards) {
3010 assert(I.arg_size() == 1 || I.arg_size() == 2);
3011
3012 assert(I.getType()->isVectorTy());
3013 assert(I.getArgOperand(0)->getType()->isVectorTy());
3014
3015 [[maybe_unused]] FixedVectorType *ParamType =
3016 cast<FixedVectorType>(I.getArgOperand(0)->getType());
3017 assert((I.arg_size() != 2) ||
3018 (ParamType == cast<FixedVectorType>(I.getArgOperand(1)->getType())));
3019 [[maybe_unused]] FixedVectorType *ReturnType =
3020 cast<FixedVectorType>(I.getType());
3021 assert(ParamType->getNumElements() * I.arg_size() ==
3022 2 * ReturnType->getNumElements());
3023
3024 IRBuilder<> IRB(&I);
3025
3026 // Horizontal OR of shadow
3027 Value *FirstArgShadow = getShadow(&I, 0);
3028 Value *SecondArgShadow = nullptr;
3029 if (I.arg_size() == 2)
3030 SecondArgShadow = getShadow(&I, 1);
3031
3032 Value *OrShadow = horizontalReduce(I, /*ReductionFactor=*/2, Shards,
3033 FirstArgShadow, SecondArgShadow);
3034
3035 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
3036
3037 setShadow(&I, OrShadow);
3038 setOriginForNaryOp(I);
3039 }
3040
3041 /// Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
3042 /// fields, with the parameters reinterpreted to have elements of a specified
3043 /// width. For example:
3044 /// @llvm.x86.ssse3.phadd.w(<1 x i64> [[VAR1]], <1 x i64> [[VAR2]])
3045 /// conceptually operates on
3046 /// (<4 x i16> [[VAR1]], <4 x i16> [[VAR2]])
3047 /// and can be handled with ReinterpretElemWidth == 16.
3048 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &I, unsigned Shards,
3049 int ReinterpretElemWidth) {
3050 assert(I.arg_size() == 1 || I.arg_size() == 2);
3051
3052 assert(I.getType()->isVectorTy());
3053 assert(I.getArgOperand(0)->getType()->isVectorTy());
3054
3055 FixedVectorType *ParamType =
3056 cast<FixedVectorType>(I.getArgOperand(0)->getType());
3057 assert((I.arg_size() != 2) ||
3058 (ParamType == cast<FixedVectorType>(I.getArgOperand(1)->getType())));
3059
3060 [[maybe_unused]] FixedVectorType *ReturnType =
3061 cast<FixedVectorType>(I.getType());
3062 assert(ParamType->getNumElements() * I.arg_size() ==
3063 2 * ReturnType->getNumElements());
3064
3065 IRBuilder<> IRB(&I);
3066
3067 FixedVectorType *ReinterpretShadowTy = nullptr;
3068 assert(isAligned(Align(ReinterpretElemWidth),
3069 ParamType->getPrimitiveSizeInBits()));
3070 ReinterpretShadowTy = FixedVectorType::get(
3071 IRB.getIntNTy(ReinterpretElemWidth),
3072 ParamType->getPrimitiveSizeInBits() / ReinterpretElemWidth);
3073
3074 // Horizontal OR of shadow
3075 Value *FirstArgShadow = getShadow(&I, 0);
3076 FirstArgShadow = IRB.CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
3077
3078 // If we had two parameters each with an odd number of elements, the total
3079 // number of elements is even, but we have never seen this in extant
3080 // instruction sets, so we enforce that each parameter must have an even
3081 // number of elements.
3083 Align(2),
3084 cast<FixedVectorType>(FirstArgShadow->getType())->getNumElements()));
3085
3086 Value *SecondArgShadow = nullptr;
3087 if (I.arg_size() == 2) {
3088 SecondArgShadow = getShadow(&I, 1);
3089 SecondArgShadow = IRB.CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
3090 }
3091
3092 Value *OrShadow = horizontalReduce(I, /*ReductionFactor=*/2, Shards,
3093 FirstArgShadow, SecondArgShadow);
3094
3095 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
3096
3097 setShadow(&I, OrShadow);
3098 setOriginForNaryOp(I);
3099 }
3100
3101 void visitFNeg(UnaryOperator &I) { handleShadowOr(I); }
3102
3103 // Handle multiplication by constant.
3104 //
3105 // Handle a special case of multiplication by constant that may have one or
3106 // more zeros in the lower bits. This makes corresponding number of lower bits
3107 // of the result zero as well. We model it by shifting the other operand
3108 // shadow left by the required number of bits. Effectively, we transform
3109 // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B).
3110 // We use multiplication by 2**N instead of shift to cover the case of
3111 // multiplication by 0, which may occur in some elements of a vector operand.
3112 void handleMulByConstant(BinaryOperator &I, Constant *ConstArg,
3113 Value *OtherArg) {
3114 Constant *ShadowMul;
3115 Type *Ty = ConstArg->getType();
3116 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
3117 unsigned NumElements = cast<FixedVectorType>(VTy)->getNumElements();
3118 Type *EltTy = VTy->getElementType();
3120 for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
3121 if (ConstantInt *Elt =
3123 const APInt &V = Elt->getValue();
3124 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
3125 Elements.push_back(ConstantInt::get(EltTy, V2));
3126 } else {
3127 Elements.push_back(ConstantInt::get(EltTy, 1));
3128 }
3129 }
3130 ShadowMul = ConstantVector::get(Elements);
3131 } else {
3132 if (ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg)) {
3133 const APInt &V = Elt->getValue();
3134 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
3135 ShadowMul = ConstantInt::get(Ty, V2);
3136 } else {
3137 ShadowMul = ConstantInt::get(Ty, 1);
3138 }
3139 }
3140
3141 IRBuilder<> IRB(&I);
3142 setShadow(&I,
3143 IRB.CreateMul(getShadow(OtherArg), ShadowMul, "msprop_mul_cst"));
3144 setOrigin(&I, getOrigin(OtherArg));
3145 }
3146
3147 void visitMul(BinaryOperator &I) {
3148 Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
3149 Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
3150 if (constOp0 && !constOp1)
3151 handleMulByConstant(I, constOp0, I.getOperand(1));
3152 else if (constOp1 && !constOp0)
3153 handleMulByConstant(I, constOp1, I.getOperand(0));
3154 else
3155 handleShadowOr(I);
3156 }
3157
3158 void visitFAdd(BinaryOperator &I) { handleShadowOr(I); }
3159 void visitFSub(BinaryOperator &I) { handleShadowOr(I); }
3160 void visitFMul(BinaryOperator &I) { handleShadowOr(I); }
3161 void visitAdd(BinaryOperator &I) { handleShadowOr(I); }
3162 void visitSub(BinaryOperator &I) { handleShadowOr(I); }
3163 void visitXor(BinaryOperator &I) { handleShadowOr(I); }
3164
3165 void handleIntegerDiv(Instruction &I) {
3166 IRBuilder<> IRB(&I);
3167 // Strict on the second argument.
3168 insertCheckShadowOf(I.getOperand(1), &I);
3169 setShadow(&I, getShadow(&I, 0));
3170 setOrigin(&I, getOrigin(&I, 0));
3171 }
3172
3173 void visitUDiv(BinaryOperator &I) { handleIntegerDiv(I); }
3174 void visitSDiv(BinaryOperator &I) { handleIntegerDiv(I); }
3175 void visitURem(BinaryOperator &I) { handleIntegerDiv(I); }
3176 void visitSRem(BinaryOperator &I) { handleIntegerDiv(I); }
3177
3178 // Floating point division is side-effect free. We can not require that the
3179 // divisor is fully initialized and must propagate shadow. See PR37523.
3180 void visitFDiv(BinaryOperator &I) { handleShadowOr(I); }
3181 void visitFRem(BinaryOperator &I) { handleShadowOr(I); }
3182
3183 /// Instrument == and != comparisons.
3184 ///
3185 /// Sometimes the comparison result is known even if some of the bits of the
3186 /// arguments are not.
3187 void handleEqualityComparison(ICmpInst &I) {
3188 IRBuilder<> IRB(&I);
3189 Value *A = I.getOperand(0);
3190 Value *B = I.getOperand(1);
3191 Value *Sa = getShadow(A);
3192 Value *Sb = getShadow(B);
3193
3194 Value *Si = propagateEqualityComparison(IRB, A, B, Sa, Sb);
3195
3196 setShadow(&I, Si);
3197 setOriginForNaryOp(I);
3198 }
3199
3200 /// Instrument relational comparisons.
3201 ///
3202 /// This function does exact shadow propagation for all relational
3203 /// comparisons of integers, pointers and vectors of those.
3204 /// FIXME: output seems suboptimal when one of the operands is a constant
3205 void handleRelationalComparisonExact(ICmpInst &I) {
3206 IRBuilder<> IRB(&I);
3207 Value *A = I.getOperand(0);
3208 Value *B = I.getOperand(1);
3209 Value *Sa = getShadow(A);
3210 Value *Sb = getShadow(B);
3211
3212 // Get rid of pointers and vectors of pointers.
3213 // For ints (and vectors of ints), types of A and Sa match,
3214 // and this is a no-op.
3215 A = IRB.CreatePointerCast(A, Sa->getType());
3216 B = IRB.CreatePointerCast(B, Sb->getType());
3217
3218 // Let [a0, a1] be the interval of possible values of A, taking into account
3219 // its undefined bits. Let [b0, b1] be the interval of possible values of B.
3220 // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
3221 bool IsSigned = I.isSigned();
3222
3223 auto GetMinMaxUnsigned = [&](Value *V, Value *S) {
3224 if (IsSigned) {
3225 // Sign-flip to map from signed range to unsigned range. Relation A vs B
3226 // should be preserved, if checked with `getUnsignedPredicate()`.
3227 // Relationship between Amin, Amax, Bmin, Bmax also will not be
3228 // affected, as they are created by effectively adding/substructing from
3229 // A (or B) a value, derived from shadow, with no overflow, either
3230 // before or after sign flip.
3231 APInt MinVal =
3232 APInt::getSignedMinValue(V->getType()->getScalarSizeInBits());
3233 V = IRB.CreateXor(V, ConstantInt::get(V->getType(), MinVal));
3234 }
3235 // Minimize undefined bits.
3236 Value *Min = IRB.CreateAnd(V, IRB.CreateNot(S));
3237 Value *Max = IRB.CreateOr(V, S);
3238 return std::make_pair(Min, Max);
3239 };
3240
3241 auto [Amin, Amax] = GetMinMaxUnsigned(A, Sa);
3242 auto [Bmin, Bmax] = GetMinMaxUnsigned(B, Sb);
3243 Value *S1 = IRB.CreateICmp(I.getUnsignedPredicate(), Amin, Bmax);
3244 Value *S2 = IRB.CreateICmp(I.getUnsignedPredicate(), Amax, Bmin);
3245
3246 Value *Si = IRB.CreateXor(S1, S2);
3247 setShadow(&I, Si);
3248 setOriginForNaryOp(I);
3249 }
3250
3251 /// Instrument signed relational comparisons.
3252 ///
3253 /// Handle sign bit tests: x<0, x>=0, x<=-1, x>-1 by propagating the highest
3254 /// bit of the shadow. Everything else is delegated to handleShadowOr().
3255 void handleSignedRelationalComparison(ICmpInst &I) {
3256 Constant *constOp;
3257 Value *op = nullptr;
3259 if ((constOp = dyn_cast<Constant>(I.getOperand(1)))) {
3260 op = I.getOperand(0);
3261 pre = I.getPredicate();
3262 } else if ((constOp = dyn_cast<Constant>(I.getOperand(0)))) {
3263 op = I.getOperand(1);
3264 pre = I.getSwappedPredicate();
3265 } else {
3266 handleShadowOr(I);
3267 return;
3268 }
3269
3270 if ((constOp->isNullValue() &&
3271 (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) ||
3272 (constOp->isAllOnesValue() &&
3273 (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE))) {
3274 IRBuilder<> IRB(&I);
3275 Value *Shadow = IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op),
3276 "_msprop_icmp_s");
3277 setShadow(&I, Shadow);
3278 setOrigin(&I, getOrigin(op));
3279 } else {
3280 handleShadowOr(I);
3281 }
3282 }
3283
3284 void visitICmpInst(ICmpInst &I) {
3285 if (!ClHandleICmp) {
3286 handleShadowOr(I);
3287 return;
3288 }
3289 if (I.isEquality()) {
3290 handleEqualityComparison(I);
3291 return;
3292 }
3293
3294 assert(I.isRelational());
3295 if (ClHandleICmpExact) {
3296 handleRelationalComparisonExact(I);
3297 return;
3298 }
3299 if (I.isSigned()) {
3300 handleSignedRelationalComparison(I);
3301 return;
3302 }
3303
3304 assert(I.isUnsigned());
3305 if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
3306 handleRelationalComparisonExact(I);
3307 return;
3308 }
3309
3310 handleShadowOr(I);
3311 }
3312
3313 void visitFCmpInst(FCmpInst &I) { handleShadowOr(I); }
3314
3315 void handleShift(BinaryOperator &I) {
3316 IRBuilder<> IRB(&I);
3317 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3318 // Otherwise perform the same shift on S1.
3319 Value *S1 = getShadow(&I, 0);
3320 Value *S2 = getShadow(&I, 1);
3321 Value *S2Conv =
3322 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
3323 Value *V2 = I.getOperand(1);
3324 Value *Shift = IRB.CreateBinOp(I.getOpcode(), S1, V2);
3325 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3326 setOriginForNaryOp(I);
3327 }
3328
3329 void visitShl(BinaryOperator &I) { handleShift(I); }
3330 void visitAShr(BinaryOperator &I) { handleShift(I); }
3331 void visitLShr(BinaryOperator &I) { handleShift(I); }
3332
3333 void handleFunnelShift(IntrinsicInst &I) {
3334 IRBuilder<> IRB(&I);
3335 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3336 // Otherwise perform the same shift on S0 and S1.
3337 Value *S0 = getShadow(&I, 0);
3338 Value *S1 = getShadow(&I, 1);
3339 Value *S2 = getShadow(&I, 2);
3340 Value *S2Conv =
3341 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
3342 Value *V2 = I.getOperand(2);
3343 Value *Shift = IRB.CreateIntrinsic(I.getIntrinsicID(), S2Conv->getType(),
3344 {S0, S1, V2});
3345 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3346 setOriginForNaryOp(I);
3347 }
3348
3349 // Instrument bit manipulation intrinsics.
3350 // All of these intrinsics are Z = I(SRC, MASK)
3351 // where the types of all operands and the result match.
3352 // The following instrumentation happens to work for all of them:
3353 // Sz = I(Ssrc, MASK) | (sext (Smask != 0))
3354 void handleGenericBitManipulation(IntrinsicInst &I) {
3355 IRBuilder<> IRB(&I);
3356 Type *ShadowTy = getShadowTy(&I);
3357
3358 // If any bit of the mask operand is poisoned, then the whole thing is.
3359 Value *SMask = getShadow(&I, 1);
3360 SMask = IRB.CreateSExt(IRB.CreateICmpNE(SMask, getCleanShadow(ShadowTy)),
3361 ShadowTy);
3362 // Apply the same intrinsic to the shadow of the first operand.
3363 Value *S;
3364 if (Function *Func = I.getCalledFunction())
3365 S = IRB.CreateCall(Func, {getShadow(&I, 0), I.getOperand(1)});
3366 else
3367 S = IRB.CreateIntrinsic(I.getIntrinsicID(), ShadowTy,
3368 {getShadow(&I, 0), I.getOperand(1)});
3369
3370 setShadow(&I, IRB.CreateOr(SMask, S));
3371 setOriginForNaryOp(I);
3372 }
3373
3374 /// Instrument llvm.memmove
3375 ///
3376 /// At this point we don't know if llvm.memmove will be inlined or not.
3377 /// If we don't instrument it and it gets inlined,
3378 /// our interceptor will not kick in and we will lose the memmove.
3379 /// If we instrument the call here, but it does not get inlined,
3380 /// we will memmove the shadow twice: which is bad in case
3381 /// of overlapping regions. So, we simply lower the intrinsic to a call.
3382 ///
3383 /// Similar situation exists for memcpy and memset.
3384 void visitMemMoveInst(MemMoveInst &I) {
3385 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
3386 IRBuilder<> IRB(&I);
3387 IRB.CreateCall(MS.MemmoveFn,
3388 {I.getArgOperand(0), I.getArgOperand(1),
3389 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3391 }
3392
3393 /// Instrument memcpy
3394 ///
3395 /// Similar to memmove: avoid copying shadow twice. This is somewhat
3396 /// unfortunate as it may slowdown small constant memcpys.
3397 /// FIXME: consider doing manual inline for small constant sizes and proper
3398 /// alignment.
3399 ///
3400 /// Note: This also handles memcpy.inline, which promises no calls to external
3401 /// functions as an optimization. However, with instrumentation enabled this
3402 /// is difficult to promise; additionally, we know that the MSan runtime
3403 /// exists and provides __msan_memcpy(). Therefore, we assume that with
3404 /// instrumentation it's safe to turn memcpy.inline into a call to
3405 /// __msan_memcpy(). Should this be wrong, such as when implementing memcpy()
3406 /// itself, instrumentation should be disabled with the no_sanitize attribute.
3407 void visitMemCpyInst(MemCpyInst &I) {
3408 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
3409 IRBuilder<> IRB(&I);
3410 IRB.CreateCall(MS.MemcpyFn,
3411 {I.getArgOperand(0), I.getArgOperand(1),
3412 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3414 }
3415
3416 // Same as memcpy.
3417 void visitMemSetInst(MemSetInst &I) {
3418 IRBuilder<> IRB(&I);
3419 IRB.CreateCall(
3420 MS.MemsetFn,
3421 {I.getArgOperand(0),
3422 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3423 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3425 }
3426
3427 void visitVAStartInst(VAStartInst &I) { VAHelper->visitVAStartInst(I); }
3428
3429 void visitVACopyInst(VACopyInst &I) { VAHelper->visitVACopyInst(I); }
3430
3431 /// Handle vector store-like intrinsics.
3432 ///
3433 /// Instrument intrinsics that look like a simple SIMD store: writes memory,
3434 /// has 1 pointer argument and 1 vector argument, returns void.
3435 bool handleVectorStoreIntrinsic(IntrinsicInst &I) {
3436 assert(I.arg_size() == 2);
3437
3438 IRBuilder<> IRB(&I);
3439 Value *Addr = I.getArgOperand(0);
3440 Value *Shadow = getShadow(&I, 1);
3441 Value *ShadowPtr, *OriginPtr;
3442
3443 // We don't know the pointer alignment (could be unaligned SSE store!).
3444 // Have to assume to worst case.
3445 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3446 Addr, IRB, Shadow->getType(), Align(1), /*isStore*/ true);
3447 IRB.CreateAlignedStore(Shadow, ShadowPtr, Align(1));
3448
3450 insertCheckShadowOf(Addr, &I);
3451
3452 // FIXME: factor out common code from materializeStores
3453 if (MS.TrackOrigins)
3454 IRB.CreateStore(getOrigin(&I, 1), OriginPtr);
3455 return true;
3456 }
3457
3458 /// Handle vector load-like intrinsics.
3459 ///
3460 /// Instrument intrinsics that look like a simple SIMD load: reads memory,
3461 /// has 1 pointer argument, returns a vector.
3462 bool handleVectorLoadIntrinsic(IntrinsicInst &I) {
3463 assert(I.arg_size() == 1);
3464
3465 IRBuilder<> IRB(&I);
3466 Value *Addr = I.getArgOperand(0);
3467
3468 Type *ShadowTy = getShadowTy(&I);
3469 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
3470 if (PropagateShadow) {
3471 // We don't know the pointer alignment (could be unaligned SSE load!).
3472 // Have to assume to worst case.
3473 const Align Alignment = Align(1);
3474 std::tie(ShadowPtr, OriginPtr) =
3475 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
3476 setShadow(&I,
3477 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
3478 } else {
3479 setShadow(&I, getCleanShadow(&I));
3480 }
3481
3483 insertCheckShadowOf(Addr, &I);
3484
3485 if (MS.TrackOrigins) {
3486 if (PropagateShadow)
3487 setOrigin(&I, IRB.CreateLoad(MS.OriginTy, OriginPtr));
3488 else
3489 setOrigin(&I, getCleanOrigin());
3490 }
3491 return true;
3492 }
3493
3494 /// Handle (SIMD arithmetic)-like intrinsics.
3495 ///
3496 /// Instrument intrinsics with any number of arguments of the same type [*],
3497 /// equal to the return type, plus a specified number of trailing flags of
3498 /// any type.
3499 ///
3500 /// [*] The type should be simple (no aggregates or pointers; vectors are
3501 /// fine).
3502 ///
3503 /// Caller guarantees that this intrinsic does not access memory.
3504 ///
3505 /// TODO: "horizontal"/"pairwise" intrinsics are often incorrectly matched by
3506 /// by this handler. See horizontalReduce().
3507 ///
3508 /// TODO: permutation intrinsics are also often incorrectly matched.
3509 [[maybe_unused]] bool
3510 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I,
3511 unsigned int trailingFlags) {
3512 Type *RetTy = I.getType();
3513 if (!(RetTy->isIntOrIntVectorTy() || RetTy->isFPOrFPVectorTy()))
3514 return false;
3515
3516 unsigned NumArgOperands = I.arg_size();
3517 assert(NumArgOperands >= trailingFlags);
3518 for (unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3519 Type *Ty = I.getArgOperand(i)->getType();
3520 if (Ty != RetTy)
3521 return false;
3522 }
3523
3524 IRBuilder<> IRB(&I);
3525 ShadowAndOriginCombiner SC(this, IRB);
3526 for (unsigned i = 0; i < NumArgOperands; ++i)
3527 SC.Add(I.getArgOperand(i));
3528 SC.Done(&I);
3529
3530 return true;
3531 }
3532
3533 /// Returns whether it was able to heuristically instrument unknown
3534 /// intrinsics.
3535 ///
3536 /// The main purpose of this code is to do something reasonable with all
3537 /// random intrinsics we might encounter, most importantly - SIMD intrinsics.
3538 /// We recognize several classes of intrinsics by their argument types and
3539 /// ModRefBehaviour and apply special instrumentation when we are reasonably
3540 /// sure that we know what the intrinsic does.
3541 ///
3542 /// We special-case intrinsics where this approach fails. See llvm.bswap
3543 /// handling as an example of that.
3544 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &I) {
3545 unsigned NumArgOperands = I.arg_size();
3546 if (NumArgOperands == 0)
3547 return false;
3548
3549 if (NumArgOperands == 2 && I.getArgOperand(0)->getType()->isPointerTy() &&
3550 I.getArgOperand(1)->getType()->isVectorTy() &&
3551 I.getType()->isVoidTy() && !I.onlyReadsMemory()) {
3552 // This looks like a vector store.
3553 return handleVectorStoreIntrinsic(I);
3554 }
3555
3556 if (NumArgOperands == 1 && I.getArgOperand(0)->getType()->isPointerTy() &&
3557 I.getType()->isVectorTy() && I.onlyReadsMemory()) {
3558 // This looks like a vector load.
3559 return handleVectorLoadIntrinsic(I);
3560 }
3561
3562 if (I.doesNotAccessMemory())
3563 if (maybeHandleSimpleNomemIntrinsic(I, /*trailingFlags=*/0))
3564 return true;
3565
3566 // FIXME: detect and handle SSE maskstore/maskload?
3567 // Some cases are now handled in handleAVXMasked{Load,Store}.
3568 return false;
3569 }
3570
3571 bool maybeHandleUnknownIntrinsic(IntrinsicInst &I) {
3572 if (maybeHandleUnknownIntrinsicUnlogged(I)) {
3574 dumpInst(I, "Heuristic");
3575
3576 LLVM_DEBUG(dbgs() << "UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " << I
3577 << "\n");
3578 return true;
3579 } else
3580 return false;
3581 }
3582
3583 void handleInvariantGroup(IntrinsicInst &I) {
3584 setShadow(&I, getShadow(&I, 0));
3585 setOrigin(&I, getOrigin(&I, 0));
3586 }
3587
3588 void handleLifetimeStart(IntrinsicInst &I) {
3589 if (!PoisonStack)
3590 return;
3591 AllocaInst *AI = dyn_cast<AllocaInst>(I.getArgOperand(0));
3592 if (AI)
3593 LifetimeStartList.push_back(std::make_pair(&I, AI));
3594 }
3595
3596 void handleBswap(IntrinsicInst &I) {
3597 IRBuilder<> IRB(&I);
3598 Value *Op = I.getArgOperand(0);
3599 Type *OpType = Op->getType();
3600 setShadow(&I, IRB.CreateIntrinsic(Intrinsic::bswap, ArrayRef(&OpType, 1),
3601 getShadow(Op)));
3602 setOrigin(&I, getOrigin(Op));
3603 }
3604
3605 // Uninitialized bits are ok if they appear after the leading/trailing 0's
3606 // and a 1. If the input is all zero, it is fully initialized iff
3607 // !is_zero_poison.
3608 //
3609 // e.g., for ctlz, with little-endian, if 0/1 are initialized bits with
3610 // concrete value 0/1, and ? is an uninitialized bit:
3611 // - 0001 0??? is fully initialized
3612 // - 000? ???? is fully uninitialized (*)
3613 // - ???? ???? is fully uninitialized
3614 // - 0000 0000 is fully uninitialized if is_zero_poison,
3615 // fully initialized otherwise
3616 //
3617 // (*) TODO: arguably, since the number of zeros is in the range [3, 8], we
3618 // only need to poison 4 bits.
3619 //
3620 // OutputShadow =
3621 // ((ConcreteZerosCount >= ShadowZerosCount) && !AllZeroShadow)
3622 // || (is_zero_poison && AllZeroSrc)
3623 void handleCountLeadingTrailingZeros(IntrinsicInst &I) {
3624 IRBuilder<> IRB(&I);
3625 Value *Src = I.getArgOperand(0);
3626 Value *SrcShadow = getShadow(Src);
3627
3628 Value *False = IRB.getInt1(false);
3629 Value *ConcreteZerosCount = IRB.CreateIntrinsic(
3630 I.getType(), I.getIntrinsicID(), {Src, /*is_zero_poison=*/False});
3631 Value *ShadowZerosCount = IRB.CreateIntrinsic(
3632 I.getType(), I.getIntrinsicID(), {SrcShadow, /*is_zero_poison=*/False});
3633
3634 Value *CompareConcreteZeros = IRB.CreateICmpUGE(
3635 ConcreteZerosCount, ShadowZerosCount, "_mscz_cmp_zeros");
3636
3637 Value *NotAllZeroShadow =
3638 IRB.CreateIsNotNull(SrcShadow, "_mscz_shadow_not_null");
3639 Value *OutputShadow =
3640 IRB.CreateAnd(CompareConcreteZeros, NotAllZeroShadow, "_mscz_main");
3641
3642 // If zero poison is requested, mix in with the shadow
3643 Constant *IsZeroPoison = cast<Constant>(I.getOperand(1));
3644 if (!IsZeroPoison->isNullValue()) {
3645 Value *BoolZeroPoison = IRB.CreateIsNull(Src, "_mscz_bzp");
3646 OutputShadow = IRB.CreateOr(OutputShadow, BoolZeroPoison, "_mscz_bs");
3647 }
3648
3649 OutputShadow = IRB.CreateSExt(OutputShadow, getShadowTy(Src), "_mscz_os");
3650
3651 setShadow(&I, OutputShadow);
3652 setOriginForNaryOp(I);
3653 }
3654
3655 /// Some instructions have additional zero-elements in the return type
3656 /// e.g., <16 x i8> @llvm.x86.avx512.mask.pmov.qb.512(<8 x i64>, ...)
3657 ///
3658 /// This function will return a vector type with the same number of elements
3659 /// as the input, but same per-element width as the return value e.g.,
3660 /// <8 x i8>.
3661 FixedVectorType *maybeShrinkVectorShadowType(Value *Src, IntrinsicInst &I) {
3662 assert(isa<FixedVectorType>(getShadowTy(&I)));
3663 FixedVectorType *ShadowType = cast<FixedVectorType>(getShadowTy(&I));
3664
3665 // TODO: generalize beyond 2x?
3666 if (ShadowType->getElementCount() ==
3667 cast<VectorType>(Src->getType())->getElementCount() * 2)
3668 ShadowType = FixedVectorType::getHalfElementsVectorType(ShadowType);
3669
3670 assert(ShadowType->getElementCount() ==
3671 cast<VectorType>(Src->getType())->getElementCount());
3672
3673 return ShadowType;
3674 }
3675
3676 /// Doubles the length of a vector shadow (extending with zeros) if necessary
3677 /// to match the length of the shadow for the instruction.
3678 /// If scalar types of the vectors are different, it will use the type of the
3679 /// input vector.
3680 /// This is more type-safe than CreateShadowCast().
3681 Value *maybeExtendVectorShadowWithZeros(Value *Shadow, IntrinsicInst &I) {
3682 IRBuilder<> IRB(&I);
3684 assert(isa<FixedVectorType>(I.getType()));
3685
3686 Value *FullShadow = getCleanShadow(&I);
3687 unsigned ShadowNumElems =
3688 cast<FixedVectorType>(Shadow->getType())->getNumElements();
3689 unsigned FullShadowNumElems =
3690 cast<FixedVectorType>(FullShadow->getType())->getNumElements();
3691
3692 assert((ShadowNumElems == FullShadowNumElems) ||
3693 (ShadowNumElems * 2 == FullShadowNumElems));
3694
3695 if (ShadowNumElems == FullShadowNumElems) {
3696 FullShadow = Shadow;
3697 } else {
3698 // TODO: generalize beyond 2x?
3699 SmallVector<int, 32> ShadowMask(FullShadowNumElems);
3700 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3701
3702 // Append zeros
3703 FullShadow =
3704 IRB.CreateShuffleVector(Shadow, getCleanShadow(Shadow), ShadowMask);
3705 }
3706
3707 return FullShadow;
3708 }
3709
3710 /// Handle x86 SSE vector conversion.
3711 ///
3712 /// e.g., single-precision to half-precision conversion:
3713 /// <8 x i16> @llvm.x86.vcvtps2ph.256(<8 x float> %a0, i32 0)
3714 /// <8 x i16> @llvm.x86.vcvtps2ph.128(<4 x float> %a0, i32 0)
3715 ///
3716 /// floating-point to integer:
3717 /// <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float>)
3718 /// <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double>)
3719 ///
3720 /// Note: if the output has more elements, they are zero-initialized (and
3721 /// therefore the shadow will also be initialized).
3722 ///
3723 /// This differs from handleSSEVectorConvertIntrinsic() because it
3724 /// propagates uninitialized shadow (instead of checking the shadow).
3725 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &I,
3726 bool HasRoundingMode) {
3727 if (HasRoundingMode) {
3728 assert(I.arg_size() == 2);
3729 [[maybe_unused]] Value *RoundingMode = I.getArgOperand(1);
3730 assert(RoundingMode->getType()->isIntegerTy());
3731 } else {
3732 assert(I.arg_size() == 1);
3733 }
3734
3735 Value *Src = I.getArgOperand(0);
3736 assert(Src->getType()->isVectorTy());
3737
3738 // The return type might have more elements than the input.
3739 // Temporarily shrink the return type's number of elements.
3740 VectorType *ShadowType = maybeShrinkVectorShadowType(Src, I);
3741
3742 IRBuilder<> IRB(&I);
3743 Value *S0 = getShadow(&I, 0);
3744
3745 /// For scalars:
3746 /// Since they are converting to and/or from floating-point, the output is:
3747 /// - fully uninitialized if *any* bit of the input is uninitialized
3748 /// - fully ininitialized if all bits of the input are ininitialized
3749 /// We apply the same principle on a per-field basis for vectors.
3750 Value *Shadow =
3751 IRB.CreateSExt(IRB.CreateICmpNE(S0, getCleanShadow(S0)), ShadowType);
3752
3753 // The return type might have more elements than the input.
3754 // Extend the return type back to its original width if necessary.
3755 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow, I);
3756
3757 setShadow(&I, FullShadow);
3758 setOriginForNaryOp(I);
3759 }
3760
3761 // Instrument x86 SSE vector convert intrinsic.
3762 //
3763 // This function instruments intrinsics like cvtsi2ss:
3764 // %Out = int_xxx_cvtyyy(%ConvertOp)
3765 // or
3766 // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp)
3767 // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same
3768 // number \p Out elements, and (if has 2 arguments) copies the rest of the
3769 // elements from \p CopyOp.
3770 // In most cases conversion involves floating-point value which may trigger a
3771 // hardware exception when not fully initialized. For this reason we require
3772 // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise.
3773 // We copy the shadow of \p CopyOp[NumUsedElements:] to \p
3774 // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
3775 // return a fully initialized value.
3776 //
3777 // For Arm NEON vector convert intrinsics, see
3778 // handleNEONVectorConvertIntrinsic().
3779 void handleSSEVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
3780 bool HasRoundingMode = false) {
3781 IRBuilder<> IRB(&I);
3782 Value *CopyOp, *ConvertOp;
3783
3784 assert((!HasRoundingMode ||
3785 isa<ConstantInt>(I.getArgOperand(I.arg_size() - 1))) &&
3786 "Invalid rounding mode");
3787
3788 switch (I.arg_size() - HasRoundingMode) {
3789 case 2:
3790 CopyOp = I.getArgOperand(0);
3791 ConvertOp = I.getArgOperand(1);
3792 break;
3793 case 1:
3794 ConvertOp = I.getArgOperand(0);
3795 CopyOp = nullptr;
3796 break;
3797 default:
3798 llvm_unreachable("Cvt intrinsic with unsupported number of arguments.");
3799 }
3800
3801 // The first *NumUsedElements* elements of ConvertOp are converted to the
3802 // same number of output elements. The rest of the output is copied from
3803 // CopyOp, or (if not available) filled with zeroes.
3804 // Combine shadow for elements of ConvertOp that are used in this operation,
3805 // and insert a check.
3806 // FIXME: consider propagating shadow of ConvertOp, at least in the case of
3807 // int->any conversion.
3808 Value *ConvertShadow = getShadow(ConvertOp);
3809 Value *AggShadow = nullptr;
3810 if (ConvertOp->getType()->isVectorTy()) {
3811 AggShadow = IRB.CreateExtractElement(
3812 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
3813 for (int i = 1; i < NumUsedElements; ++i) {
3814 Value *MoreShadow = IRB.CreateExtractElement(
3815 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), i));
3816 AggShadow = IRB.CreateOr(AggShadow, MoreShadow);
3817 }
3818 } else {
3819 AggShadow = ConvertShadow;
3820 }
3821 assert(AggShadow->getType()->isIntegerTy());
3822 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &I);
3823
3824 // Build result shadow by zero-filling parts of CopyOp shadow that come from
3825 // ConvertOp.
3826 if (CopyOp) {
3827 assert(CopyOp->getType() == I.getType());
3828 assert(CopyOp->getType()->isVectorTy());
3829 Value *ResultShadow = getShadow(CopyOp);
3830 Type *EltTy = cast<VectorType>(ResultShadow->getType())->getElementType();
3831 for (int i = 0; i < NumUsedElements; ++i) {
3832 ResultShadow = IRB.CreateInsertElement(
3833 ResultShadow, ConstantInt::getNullValue(EltTy),
3834 ConstantInt::get(IRB.getInt32Ty(), i));
3835 }
3836 setShadow(&I, ResultShadow);
3837 setOrigin(&I, getOrigin(CopyOp));
3838 } else {
3839 setShadow(&I, getCleanShadow(&I));
3840 setOrigin(&I, getCleanOrigin());
3841 }
3842 }
3843
3844 // Given a scalar or vector, extract lower 64 bits (or less), and return all
3845 // zeroes if it is zero, and all ones otherwise.
3846 Value *Lower64ShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3847 if (S->getType()->isVectorTy())
3848 S = CreateShadowCast(IRB, S, IRB.getInt64Ty(), /* Signed */ true);
3849 assert(S->getType()->getPrimitiveSizeInBits() <= 64);
3850 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3851 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3852 }
3853
3854 // Given a vector, extract its first element, and return all
3855 // zeroes if it is zero, and all ones otherwise.
3856 Value *LowerElementShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3857 Value *S1 = IRB.CreateExtractElement(S, (uint64_t)0);
3858 Value *S2 = IRB.CreateICmpNE(S1, getCleanShadow(S1));
3859 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3860 }
3861
3862 Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) {
3863 Type *T = S->getType();
3864 assert(T->isVectorTy());
3865 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3866 return IRB.CreateSExt(S2, T);
3867 }
3868
3869 // Instrument vector shift intrinsic.
3870 //
3871 // This function instruments intrinsics like int_x86_avx2_psll_w.
3872 // Intrinsic shifts %In by %ShiftSize bits.
3873 // %ShiftSize may be a vector. In that case the lower 64 bits determine shift
3874 // size, and the rest is ignored. Behavior is defined even if shift size is
3875 // greater than register (or field) width.
3876 void handleVectorShiftIntrinsic(IntrinsicInst &I, bool Variable) {
3877 assert(I.arg_size() == 2);
3878 IRBuilder<> IRB(&I);
3879 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3880 // Otherwise perform the same shift on S1.
3881 Value *S1 = getShadow(&I, 0);
3882 Value *S2 = getShadow(&I, 1);
3883 Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
3884 : Lower64ShadowExtend(IRB, S2, getShadowTy(&I));
3885 Value *V1 = I.getOperand(0);
3886 Value *V2 = I.getOperand(1);
3887 Value *Shift = IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(),
3888 {IRB.CreateBitCast(S1, V1->getType()), V2});
3889 Shift = IRB.CreateBitCast(Shift, getShadowTy(&I));
3890 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3891 setOriginForNaryOp(I);
3892 }
3893
3894 // Get an MMX-sized (64-bit) vector type, or optionally, other sized
3895 // vectors.
3896 Type *getMMXVectorTy(unsigned EltSizeInBits,
3897 unsigned X86_MMXSizeInBits = 64) {
3898 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3899 "Illegal MMX vector element size");
3900 return FixedVectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
3901 X86_MMXSizeInBits / EltSizeInBits);
3902 }
3903
3904 // Returns a signed counterpart for an (un)signed-saturate-and-pack
3905 // intrinsic.
3906 Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
3907 switch (id) {
3908 case Intrinsic::x86_sse2_packsswb_128:
3909 case Intrinsic::x86_sse2_packuswb_128:
3910 return Intrinsic::x86_sse2_packsswb_128;
3911
3912 case Intrinsic::x86_sse2_packssdw_128:
3913 case Intrinsic::x86_sse41_packusdw:
3914 return Intrinsic::x86_sse2_packssdw_128;
3915
3916 case Intrinsic::x86_avx2_packsswb:
3917 case Intrinsic::x86_avx2_packuswb:
3918 return Intrinsic::x86_avx2_packsswb;
3919
3920 case Intrinsic::x86_avx2_packssdw:
3921 case Intrinsic::x86_avx2_packusdw:
3922 return Intrinsic::x86_avx2_packssdw;
3923
3924 case Intrinsic::x86_mmx_packsswb:
3925 case Intrinsic::x86_mmx_packuswb:
3926 return Intrinsic::x86_mmx_packsswb;
3927
3928 case Intrinsic::x86_mmx_packssdw:
3929 return Intrinsic::x86_mmx_packssdw;
3930
3931 case Intrinsic::x86_avx512_packssdw_512:
3932 case Intrinsic::x86_avx512_packusdw_512:
3933 return Intrinsic::x86_avx512_packssdw_512;
3934
3935 case Intrinsic::x86_avx512_packsswb_512:
3936 case Intrinsic::x86_avx512_packuswb_512:
3937 return Intrinsic::x86_avx512_packsswb_512;
3938
3939 default:
3940 llvm_unreachable("unexpected intrinsic id");
3941 }
3942 }
3943
3944 // Instrument vector pack intrinsic.
3945 //
3946 // This function instruments intrinsics like x86_mmx_packsswb, that
3947 // packs elements of 2 input vectors into half as many bits with saturation.
3948 // Shadow is propagated with the signed variant of the same intrinsic applied
3949 // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
3950 // MMXEltSizeInBits is used only for x86mmx arguments.
3951 //
3952 // TODO: consider using GetMinMaxUnsigned() to handle saturation precisely
3953 void handleVectorPackIntrinsic(IntrinsicInst &I,
3954 unsigned MMXEltSizeInBits = 0) {
3955 assert(I.arg_size() == 2);
3956 IRBuilder<> IRB(&I);
3957 Value *S1 = getShadow(&I, 0);
3958 Value *S2 = getShadow(&I, 1);
3959 assert(S1->getType()->isVectorTy());
3960
3961 // SExt and ICmpNE below must apply to individual elements of input vectors.
3962 // In case of x86mmx arguments, cast them to appropriate vector types and
3963 // back.
3964 Type *T =
3965 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) : S1->getType();
3966 if (MMXEltSizeInBits) {
3967 S1 = IRB.CreateBitCast(S1, T);
3968 S2 = IRB.CreateBitCast(S2, T);
3969 }
3970 Value *S1_ext =
3972 Value *S2_ext =
3974 if (MMXEltSizeInBits) {
3975 S1_ext = IRB.CreateBitCast(S1_ext, getMMXVectorTy(64));
3976 S2_ext = IRB.CreateBitCast(S2_ext, getMMXVectorTy(64));
3977 }
3978
3979 Value *S = IRB.CreateIntrinsic(getSignedPackIntrinsic(I.getIntrinsicID()),
3980 {S1_ext, S2_ext}, /*FMFSource=*/nullptr,
3981 "_msprop_vector_pack");
3982 if (MMXEltSizeInBits)
3983 S = IRB.CreateBitCast(S, getShadowTy(&I));
3984 setShadow(&I, S);
3985 setOriginForNaryOp(I);
3986 }
3987
3988 // Convert `Mask` into `<n x i1>`.
3989 Constant *createDppMask(unsigned Width, unsigned Mask) {
3990 SmallVector<Constant *, 4> R(Width);
3991 for (auto &M : R) {
3992 M = ConstantInt::getBool(F.getContext(), Mask & 1);
3993 Mask >>= 1;
3994 }
3995 return ConstantVector::get(R);
3996 }
3997
3998 // Calculate output shadow as array of booleans `<n x i1>`, assuming if any
3999 // arg is poisoned, entire dot product is poisoned.
4000 Value *findDppPoisonedOutput(IRBuilder<> &IRB, Value *S, unsigned SrcMask,
4001 unsigned DstMask) {
4002 const unsigned Width =
4003 cast<FixedVectorType>(S->getType())->getNumElements();
4004
4005 S = IRB.CreateSelect(createDppMask(Width, SrcMask), S,
4007 Value *SElem = IRB.CreateOrReduce(S);
4008 Value *IsClean = IRB.CreateIsNull(SElem, "_msdpp");
4009 Value *DstMaskV = createDppMask(Width, DstMask);
4010
4011 return IRB.CreateSelect(
4012 IsClean, Constant::getNullValue(DstMaskV->getType()), DstMaskV);
4013 }
4014
4015 // See `Intel Intrinsics Guide` for `_dp_p*` instructions.
4016 //
4017 // 2 and 4 element versions produce single scalar of dot product, and then
4018 // puts it into elements of output vector, selected by 4 lowest bits of the
4019 // mask. Top 4 bits of the mask control which elements of input to use for dot
4020 // product.
4021 //
4022 // 8 element version mask still has only 4 bit for input, and 4 bit for output
4023 // mask. According to the spec it just operates as 4 element version on first
4024 // 4 elements of inputs and output, and then on last 4 elements of inputs and
4025 // output.
4026 void handleDppIntrinsic(IntrinsicInst &I) {
4027 IRBuilder<> IRB(&I);
4028
4029 Value *S0 = getShadow(&I, 0);
4030 Value *S1 = getShadow(&I, 1);
4031 Value *S = IRB.CreateOr(S0, S1);
4032
4033 const unsigned Width =
4034 cast<FixedVectorType>(S->getType())->getNumElements();
4035 assert(Width == 2 || Width == 4 || Width == 8);
4036
4037 const unsigned Mask = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
4038 const unsigned SrcMask = Mask >> 4;
4039 const unsigned DstMask = Mask & 0xf;
4040
4041 // Calculate shadow as `<n x i1>`.
4042 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
4043 if (Width == 8) {
4044 // First 4 elements of shadow are already calculated. `makeDppShadow`
4045 // operats on 32 bit masks, so we can just shift masks, and repeat.
4046 SI1 = IRB.CreateOr(
4047 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
4048 }
4049 // Extend to real size of shadow, poisoning either all or none bits of an
4050 // element.
4051 S = IRB.CreateSExt(SI1, S->getType(), "_msdpp");
4052
4053 setShadow(&I, S);
4054 setOriginForNaryOp(I);
4055 }
4056
4057 Value *convertBlendvToSelectMask(IRBuilder<> &IRB, Value *C) {
4058 C = CreateAppToShadowCast(IRB, C);
4059 FixedVectorType *FVT = cast<FixedVectorType>(C->getType());
4060 unsigned ElSize = FVT->getElementType()->getPrimitiveSizeInBits();
4061 C = IRB.CreateAShr(C, ElSize - 1);
4062 FVT = FixedVectorType::get(IRB.getInt1Ty(), FVT->getNumElements());
4063 return IRB.CreateTrunc(C, FVT);
4064 }
4065
4066 // `blendv(f, t, c)` is effectively `select(c[top_bit], t, f)`.
4067 void handleBlendvIntrinsic(IntrinsicInst &I) {
4068 Value *C = I.getOperand(2);
4069 Value *T = I.getOperand(1);
4070 Value *F = I.getOperand(0);
4071
4072 Value *Sc = getShadow(&I, 2);
4073 Value *Oc = MS.TrackOrigins ? getOrigin(C) : nullptr;
4074
4075 {
4076 IRBuilder<> IRB(&I);
4077 // Extract top bit from condition and its shadow.
4078 C = convertBlendvToSelectMask(IRB, C);
4079 Sc = convertBlendvToSelectMask(IRB, Sc);
4080
4081 setShadow(C, Sc);
4082 setOrigin(C, Oc);
4083 }
4084
4085 handleSelectLikeInst(I, C, T, F);
4086 }
4087
4088 // Instrument sum-of-absolute-differences intrinsic.
4089 void handleVectorSadIntrinsic(IntrinsicInst &I, bool IsMMX = false) {
4090 const unsigned SignificantBitsPerResultElement = 16;
4091 Type *ResTy = IsMMX ? IntegerType::get(*MS.C, 64) : I.getType();
4092 unsigned ZeroBitsPerResultElement =
4093 ResTy->getScalarSizeInBits() - SignificantBitsPerResultElement;
4094
4095 IRBuilder<> IRB(&I);
4096 auto *Shadow0 = getShadow(&I, 0);
4097 auto *Shadow1 = getShadow(&I, 1);
4098 Value *S = IRB.CreateOr(Shadow0, Shadow1);
4099 S = IRB.CreateBitCast(S, ResTy);
4100 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
4101 ResTy);
4102 S = IRB.CreateLShr(S, ZeroBitsPerResultElement);
4103 S = IRB.CreateBitCast(S, getShadowTy(&I));
4104 setShadow(&I, S);
4105 setOriginForNaryOp(I);
4106 }
4107
4108 // Instrument dot-product / multiply-add(-accumulate)? intrinsics.
4109 //
4110 // e.g., Two operands:
4111 // <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a, <8 x i16> %b)
4112 //
4113 // Two operands which require an EltSizeInBits override:
4114 // <1 x i64> @llvm.x86.mmx.pmadd.wd(<1 x i64> %a, <1 x i64> %b)
4115 //
4116 // Three operands:
4117 // <4 x i32> @llvm.x86.avx512.vpdpbusd.128
4118 // (<4 x i32> %s, <16 x i8> %a, <16 x i8> %b)
4119 // <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16
4120 // (<2 x float> %acc, <4 x bfloat> %a, <4 x bfloat> %b)
4121 // (these are equivalent to multiply-add on %a and %b, followed by
4122 // adding/"accumulating" %s. "Accumulation" stores the result in one
4123 // of the source registers, but this accumulate vs. add distinction
4124 // is lost when dealing with LLVM intrinsics.)
4125 //
4126 // ZeroPurifies means that multiplying a known-zero with an uninitialized
4127 // value results in an initialized value. This is applicable for integer
4128 // multiplication, but not floating-point (counter-example: NaN).
4129 void handleVectorDotProductIntrinsic(IntrinsicInst &I,
4130 unsigned ReductionFactor,
4131 bool ZeroPurifies,
4132 unsigned EltSizeInBits,
4133 enum OddOrEvenLanes Lanes) {
4134 IRBuilder<> IRB(&I);
4135
4136 [[maybe_unused]] FixedVectorType *ReturnType =
4137 cast<FixedVectorType>(I.getType());
4138 assert(isa<FixedVectorType>(ReturnType));
4139
4140 // Vectors A and B, and shadows
4141 Value *Va = nullptr;
4142 Value *Vb = nullptr;
4143 Value *Sa = nullptr;
4144 Value *Sb = nullptr;
4145
4146 assert(I.arg_size() == 2 || I.arg_size() == 3);
4147 if (I.arg_size() == 2) {
4148 assert(Lanes == kBothLanes);
4149
4150 Va = I.getOperand(0);
4151 Vb = I.getOperand(1);
4152
4153 Sa = getShadow(&I, 0);
4154 Sb = getShadow(&I, 1);
4155 } else if (I.arg_size() == 3) {
4156 // Operand 0 is the accumulator. We will deal with that below.
4157 Va = I.getOperand(1);
4158 Vb = I.getOperand(2);
4159
4160 Sa = getShadow(&I, 1);
4161 Sb = getShadow(&I, 2);
4162
4163 if (Lanes == kEvenLanes || Lanes == kOddLanes) {
4164 // Convert < S0, S1, S2, S3, S4, S5, S6, S7 >
4165 // to < S0, S0, S2, S2, S4, S4, S6, S6 > (if even)
4166 // to < S1, S1, S3, S3, S5, S5, S7, S7 > (if odd)
4167 //
4168 // Note: for aarch64.neon.bfmlalb/t, the odd/even-indexed values are
4169 // zeroed, not duplicated. However, for shadow propagation, this
4170 // distinction is unimportant because Step 1 below will squeeze
4171 // each pair of elements (e.g., [S0, S0]) into a single bit, and
4172 // we only care if it is fully initialized.
4173
4174 FixedVectorType *InputShadowType = cast<FixedVectorType>(Sa->getType());
4175 unsigned Width = InputShadowType->getNumElements();
4176
4177 Sa = IRB.CreateShuffleVector(
4178 Sa, getPclmulMask(Width, /*OddElements=*/Lanes == kOddLanes));
4179 Sb = IRB.CreateShuffleVector(
4180 Sb, getPclmulMask(Width, /*OddElements=*/Lanes == kOddLanes));
4181 }
4182 }
4183
4184 FixedVectorType *ParamType = cast<FixedVectorType>(Va->getType());
4185 assert(ParamType == Vb->getType());
4186
4187 assert(ParamType->getPrimitiveSizeInBits() ==
4188 ReturnType->getPrimitiveSizeInBits());
4189
4190 if (I.arg_size() == 3) {
4191 [[maybe_unused]] auto *AccumulatorType =
4192 cast<FixedVectorType>(I.getOperand(0)->getType());
4193 assert(AccumulatorType == ReturnType);
4194 }
4195
4196 FixedVectorType *ImplicitReturnType =
4197 cast<FixedVectorType>(getShadowTy(ReturnType));
4198 // Step 1: instrument multiplication of corresponding vector elements
4199 if (EltSizeInBits) {
4200 ImplicitReturnType = cast<FixedVectorType>(
4201 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4202 ParamType->getPrimitiveSizeInBits()));
4203 ParamType = cast<FixedVectorType>(
4204 getMMXVectorTy(EltSizeInBits, ParamType->getPrimitiveSizeInBits()));
4205
4206 Va = IRB.CreateBitCast(Va, ParamType);
4207 Vb = IRB.CreateBitCast(Vb, ParamType);
4208
4209 Sa = IRB.CreateBitCast(Sa, getShadowTy(ParamType));
4210 Sb = IRB.CreateBitCast(Sb, getShadowTy(ParamType));
4211 } else {
4212 assert(ParamType->getNumElements() ==
4213 ReturnType->getNumElements() * ReductionFactor);
4214 }
4215
4216 // Each element of the vector is represented by a single bit (poisoned or
4217 // not) e.g., <8 x i1>.
4218 Value *SaNonZero = IRB.CreateIsNotNull(Sa);
4219 Value *SbNonZero = IRB.CreateIsNotNull(Sb);
4220 Value *And;
4221 if (ZeroPurifies) {
4222 // Multiplying an *initialized* zero by an uninitialized element results
4223 // in an initialized zero element.
4224 //
4225 // This is analogous to bitwise AND, where "AND" of 0 and a poisoned value
4226 // results in an unpoisoned value.
4227 Value *VaInt = Va;
4228 Value *VbInt = Vb;
4229 if (!Va->getType()->isIntegerTy()) {
4230 VaInt = CreateAppToShadowCast(IRB, Va);
4231 VbInt = CreateAppToShadowCast(IRB, Vb);
4232 }
4233
4234 // We check for non-zero on a per-element basis, not per-bit.
4235 Value *VaNonZero = IRB.CreateIsNotNull(VaInt);
4236 Value *VbNonZero = IRB.CreateIsNotNull(VbInt);
4237
4238 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4239 } else {
4240 And = IRB.CreateOr({SaNonZero, SbNonZero});
4241 }
4242
4243 // Extend <8 x i1> to <8 x i16>.
4244 // (The real pmadd intrinsic would have computed intermediate values of
4245 // <8 x i32>, but that is irrelevant for our shadow purposes because we
4246 // consider each element to be either fully initialized or fully
4247 // uninitialized.)
4248 And = IRB.CreateSExt(And, Sa->getType());
4249
4250 // Step 2: instrument horizontal add
4251 // We don't need bit-precise horizontalReduce because we only want to check
4252 // if each pair/quad of elements is fully zero.
4253 // Cast to <4 x i32>.
4254 Value *Horizontal = IRB.CreateBitCast(And, ImplicitReturnType);
4255
4256 // Compute <4 x i1>, then extend back to <4 x i32>.
4257 Value *OutShadow = IRB.CreateSExt(
4258 IRB.CreateICmpNE(Horizontal,
4259 Constant::getNullValue(Horizontal->getType())),
4260 ImplicitReturnType);
4261
4262 // Cast it back to the required fake return type (if MMX: <1 x i64>; for
4263 // AVX, it is already correct).
4264 if (EltSizeInBits)
4265 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&I));
4266
4267 // Step 3 (if applicable): instrument accumulator
4268 if (I.arg_size() == 3)
4269 OutShadow = IRB.CreateOr(OutShadow, getShadow(&I, 0));
4270
4271 setShadow(&I, OutShadow);
4272 setOriginForNaryOp(I);
4273 }
4274
4275 // Instrument compare-packed intrinsic.
4276 //
4277 // x86 has the predicate as the third operand, which is ImmArg e.g.,
4278 // - <4 x double> @llvm.x86.avx.cmp.pd.256(<4 x double>, <4 x double>, i8)
4279 // - <2 x double> @llvm.x86.sse2.cmp.pd(<2 x double>, <2 x double>, i8)
4280 //
4281 // while Arm has separate intrinsics for >= and > e.g.,
4282 // - <2 x i32> @llvm.aarch64.neon.facge.v2i32.v2f32
4283 // (<2 x float> %A, <2 x float>)
4284 // - <2 x i32> @llvm.aarch64.neon.facgt.v2i32.v2f32
4285 // (<2 x float> %A, <2 x float>)
4286 //
4287 // Bonus: this also handles scalar cases e.g.,
4288 // - i32 @llvm.aarch64.neon.facgt.i32.f32(float %A, float %B)
4289 void handleVectorComparePackedIntrinsic(IntrinsicInst &I,
4290 bool PredicateAsOperand) {
4291 if (PredicateAsOperand) {
4292 assert(I.arg_size() == 3);
4293 assert(I.paramHasAttr(2, Attribute::ImmArg));
4294 } else
4295 assert(I.arg_size() == 2);
4296
4297 IRBuilder<> IRB(&I);
4298
4299 // Basically, an or followed by sext(icmp ne 0) to end up with all-zeros or
4300 // all-ones shadow.
4301 Type *ResTy = getShadowTy(&I);
4302 auto *Shadow0 = getShadow(&I, 0);
4303 auto *Shadow1 = getShadow(&I, 1);
4304 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
4305 Value *S = IRB.CreateSExt(
4306 IRB.CreateICmpNE(S0, Constant::getNullValue(ResTy)), ResTy);
4307 setShadow(&I, S);
4308 setOriginForNaryOp(I);
4309 }
4310
4311 // Instrument compare-scalar intrinsic.
4312 // This handles both cmp* intrinsics which return the result in the first
4313 // element of a vector, and comi* which return the result as i32.
4314 void handleVectorCompareScalarIntrinsic(IntrinsicInst &I) {
4315 IRBuilder<> IRB(&I);
4316 auto *Shadow0 = getShadow(&I, 0);
4317 auto *Shadow1 = getShadow(&I, 1);
4318 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
4319 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&I));
4320 setShadow(&I, S);
4321 setOriginForNaryOp(I);
4322 }
4323
4324 // Instrument generic vector reduction intrinsics
4325 // by ORing together all their fields.
4326 //
4327 // If AllowShadowCast is true, the return type does not need to be the same
4328 // type as the fields
4329 // e.g., declare i32 @llvm.aarch64.neon.uaddv.i32.v16i8(<16 x i8>)
4330 void handleVectorReduceIntrinsic(IntrinsicInst &I, bool AllowShadowCast) {
4331 assert(I.arg_size() == 1);
4332
4333 IRBuilder<> IRB(&I);
4334 Value *S = IRB.CreateOrReduce(getShadow(&I, 0));
4335 if (AllowShadowCast)
4336 S = CreateShadowCast(IRB, S, getShadowTy(&I));
4337 else
4338 assert(S->getType() == getShadowTy(&I));
4339 setShadow(&I, S);
4340 setOriginForNaryOp(I);
4341 }
4342
4343 // Similar to handleVectorReduceIntrinsic but with an initial starting value.
4344 // e.g., call float @llvm.vector.reduce.fadd.f32.v2f32(float %a0, <2 x float>
4345 // %a1)
4346 // shadow = shadow[a0] | shadow[a1.0] | shadow[a1.1]
4347 //
4348 // The type of the return value, initial starting value, and elements of the
4349 // vector must be identical.
4350 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &I) {
4351 assert(I.arg_size() == 2);
4352
4353 IRBuilder<> IRB(&I);
4354 Value *Shadow0 = getShadow(&I, 0);
4355 Value *Shadow1 = IRB.CreateOrReduce(getShadow(&I, 1));
4356 assert(Shadow0->getType() == Shadow1->getType());
4357 Value *S = IRB.CreateOr(Shadow0, Shadow1);
4358 assert(S->getType() == getShadowTy(&I));
4359 setShadow(&I, S);
4360 setOriginForNaryOp(I);
4361 }
4362
4363 // Instrument vector.reduce.or intrinsic.
4364 // Valid (non-poisoned) set bits in the operand pull low the
4365 // corresponding shadow bits.
4366 void handleVectorReduceOrIntrinsic(IntrinsicInst &I) {
4367 assert(I.arg_size() == 1);
4368
4369 IRBuilder<> IRB(&I);
4370 Value *OperandShadow = getShadow(&I, 0);
4371 Value *OperandUnsetBits = IRB.CreateNot(I.getOperand(0));
4372 Value *OperandUnsetOrPoison = IRB.CreateOr(OperandUnsetBits, OperandShadow);
4373 // Bit N is clean if any field's bit N is 1 and unpoison
4374 Value *OutShadowMask = IRB.CreateAndReduce(OperandUnsetOrPoison);
4375 // Otherwise, it is clean if every field's bit N is unpoison
4376 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
4377 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
4378
4379 setShadow(&I, S);
4380 setOrigin(&I, getOrigin(&I, 0));
4381 }
4382
4383 // Instrument vector.reduce.and intrinsic.
4384 // Valid (non-poisoned) unset bits in the operand pull down the
4385 // corresponding shadow bits.
4386 void handleVectorReduceAndIntrinsic(IntrinsicInst &I) {
4387 assert(I.arg_size() == 1);
4388
4389 IRBuilder<> IRB(&I);
4390 Value *OperandShadow = getShadow(&I, 0);
4391 Value *OperandSetOrPoison = IRB.CreateOr(I.getOperand(0), OperandShadow);
4392 // Bit N is clean if any field's bit N is 0 and unpoison
4393 Value *OutShadowMask = IRB.CreateAndReduce(OperandSetOrPoison);
4394 // Otherwise, it is clean if every field's bit N is unpoison
4395 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
4396 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
4397
4398 setShadow(&I, S);
4399 setOrigin(&I, getOrigin(&I, 0));
4400 }
4401
4402 void handleStmxcsr(IntrinsicInst &I) {
4403 IRBuilder<> IRB(&I);
4404 Value *Addr = I.getArgOperand(0);
4405 Type *Ty = IRB.getInt32Ty();
4406 Value *ShadowPtr =
4407 getShadowOriginPtr(Addr, IRB, Ty, Align(1), /*isStore*/ true).first;
4408
4409 IRB.CreateStore(getCleanShadow(Ty), ShadowPtr);
4410
4412 insertCheckShadowOf(Addr, &I);
4413 }
4414
4415 void handleLdmxcsr(IntrinsicInst &I) {
4416 if (!InsertChecks)
4417 return;
4418
4419 IRBuilder<> IRB(&I);
4420 Value *Addr = I.getArgOperand(0);
4421 Type *Ty = IRB.getInt32Ty();
4422 const Align Alignment = Align(1);
4423 Value *ShadowPtr, *OriginPtr;
4424 std::tie(ShadowPtr, OriginPtr) =
4425 getShadowOriginPtr(Addr, IRB, Ty, Alignment, /*isStore*/ false);
4426
4428 insertCheckShadowOf(Addr, &I);
4429
4430 Value *Shadow = IRB.CreateAlignedLoad(Ty, ShadowPtr, Alignment, "_ldmxcsr");
4431 Value *Origin = MS.TrackOrigins ? IRB.CreateLoad(MS.OriginTy, OriginPtr)
4432 : getCleanOrigin();
4433 insertCheckShadow(Shadow, Origin, &I);
4434 }
4435
4436 void handleMaskedExpandLoad(IntrinsicInst &I) {
4437 IRBuilder<> IRB(&I);
4438 Value *Ptr = I.getArgOperand(0);
4439 MaybeAlign Align = I.getParamAlign(0);
4440 Value *Mask = I.getArgOperand(1);
4441 Value *PassThru = I.getArgOperand(2);
4442
4444 insertCheckShadowOf(Ptr, &I);
4445 insertCheckShadowOf(Mask, &I);
4446 }
4447
4448 if (!PropagateShadow) {
4449 setShadow(&I, getCleanShadow(&I));
4450 setOrigin(&I, getCleanOrigin());
4451 return;
4452 }
4453
4454 Type *ShadowTy = getShadowTy(&I);
4455 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
4456 auto [ShadowPtr, OriginPtr] =
4457 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align, /*isStore*/ false);
4458
4459 Value *Shadow =
4460 IRB.CreateMaskedExpandLoad(ShadowTy, ShadowPtr, Align, Mask,
4461 getShadow(PassThru), "_msmaskedexpload");
4462
4463 setShadow(&I, Shadow);
4464
4465 // TODO: Store origins.
4466 setOrigin(&I, getCleanOrigin());
4467 }
4468
4469 void handleMaskedCompressStore(IntrinsicInst &I) {
4470 IRBuilder<> IRB(&I);
4471 Value *Values = I.getArgOperand(0);
4472 Value *Ptr = I.getArgOperand(1);
4473 MaybeAlign Align = I.getParamAlign(1);
4474 Value *Mask = I.getArgOperand(2);
4475
4477 insertCheckShadowOf(Ptr, &I);
4478 insertCheckShadowOf(Mask, &I);
4479 }
4480
4481 Value *Shadow = getShadow(Values);
4482 Type *ElementShadowTy =
4483 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
4484 auto [ShadowPtr, OriginPtrs] =
4485 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align, /*isStore*/ true);
4486
4487 IRB.CreateMaskedCompressStore(Shadow, ShadowPtr, Align, Mask);
4488
4489 // TODO: Store origins.
4490 }
4491
4492 void handleMaskedGather(IntrinsicInst &I) {
4493 IRBuilder<> IRB(&I);
4494 Value *Ptrs = I.getArgOperand(0);
4495 const Align Alignment = I.getParamAlign(0).valueOrOne();
4496 Value *Mask = I.getArgOperand(1);
4497 Value *PassThru = I.getArgOperand(2);
4498
4499 Type *PtrsShadowTy = getShadowTy(Ptrs);
4501 insertCheckShadowOf(Mask, &I);
4502 Value *MaskedPtrShadow = IRB.CreateSelect(
4503 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
4504 "_msmaskedptrs");
4505 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &I);
4506 }
4507
4508 if (!PropagateShadow) {
4509 setShadow(&I, getCleanShadow(&I));
4510 setOrigin(&I, getCleanOrigin());
4511 return;
4512 }
4513
4514 Type *ShadowTy = getShadowTy(&I);
4515 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
4516 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4517 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ false);
4518
4519 Value *Shadow =
4520 IRB.CreateMaskedGather(ShadowTy, ShadowPtrs, Alignment, Mask,
4521 getShadow(PassThru), "_msmaskedgather");
4522
4523 setShadow(&I, Shadow);
4524
4525 // TODO: Store origins.
4526 setOrigin(&I, getCleanOrigin());
4527 }
4528
4529 void handleMaskedScatter(IntrinsicInst &I) {
4530 IRBuilder<> IRB(&I);
4531 Value *Values = I.getArgOperand(0);
4532 Value *Ptrs = I.getArgOperand(1);
4533 const Align Alignment = I.getParamAlign(1).valueOrOne();
4534 Value *Mask = I.getArgOperand(2);
4535
4536 Type *PtrsShadowTy = getShadowTy(Ptrs);
4538 insertCheckShadowOf(Mask, &I);
4539 Value *MaskedPtrShadow = IRB.CreateSelect(
4540 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
4541 "_msmaskedptrs");
4542 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &I);
4543 }
4544
4545 Value *Shadow = getShadow(Values);
4546 Type *ElementShadowTy =
4547 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
4548 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4549 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ true);
4550
4551 IRB.CreateMaskedScatter(Shadow, ShadowPtrs, Alignment, Mask);
4552
4553 // TODO: Store origin.
4554 }
4555
4556 // Intrinsic::masked_store
4557 //
4558 // Note: handleAVXMaskedStore handles AVX/AVX2 variants, though AVX512 masked
4559 // stores are lowered to Intrinsic::masked_store.
4560 void handleMaskedStore(IntrinsicInst &I) {
4561 IRBuilder<> IRB(&I);
4562 Value *V = I.getArgOperand(0);
4563 Value *Ptr = I.getArgOperand(1);
4564 const Align Alignment = I.getParamAlign(1).valueOrOne();
4565 Value *Mask = I.getArgOperand(2);
4566 Value *Shadow = getShadow(V);
4567
4569 insertCheckShadowOf(Ptr, &I);
4570 insertCheckShadowOf(Mask, &I);
4571 }
4572
4573 Value *ShadowPtr;
4574 Value *OriginPtr;
4575 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4576 Ptr, IRB, Shadow->getType(), Alignment, /*isStore*/ true);
4577
4578 IRB.CreateMaskedStore(Shadow, ShadowPtr, Alignment, Mask);
4579
4580 if (!MS.TrackOrigins)
4581 return;
4582
4583 auto &DL = F.getDataLayout();
4584 paintOrigin(IRB, getOrigin(V), OriginPtr,
4585 DL.getTypeStoreSize(Shadow->getType()),
4586 std::max(Alignment, kMinOriginAlignment));
4587 }
4588
4589 // Intrinsic::masked_load
4590 //
4591 // Note: handleAVXMaskedLoad handles AVX/AVX2 variants, though AVX512 masked
4592 // loads are lowered to Intrinsic::masked_load.
4593 void handleMaskedLoad(IntrinsicInst &I) {
4594 IRBuilder<> IRB(&I);
4595 Value *Ptr = I.getArgOperand(0);
4596 const Align Alignment = I.getParamAlign(0).valueOrOne();
4597 Value *Mask = I.getArgOperand(1);
4598 Value *PassThru = I.getArgOperand(2);
4599
4601 insertCheckShadowOf(Ptr, &I);
4602 insertCheckShadowOf(Mask, &I);
4603 }
4604
4605 if (!PropagateShadow) {
4606 setShadow(&I, getCleanShadow(&I));
4607 setOrigin(&I, getCleanOrigin());
4608 return;
4609 }
4610
4611 Type *ShadowTy = getShadowTy(&I);
4612 Value *ShadowPtr, *OriginPtr;
4613 std::tie(ShadowPtr, OriginPtr) =
4614 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment, /*isStore*/ false);
4615 setShadow(&I, IRB.CreateMaskedLoad(ShadowTy, ShadowPtr, Alignment, Mask,
4616 getShadow(PassThru), "_msmaskedld"));
4617
4618 if (!MS.TrackOrigins)
4619 return;
4620
4621 // Choose between PassThru's and the loaded value's origins.
4622 Value *MaskedPassThruShadow = IRB.CreateAnd(
4623 getShadow(PassThru), IRB.CreateSExt(IRB.CreateNeg(Mask), ShadowTy));
4624
4625 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB, "_mscmp");
4626
4627 Value *PtrOrigin = IRB.CreateLoad(MS.OriginTy, OriginPtr);
4628 Value *Origin = IRB.CreateSelect(NotNull, getOrigin(PassThru), PtrOrigin);
4629
4630 setOrigin(&I, Origin);
4631 }
4632
4633 // e.g., <4 x i32> @llvm.masked.udiv.v4i32(<4 x i32> %dividend,
4634 // <4 x i32> %divisor,
4635 // <4 x i1> %mask)
4636 //
4637 // As handleIntegerDiv(), but per-lane: strict on the divisor and propagating
4638 // the dividend, both only on the enabled lanes. Disabled lanes cannot cause
4639 // undefined behaviour, and their result is poison.
4640 void handleMaskedIntegerDivRem(IntrinsicInst &I) {
4641 assert(I.arg_size() == 3);
4642 IRBuilder<> IRB(&I);
4643 Value *Dividend = I.getArgOperand(0);
4644 Value *Divisor = I.getArgOperand(1);
4645 Value *Mask = I.getArgOperand(2);
4646
4647 insertCheckShadowOf(Mask, &I);
4648
4649 Value *MaskedDivisorShadow = IRB.CreateSelect(
4650 Mask, getShadow(Divisor), getCleanShadow(Divisor), "_msmaskeddivisor");
4651 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &I);
4652
4653 if (!PropagateShadow) {
4654 setShadow(&I, getCleanShadow(&I));
4655 setOrigin(&I, getCleanOrigin());
4656 return;
4657 }
4658
4659 setShadow(&I, IRB.CreateSelect(Mask, getShadow(Dividend),
4660 getPoisonedShadow(&I), "_msmaskeddiv"));
4661 setOrigin(&I, getOrigin(Dividend));
4662 }
4663
4664 // e.g., void @llvm.x86.avx.maskstore.ps.256(ptr, <8 x i32>, <8 x float>)
4665 // dst mask src
4666 //
4667 // AVX512 masked stores are lowered to Intrinsic::masked_load and are handled
4668 // by handleMaskedStore.
4669 //
4670 // This function handles AVX and AVX2 masked stores; these use the MSBs of a
4671 // vector of integers, unlike the LLVM masked intrinsics, which require a
4672 // vector of booleans. X86InstCombineIntrinsic.cpp::simplifyX86MaskedLoad
4673 // mentions that the x86 backend does not know how to efficiently convert
4674 // from a vector of booleans back into the AVX mask format; therefore, they
4675 // (and we) do not reduce AVX/AVX2 masked intrinsics into LLVM masked
4676 // intrinsics.
4677 void handleAVXMaskedStore(IntrinsicInst &I) {
4678 assert(I.arg_size() == 3);
4679
4680 IRBuilder<> IRB(&I);
4681
4682 Value *Dst = I.getArgOperand(0);
4683 assert(Dst->getType()->isPointerTy() && "Destination is not a pointer!");
4684
4685 Value *Mask = I.getArgOperand(1);
4686 assert(isa<VectorType>(Mask->getType()) && "Mask is not a vector!");
4687
4688 Value *Src = I.getArgOperand(2);
4689 assert(isa<VectorType>(Src->getType()) && "Source is not a vector!");
4690
4691 const Align Alignment = Align(1);
4692
4693 Value *SrcShadow = getShadow(Src);
4694
4696 insertCheckShadowOf(Dst, &I);
4697 insertCheckShadowOf(Mask, &I);
4698 }
4699
4700 Value *DstShadowPtr;
4701 Value *DstOriginPtr;
4702 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4703 Dst, IRB, SrcShadow->getType(), Alignment, /*isStore*/ true);
4704
4705 SmallVector<Value *, 2> ShadowArgs;
4706 ShadowArgs.append(1, DstShadowPtr);
4707 ShadowArgs.append(1, Mask);
4708 // The intrinsic may require floating-point but shadows can be arbitrary
4709 // bit patterns, of which some would be interpreted as "invalid"
4710 // floating-point values (NaN etc.); we assume the intrinsic will happily
4711 // copy them.
4712 ShadowArgs.append(1, IRB.CreateBitCast(SrcShadow, Src->getType()));
4713
4714 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4715 IRB.getVoidTy(), I.getIntrinsicID(), ShadowArgs);
4716 setShadow(&I, CI);
4717
4718 if (!MS.TrackOrigins)
4719 return;
4720
4721 // Approximation only
4722 auto &DL = F.getDataLayout();
4723 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4724 DL.getTypeStoreSize(SrcShadow->getType()),
4725 std::max(Alignment, kMinOriginAlignment));
4726 }
4727
4728 // e.g., <8 x float> @llvm.x86.avx.maskload.ps.256(ptr, <8 x i32>)
4729 // return src mask
4730 //
4731 // Masked-off values are replaced with 0, which conveniently also represents
4732 // initialized memory.
4733 //
4734 // AVX512 masked stores are lowered to Intrinsic::masked_load and are handled
4735 // by handleMaskedStore.
4736 //
4737 // We do not combine this with handleMaskedLoad; see comment in
4738 // handleAVXMaskedStore for the rationale.
4739 //
4740 // This is subtly different than handleIntrinsicByApplyingToShadow(I, 1)
4741 // because we need to apply getShadowOriginPtr, not getShadow, to the first
4742 // parameter.
4743 void handleAVXMaskedLoad(IntrinsicInst &I) {
4744 assert(I.arg_size() == 2);
4745
4746 IRBuilder<> IRB(&I);
4747
4748 Value *Src = I.getArgOperand(0);
4749 assert(Src->getType()->isPointerTy() && "Source is not a pointer!");
4750
4751 Value *Mask = I.getArgOperand(1);
4752 assert(isa<VectorType>(Mask->getType()) && "Mask is not a vector!");
4753
4754 const Align Alignment = Align(1);
4755
4757 insertCheckShadowOf(Mask, &I);
4758 }
4759
4760 Type *SrcShadowTy = getShadowTy(Src);
4761 Value *SrcShadowPtr, *SrcOriginPtr;
4762 std::tie(SrcShadowPtr, SrcOriginPtr) =
4763 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment, /*isStore*/ false);
4764
4765 SmallVector<Value *, 2> ShadowArgs;
4766 ShadowArgs.append(1, SrcShadowPtr);
4767 ShadowArgs.append(1, Mask);
4768
4769 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4770 I.getType(), I.getIntrinsicID(), ShadowArgs);
4771 // The AVX masked load intrinsics do not have integer variants. We use the
4772 // floating-point variants, which will happily copy the shadows even if
4773 // they are interpreted as "invalid" floating-point values (NaN etc.).
4774 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4775
4776 if (!MS.TrackOrigins)
4777 return;
4778
4779 // The "pass-through" value is always zero (initialized). To the extent
4780 // that that results in initialized aligned 4-byte chunks, the origin value
4781 // is ignored. It is therefore correct to simply copy the origin from src.
4782 Value *PtrSrcOrigin = IRB.CreateLoad(MS.OriginTy, SrcOriginPtr);
4783 setOrigin(&I, PtrSrcOrigin);
4784 }
4785
4786 // Test whether the mask indices are initialized, only checking the bits that
4787 // are actually used.
4788 //
4789 // e.g., if Idx is <32 x i16>, only (log2(32) == 5) bits of each index are
4790 // used/checked.
4791 void maskedCheckAVXIndexShadow(IRBuilder<> &IRB, Value *Idx, Instruction *I) {
4792 assert(isFixedIntVector(Idx));
4793 auto IdxVectorSize =
4794 cast<FixedVectorType>(Idx->getType())->getNumElements();
4795 assert(isPowerOf2_64(IdxVectorSize));
4796
4797 // Compiler isn't smart enough, let's help it
4798 if (isa<Constant>(Idx))
4799 return;
4800
4801 auto *IdxShadow = getShadow(Idx);
4802 Value *Truncated = IRB.CreateTrunc(
4803 IdxShadow,
4804 FixedVectorType::get(Type::getIntNTy(*MS.C, Log2_64(IdxVectorSize)),
4805 IdxVectorSize));
4806 insertCheckShadow(Truncated, getOrigin(Idx), I);
4807 }
4808
4809 // Instrument AVX permutation intrinsic.
4810 // We apply the same permutation (argument index 1) to the shadow.
4811 void handleAVXVpermilvar(IntrinsicInst &I) {
4812 IRBuilder<> IRB(&I);
4813 Value *Shadow = getShadow(&I, 0);
4814 maskedCheckAVXIndexShadow(IRB, I.getArgOperand(1), &I);
4815
4816 // Shadows are integer-ish types but some intrinsics require a
4817 // different (e.g., floating-point) type.
4818 Shadow = IRB.CreateBitCast(Shadow, I.getArgOperand(0)->getType());
4819 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4820 I.getType(), I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4821
4822 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4823 setOriginForNaryOp(I);
4824 }
4825
4826 // Instrument AVX permutation intrinsic.
4827 // We apply the same permutation (argument index 1) to the shadows.
4828 void handleAVXVpermi2var(IntrinsicInst &I) {
4829 assert(I.arg_size() == 3);
4830 assert(isa<FixedVectorType>(I.getArgOperand(0)->getType()));
4831 assert(isa<FixedVectorType>(I.getArgOperand(1)->getType()));
4832 assert(isa<FixedVectorType>(I.getArgOperand(2)->getType()));
4833 [[maybe_unused]] auto ArgVectorSize =
4834 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4835 assert(cast<FixedVectorType>(I.getArgOperand(1)->getType())
4836 ->getNumElements() == ArgVectorSize);
4837 assert(cast<FixedVectorType>(I.getArgOperand(2)->getType())
4838 ->getNumElements() == ArgVectorSize);
4839 assert(I.getArgOperand(0)->getType() == I.getArgOperand(2)->getType());
4840 assert(I.getType() == I.getArgOperand(0)->getType());
4841 assert(I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4842 IRBuilder<> IRB(&I);
4843 Value *AShadow = getShadow(&I, 0);
4844 Value *Idx = I.getArgOperand(1);
4845 Value *BShadow = getShadow(&I, 2);
4846
4847 maskedCheckAVXIndexShadow(IRB, Idx, &I);
4848
4849 // Shadows are integer-ish types but some intrinsics require a
4850 // different (e.g., floating-point) type.
4851 AShadow = IRB.CreateBitCast(AShadow, I.getArgOperand(0)->getType());
4852 BShadow = IRB.CreateBitCast(BShadow, I.getArgOperand(2)->getType());
4853 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4854 I.getType(), I.getIntrinsicID(), {AShadow, Idx, BShadow});
4855 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4856 setOriginForNaryOp(I);
4857 }
4858
4859 [[maybe_unused]] static bool isFixedIntVectorTy(const Type *T) {
4860 return isa<FixedVectorType>(T) && T->isIntOrIntVectorTy();
4861 }
4862
4863 [[maybe_unused]] static bool isFixedFPVectorTy(const Type *T) {
4864 return isa<FixedVectorType>(T) && T->isFPOrFPVectorTy();
4865 }
4866
4867 [[maybe_unused]] static bool isFixedIntVector(const Value *V) {
4868 return isFixedIntVectorTy(V->getType());
4869 }
4870
4871 [[maybe_unused]] static bool isFixedFPVector(const Value *V) {
4872 return isFixedFPVectorTy(V->getType());
4873 }
4874
4875 // e.g., <16 x i32> @llvm.x86.avx512.mask.cvtps2dq.512
4876 // (<16 x float> a, <16 x i32> writethru, i16 mask,
4877 // i32 rounding)
4878 //
4879 // Inconveniently, some similar intrinsics have a different operand order:
4880 // <16 x i16> @llvm.x86.avx512.mask.vcvtps2ph.512
4881 // (<16 x float> a, i32 rounding, <16 x i16> writethru,
4882 // i16 mask)
4883 //
4884 // If the return type has more elements than A, the excess elements are
4885 // zeroed (and the corresponding shadow is initialized).
4886 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.128
4887 // (<4 x float> a, i32 rounding, <8 x i16> writethru,
4888 // i8 mask)
4889 //
4890 // dst[i] = mask[i] ? convert(a[i]) : writethru[i]
4891 // dst_shadow[i] = mask[i] ? all_or_nothing(a_shadow[i]) : writethru_shadow[i]
4892 // where all_or_nothing(x) is fully uninitialized if x has any
4893 // uninitialized bits
4894 void handleAVX512VectorConvertFPToInt(IntrinsicInst &I, bool LastMask) {
4895 IRBuilder<> IRB(&I);
4896
4897 assert(I.arg_size() == 4);
4898 Value *A = I.getOperand(0);
4899 Value *WriteThrough;
4900 Value *Mask;
4902 if (LastMask) {
4903 WriteThrough = I.getOperand(2);
4904 Mask = I.getOperand(3);
4905 RoundingMode = I.getOperand(1);
4906 } else {
4907 WriteThrough = I.getOperand(1);
4908 Mask = I.getOperand(2);
4909 RoundingMode = I.getOperand(3);
4910 }
4911
4912 assert(isFixedFPVector(A));
4913 assert(isFixedIntVector(WriteThrough));
4914
4915 unsigned ANumElements =
4916 cast<FixedVectorType>(A->getType())->getNumElements();
4917 [[maybe_unused]] unsigned WriteThruNumElements =
4918 cast<FixedVectorType>(WriteThrough->getType())->getNumElements();
4919 assert(ANumElements == WriteThruNumElements ||
4920 ANumElements * 2 == WriteThruNumElements);
4921
4922 assert(Mask->getType()->isIntegerTy());
4923 unsigned MaskNumElements = Mask->getType()->getScalarSizeInBits();
4924 assert(ANumElements == MaskNumElements ||
4925 ANumElements * 2 == MaskNumElements);
4926
4927 assert(WriteThruNumElements == MaskNumElements);
4928
4929 // Some bits of the mask may be unused, though it's unusual to have partly
4930 // uninitialized bits.
4931 insertCheckShadowOf(Mask, &I);
4932
4933 assert(RoundingMode->getType()->isIntegerTy());
4934 // Only some bits of the rounding mode are used, though it's very
4935 // unusual to have uninitialized bits there (more commonly, it's a
4936 // constant).
4937 insertCheckShadowOf(RoundingMode, &I);
4938
4939 assert(I.getType() == WriteThrough->getType());
4940
4941 Value *AShadow = getShadow(A);
4942 AShadow = maybeExtendVectorShadowWithZeros(AShadow, I);
4943
4944 if (ANumElements * 2 == MaskNumElements) {
4945 // Ensure that the irrelevant bits of the mask are zero, hence selecting
4946 // from the zeroed shadow instead of the writethrough's shadow.
4947 Mask =
4948 IRB.CreateTrunc(Mask, IRB.getIntNTy(ANumElements), "_ms_mask_trunc");
4949 Mask =
4950 IRB.CreateZExt(Mask, IRB.getIntNTy(MaskNumElements), "_ms_mask_zext");
4951 }
4952
4953 // Convert i16 mask to <16 x i1>
4954 Mask = IRB.CreateBitCast(
4955 Mask, FixedVectorType::get(IRB.getInt1Ty(), MaskNumElements),
4956 "_ms_mask_bitcast");
4957
4958 /// For floating-point to integer conversion, the output is:
4959 /// - fully uninitialized if *any* bit of the input is uninitialized
4960 /// - fully ininitialized if all bits of the input are ininitialized
4961 /// We apply the same principle on a per-element basis for vectors.
4962 ///
4963 /// We use the scalar width of the return type instead of A's.
4964 AShadow = IRB.CreateSExt(
4965 IRB.CreateICmpNE(AShadow, getCleanShadow(AShadow->getType())),
4966 getShadowTy(&I), "_ms_a_shadow");
4967
4968 Value *WriteThroughShadow = getShadow(WriteThrough);
4969 Value *Shadow = IRB.CreateSelect(Mask, AShadow, WriteThroughShadow,
4970 "_ms_writethru_select");
4971
4972 setShadow(&I, Shadow);
4973 setOriginForNaryOp(I);
4974 }
4975
4976 static SmallVector<int, 8> getPclmulMask(unsigned Width, bool OddElements) {
4977 SmallVector<int, 8> Mask;
4978 for (unsigned X = OddElements ? 1 : 0; X < Width; X += 2) {
4979 Mask.append(2, X);
4980 }
4981 return Mask;
4982 }
4983
4984 // Instrument pclmul intrinsics.
4985 // These intrinsics operate either on odd or on even elements of the input
4986 // vectors, depending on the constant in the 3rd argument, ignoring the rest.
4987 // Replace the unused elements with copies of the used ones, ex:
4988 // (0, 1, 2, 3) -> (0, 0, 2, 2) (even case)
4989 // or
4990 // (0, 1, 2, 3) -> (1, 1, 3, 3) (odd case)
4991 // and then apply the usual shadow combining logic.
4992 void handlePclmulIntrinsic(IntrinsicInst &I) {
4993 IRBuilder<> IRB(&I);
4994 unsigned Width =
4995 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4996 assert(isa<ConstantInt>(I.getArgOperand(2)) &&
4997 "pclmul 3rd operand must be a constant");
4998 unsigned Imm = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
4999 Value *Shuf0 = IRB.CreateShuffleVector(getShadow(&I, 0),
5000 getPclmulMask(Width, Imm & 0x01));
5001 Value *Shuf1 = IRB.CreateShuffleVector(getShadow(&I, 1),
5002 getPclmulMask(Width, Imm & 0x10));
5003 ShadowAndOriginCombiner SOC(this, IRB);
5004 SOC.Add(Shuf0, getOrigin(&I, 0));
5005 SOC.Add(Shuf1, getOrigin(&I, 1));
5006 SOC.Done(&I);
5007 }
5008
5009 // Instrument _mm_*_sd|ss intrinsics
5010 void handleUnarySdSsIntrinsic(IntrinsicInst &I) {
5011 IRBuilder<> IRB(&I);
5012 unsigned Width =
5013 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
5014 Value *First = getShadow(&I, 0);
5015 Value *Second = getShadow(&I, 1);
5016 // First element of second operand, remaining elements of first operand
5017 SmallVector<int, 16> Mask;
5018 Mask.push_back(Width);
5019 for (unsigned i = 1; i < Width; i++)
5020 Mask.push_back(i);
5021 Value *Shadow = IRB.CreateShuffleVector(First, Second, Mask);
5022
5023 setShadow(&I, Shadow);
5024 setOriginForNaryOp(I);
5025 }
5026
5027 void handleVtestIntrinsic(IntrinsicInst &I) {
5028 IRBuilder<> IRB(&I);
5029 Value *Shadow0 = getShadow(&I, 0);
5030 Value *Shadow1 = getShadow(&I, 1);
5031 Value *Or = IRB.CreateOr(Shadow0, Shadow1);
5032 Value *NZ = IRB.CreateICmpNE(Or, Constant::getNullValue(Or->getType()));
5033 Value *Scalar = convertShadowToScalar(NZ, IRB);
5034 Value *Shadow = IRB.CreateZExt(Scalar, getShadowTy(&I));
5035
5036 setShadow(&I, Shadow);
5037 setOriginForNaryOp(I);
5038 }
5039
5040 void handleBinarySdSsIntrinsic(IntrinsicInst &I) {
5041 IRBuilder<> IRB(&I);
5042 unsigned Width =
5043 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
5044 Value *First = getShadow(&I, 0);
5045 Value *Second = getShadow(&I, 1);
5046 Value *OrShadow = IRB.CreateOr(First, Second);
5047 // First element of both OR'd together, remaining elements of first operand
5048 SmallVector<int, 16> Mask;
5049 Mask.push_back(Width);
5050 for (unsigned i = 1; i < Width; i++)
5051 Mask.push_back(i);
5052 Value *Shadow = IRB.CreateShuffleVector(First, OrShadow, Mask);
5053
5054 setShadow(&I, Shadow);
5055 setOriginForNaryOp(I);
5056 }
5057
5058 // _mm_round_ps / _mm_round_ps.
5059 // Similar to maybeHandleSimpleNomemIntrinsic except
5060 // the second argument is guaranteed to be a constant integer.
5061 void handleRoundPdPsIntrinsic(IntrinsicInst &I) {
5062 assert(I.getArgOperand(0)->getType() == I.getType());
5063 assert(I.arg_size() == 2);
5064 assert(isa<ConstantInt>(I.getArgOperand(1)));
5065
5066 IRBuilder<> IRB(&I);
5067 ShadowAndOriginCombiner SC(this, IRB);
5068 SC.Add(I.getArgOperand(0));
5069 SC.Done(&I);
5070 }
5071
5072 // Instrument @llvm.abs intrinsic.
5073 //
5074 // e.g., i32 @llvm.abs.i32 (i32 <Src>, i1 <is_int_min_poison>)
5075 // <4 x i32> @llvm.abs.v4i32(<4 x i32> <Src>, i1 <is_int_min_poison>)
5076 void handleAbsIntrinsic(IntrinsicInst &I) {
5077 assert(I.arg_size() == 2);
5078 Value *Src = I.getArgOperand(0);
5079 Value *IsIntMinPoison = I.getArgOperand(1);
5080
5081 assert(I.getType()->isIntOrIntVectorTy());
5082
5083 assert(Src->getType() == I.getType());
5084
5085 assert(IsIntMinPoison->getType()->isIntegerTy());
5086 assert(IsIntMinPoison->getType()->getIntegerBitWidth() == 1);
5087
5088 IRBuilder<> IRB(&I);
5089 Value *SrcShadow = getShadow(Src);
5090
5091 APInt MinVal =
5092 APInt::getSignedMinValue(Src->getType()->getScalarSizeInBits());
5093 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5094 Value *SrcIsMin = IRB.CreateICmp(CmpInst::ICMP_EQ, Src, MinValVec);
5095
5096 Value *PoisonedShadow = getPoisonedShadow(Src);
5097 Value *PoisonedIfIntMinShadow =
5098 IRB.CreateSelect(SrcIsMin, PoisonedShadow, SrcShadow);
5099 Value *Shadow =
5100 IRB.CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5101
5102 setShadow(&I, Shadow);
5103 setOrigin(&I, getOrigin(&I, 0));
5104 }
5105
5106 void handleIsFpClass(IntrinsicInst &I) {
5107 IRBuilder<> IRB(&I);
5108 Value *Shadow = getShadow(&I, 0);
5109 setShadow(&I, IRB.CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5110 setOrigin(&I, getOrigin(&I, 0));
5111 }
5112
5113 void handleArithmeticWithOverflow(IntrinsicInst &I) {
5114 IRBuilder<> IRB(&I);
5115 Value *Shadow0 = getShadow(&I, 0);
5116 Value *Shadow1 = getShadow(&I, 1);
5117 Value *ShadowElt0 = IRB.CreateOr(Shadow0, Shadow1);
5118 Value *ShadowElt1 =
5119 IRB.CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5120
5121 Value *Shadow = PoisonValue::get(getShadowTy(&I));
5122 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt0, 0);
5123 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt1, 1);
5124
5125 setShadow(&I, Shadow);
5126 setOriginForNaryOp(I);
5127 }
5128
5129 void handleModfOrSincos(IntrinsicInst &I) {
5130 IRBuilder<> IRB(&I);
5131 Value *ArgShadow = getShadow(&I, 0);
5132 Value *Shadow = PoisonValue::get(getShadowTy(&I));
5133 Shadow = IRB.CreateInsertValue(Shadow, ArgShadow, 0);
5134 Shadow = IRB.CreateInsertValue(Shadow, ArgShadow, 1);
5135 setShadow(&I, Shadow);
5136 setOrigin(&I, getOrigin(&I, 0));
5137 }
5138
5139 Value *extractLowerShadow(IRBuilder<> &IRB, Value *V) {
5140 assert(isa<FixedVectorType>(V->getType()));
5141 assert(cast<FixedVectorType>(V->getType())->getNumElements() > 0);
5142 Value *Shadow = getShadow(V);
5143 return IRB.CreateExtractElement(Shadow,
5144 ConstantInt::get(IRB.getInt32Ty(), 0));
5145 }
5146
5147 // Handle llvm.x86.avx512.mask.pmov{,s,us}.*.{128,256,512}
5148 //
5149 // e.g., call <16 x i8> @llvm.x86.avx512.mask.pmov.qb.512
5150 // (<8 x i64>, <16 x i8>, i8)
5151 // A WriteThru Mask
5152 //
5153 // call <16 x i8> @llvm.x86.avx512.mask.pmovs.db.512
5154 // (<16 x i32>, <16 x i8>, i16)
5155 //
5156 // Dst[i] = Mask[i] ? truncate_or_saturate(A[i]) : WriteThru[i]
5157 // Dst_shadow[i] = Mask[i] ? truncate(A_shadow[i]) : WriteThru_shadow[i]
5158 //
5159 // If Dst has more elements than A, the excess elements are zeroed (and the
5160 // corresponding shadow is initialized).
5161 //
5162 // Note: for PMOV (truncation), handleIntrinsicByApplyingToShadow is precise
5163 // and is much faster than this handler.
5164 void handleAVX512VectorDownConvert(IntrinsicInst &I) {
5165 IRBuilder<> IRB(&I);
5166
5167 assert(I.arg_size() == 3);
5168 Value *A = I.getOperand(0);
5169 Value *WriteThrough = I.getOperand(1);
5170 Value *Mask = I.getOperand(2);
5171
5172 assert(isFixedIntVector(A));
5173 assert(isFixedIntVector(WriteThrough));
5174
5175 unsigned ANumElements =
5176 cast<FixedVectorType>(A->getType())->getNumElements();
5177 unsigned OutputNumElements =
5178 cast<FixedVectorType>(WriteThrough->getType())->getNumElements();
5179 assert(ANumElements == OutputNumElements ||
5180 ANumElements * 2 == OutputNumElements);
5181 // N.B. some PMOV{,S,US} instructions have a 4x or even 8x ratio in the
5182 // number of elements e.g.,
5183 // <16 x i8> @llvm.x86.avx512.mask.pmovs.qb.256
5184 // (<4 x i64>, <16 x i8>, i8)
5185 // <16 x i8> @llvm.x86.avx512.mask.pmovs.qb.128
5186 // (<2 x i64>, <16 x i8>, i8)
5187 // However, we currently handle those elsewhere.
5188
5189 assert(Mask->getType()->isIntegerTy());
5190 insertCheckShadowOf(Mask, &I);
5191
5192 // The mask has 1 bit per element of A, but a minimum of 8 bits.
5193 if (Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5194 Mask = IRB.CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5195 assert(Mask->getType()->getScalarSizeInBits() == ANumElements);
5196
5197 assert(I.getType() == WriteThrough->getType());
5198
5199 // Widen the mask, if necessary, to have one bit per element of the output
5200 // vector.
5201 // We want the extra bits to have '1's, so that the CreateSelect will
5202 // select the values from AShadow instead of WriteThroughShadow ("maskless"
5203 // versions of the intrinsics are sometimes implemented using an all-1's
5204 // mask and an undefined value for WriteThroughShadow). We accomplish this
5205 // by using bitwise NOT before and after the ZExt.
5206 if (ANumElements != OutputNumElements) {
5207 Mask = IRB.CreateNot(Mask);
5208 Mask = IRB.CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5209 "_ms_widen_mask");
5210 Mask = IRB.CreateNot(Mask);
5211 }
5212 Mask = IRB.CreateBitCast(
5213 Mask, FixedVectorType::get(IRB.getInt1Ty(), OutputNumElements));
5214
5215 Value *AShadow = getShadow(A);
5216
5217 // The return type might have more elements than the input.
5218 // Temporarily shrink the return type's number of elements.
5219 VectorType *ShadowType = maybeShrinkVectorShadowType(A, I);
5220
5221 // PMOV truncates; PMOVS/PMOVUS uses signed/unsigned saturation.
5222 // This handler treats them all as truncation, which leads to some rare
5223 // false positives in the cases where the truncated bytes could
5224 // unambiguously saturate the value e.g., if A = ??????10 ????????
5225 // (big-endian), the unsigned saturated byte conversion is 11111111 i.e.,
5226 // fully defined, but the truncated byte is ????????.
5227 //
5228 // TODO: use GetMinMaxUnsigned() to handle saturation precisely.
5229 AShadow = IRB.CreateTrunc(AShadow, ShadowType, "_ms_trunc_shadow");
5230 AShadow = maybeExtendVectorShadowWithZeros(AShadow, I);
5231
5232 Value *WriteThroughShadow = getShadow(WriteThrough);
5233
5234 Value *Shadow = IRB.CreateSelect(Mask, AShadow, WriteThroughShadow);
5235 setShadow(&I, Shadow);
5236 setOriginForNaryOp(I);
5237 }
5238
5239 // Handle llvm.x86.avx512.* instructions that take vector(s) of floating-point
5240 // values and perform an operation whose shadow propagation should be handled
5241 // as all-or-nothing [*], with masking provided by a vector and a mask
5242 // supplied as an integer.
5243 //
5244 // [*] if all bits of a vector element are initialized, the output is fully
5245 // initialized; otherwise, the output is fully uninitialized
5246 //
5247 // e.g., <16 x float> @llvm.x86.avx512.rsqrt14.ps.512
5248 // (<16 x float>, <16 x float>, i16)
5249 // A WriteThru Mask
5250 //
5251 // <2 x double> @llvm.x86.avx512.rcp14.pd.128
5252 // (<2 x double>, <2 x double>, i8)
5253 // A WriteThru Mask
5254 //
5255 // <8 x double> @llvm.x86.avx512.mask.rndscale.pd.512
5256 // (<8 x double>, i32, <8 x double>, i8, i32)
5257 // A Imm WriteThru Mask Rounding
5258 //
5259 // <16 x float> @llvm.x86.avx512.mask.scalef.ps.512
5260 // (<16 x float>, <16 x float>, <16 x float>, i16, i32)
5261 // WriteThru A B Mask Rnd
5262 //
5263 // All operands other than A, B, ..., and WriteThru (e.g., Mask, Imm,
5264 // Rounding) must be fully initialized.
5265 //
5266 // Dst[i] = Mask[i] ? some_op(A[i], B[i], ...)
5267 // : WriteThru[i]
5268 // Dst_shadow[i] = Mask[i] ? all_or_nothing(A_shadow[i] | B_shadow[i] | ...)
5269 // : WriteThru_shadow[i]
5270 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &I,
5271 SmallVector<unsigned, 4> DataIndices,
5272 unsigned WriteThruIndex,
5273 unsigned MaskIndex) {
5274 IRBuilder<> IRB(&I);
5275
5276 unsigned NumArgs = I.arg_size();
5277
5278 assert(WriteThruIndex < NumArgs);
5279 assert(MaskIndex < NumArgs);
5280 assert(WriteThruIndex != MaskIndex);
5281 Value *WriteThru = I.getOperand(WriteThruIndex);
5282
5283 unsigned OutputNumElements =
5284 cast<FixedVectorType>(WriteThru->getType())->getNumElements();
5285
5286 assert(DataIndices.size() > 0);
5287
5288 bool isData[16] = {false};
5289 assert(NumArgs <= 16);
5290 for (unsigned i : DataIndices) {
5291 assert(i < NumArgs);
5292 assert(i != WriteThruIndex);
5293 assert(i != MaskIndex);
5294
5295 isData[i] = true;
5296
5297 Value *A = I.getOperand(i);
5298 assert(isFixedFPVector(A));
5299 [[maybe_unused]] unsigned ANumElements =
5300 cast<FixedVectorType>(A->getType())->getNumElements();
5301 assert(ANumElements == OutputNumElements);
5302 }
5303
5304 Value *Mask = I.getOperand(MaskIndex);
5305
5306 assert(isFixedFPVector(WriteThru));
5307
5308 for (unsigned i = 0; i < NumArgs; ++i) {
5309 if (!isData[i] && i != WriteThruIndex) {
5310 // Imm, Mask, Rounding etc. are "control" data, hence we require that
5311 // they be fully initialized.
5312 assert(I.getOperand(i)->getType()->isIntegerTy());
5313 insertCheckShadowOf(I.getOperand(i), &I);
5314 }
5315 }
5316
5317 // The mask has 1 bit per element of A, but a minimum of 8 bits.
5318 if (Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5319 Mask = IRB.CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5320 assert(Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5321
5322 assert(I.getType() == WriteThru->getType());
5323
5324 Mask = IRB.CreateBitCast(
5325 Mask, FixedVectorType::get(IRB.getInt1Ty(), OutputNumElements));
5326
5327 Value *DataShadow = nullptr;
5328 for (unsigned i : DataIndices) {
5329 Value *A = I.getOperand(i);
5330 if (DataShadow)
5331 DataShadow = IRB.CreateOr(DataShadow, getShadow(A));
5332 else
5333 DataShadow = getShadow(A);
5334 }
5335
5336 // All-or-nothing shadow
5337 DataShadow =
5338 IRB.CreateSExt(IRB.CreateICmpNE(DataShadow, getCleanShadow(DataShadow)),
5339 DataShadow->getType());
5340
5341 Value *WriteThruShadow = getShadow(WriteThru);
5342
5343 Value *Shadow = IRB.CreateSelect(Mask, DataShadow, WriteThruShadow);
5344 setShadow(&I, Shadow);
5345
5346 setOriginForNaryOp(I);
5347 }
5348
5349 // AVX512 Floating-Point Classification
5350 //
5351 // e.g.,
5352 // - < 8 x i1> @llvm.x86.avx512.fpclass.pd.512
5353 // (<8 x double> %input, i32 %classifiers)
5354 // - <16 x i1> @llvm.x86.avx512.fpclass.ps.512
5355 // (<16 x float> %input, i32 %classifiers)
5356 void handleAVX512FPClass(IntrinsicInst &I) {
5357 IRBuilder<> IRB(&I);
5358
5359 assert(I.arg_size() == 2);
5360
5361 Value *Input = I.getOperand(0);
5362 assert(isFixedFPVector(Input));
5363 [[maybe_unused]] FixedVectorType *InputType = cast<FixedVectorType>(Input->getType());
5364
5365 Value *Classifiers = I.getOperand(1);
5366 assert(isa<ConstantInt>(Classifiers));
5367 // No shadow check needed for constants
5368
5369 assert(isFixedIntVectorTy(I.getType()));
5370 FixedVectorType *OutputType = cast<FixedVectorType>(I.getType());
5371 assert(OutputType->getScalarSizeInBits() == 1);
5372
5373 assert(OutputType->getNumElements() == InputType->getNumElements());
5374
5375 Value *OutputShadow;
5376 if (cast<ConstantInt>(Classifiers)->isZero())
5377 // Each bit specifies whether a particular classifier is enabled.
5378 // If Classifiers == 0, the output is trivially known to be zero, thus
5379 // the output is fully initialized.
5380 OutputShadow = getCleanShadow(OutputType);
5381 else
5382 // Approximate each bit of the output shadow based on whether the
5383 // corresponding input element is fully initialized. It is only
5384 // approximate because some classifications do not rely on all bits of
5385 // the input element.
5386 OutputShadow = IRB.CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5387
5388 setShadow(&I, OutputShadow);
5389
5390 setOriginForNaryOp(I);
5391 }
5392
5393 // For sh.* compiler intrinsics:
5394 // llvm.x86.avx512fp16.mask.{add/sub/mul/div/max/min}.sh.round
5395 // (<8 x half>, <8 x half>, <8 x half>, i8, i32)
5396 // A B WriteThru Mask RoundingMode
5397 //
5398 // DstShadow[0] = Mask[0] ? (AShadow[0] | BShadow[0]) : WriteThruShadow[0]
5399 // DstShadow[1..7] = AShadow[1..7]
5400 void visitGenericScalarHalfwordInst(IntrinsicInst &I) {
5401 IRBuilder<> IRB(&I);
5402
5403 assert(I.arg_size() == 5);
5404 Value *A = I.getOperand(0);
5405 Value *B = I.getOperand(1);
5406 Value *WriteThrough = I.getOperand(2);
5407 Value *Mask = I.getOperand(3);
5408 Value *RoundingMode = I.getOperand(4);
5409
5410 // Technically, we could probably just check whether the LSB is
5411 // initialized, but intuitively it feels like a partly uninitialized mask
5412 // is unintended, and we should warn the user immediately.
5413 insertCheckShadowOf(Mask, &I);
5414 insertCheckShadowOf(RoundingMode, &I);
5415
5416 assert(isa<FixedVectorType>(A->getType()));
5417 unsigned NumElements =
5418 cast<FixedVectorType>(A->getType())->getNumElements();
5419 assert(NumElements == 8);
5420 assert(A->getType() == B->getType());
5421 assert(B->getType() == WriteThrough->getType());
5422 assert(Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5423 assert(RoundingMode->getType()->isIntegerTy());
5424
5425 Value *ALowerShadow = extractLowerShadow(IRB, A);
5426 Value *BLowerShadow = extractLowerShadow(IRB, B);
5427
5428 Value *ABLowerShadow = IRB.CreateOr(ALowerShadow, BLowerShadow);
5429
5430 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5431
5432 Mask = IRB.CreateBitCast(
5433 Mask, FixedVectorType::get(IRB.getInt1Ty(), NumElements));
5434 Value *MaskLower =
5435 IRB.CreateExtractElement(Mask, ConstantInt::get(IRB.getInt32Ty(), 0));
5436
5437 Value *AShadow = getShadow(A);
5438 Value *DstLowerShadow =
5439 IRB.CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5440 Value *DstShadow = IRB.CreateInsertElement(
5441 AShadow, DstLowerShadow, ConstantInt::get(IRB.getInt32Ty(), 0),
5442 "_msprop");
5443
5444 setShadow(&I, DstShadow);
5445 setOriginForNaryOp(I);
5446 }
5447
5448 // Approximately handle AVX Galois Field Affine Transformation
5449 //
5450 // e.g.,
5451 // <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8>, <16 x i8>, i8)
5452 // <32 x i8> @llvm.x86.vgf2p8affineqb.256(<32 x i8>, <32 x i8>, i8)
5453 // <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8>, <64 x i8>, i8)
5454 // Out A x b
5455 // where A and x are packed matrices, b is a vector,
5456 // Out = A * x + b in GF(2)
5457 //
5458 // Multiplication in GF(2) is equivalent to bitwise AND. However, the matrix
5459 // computation also includes a parity calculation.
5460 //
5461 // For the bitwise AND of bits V1 and V2, the exact shadow is:
5462 // Out_Shadow = (V1_Shadow & V2_Shadow)
5463 // | (V1 & V2_Shadow)
5464 // | (V1_Shadow & V2 )
5465 //
5466 // We approximate the shadow of gf2p8affineqb using:
5467 // Out_Shadow = gf2p8affineqb(x_Shadow, A_shadow, 0)
5468 // | gf2p8affineqb(x, A_shadow, 0)
5469 // | gf2p8affineqb(x_Shadow, A, 0)
5470 // | set1_epi8(b_Shadow)
5471 //
5472 // This approximation has false negatives: if an intermediate dot-product
5473 // contains an even number of 1's, the parity is 0.
5474 // It has no false positives.
5475 void handleAVXGF2P8Affine(IntrinsicInst &I) {
5476 IRBuilder<> IRB(&I);
5477
5478 assert(I.arg_size() == 3);
5479 Value *A = I.getOperand(0);
5480 Value *X = I.getOperand(1);
5481 Value *B = I.getOperand(2);
5482
5483 assert(isFixedIntVector(A));
5484 assert(cast<VectorType>(A->getType())
5485 ->getElementType()
5486 ->getScalarSizeInBits() == 8);
5487
5488 assert(A->getType() == X->getType());
5489
5490 assert(B->getType()->isIntegerTy());
5491 assert(B->getType()->getScalarSizeInBits() == 8);
5492
5493 assert(I.getType() == A->getType());
5494
5495 Value *AShadow = getShadow(A);
5496 Value *XShadow = getShadow(X);
5497 Value *BZeroShadow = getCleanShadow(B);
5498
5499 Value *AShadowXShadow = IRB.CreateIntrinsic(
5500 I.getType(), I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5501 Value *AShadowX = IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(),
5502 {X, AShadow, BZeroShadow});
5503 Value *XShadowA = IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(),
5504 {XShadow, A, BZeroShadow});
5505
5506 unsigned NumElements = cast<FixedVectorType>(I.getType())->getNumElements();
5507 Value *BShadow = getShadow(B);
5508 Value *BBroadcastShadow = getCleanShadow(AShadow);
5509 // There is no LLVM IR intrinsic for _mm512_set1_epi8.
5510 // This loop generates a lot of LLVM IR, which we expect that CodeGen will
5511 // lower appropriately (e.g., VPBROADCASTB).
5512 // Besides, b is often a constant, in which case it is fully initialized.
5513 for (unsigned i = 0; i < NumElements; i++)
5514 BBroadcastShadow = IRB.CreateInsertElement(BBroadcastShadow, BShadow, i);
5515
5516 setShadow(&I, IRB.CreateOr(
5517 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5518 setOriginForNaryOp(I);
5519 }
5520
5521 // Handle Arm NEON vector load intrinsics (vld*).
5522 //
5523 // The WithLane instructions (ld[234]lane) are similar to:
5524 // call {<4 x i32>, <4 x i32>, <4 x i32>}
5525 // @llvm.aarch64.neon.ld3lane.v4i32.p0
5526 // (<4 x i32> %L1, <4 x i32> %L2, <4 x i32> %L3, i64 %lane, ptr
5527 // %A)
5528 //
5529 // The non-WithLane instructions (ld[234], ld1x[234], ld[234]r) are similar
5530 // to:
5531 // call {<8 x i8>, <8 x i8>} @llvm.aarch64.neon.ld2.v8i8.p0(ptr %A)
5532 void handleNEONVectorLoad(IntrinsicInst &I, bool WithLane) {
5533 unsigned int numArgs = I.arg_size();
5534
5535 // Return type is a struct of vectors of integers or floating-point
5536 assert(I.getType()->isStructTy());
5537 [[maybe_unused]] StructType *RetTy = cast<StructType>(I.getType());
5538 assert(RetTy->getNumElements() > 0);
5540 RetTy->getElementType(0)->isFPOrFPVectorTy());
5541 for (unsigned int i = 0; i < RetTy->getNumElements(); i++)
5542 assert(RetTy->getElementType(i) == RetTy->getElementType(0));
5543
5544 if (WithLane) {
5545 // 2, 3 or 4 vectors, plus lane number, plus input pointer
5546 assert(4 <= numArgs && numArgs <= 6);
5547
5548 // Return type is a struct of the input vectors
5549 assert(RetTy->getNumElements() + 2 == numArgs);
5550 for (unsigned int i = 0; i < RetTy->getNumElements(); i++)
5551 assert(I.getArgOperand(i)->getType() == RetTy->getElementType(0));
5552 } else {
5553 assert(numArgs == 1);
5554 }
5555
5556 IRBuilder<> IRB(&I);
5557
5558 SmallVector<Value *, 6> ShadowArgs;
5559 if (WithLane) {
5560 for (unsigned int i = 0; i < numArgs - 2; i++)
5561 ShadowArgs.push_back(getShadow(I.getArgOperand(i)));
5562
5563 // Lane number, passed verbatim
5564 Value *LaneNumber = I.getArgOperand(numArgs - 2);
5565 ShadowArgs.push_back(LaneNumber);
5566
5567 // TODO: blend shadow of lane number into output shadow?
5568 insertCheckShadowOf(LaneNumber, &I);
5569 }
5570
5571 Value *Src = I.getArgOperand(numArgs - 1);
5572 assert(Src->getType()->isPointerTy() && "Source is not a pointer!");
5573
5574 Type *SrcShadowTy = getShadowTy(Src);
5575 auto [SrcShadowPtr, SrcOriginPtr] =
5576 getShadowOriginPtr(Src, IRB, SrcShadowTy, Align(1), /*isStore*/ false);
5577 ShadowArgs.push_back(SrcShadowPtr);
5578
5579 // The NEON vector load instructions handled by this function all have
5580 // integer variants. It is easier to use those rather than trying to cast
5581 // a struct of vectors of floats into a struct of vectors of integers.
5582 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
5583 getShadowTy(&I), I.getIntrinsicID(), ShadowArgs);
5584 setShadow(&I, CI);
5585
5586 if (!MS.TrackOrigins)
5587 return;
5588
5589 Value *PtrSrcOrigin = IRB.CreateLoad(MS.OriginTy, SrcOriginPtr);
5590 setOrigin(&I, PtrSrcOrigin);
5591 }
5592
5593 /// Handle Arm NEON vector store intrinsics (vst{2,3,4}, vst1x_{2,3,4},
5594 /// and vst{2,3,4}lane).
5595 ///
5596 /// Arm NEON vector store intrinsics have the output address (pointer) as the
5597 /// last argument, with the initial arguments being the inputs (and lane
5598 /// number for vst{2,3,4}lane). They return void.
5599 ///
5600 /// - st4 interleaves the output e.g., st4 (inA, inB, inC, inD, outP) writes
5601 /// abcdabcdabcdabcd... into *outP
5602 /// - st1_x4 is non-interleaved e.g., st1_x4 (inA, inB, inC, inD, outP)
5603 /// writes aaaa...bbbb...cccc...dddd... into *outP
5604 /// - st4lane has arguments of (inA, inB, inC, inD, lane, outP)
5605 /// These instructions can all be instrumented with essentially the same
5606 /// MSan logic, simply by applying the corresponding intrinsic to the shadow.
5607 void handleNEONVectorStoreIntrinsic(IntrinsicInst &I, bool useLane) {
5608 IRBuilder<> IRB(&I);
5609
5610 // Don't use getNumOperands() because it includes the callee
5611 int numArgOperands = I.arg_size();
5612
5613 // The last arg operand is the output (pointer)
5614 assert(numArgOperands >= 1);
5615 Value *Addr = I.getArgOperand(numArgOperands - 1);
5616 assert(Addr->getType()->isPointerTy());
5617 int skipTrailingOperands = 1;
5618
5620 insertCheckShadowOf(Addr, &I);
5621
5622 // Second-last operand is the lane number (for vst{2,3,4}lane)
5623 if (useLane) {
5624 skipTrailingOperands++;
5625 assert(numArgOperands >= static_cast<int>(skipTrailingOperands));
5627 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5628 }
5629
5630 SmallVector<Value *, 8> ShadowArgs;
5631 // All the initial operands are the inputs
5632 for (int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5633 assert(isa<FixedVectorType>(I.getArgOperand(i)->getType()));
5634 Value *Shadow = getShadow(&I, i);
5635 ShadowArgs.append(1, Shadow);
5636 }
5637
5638 // MSan's GetShadowTy assumes the LHS is the type we want the shadow for
5639 // e.g., for:
5640 // [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to i128
5641 // we know the type of the output (and its shadow) is <16 x i8>.
5642 //
5643 // Arm NEON VST is unusual because the last argument is the output address:
5644 // define void @st2_16b(<16 x i8> %A, <16 x i8> %B, ptr %P) {
5645 // call void @llvm.aarch64.neon.st2.v16i8.p0
5646 // (<16 x i8> [[A]], <16 x i8> [[B]], ptr [[P]])
5647 // and we have no type information about P's operand. We must manually
5648 // compute the type (<16 x i8> x 2).
5649 FixedVectorType *OutputVectorTy = FixedVectorType::get(
5650 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getElementType(),
5651 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements() *
5652 (numArgOperands - skipTrailingOperands));
5653 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5654
5655 if (useLane)
5656 ShadowArgs.append(1,
5657 I.getArgOperand(numArgOperands - skipTrailingOperands));
5658
5659 Value *OutputShadowPtr, *OutputOriginPtr;
5660 // AArch64 NEON does not need alignment (unless OS requires it)
5661 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5662 Addr, IRB, OutputShadowTy, Align(1), /*isStore*/ true);
5663 ShadowArgs.append(1, OutputShadowPtr);
5664
5665 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
5666 IRB.getVoidTy(), I.getIntrinsicID(), ShadowArgs);
5667 setShadow(&I, CI);
5668
5669 if (MS.TrackOrigins) {
5670 // TODO: if we modelled the vst* instruction more precisely, we could
5671 // more accurately track the origins (e.g., if both inputs are
5672 // uninitialized for vst2, we currently blame the second input, even
5673 // though part of the output depends only on the first input).
5674 //
5675 // This is particularly imprecise for vst{2,3,4}lane, since only one
5676 // lane of each input is actually copied to the output.
5677 OriginCombiner OC(this, IRB);
5678 for (int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5679 OC.Add(I.getArgOperand(i));
5680
5681 const DataLayout &DL = F.getDataLayout();
5682 OC.DoneAndStoreOrigin(DL.getTypeStoreSize(OutputVectorTy),
5683 OutputOriginPtr);
5684 }
5685 }
5686
5687 // Integer matrix multiplication:
5688 // - <4 x i32> @llvm.aarch64.neon.{s,u,us}mmla.v4i32.v16i8
5689 // (<4 x i32> %R, <16 x i8> %A, <16 x i8> %B)
5690 // - <4 x i32> is a 2x2 matrix
5691 // - <16 x i8> %A and %B are 2x8 and 8x2 matrices respectively
5692 //
5693 // Floating-point matrix multiplication:
5694 // - <4 x float> @llvm.aarch64.neon.bfmmla
5695 // (<4 x float> %R, <8 x bfloat> %A, <8 x bfloat> %B)
5696 // - <4 x float> is a 2x2 matrix
5697 // - <8 x bfloat> %A and %B are 2x4 and 4x2 matrices respectively
5698 //
5699 // The general shadow propagation approach is:
5700 // 1) get the shadows of the input matrices %A and %B
5701 // 2) map each shadow value to 0x1 if the corresponding value is fully
5702 // initialized, and 0x0 otherwise
5703 // 3) perform a matrix multiplication on the shadows of %A and %B [*].
5704 // The output will be a 2x2 matrix. For each element, a value of 0x8
5705 // (for {s,u,us}mmla) or 0x4 (for bfmmla) means all the corresponding
5706 // inputs were clean; if so, set the shadow to zero, otherwise set to -1.
5707 // 4) blend in the shadow of %R
5708 //
5709 // [*] Since shadows are integral, the obvious approach is to always apply
5710 // ummla to the shadows. Unfortunately, Armv8.2+bf16 supports bfmmla,
5711 // but not ummla. Thus, for bfmmla, our instrumentation reuses bfmmla.
5712 //
5713 // TODO: consider allowing multiplication of zero with an uninitialized value
5714 // to result in an initialized value.
5715 void handleNEONMatrixMultiply(IntrinsicInst &I) {
5716 IRBuilder<> IRB(&I);
5717
5718 assert(I.arg_size() == 3);
5719 Value *R = I.getArgOperand(0);
5720 Value *A = I.getArgOperand(1);
5721 Value *B = I.getArgOperand(2);
5722
5723 assert(I.getType() == R->getType());
5724
5725 assert(isa<FixedVectorType>(R->getType()));
5726 assert(isa<FixedVectorType>(A->getType()));
5727 assert(isa<FixedVectorType>(B->getType()));
5728
5729 FixedVectorType *RTy = cast<FixedVectorType>(R->getType());
5730 FixedVectorType *ATy = cast<FixedVectorType>(A->getType());
5731 FixedVectorType *BTy = cast<FixedVectorType>(B->getType());
5732 assert(ATy->getElementType() == BTy->getElementType());
5733
5734 if (RTy->getElementType()->isIntegerTy()) {
5735 // <4 x i32> @llvm.aarch64.neon.ummla.v4i32.v16i8
5736 // (<4 x i32> %R, <16 x i8> %X, <16 x i8> %Y)
5737 assert(RTy == FixedVectorType::get(IntegerType::get(*MS.C, 32), 4));
5738 assert(ATy == FixedVectorType::get(IntegerType::get(*MS.C, 8), 16));
5739 assert(BTy == FixedVectorType::get(IntegerType::get(*MS.C, 8), 16));
5740 } else {
5741 // <4 x float> @llvm.aarch64.neon.bfmmla
5742 // (<4 x float> %R, <8 x bfloat> %X, <8 x bfloat> %Y)
5743 assert(RTy == FixedVectorType::get(Type::getFloatTy(*MS.C), 4));
5744 assert(ATy == FixedVectorType::get(Type::getBFloatTy(*MS.C), 8));
5745 assert(BTy == FixedVectorType::get(Type::getBFloatTy(*MS.C), 8));
5746 }
5747
5748 Value *ShadowR = getShadow(&I, 0);
5749 Value *ShadowA = getShadow(&I, 1);
5750 Value *ShadowB = getShadow(&I, 2);
5751
5752 Value *ShadowAB;
5753 Value *FullyInit;
5754
5755 if (RTy->getElementType()->isIntegerTy()) {
5756 // If the value is fully initialized, the shadow will be 000...001.
5757 // Otherwise, the shadow will be all zero.
5758 // (This is the opposite of how we typically handle shadows.)
5759 ShadowA = IRB.CreateZExt(IRB.CreateICmpEQ(ShadowA, getCleanShadow(ATy)),
5760 getShadowTy(ATy));
5761 ShadowB = IRB.CreateZExt(IRB.CreateICmpEQ(ShadowB, getCleanShadow(BTy)),
5762 getShadowTy(BTy));
5763 // TODO: the CreateSelect approach used below for floating-point is more
5764 // generic than CreateZExt. Investigate whether it is worthwhile
5765 // unifying the two approaches.
5766
5767 ShadowAB = IRB.CreateIntrinsic(RTy, Intrinsic::aarch64_neon_ummla,
5768 {getCleanShadow(RTy), ShadowA, ShadowB});
5769
5770 // ummla multiplies a 2x8 matrix with an 8x2 matrix. If all entries of the
5771 // input matrices are equal to 0x1, all entries of the output matrix will
5772 // be 0x8.
5773 FullyInit = ConstantVector::getSplat(
5774 RTy->getElementCount(), ConstantInt::get(RTy->getElementType(), 0x8));
5775
5776 ShadowAB = IRB.CreateICmpNE(ShadowAB, FullyInit);
5777 } else {
5779 ATy->getElementCount(), ConstantFP::get(ATy->getElementType(), 0));
5781 ATy->getElementCount(), ConstantFP::get(ATy->getElementType(), 1));
5782
5783 // As per the integer case, if the shadow is clean, we store 0x1,
5784 // otherwise we store 0x0 (the opposite of usual shadow arithmetic).
5785 ShadowA = IRB.CreateSelect(IRB.CreateICmpEQ(ShadowA, getCleanShadow(ATy)),
5786 ABOnes, ABZeros);
5787 ShadowB = IRB.CreateSelect(IRB.CreateICmpEQ(ShadowB, getCleanShadow(BTy)),
5788 ABOnes, ABZeros);
5789
5791 RTy->getElementCount(), ConstantFP::get(RTy->getElementType(), 0));
5792
5793 ShadowAB = IRB.CreateIntrinsic(RTy, Intrinsic::aarch64_neon_bfmmla,
5794 {RZeros, ShadowA, ShadowB});
5795
5796 // bfmmla multiplies a 2x4 matrix with an 4x2 matrix. If all entries of
5797 // the input matrices are equal to 0x1, all entries of the output matrix
5798 // will be 4.0. (To avoid floating-point error, we check if each entry
5799 // < 3.5.)
5800 FullyInit = ConstantVector::getSplat(
5801 RTy->getElementCount(), ConstantFP::get(RTy->getElementType(), 3.5));
5802
5803 // FCmpULT: "yields true if either operand is a QNAN or op1 is less than"
5804 // op2"
5805 ShadowAB = IRB.CreateFCmpULT(ShadowAB, FullyInit);
5806 }
5807
5808 ShadowR = IRB.CreateICmpNE(ShadowR, getCleanShadow(RTy));
5809 ShadowR = IRB.CreateOr(ShadowAB, ShadowR);
5810
5811 setShadow(&I, IRB.CreateSExt(ShadowR, getShadowTy(RTy)));
5812
5813 setOriginForNaryOp(I);
5814 }
5815
5816 /// Handle intrinsics by applying the intrinsic to the shadows.
5817 ///
5818 /// For example, this can be applied to the Arm NEON vector table intrinsics
5819 /// (tbl{1,2,3,4}).
5820 ///
5821 /// Typically, shadowIntrinsicID will be specified by the caller to be
5822 /// I.getIntrinsicID(), but the caller can choose to replace it with another
5823 /// intrinsic of the same type.
5824 ///
5825 /// The trailing arguments are passed verbatim to the intrinsic, though any
5826 /// uninitialized trailing arguments can also taint the shadow e.g., for an
5827 /// intrinsic with one trailing verbatim argument:
5828 /// out = intrinsic(var1, var2, opType)
5829 /// we compute:
5830 /// shadow[out] =
5831 /// intrinsic(shadow[var1], shadow[var2], opType) | shadow[opType]
5832 ///
5833 /// If an intrinsic is called with floating-point arguments, we will
5834 /// typically cast the shadows to floating-point, apply the intrinsic [*],
5835 /// then cast the result back to integer/shadow.
5836 ///
5837 /// In cases where we know the intrinsic is compatible with integer
5838 /// arguments, 'forceIntegerIntrinsic' will apply the integer variant, even
5839 /// if the arguments are floating-point, thus avoiding unnecessary casts
5840 /// e.g., if I is:
5841 /// <16 x float> @llvm.x86.avx512.mask.compress
5842 /// (<16 x float>, <16 x float>, <16 x i1> %mask)
5843 /// we would prefer to compute the shadows using:
5844 /// <16 x i32> @llvm.x86.avx512.mask.compress
5845 /// (<16 x i32>, <16 x i32>, <16 x i1> %mask)
5846 ///
5847 /// [*] CAUTION: this assumes that the intrinsic will handle arbitrary
5848 /// bit-patterns (for example, if the intrinsic accepts floats
5849 /// for var1, we require that it doesn't care if inputs are
5850 /// NaNs).
5851 ///
5852 /// The origin is approximated using setOriginForNaryOp.
5853 void handleIntrinsicByApplyingToShadow(IntrinsicInst &I,
5854 Intrinsic::ID shadowIntrinsicID,
5855 unsigned int trailingVerbatimArgs,
5856 bool forceIntegerIntrinsic) {
5857 IRBuilder<> IRB(&I);
5858
5859 assert(trailingVerbatimArgs < I.arg_size());
5860
5861 SmallVector<Value *, 8> ShadowArgs;
5862 // Don't use getNumOperands() because it includes the callee
5863 for (unsigned int i = 0; i < I.arg_size() - trailingVerbatimArgs; i++) {
5864 Value *Shadow = getShadow(&I, i);
5865
5866 if (forceIntegerIntrinsic)
5867 ShadowArgs.push_back(Shadow);
5868 else
5869 ShadowArgs.push_back(
5870 IRB.CreateBitCast(Shadow, I.getArgOperand(i)->getType()));
5871 }
5872
5873 for (unsigned int i = I.arg_size() - trailingVerbatimArgs; i < I.arg_size();
5874 i++) {
5875 Value *Arg = I.getArgOperand(i);
5876 if (forceIntegerIntrinsic)
5878 ShadowArgs.push_back(Arg);
5879 }
5880
5881 Value *CombinedShadow;
5882 if (forceIntegerIntrinsic) {
5883 CombinedShadow =
5884 IRB.CreateIntrinsic(getShadowTy(&I), shadowIntrinsicID, ShadowArgs);
5885 } else {
5886 Value *CI =
5887 IRB.CreateIntrinsic(I.getType(), shadowIntrinsicID, ShadowArgs);
5888 CombinedShadow = IRB.CreateBitCast(CI, getShadowTy(&I));
5889 }
5890
5891 // Combine the computed shadow with the shadow of trailing args
5892 for (unsigned int i = I.arg_size() - trailingVerbatimArgs; i < I.arg_size();
5893 i++) {
5894 Value *Shadow =
5895 CreateShadowCast(IRB, getShadow(&I, i), CombinedShadow->getType());
5896 CombinedShadow = IRB.CreateOr(Shadow, CombinedShadow, "_msprop");
5897 }
5898
5899 setShadow(&I, CombinedShadow);
5900
5901 setOriginForNaryOp(I);
5902 }
5903
5904 // Approximation only
5905 //
5906 // e.g., <16 x i8> @llvm.aarch64.neon.pmull64(i64, i64)
5907 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &I) {
5908 assert(I.arg_size() == 2);
5909
5910 handleShadowOr(I);
5911 }
5912
5913 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &I) {
5914 switch (I.getIntrinsicID()) {
5915 case Intrinsic::uadd_with_overflow:
5916 case Intrinsic::sadd_with_overflow:
5917 case Intrinsic::usub_with_overflow:
5918 case Intrinsic::ssub_with_overflow:
5919 case Intrinsic::umul_with_overflow:
5920 case Intrinsic::smul_with_overflow:
5921 handleArithmeticWithOverflow(I);
5922 break;
5923 case Intrinsic::modf:
5924 case Intrinsic::sincos:
5925 case Intrinsic::sincospi:
5926 handleModfOrSincos(I);
5927 break;
5928 case Intrinsic::abs:
5929 handleAbsIntrinsic(I);
5930 break;
5931 case Intrinsic::bitreverse:
5932 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
5933 /*trailingVerbatimArgs=*/0,
5934 /*forceIntegerIntrinsic=*/false);
5935 break;
5936 case Intrinsic::is_fpclass:
5937 handleIsFpClass(I);
5938 break;
5939 case Intrinsic::lifetime_start:
5940 handleLifetimeStart(I);
5941 break;
5942 case Intrinsic::launder_invariant_group:
5943 handleInvariantGroup(I);
5944 break;
5945 case Intrinsic::bswap:
5946 handleBswap(I);
5947 break;
5948 case Intrinsic::ctlz:
5949 case Intrinsic::cttz:
5950 handleCountLeadingTrailingZeros(I);
5951 break;
5952 case Intrinsic::masked_compressstore:
5953 handleMaskedCompressStore(I);
5954 break;
5955 case Intrinsic::masked_expandload:
5956 handleMaskedExpandLoad(I);
5957 break;
5958 case Intrinsic::masked_gather:
5959 handleMaskedGather(I);
5960 break;
5961 case Intrinsic::masked_scatter:
5962 handleMaskedScatter(I);
5963 break;
5964 case Intrinsic::masked_store:
5965 handleMaskedStore(I);
5966 break;
5967 case Intrinsic::masked_load:
5968 handleMaskedLoad(I);
5969 break;
5970 case Intrinsic::masked_udiv:
5971 case Intrinsic::masked_sdiv:
5972 case Intrinsic::masked_urem:
5973 case Intrinsic::masked_srem:
5974 handleMaskedIntegerDivRem(I);
5975 break;
5976 case Intrinsic::vector_reduce_and:
5977 handleVectorReduceAndIntrinsic(I);
5978 break;
5979 case Intrinsic::vector_reduce_or:
5980 handleVectorReduceOrIntrinsic(I);
5981 break;
5982
5983 case Intrinsic::vector_reduce_add:
5984 case Intrinsic::vector_reduce_xor:
5985 case Intrinsic::vector_reduce_mul:
5986 // Signed/Unsigned Min/Max
5987 // TODO: handling similarly to AND/OR may be more precise.
5988 case Intrinsic::vector_reduce_smax:
5989 case Intrinsic::vector_reduce_smin:
5990 case Intrinsic::vector_reduce_umax:
5991 case Intrinsic::vector_reduce_umin:
5992 // TODO: this has no false positives, but arguably we should check that all
5993 // the bits are initialized.
5994 case Intrinsic::vector_reduce_fmax:
5995 case Intrinsic::vector_reduce_fmin:
5996 handleVectorReduceIntrinsic(I, /*AllowShadowCast=*/false);
5997 break;
5998
5999 case Intrinsic::vector_reduce_fadd:
6000 case Intrinsic::vector_reduce_fmul:
6001 handleVectorReduceWithStarterIntrinsic(I);
6002 break;
6003
6004 case Intrinsic::scmp:
6005 case Intrinsic::ucmp: {
6006 handleShadowOr(I);
6007 break;
6008 }
6009
6010 case Intrinsic::fshl:
6011 case Intrinsic::fshr:
6012 handleFunnelShift(I);
6013 break;
6014
6015 case Intrinsic::pdep:
6016 case Intrinsic::pext:
6017 handleGenericBitManipulation(I);
6018 break;
6019
6020 case Intrinsic::is_constant:
6021 // The result of llvm.is.constant() is always defined.
6022 setShadow(&I, getCleanShadow(&I));
6023 setOrigin(&I, getCleanOrigin());
6024 break;
6025
6026 // The non-saturating versions are handled by visitFPTo[US]IInst().
6027 //
6028 // N.B. some platform-specific intrinsics, such as AArch64 fcvtz[us], are
6029 // lowered to these cross-platform intrinsics.
6030 case Intrinsic::fptosi_sat:
6031 case Intrinsic::fptoui_sat:
6032 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
6033 break;
6034
6035 default:
6036 return false;
6037 }
6038
6039 return true;
6040 }
6041
6042 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &I) {
6043 switch (I.getIntrinsicID()) {
6044 case Intrinsic::x86_sse_stmxcsr:
6045 handleStmxcsr(I);
6046 break;
6047 case Intrinsic::x86_sse_ldmxcsr:
6048 handleLdmxcsr(I);
6049 break;
6050
6051 // Convert Scalar Double Precision Floating-Point Value
6052 // to Unsigned Doubleword Integer
6053 // etc.
6054 case Intrinsic::x86_avx512_vcvtsd2usi64:
6055 case Intrinsic::x86_avx512_vcvtsd2usi32:
6056 case Intrinsic::x86_avx512_vcvtss2usi64:
6057 case Intrinsic::x86_avx512_vcvtss2usi32:
6058 case Intrinsic::x86_avx512_cvttss2usi64:
6059 case Intrinsic::x86_avx512_cvttss2usi:
6060 case Intrinsic::x86_avx512_cvttsd2usi64:
6061 case Intrinsic::x86_avx512_cvttsd2usi:
6062 case Intrinsic::x86_avx512_cvtusi2ss:
6063 case Intrinsic::x86_avx512_cvtusi642sd:
6064 case Intrinsic::x86_avx512_cvtusi642ss:
6065 handleSSEVectorConvertIntrinsic(I, 1, true);
6066 break;
6067 case Intrinsic::x86_sse2_cvtsd2si64:
6068 case Intrinsic::x86_sse2_cvtsd2si:
6069 case Intrinsic::x86_sse2_cvtsd2ss:
6070 case Intrinsic::x86_sse2_cvttsd2si64:
6071 case Intrinsic::x86_sse2_cvttsd2si:
6072 case Intrinsic::x86_sse_cvtss2si64:
6073 case Intrinsic::x86_sse_cvtss2si:
6074 case Intrinsic::x86_sse_cvttss2si64:
6075 case Intrinsic::x86_sse_cvttss2si:
6076 handleSSEVectorConvertIntrinsic(I, 1);
6077 break;
6078 case Intrinsic::x86_sse_cvtps2pi:
6079 case Intrinsic::x86_sse_cvttps2pi:
6080 handleSSEVectorConvertIntrinsic(I, 2);
6081 break;
6082
6083 // TODO:
6084 // <1 x i64> @llvm.x86.sse.cvtpd2pi(<2 x double>)
6085 // <2 x double> @llvm.x86.sse.cvtpi2pd(<1 x i64>)
6086 // <4 x float> @llvm.x86.sse.cvtpi2ps(<4 x float>, <1 x i64>)
6087
6088 case Intrinsic::x86_vcvtps2ph_128:
6089 case Intrinsic::x86_vcvtps2ph_256: {
6090 handleSSEVectorConvertIntrinsicByProp(I, /*HasRoundingMode=*/true);
6091 break;
6092 }
6093
6094 // Convert Packed Single Precision Floating-Point Values
6095 // to Packed Signed Doubleword Integer Values
6096 //
6097 // <16 x i32> @llvm.x86.avx512.mask.cvtps2dq.512
6098 // (<16 x float>, <16 x i32>, i16, i32)
6099 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6100 handleAVX512VectorConvertFPToInt(I, /*LastMask=*/false);
6101 break;
6102
6103 // Convert Packed Double Precision Floating-Point Values
6104 // to Packed Single Precision Floating-Point Values
6105 case Intrinsic::x86_sse2_cvtpd2ps:
6106 case Intrinsic::x86_sse2_cvtps2dq:
6107 case Intrinsic::x86_sse2_cvtpd2dq:
6108 case Intrinsic::x86_sse2_cvttps2dq:
6109 case Intrinsic::x86_sse2_cvttpd2dq:
6110 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6111 case Intrinsic::x86_avx_cvt_ps2dq_256:
6112 case Intrinsic::x86_avx_cvt_pd2dq_256:
6113 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6114 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6115 handleSSEVectorConvertIntrinsicByProp(I, /*HasRoundingMode=*/false);
6116 break;
6117 }
6118
6119 // Convert Single-Precision FP Value to 16-bit FP Value
6120 // <16 x i16> @llvm.x86.avx512.mask.vcvtps2ph.512
6121 // (<16 x float>, i32, <16 x i16>, i16)
6122 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.128
6123 // (<4 x float>, i32, <8 x i16>, i8)
6124 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.256
6125 // (<8 x float>, i32, <8 x i16>, i8)
6126 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6127 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6128 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6129 handleAVX512VectorConvertFPToInt(I, /*LastMask=*/true);
6130 break;
6131
6132 // Shift Packed Data (Left Logical, Right Arithmetic, Right Logical)
6133 case Intrinsic::x86_avx512_psll_w_512:
6134 case Intrinsic::x86_avx512_psll_d_512:
6135 case Intrinsic::x86_avx512_psll_q_512:
6136 case Intrinsic::x86_avx512_pslli_w_512:
6137 case Intrinsic::x86_avx512_pslli_d_512:
6138 case Intrinsic::x86_avx512_pslli_q_512:
6139 case Intrinsic::x86_avx512_psrl_w_512:
6140 case Intrinsic::x86_avx512_psrl_d_512:
6141 case Intrinsic::x86_avx512_psrl_q_512:
6142 case Intrinsic::x86_avx512_psra_w_512:
6143 case Intrinsic::x86_avx512_psra_d_512:
6144 case Intrinsic::x86_avx512_psra_q_512:
6145 case Intrinsic::x86_avx512_psrli_w_512:
6146 case Intrinsic::x86_avx512_psrli_d_512:
6147 case Intrinsic::x86_avx512_psrli_q_512:
6148 case Intrinsic::x86_avx512_psrai_w_512:
6149 case Intrinsic::x86_avx512_psrai_d_512:
6150 case Intrinsic::x86_avx512_psrai_q_512:
6151 case Intrinsic::x86_avx512_psra_q_256:
6152 case Intrinsic::x86_avx512_psra_q_128:
6153 case Intrinsic::x86_avx512_psrai_q_256:
6154 case Intrinsic::x86_avx512_psrai_q_128:
6155 case Intrinsic::x86_avx2_psll_w:
6156 case Intrinsic::x86_avx2_psll_d:
6157 case Intrinsic::x86_avx2_psll_q:
6158 case Intrinsic::x86_avx2_pslli_w:
6159 case Intrinsic::x86_avx2_pslli_d:
6160 case Intrinsic::x86_avx2_pslli_q:
6161 case Intrinsic::x86_avx2_psrl_w:
6162 case Intrinsic::x86_avx2_psrl_d:
6163 case Intrinsic::x86_avx2_psrl_q:
6164 case Intrinsic::x86_avx2_psra_w:
6165 case Intrinsic::x86_avx2_psra_d:
6166 case Intrinsic::x86_avx2_psrli_w:
6167 case Intrinsic::x86_avx2_psrli_d:
6168 case Intrinsic::x86_avx2_psrli_q:
6169 case Intrinsic::x86_avx2_psrai_w:
6170 case Intrinsic::x86_avx2_psrai_d:
6171 case Intrinsic::x86_sse2_psll_w:
6172 case Intrinsic::x86_sse2_psll_d:
6173 case Intrinsic::x86_sse2_psll_q:
6174 case Intrinsic::x86_sse2_pslli_w:
6175 case Intrinsic::x86_sse2_pslli_d:
6176 case Intrinsic::x86_sse2_pslli_q:
6177 case Intrinsic::x86_sse2_psrl_w:
6178 case Intrinsic::x86_sse2_psrl_d:
6179 case Intrinsic::x86_sse2_psrl_q:
6180 case Intrinsic::x86_sse2_psra_w:
6181 case Intrinsic::x86_sse2_psra_d:
6182 case Intrinsic::x86_sse2_psrli_w:
6183 case Intrinsic::x86_sse2_psrli_d:
6184 case Intrinsic::x86_sse2_psrli_q:
6185 case Intrinsic::x86_sse2_psrai_w:
6186 case Intrinsic::x86_sse2_psrai_d:
6187 case Intrinsic::x86_mmx_psll_w:
6188 case Intrinsic::x86_mmx_psll_d:
6189 case Intrinsic::x86_mmx_psll_q:
6190 case Intrinsic::x86_mmx_pslli_w:
6191 case Intrinsic::x86_mmx_pslli_d:
6192 case Intrinsic::x86_mmx_pslli_q:
6193 case Intrinsic::x86_mmx_psrl_w:
6194 case Intrinsic::x86_mmx_psrl_d:
6195 case Intrinsic::x86_mmx_psrl_q:
6196 case Intrinsic::x86_mmx_psra_w:
6197 case Intrinsic::x86_mmx_psra_d:
6198 case Intrinsic::x86_mmx_psrli_w:
6199 case Intrinsic::x86_mmx_psrli_d:
6200 case Intrinsic::x86_mmx_psrli_q:
6201 case Intrinsic::x86_mmx_psrai_w:
6202 case Intrinsic::x86_mmx_psrai_d:
6203 handleVectorShiftIntrinsic(I, /* Variable */ false);
6204 break;
6205 case Intrinsic::x86_avx2_psllv_d:
6206 case Intrinsic::x86_avx2_psllv_d_256:
6207 case Intrinsic::x86_avx512_psllv_d_512:
6208 case Intrinsic::x86_avx2_psllv_q:
6209 case Intrinsic::x86_avx2_psllv_q_256:
6210 case Intrinsic::x86_avx512_psllv_q_512:
6211 case Intrinsic::x86_avx2_psrlv_d:
6212 case Intrinsic::x86_avx2_psrlv_d_256:
6213 case Intrinsic::x86_avx512_psrlv_d_512:
6214 case Intrinsic::x86_avx2_psrlv_q:
6215 case Intrinsic::x86_avx2_psrlv_q_256:
6216 case Intrinsic::x86_avx512_psrlv_q_512:
6217 case Intrinsic::x86_avx2_psrav_d:
6218 case Intrinsic::x86_avx2_psrav_d_256:
6219 case Intrinsic::x86_avx512_psrav_d_512:
6220 case Intrinsic::x86_avx512_psrav_q_128:
6221 case Intrinsic::x86_avx512_psrav_q_256:
6222 case Intrinsic::x86_avx512_psrav_q_512:
6223 handleVectorShiftIntrinsic(I, /* Variable */ true);
6224 break;
6225
6226 // Pack with Signed/Unsigned Saturation
6227 case Intrinsic::x86_sse2_packsswb_128:
6228 case Intrinsic::x86_sse2_packssdw_128:
6229 case Intrinsic::x86_sse2_packuswb_128:
6230 case Intrinsic::x86_sse41_packusdw:
6231 case Intrinsic::x86_avx2_packsswb:
6232 case Intrinsic::x86_avx2_packssdw:
6233 case Intrinsic::x86_avx2_packuswb:
6234 case Intrinsic::x86_avx2_packusdw:
6235 // e.g., <64 x i8> @llvm.x86.avx512.packsswb.512
6236 // (<32 x i16> %a, <32 x i16> %b)
6237 // <32 x i16> @llvm.x86.avx512.packssdw.512
6238 // (<16 x i32> %a, <16 x i32> %b)
6239 // Note: AVX512 masked variants are auto-upgraded by LLVM.
6240 case Intrinsic::x86_avx512_packsswb_512:
6241 case Intrinsic::x86_avx512_packssdw_512:
6242 case Intrinsic::x86_avx512_packuswb_512:
6243 case Intrinsic::x86_avx512_packusdw_512:
6244 handleVectorPackIntrinsic(I);
6245 break;
6246
6247 case Intrinsic::x86_sse41_pblendvb:
6248 case Intrinsic::x86_sse41_blendvpd:
6249 case Intrinsic::x86_sse41_blendvps:
6250 case Intrinsic::x86_avx_blendv_pd_256:
6251 case Intrinsic::x86_avx_blendv_ps_256:
6252 case Intrinsic::x86_avx2_pblendvb:
6253 handleBlendvIntrinsic(I);
6254 break;
6255
6256 case Intrinsic::x86_avx_dp_ps_256:
6257 case Intrinsic::x86_sse41_dppd:
6258 case Intrinsic::x86_sse41_dpps:
6259 handleDppIntrinsic(I);
6260 break;
6261
6262 case Intrinsic::x86_mmx_packsswb:
6263 case Intrinsic::x86_mmx_packuswb:
6264 handleVectorPackIntrinsic(I, 16);
6265 break;
6266
6267 case Intrinsic::x86_mmx_packssdw:
6268 handleVectorPackIntrinsic(I, 32);
6269 break;
6270
6271 case Intrinsic::x86_mmx_psad_bw:
6272 handleVectorSadIntrinsic(I, true);
6273 break;
6274 case Intrinsic::x86_sse2_psad_bw:
6275 case Intrinsic::x86_avx2_psad_bw:
6276 handleVectorSadIntrinsic(I);
6277 break;
6278
6279 // Multiply and Add Packed Words
6280 // < 4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16>, <8 x i16>)
6281 // < 8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16>, <16 x i16>)
6282 // <16 x i32> @llvm.x86.avx512.pmaddw.d.512(<32 x i16>, <32 x i16>)
6283 //
6284 // Multiply and Add Packed Signed and Unsigned Bytes
6285 // < 8 x i16> @llvm.x86.ssse3.pmadd.ub.sw.128(<16 x i8>, <16 x i8>)
6286 // <16 x i16> @llvm.x86.avx2.pmadd.ub.sw(<32 x i8>, <32 x i8>)
6287 // <32 x i16> @llvm.x86.avx512.pmaddubs.w.512(<64 x i8>, <64 x i8>)
6288 //
6289 // These intrinsics are auto-upgraded into non-masked forms:
6290 // < 4 x i32> @llvm.x86.avx512.mask.pmaddw.d.128
6291 // (<8 x i16>, <8 x i16>, <4 x i32>, i8)
6292 // < 8 x i32> @llvm.x86.avx512.mask.pmaddw.d.256
6293 // (<16 x i16>, <16 x i16>, <8 x i32>, i8)
6294 // <16 x i32> @llvm.x86.avx512.mask.pmaddw.d.512
6295 // (<32 x i16>, <32 x i16>, <16 x i32>, i16)
6296 // < 8 x i16> @llvm.x86.avx512.mask.pmaddubs.w.128
6297 // (<16 x i8>, <16 x i8>, <8 x i16>, i8)
6298 // <16 x i16> @llvm.x86.avx512.mask.pmaddubs.w.256
6299 // (<32 x i8>, <32 x i8>, <16 x i16>, i16)
6300 // <32 x i16> @llvm.x86.avx512.mask.pmaddubs.w.512
6301 // (<64 x i8>, <64 x i8>, <32 x i16>, i32)
6302 case Intrinsic::x86_sse2_pmadd_wd:
6303 case Intrinsic::x86_avx2_pmadd_wd:
6304 case Intrinsic::x86_avx512_pmaddw_d_512:
6305 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6306 case Intrinsic::x86_avx2_pmadd_ub_sw:
6307 case Intrinsic::x86_avx512_pmaddubs_w_512:
6308 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6309 /*ZeroPurifies=*/true,
6310 /*EltSizeInBits=*/0,
6311 /*Lanes=*/kBothLanes);
6312 break;
6313
6314 // <1 x i64> @llvm.x86.ssse3.pmadd.ub.sw(<1 x i64>, <1 x i64>)
6315 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6316 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6317 /*ZeroPurifies=*/true,
6318 /*EltSizeInBits=*/8,
6319 /*Lanes=*/kBothLanes);
6320 break;
6321
6322 // <1 x i64> @llvm.x86.mmx.pmadd.wd(<1 x i64>, <1 x i64>)
6323 case Intrinsic::x86_mmx_pmadd_wd:
6324 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6325 /*ZeroPurifies=*/true,
6326 /*EltSizeInBits=*/16,
6327 /*Lanes=*/kBothLanes);
6328 break;
6329
6330 // BFloat16 multiply-add to single-precision
6331 // <4 x float> llvm.aarch64.neon.bfmlalt
6332 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6333 case Intrinsic::aarch64_neon_bfmlalt:
6334 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6335 /*ZeroPurifies=*/false,
6336 /*EltSizeInBits=*/0,
6337 /*Lanes=*/kOddLanes);
6338 break;
6339
6340 // <4 x float> llvm.aarch64.neon.bfmlalb
6341 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6342 case Intrinsic::aarch64_neon_bfmlalb:
6343 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6344 /*ZeroPurifies=*/false,
6345 /*EltSizeInBits=*/0,
6346 /*Lanes=*/kEvenLanes);
6347 break;
6348
6349 // AVX Vector Neural Network Instructions: bytes
6350 //
6351 // Multiply and Add Signed Bytes
6352 // < 4 x i32> @llvm.x86.avx2.vpdpbssd.128
6353 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6354 // < 8 x i32> @llvm.x86.avx2.vpdpbssd.256
6355 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6356 // <16 x i32> @llvm.x86.avx10.vpdpbssd.512
6357 // (<16 x i32>, <64 x i8>, <64 x i8>)
6358 //
6359 // Multiply and Add Signed Bytes With Saturation
6360 // < 4 x i32> @llvm.x86.avx2.vpdpbssds.128
6361 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6362 // < 8 x i32> @llvm.x86.avx2.vpdpbssds.256
6363 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6364 // <16 x i32> @llvm.x86.avx10.vpdpbssds.512
6365 // (<16 x i32>, <64 x i8>, <64 x i8>)
6366 //
6367 // Multiply and Add Signed and Unsigned Bytes
6368 // < 4 x i32> @llvm.x86.avx2.vpdpbsud.128
6369 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6370 // < 8 x i32> @llvm.x86.avx2.vpdpbsud.256
6371 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6372 // <16 x i32> @llvm.x86.avx10.vpdpbsud.512
6373 // (<16 x i32>, <64 x i8>, <64 x i8>)
6374 //
6375 // Multiply and Add Signed and Unsigned Bytes With Saturation
6376 // < 4 x i32> @llvm.x86.avx2.vpdpbsuds.128
6377 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6378 // < 8 x i32> @llvm.x86.avx2.vpdpbsuds.256
6379 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6380 // <16 x i32> @llvm.x86.avx512.vpdpbusds.512
6381 // (<16 x i32>, <64 x i8>, <64 x i8>)
6382 //
6383 // Multiply and Add Unsigned and Signed Bytes
6384 // < 4 x i32> @llvm.x86.avx512.vpdpbusd.128
6385 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6386 // < 8 x i32> @llvm.x86.avx512.vpdpbusd.256
6387 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6388 // <16 x i32> @llvm.x86.avx512.vpdpbusd.512
6389 // (<16 x i32>, <64 x i8>, <64 x i8>)
6390 //
6391 // Multiply and Add Unsigned and Signed Bytes With Saturation
6392 // < 4 x i32> @llvm.x86.avx512.vpdpbusds.128
6393 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6394 // < 8 x i32> @llvm.x86.avx512.vpdpbusds.256
6395 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6396 // <16 x i32> @llvm.x86.avx10.vpdpbsuds.512
6397 // (<16 x i32>, <64 x i8>, <64 x i8>)
6398 //
6399 // Multiply and Add Unsigned Bytes
6400 // < 4 x i32> @llvm.x86.avx2.vpdpbuud.128
6401 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6402 // < 8 x i32> @llvm.x86.avx2.vpdpbuud.256
6403 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6404 // <16 x i32> @llvm.x86.avx10.vpdpbuud.512
6405 // (<16 x i32>, <64 x i8>, <64 x i8>)
6406 //
6407 // Multiply and Add Unsigned Bytes With Saturation
6408 // < 4 x i32> @llvm.x86.avx2.vpdpbuuds.128
6409 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6410 // < 8 x i32> @llvm.x86.avx2.vpdpbuuds.256
6411 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6412 // <16 x i32> @llvm.x86.avx10.vpdpbuuds.512
6413 // (<16 x i32>, <64 x i8>, <64 x i8>)
6414 //
6415 // These intrinsics are auto-upgraded into non-masked forms:
6416 // <4 x i32> @llvm.x86.avx512.mask.vpdpbusd.128
6417 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6418 // <4 x i32> @llvm.x86.avx512.maskz.vpdpbusd.128
6419 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6420 // <8 x i32> @llvm.x86.avx512.mask.vpdpbusd.256
6421 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6422 // <8 x i32> @llvm.x86.avx512.maskz.vpdpbusd.256
6423 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6424 // <16 x i32> @llvm.x86.avx512.mask.vpdpbusd.512
6425 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6426 // <16 x i32> @llvm.x86.avx512.maskz.vpdpbusd.512
6427 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6428 //
6429 // <4 x i32> @llvm.x86.avx512.mask.vpdpbusds.128
6430 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6431 // <4 x i32> @llvm.x86.avx512.maskz.vpdpbusds.128
6432 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6433 // <8 x i32> @llvm.x86.avx512.mask.vpdpbusds.256
6434 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6435 // <8 x i32> @llvm.x86.avx512.maskz.vpdpbusds.256
6436 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6437 // <16 x i32> @llvm.x86.avx512.mask.vpdpbusds.512
6438 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6439 // <16 x i32> @llvm.x86.avx512.maskz.vpdpbusds.512
6440 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6441 case Intrinsic::x86_avx512_vpdpbusd_128:
6442 case Intrinsic::x86_avx512_vpdpbusd_256:
6443 case Intrinsic::x86_avx512_vpdpbusd_512:
6444 case Intrinsic::x86_avx512_vpdpbusds_128:
6445 case Intrinsic::x86_avx512_vpdpbusds_256:
6446 case Intrinsic::x86_avx512_vpdpbusds_512:
6447 case Intrinsic::x86_avx2_vpdpbssd_128:
6448 case Intrinsic::x86_avx2_vpdpbssd_256:
6449 case Intrinsic::x86_avx10_vpdpbssd_512:
6450 case Intrinsic::x86_avx2_vpdpbssds_128:
6451 case Intrinsic::x86_avx2_vpdpbssds_256:
6452 case Intrinsic::x86_avx10_vpdpbssds_512:
6453 case Intrinsic::x86_avx2_vpdpbsud_128:
6454 case Intrinsic::x86_avx2_vpdpbsud_256:
6455 case Intrinsic::x86_avx10_vpdpbsud_512:
6456 case Intrinsic::x86_avx2_vpdpbsuds_128:
6457 case Intrinsic::x86_avx2_vpdpbsuds_256:
6458 case Intrinsic::x86_avx10_vpdpbsuds_512:
6459 case Intrinsic::x86_avx2_vpdpbuud_128:
6460 case Intrinsic::x86_avx2_vpdpbuud_256:
6461 case Intrinsic::x86_avx10_vpdpbuud_512:
6462 case Intrinsic::x86_avx2_vpdpbuuds_128:
6463 case Intrinsic::x86_avx2_vpdpbuuds_256:
6464 case Intrinsic::x86_avx10_vpdpbuuds_512:
6465 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
6466 /*ZeroPurifies=*/true,
6467 /*EltSizeInBits=*/0,
6468 /*Lanes=*/kBothLanes);
6469 break;
6470
6471 // AVX Vector Neural Network Instructions: words
6472 //
6473 // Multiply and Add Signed Word Integers
6474 // < 4 x i32> @llvm.x86.avx512.vpdpwssd.128
6475 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6476 // < 8 x i32> @llvm.x86.avx512.vpdpwssd.256
6477 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6478 // <16 x i32> @llvm.x86.avx512.vpdpwssd.512
6479 // (<16 x i32>, <32 x i16>, <32 x i16>)
6480 //
6481 // Multiply and Add Signed Word Integers With Saturation
6482 // < 4 x i32> @llvm.x86.avx512.vpdpwssds.128
6483 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6484 // < 8 x i32> @llvm.x86.avx512.vpdpwssds.256
6485 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6486 // <16 x i32> @llvm.x86.avx512.vpdpwssds.512
6487 // (<16 x i32>, <32 x i16>, <32 x i16>)
6488 //
6489 // Multiply and Add Signed and Unsigned Word Integers
6490 // < 4 x i32> @llvm.x86.avx2.vpdpwsud.128
6491 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6492 // < 8 x i32> @llvm.x86.avx2.vpdpwsud.256
6493 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6494 // <16 x i32> @llvm.x86.avx10.vpdpwsud.512
6495 // (<16 x i32>, <32 x i16>, <32 x i16>)
6496 //
6497 // Multiply and Add Signed and Unsigned Word Integers With Saturation
6498 // < 4 x i32> @llvm.x86.avx2.vpdpwsuds.128
6499 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6500 // < 8 x i32> @llvm.x86.avx2.vpdpwsuds.256
6501 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6502 // <16 x i32> @llvm.x86.avx10.vpdpwsuds.512
6503 // (<16 x i32>, <32 x i16>, <32 x i16>)
6504 //
6505 // Multiply and Add Unsigned and Signed Word Integers
6506 // < 4 x i32> @llvm.x86.avx2.vpdpwusd.128
6507 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6508 // < 8 x i32> @llvm.x86.avx2.vpdpwusd.256
6509 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6510 // <16 x i32> @llvm.x86.avx10.vpdpwusd.512
6511 // (<16 x i32>, <32 x i16>, <32 x i16>)
6512 //
6513 // Multiply and Add Unsigned and Signed Word Integers With Saturation
6514 // < 4 x i32> @llvm.x86.avx2.vpdpwusds.128
6515 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6516 // < 8 x i32> @llvm.x86.avx2.vpdpwusds.256
6517 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6518 // <16 x i32> @llvm.x86.avx10.vpdpwusds.512
6519 // (<16 x i32>, <32 x i16>, <32 x i16>)
6520 //
6521 // Multiply and Add Unsigned and Unsigned Word Integers
6522 // < 4 x i32> @llvm.x86.avx2.vpdpwuud.128
6523 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6524 // < 8 x i32> @llvm.x86.avx2.vpdpwuud.256
6525 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6526 // <16 x i32> @llvm.x86.avx10.vpdpwuud.512
6527 // (<16 x i32>, <32 x i16>, <32 x i16>)
6528 //
6529 // Multiply and Add Unsigned and Unsigned Word Integers With Saturation
6530 // < 4 x i32> @llvm.x86.avx2.vpdpwuuds.128
6531 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6532 // < 8 x i32> @llvm.x86.avx2.vpdpwuuds.256
6533 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6534 // <16 x i32> @llvm.x86.avx10.vpdpwuuds.512
6535 // (<16 x i32>, <32 x i16>, <32 x i16>)
6536 //
6537 // These intrinsics are auto-upgraded into non-masked forms:
6538 // <4 x i32> @llvm.x86.avx512.mask.vpdpwssd.128
6539 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6540 // <4 x i32> @llvm.x86.avx512.maskz.vpdpwssd.128
6541 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6542 // <8 x i32> @llvm.x86.avx512.mask.vpdpwssd.256
6543 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6544 // <8 x i32> @llvm.x86.avx512.maskz.vpdpwssd.256
6545 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6546 // <16 x i32> @llvm.x86.avx512.mask.vpdpwssd.512
6547 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6548 // <16 x i32> @llvm.x86.avx512.maskz.vpdpwssd.512
6549 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6550 //
6551 // <4 x i32> @llvm.x86.avx512.mask.vpdpwssds.128
6552 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6553 // <4 x i32> @llvm.x86.avx512.maskz.vpdpwssds.128
6554 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6555 // <8 x i32> @llvm.x86.avx512.mask.vpdpwssds.256
6556 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6557 // <8 x i32> @llvm.x86.avx512.maskz.vpdpwssds.256
6558 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6559 // <16 x i32> @llvm.x86.avx512.mask.vpdpwssds.512
6560 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6561 // <16 x i32> @llvm.x86.avx512.maskz.vpdpwssds.512
6562 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6563 case Intrinsic::x86_avx512_vpdpwssd_128:
6564 case Intrinsic::x86_avx512_vpdpwssd_256:
6565 case Intrinsic::x86_avx512_vpdpwssd_512:
6566 case Intrinsic::x86_avx512_vpdpwssds_128:
6567 case Intrinsic::x86_avx512_vpdpwssds_256:
6568 case Intrinsic::x86_avx512_vpdpwssds_512:
6569 case Intrinsic::x86_avx2_vpdpwsud_128:
6570 case Intrinsic::x86_avx2_vpdpwsud_256:
6571 case Intrinsic::x86_avx10_vpdpwsud_512:
6572 case Intrinsic::x86_avx2_vpdpwsuds_128:
6573 case Intrinsic::x86_avx2_vpdpwsuds_256:
6574 case Intrinsic::x86_avx10_vpdpwsuds_512:
6575 case Intrinsic::x86_avx2_vpdpwusd_128:
6576 case Intrinsic::x86_avx2_vpdpwusd_256:
6577 case Intrinsic::x86_avx10_vpdpwusd_512:
6578 case Intrinsic::x86_avx2_vpdpwusds_128:
6579 case Intrinsic::x86_avx2_vpdpwusds_256:
6580 case Intrinsic::x86_avx10_vpdpwusds_512:
6581 case Intrinsic::x86_avx2_vpdpwuud_128:
6582 case Intrinsic::x86_avx2_vpdpwuud_256:
6583 case Intrinsic::x86_avx10_vpdpwuud_512:
6584 case Intrinsic::x86_avx2_vpdpwuuds_128:
6585 case Intrinsic::x86_avx2_vpdpwuuds_256:
6586 case Intrinsic::x86_avx10_vpdpwuuds_512:
6587 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6588 /*ZeroPurifies=*/true,
6589 /*EltSizeInBits=*/0,
6590 /*Lanes=*/kBothLanes);
6591 break;
6592
6593 // Dot Product of BF16 Pairs Accumulated Into Packed Single
6594 // Precision
6595 // <4 x float> @llvm.x86.avx512bf16.dpbf16ps.128
6596 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6597 // <8 x float> @llvm.x86.avx512bf16.dpbf16ps.256
6598 // (<8 x float>, <16 x bfloat>, <16 x bfloat>)
6599 // <16 x float> @llvm.x86.avx512bf16.dpbf16ps.512
6600 // (<16 x float>, <32 x bfloat>, <32 x bfloat>)
6601 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6602 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6603 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6604 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6605 /*ZeroPurifies=*/false,
6606 /*EltSizeInBits=*/0,
6607 /*Lanes=*/kBothLanes);
6608 break;
6609
6610 case Intrinsic::x86_sse_cmp_ss:
6611 case Intrinsic::x86_sse2_cmp_sd:
6612 case Intrinsic::x86_sse_comieq_ss:
6613 case Intrinsic::x86_sse_comilt_ss:
6614 case Intrinsic::x86_sse_comile_ss:
6615 case Intrinsic::x86_sse_comigt_ss:
6616 case Intrinsic::x86_sse_comige_ss:
6617 case Intrinsic::x86_sse_comineq_ss:
6618 case Intrinsic::x86_sse_ucomieq_ss:
6619 case Intrinsic::x86_sse_ucomilt_ss:
6620 case Intrinsic::x86_sse_ucomile_ss:
6621 case Intrinsic::x86_sse_ucomigt_ss:
6622 case Intrinsic::x86_sse_ucomige_ss:
6623 case Intrinsic::x86_sse_ucomineq_ss:
6624 case Intrinsic::x86_sse2_comieq_sd:
6625 case Intrinsic::x86_sse2_comilt_sd:
6626 case Intrinsic::x86_sse2_comile_sd:
6627 case Intrinsic::x86_sse2_comigt_sd:
6628 case Intrinsic::x86_sse2_comige_sd:
6629 case Intrinsic::x86_sse2_comineq_sd:
6630 case Intrinsic::x86_sse2_ucomieq_sd:
6631 case Intrinsic::x86_sse2_ucomilt_sd:
6632 case Intrinsic::x86_sse2_ucomile_sd:
6633 case Intrinsic::x86_sse2_ucomigt_sd:
6634 case Intrinsic::x86_sse2_ucomige_sd:
6635 case Intrinsic::x86_sse2_ucomineq_sd:
6636 handleVectorCompareScalarIntrinsic(I);
6637 break;
6638
6639 case Intrinsic::x86_avx_cmp_pd_256:
6640 case Intrinsic::x86_avx_cmp_ps_256:
6641 case Intrinsic::x86_sse2_cmp_pd:
6642 case Intrinsic::x86_sse_cmp_ps:
6643 handleVectorComparePackedIntrinsic(I, /*PredicateAsOperand=*/true);
6644 break;
6645
6646 case Intrinsic::x86_bmi_bextr_32:
6647 case Intrinsic::x86_bmi_bextr_64:
6648 case Intrinsic::x86_bmi_bzhi_32:
6649 case Intrinsic::x86_bmi_bzhi_64:
6650 handleGenericBitManipulation(I);
6651 break;
6652
6653 case Intrinsic::x86_pclmulqdq:
6654 case Intrinsic::x86_pclmulqdq_256:
6655 case Intrinsic::x86_pclmulqdq_512:
6656 handlePclmulIntrinsic(I);
6657 break;
6658
6659 case Intrinsic::x86_avx_round_pd_256:
6660 case Intrinsic::x86_avx_round_ps_256:
6661 case Intrinsic::x86_sse41_round_pd:
6662 case Intrinsic::x86_sse41_round_ps:
6663 handleRoundPdPsIntrinsic(I);
6664 break;
6665
6666 case Intrinsic::x86_sse41_round_sd:
6667 case Intrinsic::x86_sse41_round_ss:
6668 handleUnarySdSsIntrinsic(I);
6669 break;
6670
6671 case Intrinsic::x86_sse2_max_sd:
6672 case Intrinsic::x86_sse_max_ss:
6673 case Intrinsic::x86_sse2_min_sd:
6674 case Intrinsic::x86_sse_min_ss:
6675 handleBinarySdSsIntrinsic(I);
6676 break;
6677
6678 case Intrinsic::x86_avx_vtestc_pd:
6679 case Intrinsic::x86_avx_vtestc_pd_256:
6680 case Intrinsic::x86_avx_vtestc_ps:
6681 case Intrinsic::x86_avx_vtestc_ps_256:
6682 case Intrinsic::x86_avx_vtestnzc_pd:
6683 case Intrinsic::x86_avx_vtestnzc_pd_256:
6684 case Intrinsic::x86_avx_vtestnzc_ps:
6685 case Intrinsic::x86_avx_vtestnzc_ps_256:
6686 case Intrinsic::x86_avx_vtestz_pd:
6687 case Intrinsic::x86_avx_vtestz_pd_256:
6688 case Intrinsic::x86_avx_vtestz_ps:
6689 case Intrinsic::x86_avx_vtestz_ps_256:
6690 case Intrinsic::x86_avx_ptestc_256:
6691 case Intrinsic::x86_avx_ptestnzc_256:
6692 case Intrinsic::x86_avx_ptestz_256:
6693 case Intrinsic::x86_sse41_ptestc:
6694 case Intrinsic::x86_sse41_ptestnzc:
6695 case Intrinsic::x86_sse41_ptestz:
6696 handleVtestIntrinsic(I);
6697 break;
6698
6699 // Packed Horizontal Add/Subtract
6700 case Intrinsic::x86_ssse3_phadd_w:
6701 case Intrinsic::x86_ssse3_phadd_w_128:
6702 case Intrinsic::x86_ssse3_phsub_w:
6703 case Intrinsic::x86_ssse3_phsub_w_128:
6704 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6705 /*ReinterpretElemWidth=*/16);
6706 break;
6707
6708 case Intrinsic::x86_avx2_phadd_w:
6709 case Intrinsic::x86_avx2_phsub_w:
6710 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6711 /*ReinterpretElemWidth=*/16);
6712 break;
6713
6714 // Packed Horizontal Add/Subtract
6715 case Intrinsic::x86_ssse3_phadd_d:
6716 case Intrinsic::x86_ssse3_phadd_d_128:
6717 case Intrinsic::x86_ssse3_phsub_d:
6718 case Intrinsic::x86_ssse3_phsub_d_128:
6719 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6720 /*ReinterpretElemWidth=*/32);
6721 break;
6722
6723 case Intrinsic::x86_avx2_phadd_d:
6724 case Intrinsic::x86_avx2_phsub_d:
6725 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6726 /*ReinterpretElemWidth=*/32);
6727 break;
6728
6729 // Packed Horizontal Add/Subtract and Saturate
6730 case Intrinsic::x86_ssse3_phadd_sw:
6731 case Intrinsic::x86_ssse3_phadd_sw_128:
6732 case Intrinsic::x86_ssse3_phsub_sw:
6733 case Intrinsic::x86_ssse3_phsub_sw_128:
6734 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6735 /*ReinterpretElemWidth=*/16);
6736 break;
6737
6738 case Intrinsic::x86_avx2_phadd_sw:
6739 case Intrinsic::x86_avx2_phsub_sw:
6740 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6741 /*ReinterpretElemWidth=*/16);
6742 break;
6743
6744 // Packed Single/Double Precision Floating-Point Horizontal Add
6745 case Intrinsic::x86_sse3_hadd_ps:
6746 case Intrinsic::x86_sse3_hadd_pd:
6747 case Intrinsic::x86_sse3_hsub_ps:
6748 case Intrinsic::x86_sse3_hsub_pd:
6749 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1);
6750 break;
6751
6752 case Intrinsic::x86_avx_hadd_pd_256:
6753 case Intrinsic::x86_avx_hadd_ps_256:
6754 case Intrinsic::x86_avx_hsub_pd_256:
6755 case Intrinsic::x86_avx_hsub_ps_256:
6756 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2);
6757 break;
6758
6759 case Intrinsic::x86_avx_maskstore_ps:
6760 case Intrinsic::x86_avx_maskstore_pd:
6761 case Intrinsic::x86_avx_maskstore_ps_256:
6762 case Intrinsic::x86_avx_maskstore_pd_256:
6763 case Intrinsic::x86_avx2_maskstore_d:
6764 case Intrinsic::x86_avx2_maskstore_q:
6765 case Intrinsic::x86_avx2_maskstore_d_256:
6766 case Intrinsic::x86_avx2_maskstore_q_256: {
6767 handleAVXMaskedStore(I);
6768 break;
6769 }
6770
6771 case Intrinsic::x86_avx_maskload_ps:
6772 case Intrinsic::x86_avx_maskload_pd:
6773 case Intrinsic::x86_avx_maskload_ps_256:
6774 case Intrinsic::x86_avx_maskload_pd_256:
6775 case Intrinsic::x86_avx2_maskload_d:
6776 case Intrinsic::x86_avx2_maskload_q:
6777 case Intrinsic::x86_avx2_maskload_d_256:
6778 case Intrinsic::x86_avx2_maskload_q_256: {
6779 handleAVXMaskedLoad(I);
6780 break;
6781 }
6782
6783 // Packed
6784 case Intrinsic::x86_avx512fp16_add_ph_512:
6785 case Intrinsic::x86_avx512fp16_sub_ph_512:
6786 case Intrinsic::x86_avx512fp16_mul_ph_512:
6787 case Intrinsic::x86_avx512fp16_div_ph_512:
6788 case Intrinsic::x86_avx512fp16_max_ph_512:
6789 case Intrinsic::x86_avx512fp16_min_ph_512:
6790 case Intrinsic::x86_avx512_min_ps_512:
6791 case Intrinsic::x86_avx512_min_pd_512:
6792 case Intrinsic::x86_avx512_max_ps_512:
6793 case Intrinsic::x86_avx512_max_pd_512: {
6794 // These AVX512 variants contain the rounding mode as a trailing flag.
6795 // Earlier variants do not have a trailing flag and are already handled
6796 // by maybeHandleSimpleNomemIntrinsic(I, 0) via
6797 // maybeHandleUnknownIntrinsic.
6798 [[maybe_unused]] bool Success =
6799 maybeHandleSimpleNomemIntrinsic(I, /*trailingFlags=*/1);
6800 assert(Success);
6801 break;
6802 }
6803
6804 case Intrinsic::x86_avx_vpermilvar_pd:
6805 case Intrinsic::x86_avx_vpermilvar_pd_256:
6806 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6807 case Intrinsic::x86_avx_vpermilvar_ps:
6808 case Intrinsic::x86_avx_vpermilvar_ps_256:
6809 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6810 handleAVXVpermilvar(I);
6811 break;
6812 }
6813
6814 case Intrinsic::x86_avx512_vpermi2var_d_128:
6815 case Intrinsic::x86_avx512_vpermi2var_d_256:
6816 case Intrinsic::x86_avx512_vpermi2var_d_512:
6817 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6818 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6819 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6820 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6821 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6822 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6823 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6824 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6825 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6826 case Intrinsic::x86_avx512_vpermi2var_q_128:
6827 case Intrinsic::x86_avx512_vpermi2var_q_256:
6828 case Intrinsic::x86_avx512_vpermi2var_q_512:
6829 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6830 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6831 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6832 handleAVXVpermi2var(I);
6833 break;
6834
6835 // Packed Shuffle
6836 // llvm.x86.sse.pshuf.w(<1 x i64>, i8)
6837 // llvm.x86.ssse3.pshuf.b(<1 x i64>, <1 x i64>)
6838 // llvm.x86.ssse3.pshuf.b.128(<16 x i8>, <16 x i8>)
6839 // llvm.x86.avx2.pshuf.b(<32 x i8>, <32 x i8>)
6840 // llvm.x86.avx512.pshuf.b.512(<64 x i8>, <64 x i8>)
6841 //
6842 // The following intrinsics are auto-upgraded:
6843 // llvm.x86.sse2.pshuf.d(<4 x i32>, i8)
6844 // llvm.x86.sse2.gpshufh.w(<8 x i16>, i8)
6845 // llvm.x86.sse2.pshufl.w(<8 x i16>, i8)
6846 case Intrinsic::x86_avx2_pshuf_b:
6847 case Intrinsic::x86_sse_pshuf_w:
6848 case Intrinsic::x86_ssse3_pshuf_b_128:
6849 case Intrinsic::x86_ssse3_pshuf_b:
6850 case Intrinsic::x86_avx512_pshuf_b_512:
6851 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
6852 /*trailingVerbatimArgs=*/1,
6853 /*forceIntegerIntrinsic=*/false);
6854 break;
6855
6856 // AVX512 PMOV: Packed MOV, with truncation
6857 // Precisely handled by applying the same intrinsic to the shadow
6858 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6859 case Intrinsic::x86_avx512_mask_pmov_db_128:
6860 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6861 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6862 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6863 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6864 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6865 case Intrinsic::x86_avx512_mask_pmov_db_256:
6866 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6867 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6868 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6869 case Intrinsic::x86_avx512_mask_pmov_db_512:
6870 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6871 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6872 // Intrinsic::x86_avx512_mask_pmov_{qd,wb}_{256,512} were removed in
6873 // f608dc1f5775ee880e8ea30e2d06ab5a4a935c22
6874 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
6875 /*trailingVerbatimArgs=*/1,
6876 /*forceIntegerIntrinsic=*/false);
6877 break;
6878 }
6879
6880 // AVX512 PMOV{S,US}: Packed MOV, with signed/unsigned saturation
6881 // Approximately handled using the corresponding truncation intrinsic
6882 // TODO: improve handleAVX512VectorDownConvert to precisely model saturation
6883 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6884 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6885 handleIntrinsicByApplyingToShadow(
6886 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6887 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6888 break;
6889 }
6890
6891 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6892 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6893 handleIntrinsicByApplyingToShadow(
6894 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6895 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6896 break;
6897
6898 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6899 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6900 handleIntrinsicByApplyingToShadow(
6901 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6902 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6903 break;
6904
6905 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6906 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6907 handleIntrinsicByApplyingToShadow(
6908 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6909 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6910 break;
6911 }
6912
6913 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6914 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6915 handleIntrinsicByApplyingToShadow(
6916 I, Intrinsic::x86_avx512_mask_pmov_db_256,
6917 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6918 break;
6919
6920 case Intrinsic::x86_avx512_mask_pmovs_db_128:
6921 case Intrinsic::x86_avx512_mask_pmovus_db_128:
6922 handleIntrinsicByApplyingToShadow(
6923 I, Intrinsic::x86_avx512_mask_pmov_db_128,
6924 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6925 break;
6926
6927 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6928 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6929 handleIntrinsicByApplyingToShadow(
6930 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
6931 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6932 break;
6933 }
6934
6935 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
6936 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
6937 handleIntrinsicByApplyingToShadow(
6938 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
6939 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6940 break;
6941
6942 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
6943 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
6944 handleIntrinsicByApplyingToShadow(
6945 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
6946 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6947 break;
6948
6949 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
6950 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
6951 handleIntrinsicByApplyingToShadow(
6952 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
6953 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6954 break;
6955 }
6956
6957 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
6958 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
6959 handleIntrinsicByApplyingToShadow(
6960 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
6961 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6962 break;
6963
6964 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
6965 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
6966 handleIntrinsicByApplyingToShadow(
6967 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
6968 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6969 break;
6970
6971 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
6972 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
6973 handleIntrinsicByApplyingToShadow(
6974 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
6975 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6976 break;
6977
6978 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
6979 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
6980 handleIntrinsicByApplyingToShadow(
6981 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
6982 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6983 break;
6984
6985 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
6986 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
6987 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
6988 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
6989 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
6990 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
6991 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
6992 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
6993 // Since Intrinsic::x86_avx512_mask_pmov_{qd,wb}_{256,512} do not exist,
6994 // we cannot use handleIntrinsicByApplyingToShadow. Instead, we call the
6995 // slow-path handler.
6996 handleAVX512VectorDownConvert(I);
6997 break;
6998 }
6999
7000 // e.g.,
7001 // <16 x float> @llvm.x86.avx512.mask.compress
7002 // (<16 x float> %data, <16 x float> %passthru,
7003 // <16 x i1> %mask)
7004 // <16 x i32> @llvm.x86.avx512.mask.compress
7005 // (<16 x i32> %data, <16 x i32> %passthru,
7006 // <16 x i1> %mask)
7007 case Intrinsic::x86_avx512_mask_compress:
7008 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
7009 /*trailingVerbatimArgs=*/1,
7010 /*forceIntegerIntrinsic=*/true);
7011 break;
7012
7013 // AVX512/AVX10 Reciprocal
7014 // <16 x float> @llvm.x86.avx512.rsqrt14.ps.512
7015 // (<16 x float>, <16 x float>, i16)
7016 // <8 x float> @llvm.x86.avx512.rsqrt14.ps.256
7017 // (<8 x float>, <8 x float>, i8)
7018 // <4 x float> @llvm.x86.avx512.rsqrt14.ps.128
7019 // (<4 x float>, <4 x float>, i8)
7020 //
7021 // <8 x double> @llvm.x86.avx512.rsqrt14.pd.512
7022 // (<8 x double>, <8 x double>, i8)
7023 // <4 x double> @llvm.x86.avx512.rsqrt14.pd.256
7024 // (<4 x double>, <4 x double>, i8)
7025 // <2 x double> @llvm.x86.avx512.rsqrt14.pd.128
7026 // (<2 x double>, <2 x double>, i8)
7027 //
7028 // <32 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.512
7029 // (<32 x bfloat>, <32 x bfloat>, i32)
7030 // <16 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.256
7031 // (<16 x bfloat>, <16 x bfloat>, i16)
7032 // <8 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.128
7033 // (<8 x bfloat>, <8 x bfloat>, i8)
7034 //
7035 // <32 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.512
7036 // (<32 x half>, <32 x half>, i32)
7037 // <16 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.256
7038 // (<16 x half>, <16 x half>, i16)
7039 // <8 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.128
7040 // (<8 x half>, <8 x half>, i8)
7041 //
7042 // TODO: 3-operand variants are not handled:
7043 // <2 x double> @llvm.x86.avx512.rsqrt14.sd
7044 // (<2 x double>, <2 x double>, <2 x double>, i8)
7045 // <4 x float> @llvm.x86.avx512.rsqrt14.ss
7046 // (<4 x float>, <4 x float>, <4 x float>, i8)
7047 // <8 x half> @llvm.x86.avx512fp16.mask.rsqrt.sh
7048 // (<8 x half>, <8 x half>, <8 x half>, i8)
7049 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7050 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7051 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7052 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7053 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7054 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7055 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7056 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7057 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7058 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7059 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7060 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7061 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7062 /*WriteThruIndex=*/1,
7063 /*MaskIndex=*/2);
7064 break;
7065
7066 // AVX512/AVX10 Reciprocal Square Root
7067 // <16 x float> @llvm.x86.avx512.rcp14.ps.512
7068 // (<16 x float>, <16 x float>, i16)
7069 // <8 x float> @llvm.x86.avx512.rcp14.ps.256
7070 // (<8 x float>, <8 x float>, i8)
7071 // <4 x float> @llvm.x86.avx512.rcp14.ps.128
7072 // (<4 x float>, <4 x float>, i8)
7073 //
7074 // <8 x double> @llvm.x86.avx512.rcp14.pd.512
7075 // (<8 x double>, <8 x double>, i8)
7076 // <4 x double> @llvm.x86.avx512.rcp14.pd.256
7077 // (<4 x double>, <4 x double>, i8)
7078 // <2 x double> @llvm.x86.avx512.rcp14.pd.128
7079 // (<2 x double>, <2 x double>, i8)
7080 //
7081 // <32 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.512
7082 // (<32 x bfloat>, <32 x bfloat>, i32)
7083 // <16 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.256
7084 // (<16 x bfloat>, <16 x bfloat>, i16)
7085 // <8 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.128
7086 // (<8 x bfloat>, <8 x bfloat>, i8)
7087 //
7088 // <32 x half> @llvm.x86.avx512fp16.mask.rcp.ph.512
7089 // (<32 x half>, <32 x half>, i32)
7090 // <16 x half> @llvm.x86.avx512fp16.mask.rcp.ph.256
7091 // (<16 x half>, <16 x half>, i16)
7092 // <8 x half> @llvm.x86.avx512fp16.mask.rcp.ph.128
7093 // (<8 x half>, <8 x half>, i8)
7094 //
7095 // TODO: 3-operand variants are not handled:
7096 // <2 x double> @llvm.x86.avx512.rcp14.sd
7097 // (<2 x double>, <2 x double>, <2 x double>, i8)
7098 // <4 x float> @llvm.x86.avx512.rcp14.ss
7099 // (<4 x float>, <4 x float>, <4 x float>, i8)
7100 // <8 x half> @llvm.x86.avx512fp16.mask.rcp.sh
7101 // (<8 x half>, <8 x half>, <8 x half>, i8)
7102 case Intrinsic::x86_avx512_rcp14_ps_512:
7103 case Intrinsic::x86_avx512_rcp14_ps_256:
7104 case Intrinsic::x86_avx512_rcp14_ps_128:
7105 case Intrinsic::x86_avx512_rcp14_pd_512:
7106 case Intrinsic::x86_avx512_rcp14_pd_256:
7107 case Intrinsic::x86_avx512_rcp14_pd_128:
7108 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7109 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7110 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7111 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7112 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7113 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7114 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7115 /*WriteThruIndex=*/1,
7116 /*MaskIndex=*/2);
7117 break;
7118
7119 // <32 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.512
7120 // (<32 x half>, i32, <32 x half>, i32, i32)
7121 // <16 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.256
7122 // (<16 x half>, i32, <16 x half>, i32, i16)
7123 // <8 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.128
7124 // (<8 x half>, i32, <8 x half>, i32, i8)
7125 //
7126 // <16 x float> @llvm.x86.avx512.mask.rndscale.ps.512
7127 // (<16 x float>, i32, <16 x float>, i16, i32)
7128 // <8 x float> @llvm.x86.avx512.mask.rndscale.ps.256
7129 // (<8 x float>, i32, <8 x float>, i8)
7130 // <4 x float> @llvm.x86.avx512.mask.rndscale.ps.128
7131 // (<4 x float>, i32, <4 x float>, i8)
7132 //
7133 // <8 x double> @llvm.x86.avx512.mask.rndscale.pd.512
7134 // (<8 x double>, i32, <8 x double>, i8, i32)
7135 // A Imm WriteThru Mask Rounding
7136 // <4 x double> @llvm.x86.avx512.mask.rndscale.pd.256
7137 // (<4 x double>, i32, <4 x double>, i8)
7138 // <2 x double> @llvm.x86.avx512.mask.rndscale.pd.128
7139 // (<2 x double>, i32, <2 x double>, i8)
7140 // A Imm WriteThru Mask
7141 //
7142 // <32 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.512
7143 // (<32 x bfloat>, i32, <32 x bfloat>, i32)
7144 // <16 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.256
7145 // (<16 x bfloat>, i32, <16 x bfloat>, i16)
7146 // <8 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.128
7147 // (<8 x bfloat>, i32, <8 x bfloat>, i8)
7148 //
7149 // Not supported: three vectors
7150 // - <8 x half> @llvm.x86.avx512fp16.mask.rndscale.sh
7151 // (<8 x half>, <8 x half>,<8 x half>, i8, i32, i32)
7152 // - <4 x float> @llvm.x86.avx512.mask.rndscale.ss
7153 // (<4 x float>, <4 x float>, <4 x float>, i8, i32, i32)
7154 // - <2 x double> @llvm.x86.avx512.mask.rndscale.sd
7155 // (<2 x double>, <2 x double>, <2 x double>, i8, i32,
7156 // i32)
7157 // A B WriteThru Mask Imm
7158 // Rounding
7159 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7160 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7161 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7162 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7163 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7164 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7165 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7166 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7167 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7168 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7169 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7170 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7171 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7172 /*WriteThruIndex=*/2,
7173 /*MaskIndex=*/3);
7174 break;
7175
7176 // AVX512 Vector Scale Float* Packed
7177 //
7178 // < 8 x double> @llvm.x86.avx512.mask.scalef.pd.512
7179 // (<8 x double>, <8 x double>, <8 x double>, i8, i32)
7180 // A B WriteThru Msk Round
7181 // < 4 x double> @llvm.x86.avx512.mask.scalef.pd.256
7182 // (<4 x double>, <4 x double>, <4 x double>, i8)
7183 // < 2 x double> @llvm.x86.avx512.mask.scalef.pd.128
7184 // (<2 x double>, <2 x double>, <2 x double>, i8)
7185 //
7186 // <16 x float> @llvm.x86.avx512.mask.scalef.ps.512
7187 // (<16 x float>, <16 x float>, <16 x float>, i16, i32)
7188 // < 8 x float> @llvm.x86.avx512.mask.scalef.ps.256
7189 // (<8 x float>, <8 x float>, <8 x float>, i8)
7190 // < 4 x float> @llvm.x86.avx512.mask.scalef.ps.128
7191 // (<4 x float>, <4 x float>, <4 x float>, i8)
7192 //
7193 // <32 x half> @llvm.x86.avx512fp16.mask.scalef.ph.512
7194 // (<32 x half>, <32 x half>, <32 x half>, i32, i32)
7195 // <16 x half> @llvm.x86.avx512fp16.mask.scalef.ph.256
7196 // (<16 x half>, <16 x half>, <16 x half>, i16)
7197 // < 8 x half> @llvm.x86.avx512fp16.mask.scalef.ph.128
7198 // (<8 x half>, <8 x half>, <8 x half>, i8)
7199 //
7200 // TODO: AVX10
7201 // <32 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.512
7202 // (<32 x bfloat>, <32 x bfloat>, <32 x bfloat>, i32)
7203 // <16 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.256
7204 // (<16 x bfloat>, <16 x bfloat>, <16 x bfloat>, i16)
7205 // < 8 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.128
7206 // (<8 x bfloat>, <8 x bfloat>, <8 x bfloat>, i8)
7207 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7208 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7209 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7210 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7211 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7212 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7213 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7214 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7215 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7216 // The AVX512 512-bit operand variants have an extra operand (the
7217 // Rounding mode). The extra operand, if present, will be
7218 // automatically checked by the handler.
7219 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0, 1},
7220 /*WriteThruIndex=*/2,
7221 /*MaskIndex=*/3);
7222 break;
7223
7224 // TODO: AVX512 Vector Scale Float* Scalar
7225 //
7226 // This is different from the Packed variant, because some bits are copied,
7227 // and some bits are zeroed.
7228 //
7229 // < 4 x float> @llvm.x86.avx512.mask.scalef.ss
7230 // (<4 x float>, <4 x float>, <4 x float>, i8, i32)
7231 //
7232 // < 2 x double> @llvm.x86.avx512.mask.scalef.sd
7233 // (<2 x double>, <2 x double>, <2 x double>, i8, i32)
7234 //
7235 // < 8 x half> @llvm.x86.avx512fp16.mask.scalef.sh
7236 // (<8 x half>, <8 x half>, <8 x half>, i8, i32)
7237
7238 // AVX512 FP16 Arithmetic
7239 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7240 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7241 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7242 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7243 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7244 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7245 visitGenericScalarHalfwordInst(I);
7246 break;
7247 }
7248
7249 // AVX512 Floating-Point Classification
7250 // - <8 x i1> @llvm.x86.avx512.fpclass.pd.512(<8 x double>, i32)
7251 // - <16 x i1> @llvm.x86.avx512.fpclass.ps.512(<16 x float>, i32)
7252 case Intrinsic::x86_avx512_fpclass_pd_512:
7253 case Intrinsic::x86_avx512_fpclass_ps_512:
7254 handleAVX512FPClass(I);
7255 break;
7256
7257 // AVX Galois Field New Instructions
7258 case Intrinsic::x86_vgf2p8affineqb_128:
7259 case Intrinsic::x86_vgf2p8affineqb_256:
7260 case Intrinsic::x86_vgf2p8affineqb_512:
7261 handleAVXGF2P8Affine(I);
7262 break;
7263
7264 default:
7265 return false;
7266 }
7267
7268 return true;
7269 }
7270
7271 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &I) {
7272 switch (I.getIntrinsicID()) {
7273 // Two operands e.g.,
7274 // - <8 x i8> @llvm.aarch64.neon.rshrn.v8i8 (<8 x i16>, i32)
7275 // - <4 x i16> @llvm.aarch64.neon.uqrshl.v4i16(<4 x i16>, <4 x i16>)
7276 case Intrinsic::aarch64_neon_rshrn:
7277 case Intrinsic::aarch64_neon_sqrshl:
7278 case Intrinsic::aarch64_neon_sqrshrn:
7279 case Intrinsic::aarch64_neon_sqrshrun:
7280 case Intrinsic::aarch64_neon_sqshl:
7281 case Intrinsic::aarch64_neon_sqshlu:
7282 case Intrinsic::aarch64_neon_sqshrn:
7283 case Intrinsic::aarch64_neon_sqshrun:
7284 case Intrinsic::aarch64_neon_srshl:
7285 case Intrinsic::aarch64_neon_sshl:
7286 case Intrinsic::aarch64_neon_uqrshl:
7287 case Intrinsic::aarch64_neon_uqrshrn:
7288 case Intrinsic::aarch64_neon_uqshl:
7289 case Intrinsic::aarch64_neon_uqshrn:
7290 case Intrinsic::aarch64_neon_urshl:
7291 case Intrinsic::aarch64_neon_ushl:
7292 handleVectorShiftIntrinsic(I, /* Variable */ false);
7293 break;
7294
7295 // Vector Shift Left/Right and Insert
7296 //
7297 // Three operands e.g.,
7298 // - <4 x i16> @llvm.aarch64.neon.vsli.v4i16
7299 // (<4 x i16> %a, <4 x i16> %b, i32 %n)
7300 // - <16 x i8> @llvm.aarch64.neon.vsri.v16i8
7301 // (<16 x i8> %a, <16 x i8> %b, i32 %n)
7302 //
7303 // %b is shifted by %n bits, and the "missing" bits are filled in with %a
7304 // (instead of zero-extending/sign-extending).
7305 case Intrinsic::aarch64_neon_vsli:
7306 case Intrinsic::aarch64_neon_vsri:
7307 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
7308 /*trailingVerbatimArgs=*/1,
7309 /*forceIntegerIntrinsic=*/false);
7310 break;
7311
7312 // TODO: handling max/min similarly to AND/OR may be more precise
7313 // Floating-Point Maximum/Minimum Pairwise
7314 case Intrinsic::aarch64_neon_fmaxp:
7315 case Intrinsic::aarch64_neon_fminp:
7316 // Floating-Point Maximum/Minimum Number Pairwise
7317 case Intrinsic::aarch64_neon_fmaxnmp:
7318 case Intrinsic::aarch64_neon_fminnmp:
7319 // Signed/Unsigned Maximum/Minimum Pairwise
7320 case Intrinsic::aarch64_neon_smaxp:
7321 case Intrinsic::aarch64_neon_sminp:
7322 case Intrinsic::aarch64_neon_umaxp:
7323 case Intrinsic::aarch64_neon_uminp:
7324 // Add Pairwise
7325 case Intrinsic::aarch64_neon_addp:
7326 // Floating-point Add Pairwise
7327 case Intrinsic::aarch64_neon_faddp:
7328 // Add Long Pairwise
7329 case Intrinsic::aarch64_neon_saddlp:
7330 case Intrinsic::aarch64_neon_uaddlp: {
7331 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1);
7332 break;
7333 }
7334
7335 // Floating-point Convert to integer, rounding to nearest with ties to Away
7336 case Intrinsic::aarch64_neon_fcvtas:
7337 case Intrinsic::aarch64_neon_fcvtau:
7338 // Floating-point convert to integer, rounding toward minus infinity
7339 case Intrinsic::aarch64_neon_fcvtms:
7340 case Intrinsic::aarch64_neon_fcvtmu:
7341 // Floating-point convert to integer, rounding to nearest with ties to even
7342 case Intrinsic::aarch64_neon_fcvtns:
7343 case Intrinsic::aarch64_neon_fcvtnu:
7344 // Floating-point convert to integer, rounding toward plus infinity
7345 case Intrinsic::aarch64_neon_fcvtps:
7346 case Intrinsic::aarch64_neon_fcvtpu:
7347 // Floating-point Convert to integer, rounding toward Zero
7348 case Intrinsic::aarch64_neon_fcvtzs:
7349 case Intrinsic::aarch64_neon_fcvtzu:
7350 // Floating-point convert to lower precision narrow, rounding to odd
7351 case Intrinsic::aarch64_neon_fcvtxn:
7352 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
7353 break;
7354
7355 // Vector Conversions Between Fixed-Point and Floating-Point
7356 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7357 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7358 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7359 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7360 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/true);
7361 break;
7362
7363 // TODO: bfloat conversions
7364 // - bfloat @llvm.aarch64.neon.bfcvt(float)
7365 // - <8 x bfloat> @llvm.aarch64.neon.bfcvtn(<4 x float>)
7366 // - <8 x bfloat> @llvm.aarch64.neon.bfcvtn2(<8 x bfloat>, <4 x float>)
7367
7368 // Add reduction to scalar
7369 case Intrinsic::aarch64_neon_faddv:
7370 case Intrinsic::aarch64_neon_saddv:
7371 case Intrinsic::aarch64_neon_uaddv:
7372 // Signed/Unsigned min/max (Vector)
7373 // TODO: handling similarly to AND/OR may be more precise.
7374 case Intrinsic::aarch64_neon_smaxv:
7375 case Intrinsic::aarch64_neon_sminv:
7376 case Intrinsic::aarch64_neon_umaxv:
7377 case Intrinsic::aarch64_neon_uminv:
7378 // Floating-point min/max (vector)
7379 // The f{min,max}"nm"v variants handle NaN differently than f{min,max}v,
7380 // but our shadow propagation is the same.
7381 case Intrinsic::aarch64_neon_fmaxv:
7382 case Intrinsic::aarch64_neon_fminv:
7383 case Intrinsic::aarch64_neon_fmaxnmv:
7384 case Intrinsic::aarch64_neon_fminnmv:
7385 // Sum long across vector
7386 case Intrinsic::aarch64_neon_saddlv:
7387 case Intrinsic::aarch64_neon_uaddlv:
7388 handleVectorReduceIntrinsic(I, /*AllowShadowCast=*/true);
7389 break;
7390
7391 case Intrinsic::aarch64_neon_ld1x2:
7392 case Intrinsic::aarch64_neon_ld1x3:
7393 case Intrinsic::aarch64_neon_ld1x4:
7394 case Intrinsic::aarch64_neon_ld2:
7395 case Intrinsic::aarch64_neon_ld3:
7396 case Intrinsic::aarch64_neon_ld4:
7397 case Intrinsic::aarch64_neon_ld2r:
7398 case Intrinsic::aarch64_neon_ld3r:
7399 case Intrinsic::aarch64_neon_ld4r: {
7400 handleNEONVectorLoad(I, /*WithLane=*/false);
7401 break;
7402 }
7403
7404 case Intrinsic::aarch64_neon_ld2lane:
7405 case Intrinsic::aarch64_neon_ld3lane:
7406 case Intrinsic::aarch64_neon_ld4lane: {
7407 handleNEONVectorLoad(I, /*WithLane=*/true);
7408 break;
7409 }
7410
7411 // Saturating extract narrow
7412 case Intrinsic::aarch64_neon_sqxtn:
7413 case Intrinsic::aarch64_neon_sqxtun:
7414 case Intrinsic::aarch64_neon_uqxtn:
7415 // These only have one argument, but we (ab)use handleShadowOr because it
7416 // does work on single argument intrinsics and will typecast the shadow
7417 // (and update the origin).
7418 handleShadowOr(I);
7419 break;
7420
7421 case Intrinsic::aarch64_neon_st1x2:
7422 case Intrinsic::aarch64_neon_st1x3:
7423 case Intrinsic::aarch64_neon_st1x4:
7424 case Intrinsic::aarch64_neon_st2:
7425 case Intrinsic::aarch64_neon_st3:
7426 case Intrinsic::aarch64_neon_st4: {
7427 handleNEONVectorStoreIntrinsic(I, false);
7428 break;
7429 }
7430
7431 case Intrinsic::aarch64_neon_st2lane:
7432 case Intrinsic::aarch64_neon_st3lane:
7433 case Intrinsic::aarch64_neon_st4lane: {
7434 handleNEONVectorStoreIntrinsic(I, true);
7435 break;
7436 }
7437
7438 // Arm NEON vector table intrinsics have the source/table register(s) as
7439 // arguments, followed by the index register. They return the output.
7440 //
7441 // 'TBL writes a zero if an index is out-of-range, while TBX leaves the
7442 // original value unchanged in the destination register.'
7443 // Conveniently, zero denotes a clean shadow, which means out-of-range
7444 // indices for TBL will initialize the user data with zero and also clean
7445 // the shadow. (For TBX, neither the user data nor the shadow will be
7446 // updated, which is also correct.)
7447 case Intrinsic::aarch64_neon_tbl1:
7448 case Intrinsic::aarch64_neon_tbl2:
7449 case Intrinsic::aarch64_neon_tbl3:
7450 case Intrinsic::aarch64_neon_tbl4:
7451 case Intrinsic::aarch64_neon_tbx1:
7452 case Intrinsic::aarch64_neon_tbx2:
7453 case Intrinsic::aarch64_neon_tbx3:
7454 case Intrinsic::aarch64_neon_tbx4: {
7455 // The last trailing argument (index register) should be handled verbatim
7456 handleIntrinsicByApplyingToShadow(
7457 I, /*shadowIntrinsicID=*/I.getIntrinsicID(),
7458 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7459 break;
7460 }
7461
7462 case Intrinsic::aarch64_neon_fmulx:
7463 case Intrinsic::aarch64_neon_pmul:
7464 case Intrinsic::aarch64_neon_pmull:
7465 case Intrinsic::aarch64_neon_smull:
7466 case Intrinsic::aarch64_neon_pmull64:
7467 case Intrinsic::aarch64_neon_umull: {
7468 handleNEONVectorMultiplyIntrinsic(I);
7469 break;
7470 }
7471
7472 case Intrinsic::aarch64_neon_smmla:
7473 case Intrinsic::aarch64_neon_ummla:
7474 case Intrinsic::aarch64_neon_usmmla:
7475 case Intrinsic::aarch64_neon_bfmmla:
7476 handleNEONMatrixMultiply(I);
7477 break;
7478
7479 // <2 x i32> @llvm.aarch64.neon.{u,s,us}dot.v2i32.v8i8
7480 // (<2 x i32> %acc, <8 x i8> %a, <8 x i8> %b)
7481 // <4 x i32> @llvm.aarch64.neon.{u,s,us}dot.v4i32.v16i8
7482 // (<4 x i32> %acc, <16 x i8> %a, <16 x i8> %b)
7483 case Intrinsic::aarch64_neon_sdot:
7484 case Intrinsic::aarch64_neon_udot:
7485 case Intrinsic::aarch64_neon_usdot:
7486 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
7487 /*ZeroPurifies=*/true,
7488 /*EltSizeInBits=*/0,
7489 /*Lanes=*/kBothLanes);
7490 break;
7491
7492 // <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16
7493 // (<2 x float> %acc, <4 x bfloat> %a, <4 x bfloat> %b)
7494 // <4 x float> @llvm.aarch64.neon.bfdot.v4f32.v8bf16
7495 // (<4 x float> %acc, <8 x bfloat> %a, <8 x bfloat> %b)
7496 case Intrinsic::aarch64_neon_bfdot:
7497 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
7498 /*ZeroPurifies=*/false,
7499 /*EltSizeInBits=*/0,
7500 /*Lanes=*/kBothLanes);
7501 break;
7502
7503 // <4 x half > @llvm.aarch64.neon.fp8.fdot2
7504 // (<4 x half >, < 8 x i8>, < 8 x i8>)
7505 // <8 x half > @llvm.aarch64.neon.fp8.fdot2
7506 // (<8 x half >, <16 x i8>, <16 x i8>)
7507 //
7508 // N.B. although the multiplicands are i8, they are actually fp8, thus
7509 // ZeroPurifies is not applicable.
7510 case Intrinsic::aarch64_neon_fp8_fdot2:
7511 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
7512 /*ZeroPurifies=*/false,
7513 /*EltSizeInBits=*/0,
7514 /*Lanes=*/kBothLanes);
7515 break;
7516
7517 // <2 x float> @llvm.aarch64.neon.fp8.fdot4
7518 // (<2 x float>, < 8 x i8>, < 8 x i8>)
7519 // <4 x float> @llvm.aarch64.neon.fp8.fdot4
7520 // (<4 x float>, <16 x i8>, <16 x i8>)
7521 //
7522 // N.B. although the multiplicands are i8, they are actually fp8, thus
7523 // ZeroPurifies is not applicable.
7524 case Intrinsic::aarch64_neon_fp8_fdot4:
7525 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
7526 /*ZeroPurifies=*/false,
7527 /*EltSizeInBits=*/0,
7528 /*Lanes=*/kBothLanes);
7529 break;
7530
7531 // Floating-Point Absolute Compare Greater Than/Equal
7532 case Intrinsic::aarch64_neon_facge:
7533 case Intrinsic::aarch64_neon_facgt:
7534 handleVectorComparePackedIntrinsic(I, /*PredicateAsOperand=*/false);
7535 break;
7536
7537 default:
7538 return false;
7539 }
7540
7541 return true;
7542 }
7543
7544 void visitIntrinsicInst(IntrinsicInst &I) {
7545 if (maybeHandleCrossPlatformIntrinsic(I))
7546 return;
7547
7548 if (maybeHandleX86SIMDIntrinsic(I))
7549 return;
7550
7551 if (maybeHandleArmSIMDIntrinsic(I))
7552 return;
7553
7554 if (maybeHandleUnknownIntrinsic(I))
7555 return;
7556
7557 visitInstruction(I);
7558 }
7559
7560 void visitLibAtomicLoad(CallBase &CB) {
7561 // Since we use getNextNode here, we can't have CB terminate the BB.
7562 assert(isa<CallInst>(CB));
7563
7564 IRBuilder<> IRB(&CB);
7565 Value *Size = CB.getArgOperand(0);
7566 Value *SrcPtr = CB.getArgOperand(1);
7567 Value *DstPtr = CB.getArgOperand(2);
7568 Value *Ordering = CB.getArgOperand(3);
7569 // Convert the call to have at least Acquire ordering to make sure
7570 // the shadow operations aren't reordered before it.
7571 Value *NewOrdering =
7572 IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
7573 CB.setArgOperand(3, NewOrdering);
7574
7575 NextNodeIRBuilder NextIRB(&CB);
7576 Value *SrcShadowPtr, *SrcOriginPtr;
7577 std::tie(SrcShadowPtr, SrcOriginPtr) =
7578 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
7579 /*isStore*/ false);
7580 Value *DstShadowPtr =
7581 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
7582 /*isStore*/ true)
7583 .first;
7584
7585 NextIRB.CreateMemCpy(DstShadowPtr, Align(1), SrcShadowPtr, Align(1), Size);
7586 if (MS.TrackOrigins) {
7587 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7589 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7590 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7591 }
7592 }
7593
7594 void visitLibAtomicStore(CallBase &CB) {
7595 IRBuilder<> IRB(&CB);
7596 Value *Size = CB.getArgOperand(0);
7597 Value *DstPtr = CB.getArgOperand(2);
7598 Value *Ordering = CB.getArgOperand(3);
7599 // Convert the call to have at least Release ordering to make sure
7600 // the shadow operations aren't reordered after it.
7601 Value *NewOrdering =
7602 IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
7603 CB.setArgOperand(3, NewOrdering);
7604
7605 Value *DstShadowPtr =
7606 getShadowOriginPtr(DstPtr, IRB, IRB.getInt8Ty(), Align(1),
7607 /*isStore*/ true)
7608 .first;
7609
7610 // Atomic store always paints clean shadow/origin. See file header.
7611 IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
7612 Align(1));
7613 }
7614
7615 void visitCallBase(CallBase &CB) {
7616 assert(!CB.getMetadata(LLVMContext::MD_nosanitize));
7617 if (CB.isInlineAsm()) {
7618 // For inline asm (either a call to asm function, or callbr instruction),
7619 // do the usual thing: check argument shadow and mark all outputs as
7620 // clean. Note that any side effects of the inline asm that are not
7621 // immediately visible in its constraints are not handled.
7623 visitAsmInstruction(CB);
7624 else
7625 visitInstruction(CB);
7626 return;
7627 }
7628 LibFunc LF = TLI->getLibFunc(CB);
7629 if (LF != NotLibFunc) {
7630 // libatomic.a functions need to have special handling because there isn't
7631 // a good way to intercept them or compile the library with
7632 // instrumentation.
7633 switch (LF) {
7634 case LibFunc_atomic_load:
7635 if (!isa<CallInst>(CB)) {
7636 llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
7637 "Ignoring!\n";
7638 break;
7639 }
7640 visitLibAtomicLoad(CB);
7641 return;
7642 case LibFunc_atomic_store:
7643 visitLibAtomicStore(CB);
7644 return;
7645 default:
7646 break;
7647 }
7648 }
7649
7650 if (auto *Call = dyn_cast<CallInst>(&CB)) {
7651 assert(!isa<IntrinsicInst>(Call) && "intrinsics are handled elsewhere");
7652
7653 // We are going to insert code that relies on the fact that the callee
7654 // will become a non-readonly function after it is instrumented by us. To
7655 // prevent this code from being optimized out, mark that function
7656 // non-readonly in advance.
7657 // TODO: We can likely do better than dropping memory() completely here.
7658 AttributeMask B;
7659 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7660
7662 if (Function *Func = Call->getCalledFunction()) {
7663 Func->removeFnAttrs(B);
7664 }
7665
7667 }
7668 IRBuilder<> IRB(&CB);
7669 bool MayCheckCall = MS.EagerChecks;
7670 if (Function *Func = CB.getCalledFunction()) {
7671 // __sanitizer_unaligned_{load,store} functions may be called by users
7672 // and always expects shadows in the TLS. So don't check them.
7673 MayCheckCall &= !Func->getName().starts_with("__sanitizer_unaligned_");
7674 }
7675
7676 unsigned ArgOffset = 0;
7677 LLVM_DEBUG(dbgs() << " CallSite: " << CB << "\n");
7678 for (const auto &[i, A] : llvm::enumerate(CB.args())) {
7679 if (!A->getType()->isSized()) {
7680 LLVM_DEBUG(dbgs() << "Arg " << i << " is not sized: " << CB << "\n");
7681 continue;
7682 }
7683
7684 if (A->getType()->isScalableTy()) {
7685 LLVM_DEBUG(dbgs() << "Arg " << i << " is vscale: " << CB << "\n");
7686 // Handle as noundef, but don't reserve tls slots.
7687 insertCheckShadowOf(A, &CB);
7688 continue;
7689 }
7690
7691 unsigned Size = 0;
7692 const DataLayout &DL = F.getDataLayout();
7693
7694 bool ByVal = CB.isByValArgument(i);
7695 bool NoUndef = CB.paramHasAttr(i, Attribute::NoUndef);
7696 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7697
7698 if (EagerCheck) {
7699 insertCheckShadowOf(A, &CB);
7700 Size = DL.getTypeAllocSize(A->getType());
7701 } else {
7702 [[maybe_unused]] Value *Store = nullptr;
7703 // Compute the Shadow for arg even if it is ByVal, because
7704 // in that case getShadow() will copy the actual arg shadow to
7705 // __msan_param_tls.
7706 Value *ArgShadow = getShadow(A);
7707 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7708 LLVM_DEBUG(dbgs() << " Arg#" << i << ": " << *A
7709 << " Shadow: " << *ArgShadow << "\n");
7710 if (ByVal) {
7711 // ByVal requires some special handling as it's too big for a single
7712 // load
7713 assert(A->getType()->isPointerTy() &&
7714 "ByVal argument is not a pointer!");
7715 Size = DL.getTypeAllocSize(CB.getParamByValType(i));
7716 if (ArgOffset + Size > kParamTLSSize)
7717 break;
7718 const MaybeAlign ParamAlignment(CB.getParamAlign(i));
7719 MaybeAlign Alignment = std::nullopt;
7720 if (ParamAlignment)
7721 Alignment = std::min(*ParamAlignment, kShadowTLSAlignment);
7722 Value *AShadowPtr, *AOriginPtr;
7723 std::tie(AShadowPtr, AOriginPtr) =
7724 getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
7725 /*isStore*/ false);
7726 if (!PropagateShadow) {
7727 Store = IRB.CreateMemSet(ArgShadowBase,
7729 Size, Alignment);
7730 } else {
7731 Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr,
7732 Alignment, Size);
7733 if (MS.TrackOrigins) {
7734 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7735 // FIXME: OriginSize should be:
7736 // alignTo(A % kMinOriginAlignment + Size, kMinOriginAlignment)
7737 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
7738 IRB.CreateMemCpy(
7739 ArgOriginBase,
7740 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
7741 AOriginPtr,
7742 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginSize);
7743 }
7744 }
7745 } else {
7746 // Any other parameters mean we need bit-grained tracking of uninit
7747 // data
7748 Size = DL.getTypeAllocSize(A->getType());
7749 if (ArgOffset + Size > kParamTLSSize)
7750 break;
7751 Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
7753 Constant *Cst = dyn_cast<Constant>(ArgShadow);
7754 if (MS.TrackOrigins && !(Cst && Cst->isNullValue())) {
7755 IRB.CreateStore(getOrigin(A),
7756 getOriginPtrForArgument(IRB, ArgOffset));
7757 }
7758 }
7759 assert(Store != nullptr);
7760 LLVM_DEBUG(dbgs() << " Param:" << *Store << "\n");
7761 }
7762 assert(Size != 0);
7763 ArgOffset += alignTo(Size, kShadowTLSAlignment);
7764 }
7765 LLVM_DEBUG(dbgs() << " done with call args\n");
7766
7767 FunctionType *FT = CB.getFunctionType();
7768 if (FT->isVarArg()) {
7769 VAHelper->visitCallBase(CB, IRB);
7770 }
7771
7772 // Now, get the shadow for the RetVal.
7773 if (!CB.getType()->isSized())
7774 return;
7775 // Don't emit the epilogue for musttail call returns.
7776 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
7777 return;
7778
7779 if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
7780 setShadow(&CB, getCleanShadow(&CB));
7781 setOrigin(&CB, getCleanOrigin());
7782 return;
7783 }
7784
7785 IRBuilder<> IRBBefore(&CB);
7786 // Until we have full dynamic coverage, make sure the retval shadow is 0.
7787 Value *Base = getShadowPtrForRetval(IRBBefore);
7788 IRBBefore.CreateAlignedStore(getCleanShadow(&CB), Base,
7790 BasicBlock::iterator NextInsn;
7791 if (isa<CallInst>(CB)) {
7792 NextInsn = ++CB.getIterator();
7793 assert(NextInsn != CB.getParent()->end());
7794 } else {
7795 BasicBlock *NormalDest = cast<InvokeInst>(CB).getNormalDest();
7796 if (!NormalDest->getSinglePredecessor()) {
7797 // FIXME: this case is tricky, so we are just conservative here.
7798 // Perhaps we need to split the edge between this BB and NormalDest,
7799 // but a naive attempt to use SplitEdge leads to a crash.
7800 setShadow(&CB, getCleanShadow(&CB));
7801 setOrigin(&CB, getCleanOrigin());
7802 return;
7803 }
7804 // FIXME: NextInsn is likely in a basic block that has not been visited
7805 // yet. Anything inserted there will be instrumented by MSan later!
7806 NextInsn = NormalDest->getFirstInsertionPt();
7807 assert(NextInsn != NormalDest->end() &&
7808 "Could not find insertion point for retval shadow load");
7809 }
7810 IRBuilder<> IRBAfter(&*NextInsn);
7811 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7812 getShadowTy(&CB), getShadowPtrForRetval(IRBAfter), kShadowTLSAlignment,
7813 "_msret");
7814 setShadow(&CB, RetvalShadow);
7815 if (MS.TrackOrigins)
7816 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7817 }
7818
7819 bool isAMustTailRetVal(Value *RetVal) {
7820 if (auto *I = dyn_cast<BitCastInst>(RetVal)) {
7821 RetVal = I->getOperand(0);
7822 }
7823 if (auto *I = dyn_cast<CallInst>(RetVal)) {
7824 return I->isMustTailCall();
7825 }
7826 return false;
7827 }
7828
7829 void visitReturnInst(ReturnInst &I) {
7830 IRBuilder<> IRB(&I);
7831 Value *RetVal = I.getReturnValue();
7832 if (!RetVal)
7833 return;
7834 // Don't emit the epilogue for musttail call returns.
7835 if (isAMustTailRetVal(RetVal))
7836 return;
7837 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7838 bool HasNoUndef = F.hasRetAttribute(Attribute::NoUndef);
7839 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7840 // FIXME: Consider using SpecialCaseList to specify a list of functions that
7841 // must always return fully initialized values. For now, we hardcode "main".
7842 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (F.getName() == "main");
7843
7844 Value *Shadow = getShadow(RetVal);
7845 bool StoreOrigin = true;
7846 if (EagerCheck) {
7847 insertCheckShadowOf(RetVal, &I);
7848 Shadow = getCleanShadow(RetVal);
7849 StoreOrigin = false;
7850 }
7851
7852 // The caller may still expect information passed over TLS if we pass our
7853 // check
7854 if (StoreShadow) {
7855 IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
7856 if (MS.TrackOrigins && StoreOrigin)
7857 IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7858 }
7859 }
7860
7861 void visitPHINode(PHINode &I) {
7862 IRBuilder<> IRB(&I);
7863 if (!PropagateShadow) {
7864 setShadow(&I, getCleanShadow(&I));
7865 setOrigin(&I, getCleanOrigin());
7866 return;
7867 }
7868
7869 ShadowPHINodes.push_back(&I);
7870 setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
7871 "_msphi_s"));
7872 if (MS.TrackOrigins)
7873 setOrigin(
7874 &I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(), "_msphi_o"));
7875 }
7876
7877 Value *getLocalVarIdptr(AllocaInst &I) {
7878 ConstantInt *IntConst =
7879 ConstantInt::get(Type::getInt32Ty((*F.getParent()).getContext()), 0);
7880 return new GlobalVariable(*F.getParent(), IntConst->getType(),
7881 /*isConstant=*/false, GlobalValue::PrivateLinkage,
7882 IntConst);
7883 }
7884
7885 Value *getLocalVarDescription(AllocaInst &I) {
7886 return createPrivateConstGlobalForString(*F.getParent(), I.getName());
7887 }
7888
7889 void poisonAllocaUserspace(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
7890 if (PoisonStack && ClPoisonStackWithCall) {
7891 IRB.CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7892 } else {
7893 Value *ShadowBase, *OriginBase;
7894 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7895 &I, IRB, IRB.getInt8Ty(), Align(1), /*isStore*/ true);
7896
7897 Value *PoisonValue = IRB.getInt8(PoisonStack ? ClPoisonStackPattern : 0);
7898 IRB.CreateMemSet(ShadowBase, PoisonValue, Len, I.getAlign());
7899 }
7900
7901 if (PoisonStack && MS.TrackOrigins) {
7902 Value *Idptr = getLocalVarIdptr(I);
7903 if (ClPrintStackNames) {
7904 Value *Descr = getLocalVarDescription(I);
7905 IRB.CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7906 {&I, Len, Idptr, Descr});
7907 } else {
7908 IRB.CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7909 }
7910 }
7911 }
7912
7913 void poisonAllocaKmsan(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
7914 Value *Descr = getLocalVarDescription(I);
7915 if (PoisonStack) {
7916 IRB.CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
7917 } else {
7918 IRB.CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
7919 }
7920 }
7921
7922 void instrumentAlloca(AllocaInst &I, Instruction *InsPoint = nullptr) {
7923 if (!InsPoint)
7924 InsPoint = &I;
7925 NextNodeIRBuilder IRB(InsPoint);
7926 Value *Len = IRB.CreateAllocationSize(MS.IntptrTy, &I);
7927
7928 if (MS.CompileKernel)
7929 poisonAllocaKmsan(I, IRB, Len);
7930 else
7931 poisonAllocaUserspace(I, IRB, Len);
7932 }
7933
7934 void visitAllocaInst(AllocaInst &I) {
7935 setShadow(&I, getCleanShadow(&I));
7936 setOrigin(&I, getCleanOrigin());
7937 // We'll get to this alloca later unless it's poisoned at the corresponding
7938 // llvm.lifetime.start.
7939 AllocaSet.insert(&I);
7940 }
7941
7942 void visitSelectInst(SelectInst &I) {
7943 // a = select b, c, d
7944 Value *B = I.getCondition();
7945 Value *C = I.getTrueValue();
7946 Value *D = I.getFalseValue();
7947
7948 handleSelectLikeInst(I, B, C, D);
7949 }
7950
7951 void handleSelectLikeInst(Instruction &I, Value *B, Value *C, Value *D) {
7952 IRBuilder<> IRB(&I);
7953
7954 Value *Sb = getShadow(B);
7955 Value *Sc = getShadow(C);
7956 Value *Sd = getShadow(D);
7957
7958 Value *Ob = MS.TrackOrigins ? getOrigin(B) : nullptr;
7959 Value *Oc = MS.TrackOrigins ? getOrigin(C) : nullptr;
7960 Value *Od = MS.TrackOrigins ? getOrigin(D) : nullptr;
7961
7962 // Result shadow if condition shadow is 0.
7963 Value *Sa0 = IRB.CreateSelect(B, Sc, Sd);
7964 Value *Sa1;
7965 if (I.getType()->isAggregateType()) {
7966 // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do
7967 // an extra "select". This results in much more compact IR.
7968 // Sa = select Sb, poisoned, (select b, Sc, Sd)
7969 Sa1 = getPoisonedShadow(getShadowTy(I.getType()));
7970 } else if (isScalableNonVectorType(I.getType())) {
7971 // This is intended to handle target("aarch64.svcount"), which can't be
7972 // handled in the else branch because of incompatibility with CreateXor
7973 // ("The supported LLVM operations on this type are limited to load,
7974 // store, phi, select and alloca instructions").
7975
7976 // TODO: this currently underapproximates. Use Arm SVE EOR in the else
7977 // branch as needed instead.
7978 Sa1 = getCleanShadow(getShadowTy(I.getType()));
7979 } else {
7980 // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ]
7981 // If Sb (condition is poisoned), look for bits in c and d that are equal
7982 // and both unpoisoned.
7983 // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd.
7984
7985 // Cast arguments to shadow-compatible type.
7986 C = CreateAppToShadowCast(IRB, C);
7987 D = CreateAppToShadowCast(IRB, D);
7988
7989 // Result shadow if condition shadow is 1.
7990 Sa1 = IRB.CreateOr({IRB.CreateXor(C, D), Sc, Sd});
7991 }
7992 Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
7993 setShadow(&I, Sa);
7994 if (MS.TrackOrigins) {
7995 // Origins are always i32, so any vector conditions must be flattened.
7996 // FIXME: consider tracking vector origins for app vectors?
7997 if (B->getType()->isVectorTy()) {
7998 B = convertToBool(B, IRB);
7999 Sb = convertToBool(Sb, IRB);
8000 }
8001 // a = select b, c, d
8002 // Oa = Sb ? Ob : (b ? Oc : Od)
8003 setOrigin(&I, IRB.CreateSelect(Sb, Ob, IRB.CreateSelect(B, Oc, Od)));
8004 }
8005 }
8006
8007 void visitLandingPadInst(LandingPadInst &I) {
8008 // Do nothing.
8009 // See https://github.com/google/sanitizers/issues/504
8010 setShadow(&I, getCleanShadow(&I));
8011 setOrigin(&I, getCleanOrigin());
8012 }
8013
8014 void visitCatchSwitchInst(CatchSwitchInst &I) {
8015 setShadow(&I, getCleanShadow(&I));
8016 setOrigin(&I, getCleanOrigin());
8017 }
8018
8019 void visitFuncletPadInst(FuncletPadInst &I) {
8020 setShadow(&I, getCleanShadow(&I));
8021 setOrigin(&I, getCleanOrigin());
8022 }
8023
8024 void visitGetElementPtrInst(GetElementPtrInst &I) { handleShadowOr(I); }
8025
8026 void visitExtractValueInst(ExtractValueInst &I) {
8027 IRBuilder<> IRB(&I);
8028 Value *Agg = I.getAggregateOperand();
8029 LLVM_DEBUG(dbgs() << "ExtractValue: " << I << "\n");
8030 Value *AggShadow = getShadow(Agg);
8031 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
8032 Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
8033 LLVM_DEBUG(dbgs() << " ResShadow: " << *ResShadow << "\n");
8034 setShadow(&I, ResShadow);
8035 setOriginForNaryOp(I);
8036 }
8037
8038 void visitInsertValueInst(InsertValueInst &I) {
8039 IRBuilder<> IRB(&I);
8040 LLVM_DEBUG(dbgs() << "InsertValue: " << I << "\n");
8041 Value *AggShadow = getShadow(I.getAggregateOperand());
8042 Value *InsShadow = getShadow(I.getInsertedValueOperand());
8043 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
8044 LLVM_DEBUG(dbgs() << " InsShadow: " << *InsShadow << "\n");
8045 Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
8046 LLVM_DEBUG(dbgs() << " Res: " << *Res << "\n");
8047 setShadow(&I, Res);
8048 setOriginForNaryOp(I);
8049 }
8050
8051 void dumpInst(Instruction &I, const Twine &Prefix) {
8052 // Instruction name only
8053 // For intrinsics, the full/overloaded name is used
8054 //
8055 // e.g., "call llvm.aarch64.neon.uqsub.v16i8"
8056 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
8057 errs() << "ZZZ:" << Prefix << " call "
8058 << CI->getCalledFunction()->getName() << "\n";
8059 } else {
8060 errs() << "ZZZ:" << Prefix << " " << I.getOpcodeName() << "\n";
8061 }
8062
8063 // Instruction prototype (including return type and parameter types)
8064 // For intrinsics, we use the base/non-overloaded name
8065 //
8066 // e.g., "call <16 x i8> @llvm.aarch64.neon.uqsub(<16 x i8>, <16 x i8>)"
8067 unsigned NumOperands = I.getNumOperands();
8068 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
8069 errs() << "YYY:" << Prefix << " call " << *I.getType() << " @";
8070
8071 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI))
8072 errs() << Intrinsic::getBaseName(II->getIntrinsicID());
8073 else
8074 errs() << CI->getCalledFunction()->getName();
8075
8076 errs() << "(";
8077
8078 // The last operand of a CallInst is the function itself.
8079 NumOperands--;
8080 } else
8081 errs() << "YYY:" << Prefix << " " << *I.getType() << " "
8082 << I.getOpcodeName() << "(";
8083
8084 for (size_t i = 0; i < NumOperands; i++) {
8085 if (i > 0)
8086 errs() << ", ";
8087
8088 errs() << *(I.getOperand(i)->getType());
8089 }
8090
8091 errs() << ")\n";
8092
8093 // Full instruction, including types and operand values
8094 // For intrinsics, the full/overloaded name is used
8095 //
8096 // e.g., "%vqsubq_v.i15 = call noundef <16 x i8>
8097 // @llvm.aarch64.neon.uqsub.v16i8(<16 x i8> %vext21.i,
8098 // <16 x i8> splat (i8 1)), !dbg !66"
8099 errs() << "QQQ:" << Prefix << " " << I << "\n";
8100 }
8101
8102 void visitResumeInst(ResumeInst &I) {
8103 LLVM_DEBUG(dbgs() << "Resume: " << I << "\n");
8104 // Nothing to do here.
8105 }
8106
8107 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8108 LLVM_DEBUG(dbgs() << "CleanupReturn: " << CRI << "\n");
8109 // Nothing to do here.
8110 }
8111
8112 void visitCatchReturnInst(CatchReturnInst &CRI) {
8113 LLVM_DEBUG(dbgs() << "CatchReturn: " << CRI << "\n");
8114 // Nothing to do here.
8115 }
8116
8117 void instrumentAsmArgument(Value *Operand, Type *ElemTy, Instruction &I,
8118 IRBuilder<> &IRB, const DataLayout &DL,
8119 bool isOutput) {
8120 // For each assembly argument, we check its value for being initialized.
8121 // If the argument is a pointer, we assume it points to a single element
8122 // of the corresponding type (or to a 8-byte word, if the type is unsized).
8123 // Each such pointer is instrumented with a call to the runtime library.
8124 Type *OpType = Operand->getType();
8125 // Check the operand value itself.
8126 insertCheckShadowOf(Operand, &I);
8127 if (!OpType->isPointerTy() || !isOutput) {
8128 assert(!isOutput);
8129 return;
8130 }
8131 if (!ElemTy->isSized())
8132 return;
8133 auto Size = DL.getTypeStoreSize(ElemTy);
8134 Value *SizeVal = IRB.CreateTypeSize(MS.IntptrTy, Size);
8135 if (MS.CompileKernel) {
8136 IRB.CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8137 } else {
8138 // ElemTy, derived from elementtype(), does not encode the alignment of
8139 // the pointer. Conservatively assume that the shadow memory is unaligned.
8140 // When Size is large, avoid StoreInst as it would expand to many
8141 // instructions.
8142 auto [ShadowPtr, _] =
8143 getShadowOriginPtrUserspace(Operand, IRB, IRB.getInt8Ty(), Align(1));
8144 if (Size <= 32)
8145 IRB.CreateAlignedStore(getCleanShadow(ElemTy), ShadowPtr, Align(1));
8146 else
8147 IRB.CreateMemSet(ShadowPtr, ConstantInt::getNullValue(IRB.getInt8Ty()),
8148 SizeVal, Align(1));
8149 }
8150 }
8151
8152 /// Get the number of output arguments returned by pointers.
8153 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8154 int NumRetOutputs = 0;
8155 int NumOutputs = 0;
8156 Type *RetTy = cast<Value>(CB)->getType();
8157 if (!RetTy->isVoidTy()) {
8158 // Register outputs are returned via the CallInst return value.
8159 auto *ST = dyn_cast<StructType>(RetTy);
8160 if (ST)
8161 NumRetOutputs = ST->getNumElements();
8162 else
8163 NumRetOutputs = 1;
8164 }
8165 InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
8166 for (const InlineAsm::ConstraintInfo &Info : Constraints) {
8167 switch (Info.Type) {
8169 NumOutputs++;
8170 break;
8171 default:
8172 break;
8173 }
8174 }
8175 return NumOutputs - NumRetOutputs;
8176 }
8177
8178 void visitAsmInstruction(Instruction &I) {
8179 // Conservative inline assembly handling: check for poisoned shadow of
8180 // asm() arguments, then unpoison the result and all the memory locations
8181 // pointed to by those arguments.
8182 // An inline asm() statement in C++ contains lists of input and output
8183 // arguments used by the assembly code. These are mapped to operands of the
8184 // CallInst as follows:
8185 // - nR register outputs ("=r) are returned by value in a single structure
8186 // (SSA value of the CallInst);
8187 // - nO other outputs ("=m" and others) are returned by pointer as first
8188 // nO operands of the CallInst;
8189 // - nI inputs ("r", "m" and others) are passed to CallInst as the
8190 // remaining nI operands.
8191 // The total number of asm() arguments in the source is nR+nO+nI, and the
8192 // corresponding CallInst has nO+nI+1 operands (the last operand is the
8193 // function to be called).
8194 const DataLayout &DL = F.getDataLayout();
8195 CallBase *CB = cast<CallBase>(&I);
8196 IRBuilder<> IRB(&I);
8197 InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
8198 int OutputArgs = getNumOutputArgs(IA, CB);
8199 // The last operand of a CallInst is the function itself.
8200 int NumOperands = CB->getNumOperands() - 1;
8201
8202 // Check input arguments. Doing so before unpoisoning output arguments, so
8203 // that we won't overwrite uninit values before checking them.
8204 for (int i = OutputArgs; i < NumOperands; i++) {
8205 Value *Operand = CB->getOperand(i);
8206 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
8207 /*isOutput*/ false);
8208 }
8209 // Unpoison output arguments. This must happen before the actual InlineAsm
8210 // call, so that the shadow for memory published in the asm() statement
8211 // remains valid.
8212 for (int i = 0; i < OutputArgs; i++) {
8213 Value *Operand = CB->getOperand(i);
8214 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
8215 /*isOutput*/ true);
8216 }
8217
8218 setShadow(&I, getCleanShadow(&I));
8219 setOrigin(&I, getCleanOrigin());
8220 }
8221
8222 void visitFreezeInst(FreezeInst &I) {
8223 // Freeze always returns a fully defined value.
8224 setShadow(&I, getCleanShadow(&I));
8225 setOrigin(&I, getCleanOrigin());
8226 }
8227
8228 void visitInstruction(Instruction &I) {
8229 // Everything else: stop propagating and check for poisoned shadow.
8231 dumpInst(I, "Strict");
8232 LLVM_DEBUG(dbgs() << "DEFAULT: " << I << "\n");
8233 for (size_t i = 0, n = I.getNumOperands(); i < n; i++) {
8234 Value *Operand = I.getOperand(i);
8235 if (Operand->getType()->isSized())
8236 insertCheckShadowOf(Operand, &I);
8237 }
8238 setShadow(&I, getCleanShadow(&I));
8239 setOrigin(&I, getCleanOrigin());
8240 }
8241};
8242
8243struct VarArgHelperBase : public VarArgHelper {
8244 Function &F;
8245 MemorySanitizer &MS;
8246 MemorySanitizerVisitor &MSV;
8247 SmallVector<CallInst *, 16> VAStartInstrumentationList;
8248 const unsigned VAListTagSize;
8249
8250 VarArgHelperBase(Function &F, MemorySanitizer &MS,
8251 MemorySanitizerVisitor &MSV, unsigned VAListTagSize)
8252 : F(F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8253
8254 Value *getShadowAddrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
8255 Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
8256 return IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8257 }
8258
8259 /// Compute the shadow address for a given va_arg.
8260 Value *getShadowPtrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
8261 return IRB.CreatePtrAdd(
8262 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset), "_msarg_va_s");
8263 }
8264
8265 /// Compute the shadow address for a given va_arg.
8266 Value *getShadowPtrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset,
8267 unsigned ArgSize) {
8268 // Make sure we don't overflow __msan_va_arg_tls.
8269 if (ArgOffset + ArgSize > kParamTLSSize)
8270 return nullptr;
8271 return getShadowPtrForVAArgument(IRB, ArgOffset);
8272 }
8273
8274 /// Compute the origin address for a given va_arg.
8275 Value *getOriginPtrForVAArgument(IRBuilder<> &IRB, int ArgOffset) {
8276 // getOriginPtrForVAArgument() is always called after
8277 // getShadowPtrForVAArgument(), so __msan_va_arg_origin_tls can never
8278 // overflow.
8279 return IRB.CreatePtrAdd(MS.VAArgOriginTLS,
8280 ConstantInt::get(MS.IntptrTy, ArgOffset),
8281 "_msarg_va_o");
8282 }
8283
8284 void CleanUnusedTLS(IRBuilder<> &IRB, Value *ShadowBase,
8285 unsigned BaseOffset) {
8286 // The tails of __msan_va_arg_tls is not large enough to fit full
8287 // value shadow, but it will be copied to backup anyway. Make it
8288 // clean.
8289 if (BaseOffset >= kParamTLSSize)
8290 return;
8291 Value *TailSize =
8292 ConstantInt::getSigned(IRB.getInt32Ty(), kParamTLSSize - BaseOffset);
8293 IRB.CreateMemSet(ShadowBase, ConstantInt::getNullValue(IRB.getInt8Ty()),
8294 TailSize, Align(8));
8295 }
8296
8297 void unpoisonVAListTagForInst(IntrinsicInst &I) {
8298 IRBuilder<> IRB(&I);
8299 Value *VAListTag = I.getArgOperand(0);
8300 const Align Alignment = Align(8);
8301 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8302 VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
8303 // Unpoison the whole __va_list_tag.
8304 IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
8305 VAListTagSize, Alignment, false);
8306 }
8307
8308 void visitVAStartInst(VAStartInst &I) override {
8309 if (F.getCallingConv() == CallingConv::Win64)
8310 return;
8311 VAStartInstrumentationList.push_back(&I);
8312 unpoisonVAListTagForInst(I);
8313 }
8314
8315 void visitVACopyInst(VACopyInst &I) override {
8316 if (F.getCallingConv() == CallingConv::Win64)
8317 return;
8318 unpoisonVAListTagForInst(I);
8319 }
8320};
8321
8322/// AMD64-specific implementation of VarArgHelper.
8323struct VarArgAMD64Helper : public VarArgHelperBase {
8324 // An unfortunate workaround for asymmetric lowering of va_arg stuff.
8325 // See a comment in visitCallBase for more details.
8326 static const unsigned AMD64GpEndOffset = 48; // AMD64 ABI Draft 0.99.6 p3.5.7
8327 static const unsigned AMD64FpEndOffsetSSE = 176;
8328 // If SSE is disabled, fp_offset in va_list is zero.
8329 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8330
8331 unsigned AMD64FpEndOffset;
8332 AllocaInst *VAArgTLSCopy = nullptr;
8333 AllocaInst *VAArgTLSOriginCopy = nullptr;
8334 Value *VAArgOverflowSize = nullptr;
8335
8336 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8337
8338 VarArgAMD64Helper(Function &F, MemorySanitizer &MS,
8339 MemorySanitizerVisitor &MSV)
8340 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/24) {
8341 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8342 for (const auto &Attr : F.getAttributes().getFnAttrs()) {
8343 if (Attr.isStringAttribute() &&
8344 (Attr.getKindAsString() == "target-features")) {
8345 if (Attr.getValueAsString().contains("-sse"))
8346 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8347 break;
8348 }
8349 }
8350 }
8351
8352 ArgKind classifyArgument(Value *arg) {
8353 // A very rough approximation of X86_64 argument classification rules.
8354 Type *T = arg->getType();
8355 if (T->isX86_FP80Ty())
8356 return AK_Memory;
8357 if (T->isFPOrFPVectorTy())
8358 return AK_FloatingPoint;
8359 if (T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64)
8360 return AK_GeneralPurpose;
8361 if (T->isPointerTy())
8362 return AK_GeneralPurpose;
8363 return AK_Memory;
8364 }
8365
8366 // For VarArg functions, store the argument shadow in an ABI-specific format
8367 // that corresponds to va_list layout.
8368 // We do this because Clang lowers va_arg in the frontend, and this pass
8369 // only sees the low level code that deals with va_list internals.
8370 // A much easier alternative (provided that Clang emits va_arg instructions)
8371 // would have been to associate each live instance of va_list with a copy of
8372 // MSanParamTLS, and extract shadow on va_arg() call in the argument list
8373 // order.
8374 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8375 unsigned GpOffset = 0;
8376 unsigned FpOffset = AMD64GpEndOffset;
8377 unsigned OverflowOffset = AMD64FpEndOffset;
8378 const DataLayout &DL = F.getDataLayout();
8379
8380 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8381 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8382 bool IsByVal = CB.isByValArgument(ArgNo);
8383 if (IsByVal) {
8384 // ByVal arguments always go to the overflow area.
8385 // Fixed arguments passed through the overflow area will be stepped
8386 // over by va_start, so don't count them towards the offset.
8387 if (IsFixed)
8388 continue;
8389 assert(A->getType()->isPointerTy());
8390 Type *RealTy = CB.getParamByValType(ArgNo);
8391 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
8392 uint64_t AlignedSize = alignTo(ArgSize, 8);
8393 unsigned BaseOffset = OverflowOffset;
8394 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8395 Value *OriginBase = nullptr;
8396 if (MS.TrackOrigins)
8397 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8398 OverflowOffset += AlignedSize;
8399
8400 if (OverflowOffset > kParamTLSSize) {
8401 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8402 continue; // We have no space to copy shadow there.
8403 }
8404
8405 Value *ShadowPtr, *OriginPtr;
8406 std::tie(ShadowPtr, OriginPtr) =
8407 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), kShadowTLSAlignment,
8408 /*isStore*/ false);
8409 IRB.CreateMemCpy(ShadowBase, kShadowTLSAlignment, ShadowPtr,
8410 kShadowTLSAlignment, ArgSize);
8411 if (MS.TrackOrigins)
8412 IRB.CreateMemCpy(OriginBase, kShadowTLSAlignment, OriginPtr,
8413 kShadowTLSAlignment, ArgSize);
8414 } else {
8415 ArgKind AK = classifyArgument(A);
8416 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8417 AK = AK_Memory;
8418 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8419 AK = AK_Memory;
8420 Value *ShadowBase, *OriginBase = nullptr;
8421 switch (AK) {
8422 case AK_GeneralPurpose:
8423 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8424 if (MS.TrackOrigins)
8425 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8426 GpOffset += 8;
8427 assert(GpOffset <= kParamTLSSize);
8428 break;
8429 case AK_FloatingPoint:
8430 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8431 if (MS.TrackOrigins)
8432 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8433 FpOffset += 16;
8434 assert(FpOffset <= kParamTLSSize);
8435 break;
8436 case AK_Memory:
8437 if (IsFixed)
8438 continue;
8439 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8440 uint64_t AlignedSize = alignTo(ArgSize, 8);
8441 unsigned BaseOffset = OverflowOffset;
8442 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8443 if (MS.TrackOrigins) {
8444 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8445 }
8446 OverflowOffset += AlignedSize;
8447 if (OverflowOffset > kParamTLSSize) {
8448 // We have no space to copy shadow there.
8449 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8450 continue;
8451 }
8452 }
8453 // Take fixed arguments into account for GpOffset and FpOffset,
8454 // but don't actually store shadows for them.
8455 // TODO(glider): don't call get*PtrForVAArgument() for them.
8456 if (IsFixed)
8457 continue;
8458 Value *Shadow = MSV.getShadow(A);
8459 IRB.CreateAlignedStore(Shadow, ShadowBase, kShadowTLSAlignment);
8460 if (MS.TrackOrigins) {
8461 Value *Origin = MSV.getOrigin(A);
8462 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
8463 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8465 }
8466 }
8467 }
8468 Constant *OverflowSize =
8469 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8470 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8471 }
8472
8473 void finalizeInstrumentation() override {
8474 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8475 "finalizeInstrumentation called twice");
8476 if (!VAStartInstrumentationList.empty()) {
8477 // If there is a va_start in this function, make a backup copy of
8478 // va_arg_tls somewhere in the function entry block.
8479 IRBuilder<> IRB(MSV.FnPrologueEnd);
8480 VAArgOverflowSize =
8481 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8482 Value *CopySize = IRB.CreateAdd(
8483 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8484 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8485 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8486 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8487 CopySize, kShadowTLSAlignment, false);
8488
8489 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8490 Intrinsic::umin, CopySize,
8491 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
8492 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8493 kShadowTLSAlignment, SrcSize);
8494 if (MS.TrackOrigins) {
8495 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8496 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
8497 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
8498 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
8499 }
8500 }
8501
8502 // Instrument va_start.
8503 // Copy va_list shadow from the backup copy of the TLS contents.
8504 for (CallInst *OrigInst : VAStartInstrumentationList) {
8505 NextNodeIRBuilder IRB(OrigInst);
8506 Value *VAListTag = OrigInst->getArgOperand(0);
8507
8508 Value *RegSaveAreaPtrPtr =
8509 IRB.CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8510 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
8511 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8512 const Align Alignment = Align(16);
8513 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8514 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8515 Alignment, /*isStore*/ true);
8516 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8517 AMD64FpEndOffset);
8518 if (MS.TrackOrigins)
8519 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8520 Alignment, AMD64FpEndOffset);
8521 Value *OverflowArgAreaPtrPtr =
8522 IRB.CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8523 Value *OverflowArgAreaPtr =
8524 IRB.CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8525 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8526 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8527 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
8528 Alignment, /*isStore*/ true);
8529 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
8530 AMD64FpEndOffset);
8531 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8532 VAArgOverflowSize);
8533 if (MS.TrackOrigins) {
8534 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
8535 AMD64FpEndOffset);
8536 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8537 VAArgOverflowSize);
8538 }
8539 }
8540 }
8541};
8542
8543/// AArch64-specific implementation of VarArgHelper.
8544struct VarArgAArch64Helper : public VarArgHelperBase {
8545 static const unsigned kAArch64GrArgSize = 64;
8546 static const unsigned kAArch64VrArgSize = 128;
8547
8548 static const unsigned AArch64GrBegOffset = 0;
8549 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8550 // Make VR space aligned to 16 bytes.
8551 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8552 static const unsigned AArch64VrEndOffset =
8553 AArch64VrBegOffset + kAArch64VrArgSize;
8554 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8555
8556 AllocaInst *VAArgTLSCopy = nullptr;
8557 Value *VAArgOverflowSize = nullptr;
8558
8559 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8560
8561 VarArgAArch64Helper(Function &F, MemorySanitizer &MS,
8562 MemorySanitizerVisitor &MSV)
8563 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/32) {}
8564
8565 // A very rough approximation of aarch64 argument classification rules.
8566 std::pair<ArgKind, uint64_t> classifyArgument(Type *T) {
8567 if (T->isIntOrPtrTy() && T->getPrimitiveSizeInBits() <= 64)
8568 return {AK_GeneralPurpose, 1};
8569 if (T->isFloatingPointTy() && T->getPrimitiveSizeInBits() <= 128)
8570 return {AK_FloatingPoint, 1};
8571
8572 if (T->isArrayTy()) {
8573 auto R = classifyArgument(T->getArrayElementType());
8574 R.second *= T->getScalarType()->getArrayNumElements();
8575 return R;
8576 }
8577
8578 if (const FixedVectorType *FV = dyn_cast<FixedVectorType>(T)) {
8579 auto R = classifyArgument(FV->getScalarType());
8580 R.second *= FV->getNumElements();
8581 return R;
8582 }
8583
8584 LLVM_DEBUG(errs() << "Unknown vararg type: " << *T << "\n");
8585 return {AK_Memory, 0};
8586 }
8587
8588 // The instrumentation stores the argument shadow in a non ABI-specific
8589 // format because it does not know which argument is named (since Clang,
8590 // like x86_64 case, lowers the va_args in the frontend and this pass only
8591 // sees the low level code that deals with va_list internals).
8592 // The first seven GR registers are saved in the first 56 bytes of the
8593 // va_arg tls arra, followed by the first 8 FP/SIMD registers, and then
8594 // the remaining arguments.
8595 // Using constant offset within the va_arg TLS array allows fast copy
8596 // in the finalize instrumentation.
8597 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8598 unsigned GrOffset = AArch64GrBegOffset;
8599 unsigned VrOffset = AArch64VrBegOffset;
8600 unsigned OverflowOffset = AArch64VAEndOffset;
8601
8602 const DataLayout &DL = F.getDataLayout();
8603 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8604 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8605 auto [AK, RegNum] = classifyArgument(A->getType());
8606 if (AK == AK_GeneralPurpose &&
8607 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8608 AK = AK_Memory;
8609 if (AK == AK_FloatingPoint &&
8610 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8611 AK = AK_Memory;
8612 Value *Base;
8613 switch (AK) {
8614 case AK_GeneralPurpose:
8615 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8616 GrOffset += 8 * RegNum;
8617 break;
8618 case AK_FloatingPoint:
8619 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8620 VrOffset += 16 * RegNum;
8621 break;
8622 case AK_Memory:
8623 // Don't count fixed arguments in the overflow area - va_start will
8624 // skip right over them.
8625 if (IsFixed)
8626 continue;
8627 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8628 uint64_t AlignedSize = alignTo(ArgSize, 8);
8629 unsigned BaseOffset = OverflowOffset;
8630 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8631 OverflowOffset += AlignedSize;
8632 if (OverflowOffset > kParamTLSSize) {
8633 // We have no space to copy shadow there.
8634 CleanUnusedTLS(IRB, Base, BaseOffset);
8635 continue;
8636 }
8637 break;
8638 }
8639 // Count Gp/Vr fixed arguments to their respective offsets, but don't
8640 // bother to actually store a shadow.
8641 if (IsFixed)
8642 continue;
8643 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
8644 }
8645 Constant *OverflowSize =
8646 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8647 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8648 }
8649
8650 // Retrieve a va_list field of 'void*' size.
8651 Value *getVAField64(IRBuilder<> &IRB, Value *VAListTag, int offset) {
8652 Value *SaveAreaPtrPtr =
8653 IRB.CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8654 return IRB.CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8655 }
8656
8657 // Retrieve a va_list field of 'int' size.
8658 Value *getVAField32(IRBuilder<> &IRB, Value *VAListTag, int offset) {
8659 Value *SaveAreaPtr =
8660 IRB.CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8661 Value *SaveArea32 = IRB.CreateLoad(IRB.getInt32Ty(), SaveAreaPtr);
8662 return IRB.CreateSExt(SaveArea32, MS.IntptrTy);
8663 }
8664
8665 void finalizeInstrumentation() override {
8666 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8667 "finalizeInstrumentation called twice");
8668 if (!VAStartInstrumentationList.empty()) {
8669 // If there is a va_start in this function, make a backup copy of
8670 // va_arg_tls somewhere in the function entry block.
8671 IRBuilder<> IRB(MSV.FnPrologueEnd);
8672 VAArgOverflowSize =
8673 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8674 Value *CopySize = IRB.CreateAdd(
8675 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8676 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8677 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8678 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8679 CopySize, kShadowTLSAlignment, false);
8680
8681 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8682 Intrinsic::umin, CopySize,
8683 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
8684 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8685 kShadowTLSAlignment, SrcSize);
8686 }
8687
8688 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8689 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8690
8691 // Instrument va_start, copy va_list shadow from the backup copy of
8692 // the TLS contents.
8693 for (CallInst *OrigInst : VAStartInstrumentationList) {
8694 NextNodeIRBuilder IRB(OrigInst);
8695
8696 Value *VAListTag = OrigInst->getArgOperand(0);
8697
8698 // The variadic ABI for AArch64 creates two areas to save the incoming
8699 // argument registers (one for 64-bit general register xn-x7 and another
8700 // for 128-bit FP/SIMD vn-v7).
8701 // We need then to propagate the shadow arguments on both regions
8702 // 'va::__gr_top + va::__gr_offs' and 'va::__vr_top + va::__vr_offs'.
8703 // The remaining arguments are saved on shadow for 'va::stack'.
8704 // One caveat is it requires only to propagate the non-named arguments,
8705 // however on the call site instrumentation 'all' the arguments are
8706 // saved. So to copy the shadow values from the va_arg TLS array
8707 // we need to adjust the offset for both GR and VR fields based on
8708 // the __{gr,vr}_offs value (since they are stores based on incoming
8709 // named arguments).
8710 Type *RegSaveAreaPtrTy = IRB.getPtrTy();
8711
8712 // Read the stack pointer from the va_list.
8713 Value *StackSaveAreaPtr =
8714 IRB.CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8715
8716 // Read both the __gr_top and __gr_off and add them up.
8717 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8718 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8719
8720 Value *GrRegSaveAreaPtr = IRB.CreateIntToPtr(
8721 IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8722
8723 // Read both the __vr_top and __vr_off and add them up.
8724 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8725 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8726
8727 Value *VrRegSaveAreaPtr = IRB.CreateIntToPtr(
8728 IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8729
8730 // It does not know how many named arguments is being used and, on the
8731 // callsite all the arguments were saved. Since __gr_off is defined as
8732 // '0 - ((8 - named_gr) * 8)', the idea is to just propagate the variadic
8733 // argument by ignoring the bytes of shadow from named arguments.
8734 Value *GrRegSaveAreaShadowPtrOff =
8735 IRB.CreateAdd(GrArgSize, GrOffSaveArea);
8736
8737 Value *GrRegSaveAreaShadowPtr =
8738 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8739 Align(8), /*isStore*/ true)
8740 .first;
8741
8742 Value *GrSrcPtr =
8743 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy, GrRegSaveAreaShadowPtrOff);
8744 Value *GrCopySize = IRB.CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8745
8746 IRB.CreateMemCpy(GrRegSaveAreaShadowPtr, Align(8), GrSrcPtr, Align(8),
8747 GrCopySize);
8748
8749 // Again, but for FP/SIMD values.
8750 Value *VrRegSaveAreaShadowPtrOff =
8751 IRB.CreateAdd(VrArgSize, VrOffSaveArea);
8752
8753 Value *VrRegSaveAreaShadowPtr =
8754 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8755 Align(8), /*isStore*/ true)
8756 .first;
8757
8758 Value *VrSrcPtr = IRB.CreateInBoundsPtrAdd(
8759 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy,
8760 IRB.getInt32(AArch64VrBegOffset)),
8761 VrRegSaveAreaShadowPtrOff);
8762 Value *VrCopySize = IRB.CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8763
8764 IRB.CreateMemCpy(VrRegSaveAreaShadowPtr, Align(8), VrSrcPtr, Align(8),
8765 VrCopySize);
8766
8767 // And finally for remaining arguments.
8768 Value *StackSaveAreaShadowPtr =
8769 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.getInt8Ty(),
8770 Align(16), /*isStore*/ true)
8771 .first;
8772
8773 Value *StackSrcPtr = IRB.CreateInBoundsPtrAdd(
8774 VAArgTLSCopy, IRB.getInt32(AArch64VAEndOffset));
8775
8776 IRB.CreateMemCpy(StackSaveAreaShadowPtr, Align(16), StackSrcPtr,
8777 Align(16), VAArgOverflowSize);
8778 }
8779 }
8780};
8781
8782/// PowerPC64-specific implementation of VarArgHelper.
8783struct VarArgPowerPC64Helper : public VarArgHelperBase {
8784 AllocaInst *VAArgTLSCopy = nullptr;
8785 Value *VAArgSize = nullptr;
8786
8787 VarArgPowerPC64Helper(Function &F, MemorySanitizer &MS,
8788 MemorySanitizerVisitor &MSV)
8789 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/8) {}
8790
8791 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8792 // For PowerPC, we need to deal with alignment of stack arguments -
8793 // they are mostly aligned to 8 bytes, but vectors and i128 arrays
8794 // are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
8795 // For that reason, we compute current offset from stack pointer (which is
8796 // always properly aligned), and offset for the first vararg, then subtract
8797 // them.
8798 unsigned VAArgBase;
8799 Triple TargetTriple(F.getParent()->getTargetTriple());
8800 // Parameter save area starts at 48 bytes from frame pointer for ABIv1,
8801 // and 32 bytes for ABIv2. This is usually determined by target
8802 // endianness, but in theory could be overridden by function attribute.
8803 if (TargetTriple.isPPC64ELFv2ABI())
8804 VAArgBase = 32;
8805 else
8806 VAArgBase = 48;
8807 unsigned VAArgOffset = VAArgBase;
8808 const DataLayout &DL = F.getDataLayout();
8809 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8810 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8811 bool IsByVal = CB.isByValArgument(ArgNo);
8812 if (IsByVal) {
8813 assert(A->getType()->isPointerTy());
8814 Type *RealTy = CB.getParamByValType(ArgNo);
8815 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
8816 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(8));
8817 if (ArgAlign < 8)
8818 ArgAlign = Align(8);
8819 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
8820 if (!IsFixed) {
8821 Value *Base =
8822 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8823 if (Base) {
8824 Value *AShadowPtr, *AOriginPtr;
8825 std::tie(AShadowPtr, AOriginPtr) =
8826 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
8827 kShadowTLSAlignment, /*isStore*/ false);
8828
8829 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
8830 kShadowTLSAlignment, ArgSize);
8831 }
8832 }
8833 VAArgOffset += alignTo(ArgSize, Align(8));
8834 } else {
8835 Value *Base;
8836 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8837 Align ArgAlign = Align(8);
8838 if (A->getType()->isArrayTy()) {
8839 // Arrays are aligned to element size, except for long double
8840 // arrays, which are aligned to 8 bytes.
8841 Type *ElementTy = A->getType()->getArrayElementType();
8842 if (!ElementTy->isPPC_FP128Ty())
8843 ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
8844 } else if (A->getType()->isVectorTy()) {
8845 // Vectors are naturally aligned.
8846 ArgAlign = Align(ArgSize);
8847 }
8848 if (ArgAlign < 8)
8849 ArgAlign = Align(8);
8850 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
8851 if (DL.isBigEndian()) {
8852 // Adjusting the shadow for argument with size < 8 to match the
8853 // placement of bits in big endian system
8854 if (ArgSize < 8)
8855 VAArgOffset += (8 - ArgSize);
8856 }
8857 if (!IsFixed) {
8858 Base =
8859 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8860 if (Base)
8861 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
8862 }
8863 VAArgOffset += ArgSize;
8864 VAArgOffset = alignTo(VAArgOffset, Align(8));
8865 }
8866 if (IsFixed)
8867 VAArgBase = VAArgOffset;
8868 }
8869
8870 Constant *TotalVAArgSize =
8871 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8872 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
8873 // a new class member i.e. it is the total size of all VarArgs.
8874 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8875 }
8876
8877 void finalizeInstrumentation() override {
8878 assert(!VAArgSize && !VAArgTLSCopy &&
8879 "finalizeInstrumentation called twice");
8880 IRBuilder<> IRB(MSV.FnPrologueEnd);
8881 VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8882 Value *CopySize = VAArgSize;
8883
8884 if (!VAStartInstrumentationList.empty()) {
8885 // If there is a va_start in this function, make a backup copy of
8886 // va_arg_tls somewhere in the function entry block.
8887
8888 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8889 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8890 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8891 CopySize, kShadowTLSAlignment, false);
8892
8893 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8894 Intrinsic::umin, CopySize,
8895 ConstantInt::get(IRB.getInt64Ty(), kParamTLSSize));
8896 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8897 kShadowTLSAlignment, SrcSize);
8898 }
8899
8900 // Instrument va_start.
8901 // Copy va_list shadow from the backup copy of the TLS contents.
8902 for (CallInst *OrigInst : VAStartInstrumentationList) {
8903 NextNodeIRBuilder IRB(OrigInst);
8904 Value *VAListTag = OrigInst->getArgOperand(0);
8905 Value *RegSaveAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
8906
8907 RegSaveAreaPtrPtr = IRB.CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8908
8909 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
8910 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8911 const DataLayout &DL = F.getDataLayout();
8912 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
8913 const Align Alignment = Align(IntptrSize);
8914 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8915 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8916 Alignment, /*isStore*/ true);
8917 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8918 CopySize);
8919 }
8920 }
8921};
8922
8923/// PowerPC32-specific implementation of VarArgHelper.
8924struct VarArgPowerPC32Helper : public VarArgHelperBase {
8925 AllocaInst *VAArgTLSCopy = nullptr;
8926 Value *VAArgSize = nullptr;
8927
8928 VarArgPowerPC32Helper(Function &F, MemorySanitizer &MS,
8929 MemorySanitizerVisitor &MSV)
8930 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/12) {}
8931
8932 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8933 unsigned VAArgBase;
8934 // Parameter save area is 8 bytes from frame pointer in PPC32
8935 VAArgBase = 8;
8936 unsigned VAArgOffset = VAArgBase;
8937 const DataLayout &DL = F.getDataLayout();
8938 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
8939 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8940 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8941 bool IsByVal = CB.isByValArgument(ArgNo);
8942 if (IsByVal) {
8943 assert(A->getType()->isPointerTy());
8944 Type *RealTy = CB.getParamByValType(ArgNo);
8945 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
8946 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(IntptrSize));
8947 if (ArgAlign < IntptrSize)
8948 ArgAlign = Align(IntptrSize);
8949 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
8950 if (!IsFixed) {
8951 Value *Base =
8952 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8953 if (Base) {
8954 Value *AShadowPtr, *AOriginPtr;
8955 std::tie(AShadowPtr, AOriginPtr) =
8956 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
8957 kShadowTLSAlignment, /*isStore*/ false);
8958
8959 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
8960 kShadowTLSAlignment, ArgSize);
8961 }
8962 }
8963 VAArgOffset += alignTo(ArgSize, Align(IntptrSize));
8964 } else {
8965 Value *Base;
8966 Type *ArgTy = A->getType();
8967
8968 // On PPC 32 floating point variable arguments are stored in separate
8969 // area: fp_save_area = reg_save_area + 4*8. We do not copy shaodow for
8970 // them as they will be found when checking call arguments.
8971 if (!ArgTy->isFloatingPointTy()) {
8972 uint64_t ArgSize = DL.getTypeAllocSize(ArgTy);
8973 Align ArgAlign = Align(IntptrSize);
8974 if (ArgTy->isArrayTy()) {
8975 // Arrays are aligned to element size, except for long double
8976 // arrays, which are aligned to 8 bytes.
8977 Type *ElementTy = ArgTy->getArrayElementType();
8978 if (!ElementTy->isPPC_FP128Ty())
8979 ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
8980 } else if (ArgTy->isVectorTy()) {
8981 // Vectors are naturally aligned.
8982 ArgAlign = Align(ArgSize);
8983 }
8984 if (ArgAlign < IntptrSize)
8985 ArgAlign = Align(IntptrSize);
8986 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
8987 if (DL.isBigEndian()) {
8988 // Adjusting the shadow for argument with size < IntptrSize to match
8989 // the placement of bits in big endian system
8990 if (ArgSize < IntptrSize)
8991 VAArgOffset += (IntptrSize - ArgSize);
8992 }
8993 if (!IsFixed) {
8994 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
8995 ArgSize);
8996 if (Base)
8997 IRB.CreateAlignedStore(MSV.getShadow(A), Base,
8999 }
9000 VAArgOffset += ArgSize;
9001 VAArgOffset = alignTo(VAArgOffset, Align(IntptrSize));
9002 }
9003 }
9004 }
9005
9006 Constant *TotalVAArgSize =
9007 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
9008 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9009 // a new class member i.e. it is the total size of all VarArgs.
9010 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9011 }
9012
9013 void finalizeInstrumentation() override {
9014 assert(!VAArgSize && !VAArgTLSCopy &&
9015 "finalizeInstrumentation called twice");
9016 IRBuilder<> IRB(MSV.FnPrologueEnd);
9017 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9018 Value *CopySize = VAArgSize;
9019
9020 if (!VAStartInstrumentationList.empty()) {
9021 // If there is a va_start in this function, make a backup copy of
9022 // va_arg_tls somewhere in the function entry block.
9023
9024 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9025 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9026 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9027 CopySize, kShadowTLSAlignment, false);
9028
9029 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9030 Intrinsic::umin, CopySize,
9031 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9032 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9033 kShadowTLSAlignment, SrcSize);
9034 }
9035
9036 // Instrument va_start.
9037 // Copy va_list shadow from the backup copy of the TLS contents.
9038 for (CallInst *OrigInst : VAStartInstrumentationList) {
9039 NextNodeIRBuilder IRB(OrigInst);
9040 Value *VAListTag = OrigInst->getArgOperand(0);
9041 Value *RegSaveAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
9042 Value *RegSaveAreaSize = CopySize;
9043
9044 // In PPC32 va_list_tag is a struct
9045 RegSaveAreaPtrPtr =
9046 IRB.CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9047
9048 // On PPC 32 reg_save_area can only hold 32 bytes of data
9049 RegSaveAreaSize = IRB.CreateBinaryIntrinsic(
9050 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9051
9052 RegSaveAreaPtrPtr = IRB.CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9053 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
9054
9055 const DataLayout &DL = F.getDataLayout();
9056 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9057 const Align Alignment = Align(IntptrSize);
9058
9059 { // Copy reg save area
9060 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9061 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9062 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9063 Alignment, /*isStore*/ true);
9064 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9065 Alignment, RegSaveAreaSize);
9066
9067 RegSaveAreaShadowPtr =
9068 IRB.CreatePtrToInt(RegSaveAreaShadowPtr, MS.IntptrTy);
9069 Value *FPSaveArea = IRB.CreateAdd(RegSaveAreaShadowPtr,
9070 ConstantInt::get(MS.IntptrTy, 32));
9071 FPSaveArea = IRB.CreateIntToPtr(FPSaveArea, MS.PtrTy);
9072 // We fill fp shadow with zeroes as uninitialized fp args should have
9073 // been found during call base check
9074 IRB.CreateMemSet(FPSaveArea, ConstantInt::getNullValue(IRB.getInt8Ty()),
9075 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9076 }
9077
9078 { // Copy overflow area
9079 // RegSaveAreaSize is min(CopySize, 32) -> no overflow can occur
9080 Value *OverflowAreaSize = IRB.CreateSub(CopySize, RegSaveAreaSize);
9081
9082 Value *OverflowAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
9083 OverflowAreaPtrPtr =
9084 IRB.CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9085 OverflowAreaPtrPtr = IRB.CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9086
9087 Value *OverflowAreaPtr = IRB.CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9088
9089 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9090 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9091 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.getInt8Ty(),
9092 Alignment, /*isStore*/ true);
9093
9094 Value *OverflowVAArgTLSCopyPtr =
9095 IRB.CreatePtrToInt(VAArgTLSCopy, MS.IntptrTy);
9096 OverflowVAArgTLSCopyPtr =
9097 IRB.CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9098
9099 OverflowVAArgTLSCopyPtr =
9100 IRB.CreateIntToPtr(OverflowVAArgTLSCopyPtr, MS.PtrTy);
9101 IRB.CreateMemCpy(OverflowAreaShadowPtr, Alignment,
9102 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9103 }
9104 }
9105 }
9106};
9107
9108/// SystemZ-specific implementation of VarArgHelper.
9109struct VarArgSystemZHelper : public VarArgHelperBase {
9110 static const unsigned SystemZGpOffset = 16;
9111 static const unsigned SystemZGpEndOffset = 56;
9112 static const unsigned SystemZFpOffset = 128;
9113 static const unsigned SystemZFpEndOffset = 160;
9114 static const unsigned SystemZMaxVrArgs = 8;
9115 static const unsigned SystemZRegSaveAreaSize = 160;
9116 static const unsigned SystemZOverflowOffset = 160;
9117 static const unsigned SystemZVAListTagSize = 32;
9118 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9119 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9120
9121 bool IsSoftFloatABI;
9122 AllocaInst *VAArgTLSCopy = nullptr;
9123 AllocaInst *VAArgTLSOriginCopy = nullptr;
9124 Value *VAArgOverflowSize = nullptr;
9125
9126 enum class ArgKind {
9127 GeneralPurpose,
9128 FloatingPoint,
9129 Vector,
9130 Memory,
9131 Indirect,
9132 };
9133
9134 enum class ShadowExtension { None, Zero, Sign };
9135
9136 VarArgSystemZHelper(Function &F, MemorySanitizer &MS,
9137 MemorySanitizerVisitor &MSV)
9138 : VarArgHelperBase(F, MS, MSV, SystemZVAListTagSize),
9139 IsSoftFloatABI(F.getFnAttribute("use-soft-float").getValueAsBool()) {}
9140
9141 ArgKind classifyArgument(Type *T) {
9142 // T is a SystemZABIInfo::classifyArgumentType() output, and there are
9143 // only a few possibilities of what it can be. In particular, enums, single
9144 // element structs and large types have already been taken care of.
9145
9146 // Some i128 and fp128 arguments are converted to pointers only in the
9147 // back end.
9148 if (T->isIntegerTy(128) || T->isFP128Ty())
9149 return ArgKind::Indirect;
9150 if (T->isFloatingPointTy())
9151 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9152 if (T->isIntegerTy() || T->isPointerTy())
9153 return ArgKind::GeneralPurpose;
9154 if (T->isVectorTy())
9155 return ArgKind::Vector;
9156 return ArgKind::Memory;
9157 }
9158
9159 ShadowExtension getShadowExtension(const CallBase &CB, unsigned ArgNo) {
9160 // ABI says: "One of the simple integer types no more than 64 bits wide.
9161 // ... If such an argument is shorter than 64 bits, replace it by a full
9162 // 64-bit integer representing the same number, using sign or zero
9163 // extension". Shadow for an integer argument has the same type as the
9164 // argument itself, so it can be sign or zero extended as well.
9165 bool ZExt = CB.paramHasAttr(ArgNo, Attribute::ZExt);
9166 bool SExt = CB.paramHasAttr(ArgNo, Attribute::SExt);
9167 if (ZExt) {
9168 assert(!SExt);
9169 return ShadowExtension::Zero;
9170 }
9171 if (SExt) {
9172 assert(!ZExt);
9173 return ShadowExtension::Sign;
9174 }
9175 return ShadowExtension::None;
9176 }
9177
9178 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9179 unsigned GpOffset = SystemZGpOffset;
9180 unsigned FpOffset = SystemZFpOffset;
9181 unsigned VrIndex = 0;
9182 unsigned OverflowOffset = SystemZOverflowOffset;
9183 const DataLayout &DL = F.getDataLayout();
9184 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9185 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9186 // SystemZABIInfo does not produce ByVal parameters.
9187 assert(!CB.isByValArgument(ArgNo));
9188 Type *T = A->getType();
9189 ArgKind AK = classifyArgument(T);
9190 if (AK == ArgKind::Indirect) {
9191 T = MS.PtrTy;
9192 AK = ArgKind::GeneralPurpose;
9193 }
9194 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9195 AK = ArgKind::Memory;
9196 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9197 AK = ArgKind::Memory;
9198 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9199 AK = ArgKind::Memory;
9200 Value *ShadowBase = nullptr;
9201 Value *OriginBase = nullptr;
9202 ShadowExtension SE = ShadowExtension::None;
9203 switch (AK) {
9204 case ArgKind::GeneralPurpose: {
9205 // Always keep track of GpOffset, but store shadow only for varargs.
9206 uint64_t ArgSize = 8;
9207 if (GpOffset + ArgSize <= kParamTLSSize) {
9208 if (!IsFixed) {
9209 SE = getShadowExtension(CB, ArgNo);
9210 uint64_t GapSize = 0;
9211 if (SE == ShadowExtension::None) {
9212 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
9213 assert(ArgAllocSize <= ArgSize);
9214 GapSize = ArgSize - ArgAllocSize;
9215 }
9216 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9217 if (MS.TrackOrigins)
9218 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9219 }
9220 GpOffset += ArgSize;
9221 } else {
9222 GpOffset = kParamTLSSize;
9223 }
9224 break;
9225 }
9226 case ArgKind::FloatingPoint: {
9227 // Always keep track of FpOffset, but store shadow only for varargs.
9228 uint64_t ArgSize = 8;
9229 if (FpOffset + ArgSize <= kParamTLSSize) {
9230 if (!IsFixed) {
9231 // PoP says: "A short floating-point datum requires only the
9232 // left-most 32 bit positions of a floating-point register".
9233 // Therefore, in contrast to AK_GeneralPurpose and AK_Memory,
9234 // don't extend shadow and don't mind the gap.
9235 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9236 if (MS.TrackOrigins)
9237 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9238 }
9239 FpOffset += ArgSize;
9240 } else {
9241 FpOffset = kParamTLSSize;
9242 }
9243 break;
9244 }
9245 case ArgKind::Vector: {
9246 // Keep track of VrIndex. No need to store shadow, since vector varargs
9247 // go through AK_Memory.
9248 assert(IsFixed);
9249 VrIndex++;
9250 break;
9251 }
9252 case ArgKind::Memory: {
9253 // Keep track of OverflowOffset and store shadow only for varargs.
9254 // Ignore fixed args, since we need to copy only the vararg portion of
9255 // the overflow area shadow.
9256 if (!IsFixed) {
9257 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
9258 uint64_t ArgSize = alignTo(ArgAllocSize, 8);
9259 if (OverflowOffset + ArgSize <= kParamTLSSize) {
9260 SE = getShadowExtension(CB, ArgNo);
9261 uint64_t GapSize =
9262 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9263 ShadowBase =
9264 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9265 if (MS.TrackOrigins)
9266 OriginBase =
9267 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9268 OverflowOffset += ArgSize;
9269 } else {
9270 OverflowOffset = kParamTLSSize;
9271 }
9272 }
9273 break;
9274 }
9275 case ArgKind::Indirect:
9276 llvm_unreachable("Indirect must be converted to GeneralPurpose");
9277 }
9278 if (ShadowBase == nullptr)
9279 continue;
9280 Value *Shadow = MSV.getShadow(A);
9281 if (SE != ShadowExtension::None)
9282 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.getInt64Ty(),
9283 /*Signed*/ SE == ShadowExtension::Sign);
9284 ShadowBase = IRB.CreateIntToPtr(ShadowBase, MS.PtrTy, "_msarg_va_s");
9285 IRB.CreateStore(Shadow, ShadowBase);
9286 if (MS.TrackOrigins) {
9287 Value *Origin = MSV.getOrigin(A);
9288 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
9289 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9291 }
9292 }
9293 Constant *OverflowSize = ConstantInt::get(
9294 IRB.getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9295 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9296 }
9297
9298 void copyRegSaveArea(IRBuilder<> &IRB, Value *VAListTag) {
9299 Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
9300 IRB.CreateAdd(
9301 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9302 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9303 MS.PtrTy);
9304 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
9305 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9306 const Align Alignment = Align(8);
9307 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9308 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), Alignment,
9309 /*isStore*/ true);
9310 // TODO(iii): copy only fragments filled by visitCallBase()
9311 // TODO(iii): support packed-stack && !use-soft-float
9312 // For use-soft-float functions, it is enough to copy just the GPRs.
9313 unsigned RegSaveAreaSize =
9314 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9315 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9316 RegSaveAreaSize);
9317 if (MS.TrackOrigins)
9318 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9319 Alignment, RegSaveAreaSize);
9320 }
9321
9322 // FIXME: This implementation limits OverflowOffset to kParamTLSSize, so we
9323 // don't know real overflow size and can't clear shadow beyond kParamTLSSize.
9324 void copyOverflowArea(IRBuilder<> &IRB, Value *VAListTag) {
9325 Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
9326 IRB.CreateAdd(
9327 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9328 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9329 MS.PtrTy);
9330 Value *OverflowArgAreaPtr = IRB.CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9331 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9332 const Align Alignment = Align(8);
9333 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9334 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
9335 Alignment, /*isStore*/ true);
9336 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
9337 SystemZOverflowOffset);
9338 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9339 VAArgOverflowSize);
9340 if (MS.TrackOrigins) {
9341 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
9342 SystemZOverflowOffset);
9343 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9344 VAArgOverflowSize);
9345 }
9346 }
9347
9348 void finalizeInstrumentation() override {
9349 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9350 "finalizeInstrumentation called twice");
9351 if (!VAStartInstrumentationList.empty()) {
9352 // If there is a va_start in this function, make a backup copy of
9353 // va_arg_tls somewhere in the function entry block.
9354 IRBuilder<> IRB(MSV.FnPrologueEnd);
9355 VAArgOverflowSize =
9356 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
9357 Value *CopySize =
9358 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9359 VAArgOverflowSize);
9360 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9361 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9362 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9363 CopySize, kShadowTLSAlignment, false);
9364
9365 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9366 Intrinsic::umin, CopySize,
9367 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9368 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9369 kShadowTLSAlignment, SrcSize);
9370 if (MS.TrackOrigins) {
9371 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9372 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
9373 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
9374 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
9375 }
9376 }
9377
9378 // Instrument va_start.
9379 // Copy va_list shadow from the backup copy of the TLS contents.
9380 for (CallInst *OrigInst : VAStartInstrumentationList) {
9381 NextNodeIRBuilder IRB(OrigInst);
9382 Value *VAListTag = OrigInst->getArgOperand(0);
9383 copyRegSaveArea(IRB, VAListTag);
9384 copyOverflowArea(IRB, VAListTag);
9385 }
9386 }
9387};
9388
9389/// i386-specific implementation of VarArgHelper.
9390struct VarArgI386Helper : public VarArgHelperBase {
9391 AllocaInst *VAArgTLSCopy = nullptr;
9392 Value *VAArgSize = nullptr;
9393
9394 VarArgI386Helper(Function &F, MemorySanitizer &MS,
9395 MemorySanitizerVisitor &MSV)
9396 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/4) {}
9397
9398 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9399 const DataLayout &DL = F.getDataLayout();
9400 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9401 unsigned VAArgOffset = 0;
9402 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9403 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9404 bool IsByVal = CB.isByValArgument(ArgNo);
9405 if (IsByVal) {
9406 assert(A->getType()->isPointerTy());
9407 Type *RealTy = CB.getParamByValType(ArgNo);
9408 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
9409 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(IntptrSize));
9410 if (ArgAlign < IntptrSize)
9411 ArgAlign = Align(IntptrSize);
9412 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9413 if (!IsFixed) {
9414 Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9415 if (Base) {
9416 Value *AShadowPtr, *AOriginPtr;
9417 std::tie(AShadowPtr, AOriginPtr) =
9418 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
9419 kShadowTLSAlignment, /*isStore*/ false);
9420
9421 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
9422 kShadowTLSAlignment, ArgSize);
9423 }
9424 VAArgOffset += alignTo(ArgSize, Align(IntptrSize));
9425 }
9426 } else {
9427 Value *Base;
9428 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
9429 Align ArgAlign = Align(IntptrSize);
9430 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9431 if (DL.isBigEndian()) {
9432 // Adjusting the shadow for argument with size < IntptrSize to match
9433 // the placement of bits in big endian system
9434 if (ArgSize < IntptrSize)
9435 VAArgOffset += (IntptrSize - ArgSize);
9436 }
9437 if (!IsFixed) {
9438 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9439 if (Base)
9440 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
9441 VAArgOffset += ArgSize;
9442 VAArgOffset = alignTo(VAArgOffset, Align(IntptrSize));
9443 }
9444 }
9445 }
9446
9447 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9448 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9449 // a new class member i.e. it is the total size of all VarArgs.
9450 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9451 }
9452
9453 void finalizeInstrumentation() override {
9454 assert(!VAArgSize && !VAArgTLSCopy &&
9455 "finalizeInstrumentation called twice");
9456 IRBuilder<> IRB(MSV.FnPrologueEnd);
9457 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9458 Value *CopySize = VAArgSize;
9459
9460 if (!VAStartInstrumentationList.empty()) {
9461 // If there is a va_start in this function, make a backup copy of
9462 // va_arg_tls somewhere in the function entry block.
9463 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9464 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9465 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9466 CopySize, kShadowTLSAlignment, false);
9467
9468 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9469 Intrinsic::umin, CopySize,
9470 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9471 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9472 kShadowTLSAlignment, SrcSize);
9473 }
9474
9475 // Instrument va_start.
9476 // Copy va_list shadow from the backup copy of the TLS contents.
9477 for (CallInst *OrigInst : VAStartInstrumentationList) {
9478 NextNodeIRBuilder IRB(OrigInst);
9479 Value *VAListTag = OrigInst->getArgOperand(0);
9480 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9481 Value *RegSaveAreaPtrPtr =
9482 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9483 PointerType::get(*MS.C, 0));
9484 Value *RegSaveAreaPtr =
9485 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9486 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9487 const DataLayout &DL = F.getDataLayout();
9488 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9489 const Align Alignment = Align(IntptrSize);
9490 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9491 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9492 Alignment, /*isStore*/ true);
9493 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9494 CopySize);
9495 }
9496 }
9497};
9498
9499/// Implementation of VarArgHelper that is used for ARM32, MIPS, RISCV,
9500/// LoongArch64.
9501struct VarArgGenericHelper : public VarArgHelperBase {
9502 AllocaInst *VAArgTLSCopy = nullptr;
9503 Value *VAArgSize = nullptr;
9504
9505 VarArgGenericHelper(Function &F, MemorySanitizer &MS,
9506 MemorySanitizerVisitor &MSV, const unsigned VAListTagSize)
9507 : VarArgHelperBase(F, MS, MSV, VAListTagSize) {}
9508
9509 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9510 unsigned VAArgOffset = 0;
9511 const DataLayout &DL = F.getDataLayout();
9512 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9513 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9514 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9515 if (IsFixed)
9516 continue;
9517 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
9518 if (DL.isBigEndian()) {
9519 // Adjusting the shadow for argument with size < IntptrSize to match the
9520 // placement of bits in big endian system
9521 if (ArgSize < IntptrSize)
9522 VAArgOffset += (IntptrSize - ArgSize);
9523 }
9524 Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9525 VAArgOffset += ArgSize;
9526 VAArgOffset = alignTo(VAArgOffset, IntptrSize);
9527 if (!Base)
9528 continue;
9529 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
9530 }
9531
9532 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9533 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9534 // a new class member i.e. it is the total size of all VarArgs.
9535 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9536 }
9537
9538 void finalizeInstrumentation() override {
9539 assert(!VAArgSize && !VAArgTLSCopy &&
9540 "finalizeInstrumentation called twice");
9541 IRBuilder<> IRB(MSV.FnPrologueEnd);
9542 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9543 Value *CopySize = VAArgSize;
9544
9545 if (!VAStartInstrumentationList.empty()) {
9546 // If there is a va_start in this function, make a backup copy of
9547 // va_arg_tls somewhere in the function entry block.
9548 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9549 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9550 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9551 CopySize, kShadowTLSAlignment, false);
9552
9553 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9554 Intrinsic::umin, CopySize,
9555 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9556 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9557 kShadowTLSAlignment, SrcSize);
9558 }
9559
9560 // Instrument va_start.
9561 // Copy va_list shadow from the backup copy of the TLS contents.
9562 for (CallInst *OrigInst : VAStartInstrumentationList) {
9563 NextNodeIRBuilder IRB(OrigInst);
9564 Value *VAListTag = OrigInst->getArgOperand(0);
9565 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9566 Value *RegSaveAreaPtrPtr =
9567 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9568 PointerType::get(*MS.C, 0));
9569 Value *RegSaveAreaPtr =
9570 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9571 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9572 const DataLayout &DL = F.getDataLayout();
9573 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9574 const Align Alignment = Align(IntptrSize);
9575 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9576 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9577 Alignment, /*isStore*/ true);
9578 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9579 CopySize);
9580 }
9581 }
9582};
9583
9584// ARM32, Loongarch64, MIPS and RISCV share the same calling conventions
9585// regarding VAArgs.
9586using VarArgARM32Helper = VarArgGenericHelper;
9587using VarArgRISCVHelper = VarArgGenericHelper;
9588using VarArgMIPSHelper = VarArgGenericHelper;
9589using VarArgLoongArch64Helper = VarArgGenericHelper;
9590using VarArgHexagonHelper = VarArgGenericHelper;
9591
9592/// A no-op implementation of VarArgHelper.
9593struct VarArgNoOpHelper : public VarArgHelper {
9594 VarArgNoOpHelper(Function &F, MemorySanitizer &MS,
9595 MemorySanitizerVisitor &MSV) {}
9596
9597 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {}
9598
9599 void visitVAStartInst(VAStartInst &I) override {}
9600
9601 void visitVACopyInst(VACopyInst &I) override {}
9602
9603 void finalizeInstrumentation() override {}
9604};
9605
9606} // end anonymous namespace
9607
9608static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
9609 MemorySanitizerVisitor &Visitor) {
9610 // VarArg handling is only implemented on AMD64. False positives are possible
9611 // on other platforms.
9612 Triple TargetTriple(Func.getParent()->getTargetTriple());
9613
9614 if (TargetTriple.getArch() == Triple::x86)
9615 return new VarArgI386Helper(Func, Msan, Visitor);
9616
9617 if (TargetTriple.getArch() == Triple::x86_64)
9618 return new VarArgAMD64Helper(Func, Msan, Visitor);
9619
9620 if (TargetTriple.isARM())
9621 return new VarArgARM32Helper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9622
9623 if (TargetTriple.isAArch64())
9624 return new VarArgAArch64Helper(Func, Msan, Visitor);
9625
9626 if (TargetTriple.isSystemZ())
9627 return new VarArgSystemZHelper(Func, Msan, Visitor);
9628
9629 // On PowerPC32 VAListTag is a struct
9630 // {char, char, i16 padding, char *, char *}
9631 if (TargetTriple.isPPC32())
9632 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9633
9634 if (TargetTriple.isPPC64())
9635 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9636
9637 if (TargetTriple.isRISCV32())
9638 return new VarArgRISCVHelper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9639
9640 if (TargetTriple.isRISCV64())
9641 return new VarArgRISCVHelper(Func, Msan, Visitor, /*VAListTagSize=*/8);
9642
9643 if (TargetTriple.isMIPS32())
9644 return new VarArgMIPSHelper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9645
9646 if (TargetTriple.isMIPS64())
9647 return new VarArgMIPSHelper(Func, Msan, Visitor, /*VAListTagSize=*/8);
9648
9649 if (TargetTriple.isLoongArch64())
9650 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9651 /*VAListTagSize=*/8);
9652
9653 if (TargetTriple.getArch() == Triple::hexagon)
9654 return new VarArgHexagonHelper(Func, Msan, Visitor, /*VAListTagSize=*/12);
9655
9656 return new VarArgNoOpHelper(Func, Msan, Visitor);
9657}
9658
9659bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
9660 if (!CompileKernel && F.getName() == kMsanModuleCtorName)
9661 return false;
9662
9663 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9664 return false;
9665
9666 MemorySanitizerVisitor Visitor(F, *this, TLI);
9667
9668 // Clear out memory attributes.
9670 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
9671 F.removeFnAttrs(B);
9672
9673 return Visitor.runOnFunction();
9674}
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Imm
unsigned uint64_t
constexpr LLT S1
AMDGPU Uniform Intrinsic Combine
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isStore(int Opcode)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static const size_t kNumberOfAccessSizes
static cl::opt< bool > ClWithComdat("asan-with-comdat", cl::desc("Place ASan constructors in comdat sections"), cl::Hidden, cl::init(true))
VarLocInsertPt getNextNode(const DbgRecord *DVR)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool insertModuleCtor(Module &M)
Definition CopyProf.cpp:77
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< int > ClTrackOrigins("dfsan-track-origins", cl::desc("Track origins of labels"), cl::Hidden, cl::init(0))
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_S390X_MemoryMapParams
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_AArch64_MemoryMapParams
static bool isAMustTailRetVal(Value *RetVal)
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
@ Default
static bool runOnFunction(Function &F, bool PostInlining)
This is the interface for a simple mod/ref and alias analysis over globals.
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
#define op(i)
Hexagon Common GEP
#define _
Module.h This file contains the declarations for the Module class.
static LVOptions Options
Definition LVOptions.cpp:25
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Definition Lint.cpp:540
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static cl::opt< uint64_t > ClShadowBase("msan-shadow-base", cl::desc("Define custom MSan ShadowBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClPoisonUndef("msan-poison-undef", cl::desc("Poison fully undef temporary values. " "Partially undefined constant vectors " "are unaffected by this flag (see " "-msan-poison-undef-vectors)."), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static cl::opt< uint64_t > ClOriginBase("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClCheckConstantShadow("msan-check-constant-shadow", cl::desc("Insert checks for constant shadow values"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static cl::opt< bool > ClWithComdat("msan-with-comdat", cl::desc("Place MSan constructors in comdat sections"), cl::Hidden, cl::init(false))
static cl::opt< int > ClTrackOrigins("msan-track-origins", cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden, cl::init(0))
Track origins of uninitialized values.
static cl::opt< int > ClInstrumentationWithCallThreshold("msan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of checks and origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< int > ClPoisonStackPattern("msan-poison-stack-pattern", cl::desc("poison uninitialized stack variables with the given pattern"), cl::Hidden, cl::init(0xff))
static const Align kShadowTLSAlignment
static cl::opt< bool > ClHandleICmpExact("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static cl::opt< bool > ClDumpStrictInstructions("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics i.e.," "check that all the inputs are fully initialized, and mark " "the output as fully initialized. These semantics are applied " "to instructions that could not be handled explicitly nor " "heuristically."), cl::Hidden, cl::init(false))
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static cl::opt< bool > ClPreciseDisjointOr("msan-precise-disjoint-or", cl::desc("Precisely poison disjoint OR. If false (legacy behavior), " "disjointedness is ignored (i.e., 1|1 is initialized)."), cl::Hidden, cl::init(false))
static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P
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 > ClPoisonUndefVectors("msan-poison-undef-vectors", cl::desc("Precisely poison partially undefined constant vectors. " "If false (legacy behavior), the entire vector is " "considered fully initialized, which may lead to false " "negatives. Fully undefined constant vectors are " "unaffected by this flag (see -msan-poison-undef)."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClPrintStackNames("msan-print-stack-names", cl::desc("Print name of local stack variable"), cl::Hidden, cl::init(true))
OddOrEvenLanes
@ kOddLanes
@ kEvenLanes
@ kBothLanes
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< int > ClSwitchPrecision("msan-switch-precision", cl::desc("Controls the number of cases considered by MSan for LLVM switch " "instructions. 0 means no UUMs detected. Higher values lead to " "fewer false negatives but may impact compiler and/or " "application performance. N.B. LLVM switch instructions do not " "correspond exactly to C++ switch statements."), cl::Hidden, cl::init(99))
static cl::opt< uint64_t > ClXorMask("msan-xor-mask", cl::desc("Define custom MSan XorMask"), cl::Hidden, cl::init(0))
static const MemoryMapParams Linux_Hexagon_MemoryMapParams
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 cl::opt< bool > ClDumpHeuristicInstructions("msan-dump-heuristic-instructions", cl::desc("Prints 'unknown' instructions that were handled heuristically. " "Use -msan-dump-strict-instructions to print instructions that " "could not be handled explicitly nor heuristically."), cl::Hidden, cl::init(false))
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))
#define T
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
if(PassOpts->AAPipeline)
const SmallVectorImpl< MachineOperand > & Cond
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
static const char * name
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
Value * RHS
Value * LHS
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition APInt.h:215
void setAlignment(Align Align)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const T & front() const
Get the first element.
Definition ArrayRef.h:144
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
iterator end()
Definition BasicBlock.h:459
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
bool isInlineAsm() const
Check if this call is an inline asm statement.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
void removeFnAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the function.
void setCannotMerge()
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Value * getCalledOperand() const
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_SLT
signed less than
Definition InstrTypes.h:769
@ ICMP_SLE
signed less or equal
Definition InstrTypes.h:770
@ ICMP_SGT
signed greater than
Definition InstrTypes.h:767
@ ICMP_SGE
signed greater or equal
Definition InstrTypes.h:768
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true, bool ByteString=false)
This method constructs a CDS and initializes it with a text string.
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
Definition Constants.h:135
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
Definition Constant.h:43
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition Constant.h:64
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
LLVM_ABI bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
Definition Constants.cpp:68
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
static bool shouldExecute(CounterInfo &Counter)
bool empty() const
Definition DenseMap.h:717
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
static FixedVectorType * getHalfElementsVectorType(FixedVectorType *VTy)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:287
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
Analysis pass providing a never-invalidated alias analysis result.
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
Definition IRBuilder.h:431
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
LLVM_ABI Value * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2661
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition IRBuilder.h:2016
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1871
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition IRBuilder.h:498
LLVM_ABI CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2715
LLVM_ABI Value * CreateAllocationSize(Type *DestTy, AllocaInst *AI)
Get allocation size of an alloca as a runtime Value* (handles both static and dynamic allocas and vsc...
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition IRBuilder.h:2649
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition IRBuilder.h:526
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1926
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memcpy between the specified pointers.
Definition IRBuilder.h:642
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2289
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2708
LLVM_ABI CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Definition IRBuilder.h:176
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2125
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2230
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1519
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:513
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Definition IRBuilder.h:446
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2084
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition IRBuilder.h:518
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1460
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2378
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2003
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Definition IRBuilder.h:1817
LLVM_ABI Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, FMFSource FMFSource={}, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
LLVM_ABI Value * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition IRBuilder.h:456
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2539
Value * CreateNot(Value *V, const Twine &Name="")
Definition IRBuilder.h:1841
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2374
LLVM_ABI DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Definition IRBuilder.cpp:65
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1426
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2235
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
Definition IRBuilder.h:466
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:1898
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1498
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Definition IRBuilder.h:587
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2113
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition IRBuilder.h:2683
LLVMContext & getContext() const
Definition IRBuilder.h:177
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1557
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1917
LLVM_ABI CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1409
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2225
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Definition IRBuilder.h:2755
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2553
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2099
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:556
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1718
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2406
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2386
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2315
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
Definition IRBuilder.h:2750
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:181
Type * getVoidTy()
Fetch the type representing void.
Definition IRBuilder.h:551
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition IRBuilder.h:1945
LLVM_ABI CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, MaybeAlign Align, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Definition IRBuilder.h:2089
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1538
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1609
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2484
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1579
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:503
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1443
LLVM_ABI CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
LLVM_ABI CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
Value * CreateFCmpULT(Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2469
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2901
std::vector< ConstraintInfo > ConstraintInfoVector
Definition InlineAsm.h:123
void visit(Iterator Start, Iterator End)
Definition InstVisitor.h:87
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition Type.cpp:338
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition MDBuilder.cpp:48
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Definition Analysis.h:171
bool remove(const value_type &X)
Remove an item from the set vector.
Definition SetVector.h:187
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition Type.cpp:467
unsigned getNumElements() const
Random access to the elements.
Type * getElementType(unsigned N) const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
LibFunc getLibFunc(StringRef funcName) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
Definition Triple.h:1132
@ loongarch64
Definition Triple.h:66
bool isRISCV32() const
Tests whether the target is 32-bit RISC-V.
Definition Triple.h:1173
bool isPPC32() const
Tests whether the target is 32-bit PowerPC (little and big endian).
Definition Triple.h:1146
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:514
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
Definition Triple.h:1178
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
Definition Triple.h:1121
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
Definition Triple.h:1127
bool isARM() const
Tests whether the target is ARM (little and big endian).
Definition Triple.h:1005
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
Definition Triple.h:1151
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
Definition Triple.h:1098
bool isSystemZ() const
Tests whether the target is SystemZ.
Definition Triple.h:1197
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition Type.h:283
bool isArrayTy() const
True if this is an instance of ArrayType.
Definition Type.h:274
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
Definition Type.h:258
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:277
Type * getArrayElementType() const
Definition Type.h:420
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
Definition Type.h:167
bool isSized() const
Return true if it makes sense to take the size of this type.
Definition Type.h:321
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
Definition Type.h:186
LLVM_ABI bool isScalableTy() const
Return true if this is a type whose size is a known multiple of vscale.
Definition Type.cpp:61
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
Definition Type.h:265
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isFPOrFPVectorTy() const
Return true if this is a FP type or a vector of FP.
Definition Type.h:222
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition ValueMap.h:156
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:394
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
int getNumOccurrences() const
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
LLVM_ABI StringRef getBaseName(ID id)
Return the LLVM name for an intrinsic, without encoded types for overloading, such as "llvm....
initializer< Ty > init(const Ty &Val)
Function * Kernel
Summary of a kernel (=entry point for target offloading).
Definition OpenMPOpt.h:21
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition MathExtras.h:339
@ Offset
Definition DWP.cpp:577
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Done
Definition Threading.h:60
bool isAligned(Align Lhs, uint64_t SizeInBytes)
Checks that SizeInBytes is a multiple of the alignment.
Definition Alignment.h:134
@ Store
The extracted value is stored (ExtractElement only).
LLVM_ABI std::pair< Instruction *, Value * > SplitBlockAndInsertSimpleForLoop(Value *End, BasicBlock::iterator SplitBefore)
Insert a for (int i = 0; i < End; i++) loop structure (with the exception that End is assumed > 0,...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:332
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
Definition Local.cpp:2912
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
@ Add
Sum of integers.
IntPtrTy
Definition InstrProf.h:82
DWARFExpression::Operation Op
RoundingMode
Rounding mode.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
Definition Local.cpp:3898
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
std::string itostr(int64_t X)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)