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
153#include "llvm/ADT/APInt.h"
154#include "llvm/ADT/ArrayRef.h"
155#include "llvm/ADT/DenseMap.h"
157#include "llvm/ADT/SetVector.h"
158#include "llvm/ADT/SmallPtrSet.h"
159#include "llvm/ADT/SmallVector.h"
161#include "llvm/ADT/StringRef.h"
165#include "llvm/IR/Argument.h"
167#include "llvm/IR/Attributes.h"
168#include "llvm/IR/BasicBlock.h"
169#include "llvm/IR/CallingConv.h"
170#include "llvm/IR/Constant.h"
171#include "llvm/IR/Constants.h"
172#include "llvm/IR/DataLayout.h"
173#include "llvm/IR/DerivedTypes.h"
174#include "llvm/IR/Function.h"
175#include "llvm/IR/GlobalValue.h"
177#include "llvm/IR/IRBuilder.h"
178#include "llvm/IR/InlineAsm.h"
179#include "llvm/IR/InstVisitor.h"
180#include "llvm/IR/InstrTypes.h"
181#include "llvm/IR/Instruction.h"
182#include "llvm/IR/Instructions.h"
184#include "llvm/IR/Intrinsics.h"
185#include "llvm/IR/IntrinsicsAArch64.h"
186#include "llvm/IR/IntrinsicsX86.h"
187#include "llvm/IR/MDBuilder.h"
188#include "llvm/IR/Module.h"
189#include "llvm/IR/Type.h"
190#include "llvm/IR/Value.h"
191#include "llvm/IR/ValueMap.h"
194#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
236const char kMsanModuleCtorName[] = "msan.module_ctor";
237const char kMsanInitName[] = "__msan_init";
238
239namespace {
240
241// Memory map parameters used in application-to-shadow address calculation.
242// Offset = (Addr & ~AndMask) ^ XorMask
243// Shadow = ShadowBase + Offset
244// Origin = OriginBase + Offset
245struct MemoryMapParams {
246 uint64_t AndMask;
247 uint64_t XorMask;
248 uint64_t ShadowBase;
249 uint64_t OriginBase;
250};
251
252struct PlatformMemoryMapParams {
253 const MemoryMapParams *bits32;
254 const MemoryMapParams *bits64;
255};
256
257} // end anonymous namespace
258
259// i386 Linux
260static const MemoryMapParams Linux_I386_MemoryMapParams = {
261 0x000080000000, // AndMask
262 0, // XorMask (not used)
263 0, // ShadowBase (not used)
264 0x000040000000, // OriginBase
265};
266
267// x86_64 Linux
268static const MemoryMapParams Linux_X86_64_MemoryMapParams = {
269 0, // AndMask (not used)
270 0x500000000000, // XorMask
271 0, // ShadowBase (not used)
272 0x100000000000, // OriginBase
273};
274
275// mips32 Linux
276// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
277// after picking good constants
278
279// mips64 Linux
280static const MemoryMapParams Linux_MIPS64_MemoryMapParams = {
281 0, // AndMask (not used)
282 0x008000000000, // XorMask
283 0, // ShadowBase (not used)
284 0x002000000000, // OriginBase
285};
286
287// ppc32 Linux
288// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
289// after picking good constants
290
291// ppc64 Linux
292static const MemoryMapParams Linux_PowerPC64_MemoryMapParams = {
293 0xE00000000000, // AndMask
294 0x100000000000, // XorMask
295 0x080000000000, // ShadowBase
296 0x1C0000000000, // OriginBase
297};
298
299// s390x Linux
300static const MemoryMapParams Linux_S390X_MemoryMapParams = {
301 0xC00000000000, // AndMask
302 0, // XorMask (not used)
303 0x080000000000, // ShadowBase
304 0x1C0000000000, // OriginBase
305};
306
307// arm32 Linux
308// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
309// after picking good constants
310
311// aarch64 Linux
312static const MemoryMapParams Linux_AArch64_MemoryMapParams = {
313 0, // AndMask (not used)
314 0x0B00000000000, // XorMask
315 0, // ShadowBase (not used)
316 0x0200000000000, // OriginBase
317};
318
319// loongarch64 Linux
320static const MemoryMapParams Linux_LoongArch64_MemoryMapParams = {
321 0, // AndMask (not used)
322 0x500000000000, // XorMask
323 0, // ShadowBase (not used)
324 0x100000000000, // OriginBase
325};
326
327// hexagon Linux
328static const MemoryMapParams Linux_Hexagon_MemoryMapParams = {
329 0, // AndMask (not used)
330 0x20000000, // XorMask
331 0, // ShadowBase (not used)
332 0x50000000, // OriginBase
333};
334
335// riscv32 Linux
336// FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
337// after picking good constants
338
339// aarch64 FreeBSD
340static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams = {
341 0x1800000000000, // AndMask
342 0x0400000000000, // XorMask
343 0x0200000000000, // ShadowBase
344 0x0700000000000, // OriginBase
345};
346
347// i386 FreeBSD
348static const MemoryMapParams FreeBSD_I386_MemoryMapParams = {
349 0x000180000000, // AndMask
350 0x000040000000, // XorMask
351 0x000020000000, // ShadowBase
352 0x000700000000, // OriginBase
353};
354
355// x86_64 FreeBSD
356static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams = {
357 0xc00000000000, // AndMask
358 0x200000000000, // XorMask
359 0x100000000000, // ShadowBase
360 0x380000000000, // OriginBase
361};
362
363// x86_64 NetBSD
364static const MemoryMapParams NetBSD_X86_64_MemoryMapParams = {
365 0, // AndMask
366 0x500000000000, // XorMask
367 0, // ShadowBase
368 0x100000000000, // OriginBase
369};
370
371static const PlatformMemoryMapParams Linux_X86_MemoryMapParams = {
374};
375
376static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams = {
377 nullptr,
379};
380
381static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams = {
382 nullptr,
384};
385
386static const PlatformMemoryMapParams Linux_S390_MemoryMapParams = {
387 nullptr,
389};
390
391static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams = {
392 nullptr,
394};
395
396static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams = {
397 nullptr,
399};
400
401static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P = {
403 nullptr,
404};
405
406static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams = {
407 nullptr,
409};
410
411static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams = {
414};
415
416static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams = {
417 nullptr,
419};
420
422
423namespace {
424
425/// Instrument functions of a module to detect uninitialized reads.
426///
427/// Instantiating MemorySanitizer inserts the msan runtime library API function
428/// declarations into the module if they don't exist already. Instantiating
429/// ensures the __msan_init function is in the list of global constructors for
430/// the module.
431class MemorySanitizer {
432public:
433 MemorySanitizer(const InstrumentationOptions &Opts, Module &M,
434 MemorySanitizerOptions Options)
435 : Opts(Opts), CompileKernel(Options.Kernel),
436 TrackOrigins(Options.TrackOrigins), Recover(Options.Recover),
437 EagerChecks(Options.EagerChecks) {
438 initializeModule(M);
439 }
440
441 // MSan cannot be moved or copied because of MapParams.
442 MemorySanitizer(MemorySanitizer &&) = delete;
443 MemorySanitizer &operator=(MemorySanitizer &&) = delete;
444 MemorySanitizer(const MemorySanitizer &) = delete;
445 MemorySanitizer &operator=(const MemorySanitizer &) = delete;
446
447 bool sanitizeFunction(Function &F, TargetLibraryInfo &TLI);
448
449private:
450 friend struct MemorySanitizerVisitor;
451 friend struct VarArgHelperBase;
452 friend struct VarArgAMD64Helper;
453 friend struct VarArgAArch64Helper;
454 friend struct VarArgPowerPC64Helper;
455 friend struct VarArgPowerPC32Helper;
456 friend struct VarArgSystemZHelper;
457 friend struct VarArgI386Helper;
458 friend struct VarArgGenericHelper;
459
460 void initializeModule(Module &M);
461 void initializeCallbacks(Module &M, const TargetLibraryInfo &TLI);
462 void createKernelApi(Module &M, const TargetLibraryInfo &TLI);
463 void createUserspaceApi(Module &M, const TargetLibraryInfo &TLI);
464
465 template <typename... ArgsTy>
466 FunctionCallee getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
467 ArgsTy... Args);
468
469 const InstrumentationOptions &Opts;
470 /// True if we're compiling the Linux kernel.
471 bool CompileKernel;
472 /// Track origins (allocation points) of uninitialized values.
473 int TrackOrigins;
474 bool Recover;
475 bool EagerChecks;
476
477 Triple TargetTriple;
478 LLVMContext *C;
479 Type *IntptrTy; ///< Integer type with the size of a ptr in default AS.
480 Type *OriginTy;
481 PointerType *PtrTy; ///< Integer type with the size of a ptr in default AS.
482
483 // XxxTLS variables represent the per-thread state in MSan and per-task state
484 // in KMSAN.
485 // For the userspace these point to thread-local globals. In the kernel land
486 // they point to the members of a per-task struct obtained via a call to
487 // __msan_get_context_state().
488
489 /// Thread-local shadow storage for function parameters.
490 Value *ParamTLS;
491
492 /// Thread-local origin storage for function parameters.
493 Value *ParamOriginTLS;
494
495 /// Thread-local shadow storage for function return value.
496 Value *RetvalTLS;
497
498 /// Thread-local origin storage for function return value.
499 Value *RetvalOriginTLS;
500
501 /// Thread-local shadow storage for in-register va_arg function.
502 Value *VAArgTLS;
503
504 /// Thread-local shadow storage for in-register va_arg function.
505 Value *VAArgOriginTLS;
506
507 /// Thread-local shadow storage for va_arg overflow area.
508 Value *VAArgOverflowSizeTLS;
509
510 /// Are the instrumentation callbacks set up?
511 bool CallbacksInitialized = false;
512
513 /// The run-time callback to print a warning.
514 FunctionCallee WarningFn;
515
516 // These arrays are indexed by log2(AccessSize).
517 FunctionCallee MaybeWarningFn[kNumberOfAccessSizes];
518 FunctionCallee MaybeWarningVarSizeFn;
519 FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes];
520
521 /// Run-time helper that generates a new origin value for a stack
522 /// allocation.
523 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
524 // No description version
525 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
526
527 /// Run-time helper that poisons stack on function entry.
528 FunctionCallee MsanPoisonStackFn;
529
530 /// Run-time helper that records a store (or any event) of an
531 /// uninitialized value and returns an updated origin id encoding this info.
532 FunctionCallee MsanChainOriginFn;
533
534 /// Run-time helper that paints an origin over a region.
535 FunctionCallee MsanSetOriginFn;
536
537 /// MSan runtime replacements for memmove, memcpy and memset.
538 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
539
540 /// KMSAN callback for task-local function argument shadow.
541 StructType *MsanContextStateTy;
542 FunctionCallee MsanGetContextStateFn;
543
544 /// Functions for poisoning/unpoisoning local variables
545 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
546
547 /// Pair of shadow/origin pointers.
548 Type *MsanMetadata;
549
550 /// Each of the MsanMetadataPtrXxx functions returns a MsanMetadata.
551 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
552 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
553 FunctionCallee MsanMetadataPtrForStore_1_8[4];
554 FunctionCallee MsanInstrumentAsmStoreFn;
555
556 /// Storage for return values of the MsanMetadataPtrXxx functions.
557 Value *MsanMetadataAlloca;
558
559 /// Helper to choose between different MsanMetadataPtrXxx().
560 FunctionCallee getKmsanShadowOriginAccessFn(bool isStore, int size);
561
562 /// Memory map parameters used in application-to-shadow calculation.
563 const MemoryMapParams *MapParams;
564
565 /// Custom memory map parameters used when -msan-shadow-base or
566 // -msan-origin-base is provided.
567 MemoryMapParams CustomMapParams;
568
569 MDNode *ColdCallWeights;
570
571 /// Branch weights for origin store.
572 MDNode *OriginStoreWeights;
573};
574
575void insertModuleCtor(const InstrumentationOptions &Opts, Module &M) {
578 /*InitArgTypes=*/{},
579 /*InitArgs=*/{},
580 // This callback is invoked when the functions are created the first
581 // time. Hook them into the global ctors list in that case:
582 [&](Function *Ctor, FunctionCallee) {
583 if (!Opts.msan_with_comdat) {
584 appendToGlobalCtors(M, Ctor, 0);
585 return;
586 }
587 Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
588 Ctor->setComdat(MsanCtorComdat);
589 appendToGlobalCtors(M, Ctor, 0, Ctor);
590 });
591}
592
593} // end anonymous namespace
594
596 : Kernel(K), TrackOrigins(TO), Recover(R), EagerChecks(EC) {}
597
598static MemorySanitizerOptions resolveOptions(const InstrumentationOptions &Opts,
600 O.Kernel = valueOr(Opts.msan_kernel, O.Kernel);
601 O.TrackOrigins =
602 Opts.msan_track_origins.value_or(O.Kernel ? 2 : O.TrackOrigins);
603 O.Recover = valueOr(Opts.msan_keep_going, O.Kernel || O.Recover);
604 O.EagerChecks = valueOr(Opts.msan_eager_checks, O.EagerChecks);
605 return O;
606}
607
610 // Return early if nosanitize_memory module flag is present for the module.
611 if (checkIfAlreadyInstrumented(M, "nosanitize_memory"))
612 return PreservedAnalyses::all();
613 const InstrumentationOptions &Opts = getInstrumentationOptions(M);
614 MemorySanitizerOptions MSanOpts = resolveOptions(Opts, Options);
615 bool Modified = false;
616 if (!MSanOpts.Kernel) {
617 insertModuleCtor(Opts, M);
618 Modified = true;
619 }
620
621 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
622 for (Function &F : M) {
623 if (F.empty())
624 continue;
625 MemorySanitizer Msan(Opts, *F.getParent(), MSanOpts);
626 Modified |=
627 Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
628 }
629
630 if (!Modified)
631 return PreservedAnalyses::all();
632
634 // GlobalsAA is considered stateless and does not get invalidated unless
635 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
636 // make changes that require GlobalsAA to be invalidated.
637 PA.abandon<GlobalsAA>();
638 return PA;
639}
640
642 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
643 static_cast<PassInfoMixin<MemorySanitizerPass> *>(this)->printPipeline(
644 OS, MapClassName2PassName);
645 OS << '<';
646 if (Options.Recover)
647 OS << "recover;";
648 if (Options.Kernel)
649 OS << "kernel;";
650 if (Options.EagerChecks)
651 OS << "eager-checks;";
652 OS << "track-origins=" << Options.TrackOrigins;
653 OS << '>';
654}
655
656/// Create a non-const global initialized with the given string.
657///
658/// Creates a writable global for Str so that we can pass it to the
659/// run-time lib. Runtime uses first 4 bytes of the string to store the
660/// frame ID, so the string needs to be mutable.
662 StringRef Str) {
663 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
664 return new GlobalVariable(M, StrConst->getType(), /*isConstant=*/true,
665 GlobalValue::PrivateLinkage, StrConst, "");
666}
667
668template <typename... ArgsTy>
670MemorySanitizer::getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
671 ArgsTy... Args) {
672 if (TargetTriple.getArch() == Triple::systemz) {
673 // SystemZ ABI: shadow/origin pair is returned via a hidden parameter.
674 return M.getOrInsertFunction(Name, Type::getVoidTy(*C), PtrTy,
675 std::forward<ArgsTy>(Args)...);
676 }
677
678 return M.getOrInsertFunction(Name, MsanMetadata,
679 std::forward<ArgsTy>(Args)...);
680}
681
682/// Create KMSAN API callbacks.
683void MemorySanitizer::createKernelApi(Module &M, const TargetLibraryInfo &TLI) {
684 IRBuilder<> IRB(M);
685
686 // These will be initialized in insertKmsanPrologue().
687 RetvalTLS = nullptr;
688 RetvalOriginTLS = nullptr;
689 ParamTLS = nullptr;
690 ParamOriginTLS = nullptr;
691 VAArgTLS = nullptr;
692 VAArgOriginTLS = nullptr;
693 VAArgOverflowSizeTLS = nullptr;
694
695 WarningFn = M.getOrInsertFunction("__msan_warning",
696 TLI.getAttrList(C, {0}, /*Signed=*/false),
697 IRB.getVoidTy(), IRB.getInt32Ty());
698
699 // Requests the per-task context state (kmsan_context_state*) from the
700 // runtime library.
701 MsanContextStateTy = StructType::get(
702 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
703 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8),
704 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
705 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), /* va_arg_origin */
706 IRB.getInt64Ty(), ArrayType::get(OriginTy, kParamTLSSize / 4), OriginTy,
707 OriginTy);
708 MsanGetContextStateFn =
709 M.getOrInsertFunction("__msan_get_context_state", PtrTy);
710
711 MsanMetadata = StructType::get(PtrTy, PtrTy);
712
713 for (int ind = 0, size = 1; ind < 4; ind++, size <<= 1) {
714 std::string name_load =
715 "__msan_metadata_ptr_for_load_" + std::to_string(size);
716 std::string name_store =
717 "__msan_metadata_ptr_for_store_" + std::to_string(size);
718 MsanMetadataPtrForLoad_1_8[ind] =
719 getOrInsertMsanMetadataFunction(M, name_load, PtrTy);
720 MsanMetadataPtrForStore_1_8[ind] =
721 getOrInsertMsanMetadataFunction(M, name_store, PtrTy);
722 }
723
724 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
725 M, "__msan_metadata_ptr_for_load_n", PtrTy, IntptrTy);
726 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
727 M, "__msan_metadata_ptr_for_store_n", PtrTy, IntptrTy);
728
729 // Functions for poisoning and unpoisoning memory.
730 MsanPoisonAllocaFn = M.getOrInsertFunction(
731 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
732 MsanUnpoisonAllocaFn = M.getOrInsertFunction(
733 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
734}
735
737 return M.getOrInsertGlobal(Name, Ty, [&] {
738 return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
739 nullptr, Name, nullptr,
741 });
742}
743
744/// Insert declarations for userspace-specific functions and globals.
745void MemorySanitizer::createUserspaceApi(Module &M,
746 const TargetLibraryInfo &TLI) {
747 IRBuilder<> IRB(M);
748
749 // Create the callback.
750 // FIXME: this function should have "Cold" calling conv,
751 // which is not yet implemented.
752 if (TrackOrigins) {
753 StringRef WarningFnName = Recover ? "__msan_warning_with_origin"
754 : "__msan_warning_with_origin_noreturn";
755 WarningFn = M.getOrInsertFunction(WarningFnName,
756 TLI.getAttrList(C, {0}, /*Signed=*/false),
757 IRB.getVoidTy(), IRB.getInt32Ty());
758 } else {
759 StringRef WarningFnName =
760 Recover ? "__msan_warning" : "__msan_warning_noreturn";
761 WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
762 }
763
764 // Create the global TLS variables.
765 RetvalTLS =
766 getOrInsertGlobal(M, "__msan_retval_tls",
767 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8));
768
769 RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy);
770
771 ParamTLS =
772 getOrInsertGlobal(M, "__msan_param_tls",
773 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
774
775 ParamOriginTLS =
776 getOrInsertGlobal(M, "__msan_param_origin_tls",
777 ArrayType::get(OriginTy, kParamTLSSize / 4));
778
779 VAArgTLS =
780 getOrInsertGlobal(M, "__msan_va_arg_tls",
781 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
782
783 VAArgOriginTLS =
784 getOrInsertGlobal(M, "__msan_va_arg_origin_tls",
785 ArrayType::get(OriginTy, kParamTLSSize / 4));
786
787 VAArgOverflowSizeTLS = getOrInsertGlobal(M, "__msan_va_arg_overflow_size_tls",
788 IRB.getIntPtrTy(M.getDataLayout()));
789
790 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
791 AccessSizeIndex++) {
792 unsigned AccessSize = 1 << AccessSizeIndex;
793 std::string FunctionName = "__msan_maybe_warning_" + itostr(AccessSize);
794 MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction(
795 FunctionName, TLI.getAttrList(C, {0, 1}, /*Signed=*/false),
796 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
797 MaybeWarningVarSizeFn = M.getOrInsertFunction(
798 "__msan_maybe_warning_N", TLI.getAttrList(C, {}, /*Signed=*/false),
799 IRB.getVoidTy(), PtrTy, IRB.getInt64Ty(), IRB.getInt32Ty());
800 FunctionName = "__msan_maybe_store_origin_" + itostr(AccessSize);
801 MaybeStoreOriginFn[AccessSizeIndex] = M.getOrInsertFunction(
802 FunctionName, TLI.getAttrList(C, {0, 2}, /*Signed=*/false),
803 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
804 IRB.getInt32Ty());
805 }
806
807 MsanSetAllocaOriginWithDescriptionFn =
808 M.getOrInsertFunction("__msan_set_alloca_origin_with_descr",
809 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
810 MsanSetAllocaOriginNoDescriptionFn =
811 M.getOrInsertFunction("__msan_set_alloca_origin_no_descr",
812 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
813 MsanPoisonStackFn = M.getOrInsertFunction("__msan_poison_stack",
814 IRB.getVoidTy(), PtrTy, IntptrTy);
815}
816
817/// Insert extern declaration of runtime-provided functions and globals.
818void MemorySanitizer::initializeCallbacks(Module &M,
819 const TargetLibraryInfo &TLI) {
820 // Only do this once.
821 if (CallbacksInitialized)
822 return;
823
824 IRBuilder<> IRB(M);
825 // Initialize callbacks that are common for kernel and userspace
826 // instrumentation.
827 MsanChainOriginFn = M.getOrInsertFunction(
828 "__msan_chain_origin",
829 TLI.getAttrList(C, {0}, /*Signed=*/false, /*Ret=*/true), IRB.getInt32Ty(),
830 IRB.getInt32Ty());
831 MsanSetOriginFn = M.getOrInsertFunction(
832 "__msan_set_origin", TLI.getAttrList(C, {2}, /*Signed=*/false),
833 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
834 MemmoveFn =
835 M.getOrInsertFunction("__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
836 MemcpyFn =
837 M.getOrInsertFunction("__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
838 MemsetFn = M.getOrInsertFunction("__msan_memset",
839 TLI.getAttrList(C, {1}, /*Signed=*/true),
840 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
841
842 MsanInstrumentAsmStoreFn = M.getOrInsertFunction(
843 "__msan_instrument_asm_store", IRB.getVoidTy(), PtrTy, IntptrTy);
844
845 if (CompileKernel) {
846 createKernelApi(M, TLI);
847 } else {
848 createUserspaceApi(M, TLI);
849 }
850 CallbacksInitialized = true;
851}
852
853FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore,
854 int size) {
855 FunctionCallee *Fns =
856 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
857 switch (size) {
858 case 1:
859 return Fns[0];
860 case 2:
861 return Fns[1];
862 case 4:
863 return Fns[2];
864 case 8:
865 return Fns[3];
866 default:
867 return nullptr;
868 }
869}
870
871/// Module-level initialization.
872///
873/// inserts a call to __msan_init to the module's constructor list.
874void MemorySanitizer::initializeModule(Module &M) {
875 auto &DL = M.getDataLayout();
876
877 TargetTriple = M.getTargetTriple();
878
879 bool ShadowPassed = Opts.msan_shadow_base.has_value();
880 bool OriginPassed = Opts.msan_origin_base.has_value();
881 // Check the overrides first
882 if (ShadowPassed || OriginPassed) {
883 CustomMapParams.AndMask = Opts.msan_and_mask;
884 CustomMapParams.XorMask = Opts.msan_xor_mask;
885 CustomMapParams.ShadowBase = Opts.msan_shadow_base.value_or(0);
886 CustomMapParams.OriginBase = Opts.msan_origin_base.value_or(0);
887 MapParams = &CustomMapParams;
888 } else {
889 switch (TargetTriple.getOS()) {
890 case Triple::FreeBSD:
891 switch (TargetTriple.getArch()) {
892 case Triple::aarch64:
893 MapParams = FreeBSD_ARM_MemoryMapParams.bits64;
894 break;
895 case Triple::x86_64:
896 MapParams = FreeBSD_X86_MemoryMapParams.bits64;
897 break;
898 case Triple::x86:
899 MapParams = FreeBSD_X86_MemoryMapParams.bits32;
900 break;
901 default:
902 report_fatal_error("unsupported architecture");
903 }
904 break;
905 case Triple::NetBSD:
906 switch (TargetTriple.getArch()) {
907 case Triple::x86_64:
908 MapParams = NetBSD_X86_MemoryMapParams.bits64;
909 break;
910 default:
911 report_fatal_error("unsupported architecture");
912 }
913 break;
914 case Triple::Linux:
915 switch (TargetTriple.getArch()) {
916 case Triple::x86_64:
917 MapParams = Linux_X86_MemoryMapParams.bits64;
918 break;
919 case Triple::x86:
920 MapParams = Linux_X86_MemoryMapParams.bits32;
921 break;
922 case Triple::mips64:
923 case Triple::mips64el:
924 MapParams = Linux_MIPS_MemoryMapParams.bits64;
925 break;
926 case Triple::ppc64:
927 case Triple::ppc64le:
928 MapParams = Linux_PowerPC_MemoryMapParams.bits64;
929 break;
930 case Triple::systemz:
931 MapParams = Linux_S390_MemoryMapParams.bits64;
932 break;
933 case Triple::aarch64:
935 MapParams = Linux_ARM_MemoryMapParams.bits64;
936 break;
938 MapParams = Linux_LoongArch_MemoryMapParams.bits64;
939 break;
940 case Triple::hexagon:
941 MapParams = Linux_Hexagon_MemoryMapParams_P.bits32;
942 break;
943 default:
944 report_fatal_error("unsupported architecture");
945 }
946 break;
947 default:
948 report_fatal_error("unsupported operating system");
949 }
950 }
951
952 C = &(M.getContext());
953 IRBuilder<> IRB(M);
954 IntptrTy = IRB.getIntPtrTy(DL);
955 OriginTy = IRB.getInt32Ty();
956 PtrTy = IRB.getPtrTy();
957
958 ColdCallWeights = MDBuilder(*C).createUnlikelyBranchWeights();
959 OriginStoreWeights = MDBuilder(*C).createUnlikelyBranchWeights();
960
961 if (!CompileKernel) {
962 if (TrackOrigins)
963 M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
964 return new GlobalVariable(
965 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
966 IRB.getInt32(TrackOrigins), "__msan_track_origins");
967 });
968
969 if (Recover)
970 M.getOrInsertGlobal("__msan_keep_going", IRB.getInt32Ty(), [&] {
971 return new GlobalVariable(M, IRB.getInt32Ty(), true,
972 GlobalValue::WeakODRLinkage,
973 IRB.getInt32(Recover), "__msan_keep_going");
974 });
975 }
976}
977
978namespace {
979
980/// A helper class that handles instrumentation of VarArg
981/// functions on a particular platform.
982///
983/// Implementations are expected to insert the instrumentation
984/// necessary to propagate argument shadow through VarArg function
985/// calls. Visit* methods are called during an InstVisitor pass over
986/// the function, and should avoid creating new basic blocks. A new
987/// instance of this class is created for each instrumented function.
988struct VarArgHelper {
989 virtual ~VarArgHelper() = default;
990
991 /// Visit a CallBase.
992 virtual void visitCallBase(CallBase &CB, IRBuilder<> &IRB) = 0;
993
994 /// Visit a va_start call.
995 virtual void visitVAStartInst(VAStartInst &I) = 0;
996
997 /// Visit a va_copy call.
998 virtual void visitVACopyInst(VACopyInst &I) = 0;
999
1000 /// Finalize function instrumentation.
1001 ///
1002 /// This method is called after visiting all interesting (see above)
1003 /// instructions in a function.
1004 virtual void finalizeInstrumentation() = 0;
1005};
1006
1007struct MemorySanitizerVisitor;
1008
1009} // end anonymous namespace
1010
1011static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
1012 MemorySanitizerVisitor &Visitor);
1013
1014static unsigned TypeSizeToSizeIndex(TypeSize TS) {
1015 if (TS.isScalable())
1016 // Scalable types unconditionally take slowpaths.
1017 return kNumberOfAccessSizes;
1018 unsigned TypeSizeFixed = TS.getFixedValue();
1019 if (TypeSizeFixed <= 8)
1020 return 0;
1021 return Log2_32_Ceil((TypeSizeFixed + 7) / 8);
1022}
1023
1024namespace {
1025
1026/// Helper class to attach debug information of the given instruction onto new
1027/// instructions inserted after.
1028class NextNodeIRBuilder : public IRBuilder<> {
1029public:
1030 explicit NextNodeIRBuilder(Instruction *IP) : IRBuilder<>(IP->getNextNode()) {
1031 SetCurrentDebugLocation(IP->getDebugLoc());
1032 }
1033};
1034
1035/// This class does all the work for a given function. Store and Load
1036/// instructions store and load corresponding shadow and origin
1037/// values. Most instructions propagate shadow from arguments to their
1038/// return values. Certain instructions (most importantly, BranchInst)
1039/// test their argument shadow and print reports (with a runtime call) if it's
1040/// non-zero.
1041struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1042 const InstrumentationOptions &Opts;
1043 Function &F;
1044 MemorySanitizer &MS;
1045 SmallVector<PHINode *, 16> ShadowPHINodes, OriginPHINodes;
1046 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1047 std::unique_ptr<VarArgHelper> VAHelper;
1048 const TargetLibraryInfo *TLI;
1049 Instruction *FnPrologueEnd;
1050 SmallVector<Instruction *, 16> Instructions;
1051
1052 // The following flags disable parts of MSan instrumentation based on
1053 // exclusion list contents and command-line options.
1054 bool InsertChecks;
1055 bool PropagateShadow;
1056 bool PoisonStack;
1057 bool PoisonUndef;
1058 bool PoisonUndefVectors;
1059
1060 struct ShadowOriginAndInsertPoint {
1061 Value *Shadow;
1062 Value *Origin;
1063 Instruction *OrigIns;
1064
1065 ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I)
1066 : Shadow(S), Origin(O), OrigIns(I) {}
1067 };
1069 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1070 SmallSetVector<AllocaInst *, 16> AllocaSet;
1073 int64_t SplittableBlocksCount = 0;
1074
1075 MemorySanitizerVisitor(Function &F, MemorySanitizer &MS,
1076 const TargetLibraryInfo &TLI)
1077 : Opts(MS.Opts), F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)),
1078 TLI(&TLI) {
1079 bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeMemory) &&
1080 !Opts.msan_disable_checks;
1081 InsertChecks = SanitizeFunction;
1082 PropagateShadow = SanitizeFunction;
1083 PoisonStack = SanitizeFunction && Opts.msan_poison_stack;
1084 PoisonUndef = SanitizeFunction && Opts.msan_poison_undef;
1085 PoisonUndefVectors = SanitizeFunction && Opts.msan_poison_undef_vectors;
1086
1087 // In the presence of unreachable blocks, we may see Phi nodes with
1088 // incoming nodes from such blocks. Since InstVisitor skips unreachable
1089 // blocks, such nodes will not have any shadow value associated with them.
1090 // It's easier to remove unreachable blocks than deal with missing shadow.
1092
1093 MS.initializeCallbacks(*F.getParent(), TLI);
1094 FnPrologueEnd =
1095 IRBuilder<>(F.getEntryBlock().getFirstNonPHIIt())
1096 .CreateIntrinsicWithoutFolding(Intrinsic::donothing, {});
1097
1098 if (MS.CompileKernel) {
1099 IRBuilder<> IRB(FnPrologueEnd);
1100 insertKmsanPrologue(IRB);
1101 }
1102
1103 LLVM_DEBUG(if (!InsertChecks) dbgs()
1104 << "MemorySanitizer is not inserting checks into '"
1105 << F.getName() << "'\n");
1106 }
1107
1108 bool instrumentWithCalls(Value *V) {
1109 // Constants likely will be eliminated by follow-up passes.
1110 if (isa<Constant>(V))
1111 return false;
1112 ++SplittableBlocksCount;
1113 return Opts.msan_instrumentation_with_call_threshold >= 0 &&
1114 SplittableBlocksCount >
1115 Opts.msan_instrumentation_with_call_threshold;
1116 }
1117
1118 bool isInPrologue(Instruction &I) {
1119 return I.getParent() == FnPrologueEnd->getParent() &&
1120 (&I == FnPrologueEnd || I.comesBefore(FnPrologueEnd));
1121 }
1122
1123 // Creates a new origin and records the stack trace. In general we can call
1124 // this function for any origin manipulation we like. However it will cost
1125 // runtime resources. So use this wisely only if it can provide additional
1126 // information helpful to a user.
1127 Value *updateOrigin(Value *V, IRBuilder<> &IRB) {
1128 if (MS.TrackOrigins <= 1)
1129 return V;
1130 return IRB.CreateCall(MS.MsanChainOriginFn, V);
1131 }
1132
1133 Value *originToIntptr(IRBuilder<> &IRB, Value *Origin) {
1134 const DataLayout &DL = F.getDataLayout();
1135 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1136 if (IntptrSize == kOriginSize)
1137 return Origin;
1138 assert(IntptrSize == kOriginSize * 2);
1139 Origin = IRB.CreateIntCast(Origin, MS.IntptrTy, /* isSigned */ false);
1140 return IRB.CreateOr(Origin, IRB.CreateShl(Origin, kOriginSize * 8));
1141 }
1142
1143 /// Fill memory range with the given origin value.
1144 void paintOrigin(IRBuilder<> &IRB, Value *Origin, Value *OriginPtr,
1145 TypeSize TS, Align Alignment) {
1146 const DataLayout &DL = F.getDataLayout();
1147 const Align IntptrAlignment = DL.getABITypeAlign(MS.IntptrTy);
1148 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1149 assert(IntptrAlignment >= kMinOriginAlignment);
1150 assert(IntptrSize >= kOriginSize);
1151
1152 // Note: The loop based formation works for fixed length vectors too,
1153 // however we prefer to unroll and specialize alignment below.
1154 if (TS.isScalable()) {
1155 Value *Size = IRB.CreateTypeSize(MS.IntptrTy, TS);
1156 Value *RoundUp =
1157 IRB.CreateAdd(Size, ConstantInt::get(MS.IntptrTy, kOriginSize - 1));
1158 Value *End =
1159 IRB.CreateUDiv(RoundUp, ConstantInt::get(MS.IntptrTy, kOriginSize));
1160 auto [InsertPt, Index] =
1162 IRB.SetInsertPoint(InsertPt);
1163
1164 Value *GEP = IRB.CreateGEP(MS.OriginTy, OriginPtr, Index);
1166 return;
1167 }
1168
1169 unsigned Size = TS.getFixedValue();
1170
1171 unsigned Ofs = 0;
1172 Align CurrentAlignment = Alignment;
1173 if (Alignment >= IntptrAlignment && IntptrSize > kOriginSize) {
1174 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1175 Value *IntptrOriginPtr = IRB.CreatePointerCast(OriginPtr, MS.PtrTy);
1176 for (unsigned i = 0; i < Size / IntptrSize; ++i) {
1177 Value *Ptr = i ? IRB.CreateConstGEP1_32(MS.IntptrTy, IntptrOriginPtr, i)
1178 : IntptrOriginPtr;
1179 IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
1180 Ofs += IntptrSize / kOriginSize;
1181 CurrentAlignment = IntptrAlignment;
1182 }
1183 }
1184
1185 for (unsigned i = Ofs; i < (Size + kOriginSize - 1) / kOriginSize; ++i) {
1186 Value *GEP =
1187 i ? IRB.CreateConstGEP1_32(MS.OriginTy, OriginPtr, i) : OriginPtr;
1188 IRB.CreateAlignedStore(Origin, GEP, CurrentAlignment);
1189 CurrentAlignment = kMinOriginAlignment;
1190 }
1191 }
1192
1193 void storeOrigin(IRBuilder<> &IRB, Value *Addr, Value *Shadow, Value *Origin,
1194 Value *OriginPtr, Align Alignment) {
1195 const DataLayout &DL = F.getDataLayout();
1196 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1197 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
1198 // ZExt cannot convert between vector and scalar
1199 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1200 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1201 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1202 // Origin is not needed: value is initialized or const shadow is
1203 // ignored.
1204 return;
1205 }
1206 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1207 // Copy origin as the value is definitely uninitialized.
1208 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1209 OriginAlignment);
1210 return;
1211 }
1212 // Fallback to runtime check, which still can be optimized out later.
1213 }
1214
1215 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1216 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1217 if (instrumentWithCalls(ConvertedShadow) &&
1218 SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
1219 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1220 Value *ConvertedShadow2 =
1221 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1222 CallBase *CB = IRB.CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1223 CB->addParamAttr(0, Attribute::ZExt);
1224 CB->addParamAttr(2, Attribute::ZExt);
1225 } else {
1226 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1228 Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
1229 IRBuilder<> IRBNew(CheckTerm);
1230 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1231 OriginAlignment);
1232 }
1233 }
1234
1235 void materializeStores() {
1236 for (StoreInst *SI : StoreList) {
1237 IRBuilder<> IRB(SI);
1238 Value *Val = SI->getValueOperand();
1239 Value *Addr = SI->getPointerOperand();
1240 Value *Shadow = SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1241 Value *ShadowPtr, *OriginPtr;
1242 Type *ShadowTy = Shadow->getType();
1243 const Align Alignment = SI->getAlign();
1244 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1245 std::tie(ShadowPtr, OriginPtr) =
1246 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ true);
1247
1248 [[maybe_unused]] StoreInst *NewSI =
1249 IRB.CreateAlignedStore(Shadow, ShadowPtr, Alignment);
1250 LLVM_DEBUG(dbgs() << " STORE: " << *NewSI << "\n");
1251
1252 if (SI->isAtomic())
1253 SI->setOrdering(addReleaseOrdering(SI->getOrdering()));
1254
1255 if (MS.TrackOrigins && !SI->isAtomic())
1256 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1257 OriginAlignment);
1258 }
1259 }
1260
1261 // Returns true if Debug Location corresponds to multiple warnings.
1262 bool shouldDisambiguateWarningLocation(const DebugLoc &DebugLoc) {
1263 if (MS.TrackOrigins < 2)
1264 return false;
1265
1266 if (LazyWarningDebugLocationCount.empty())
1267 for (const auto &I : InstrumentationList)
1268 ++LazyWarningDebugLocationCount[I.OrigIns->getDebugLoc()];
1269
1270 return LazyWarningDebugLocationCount[DebugLoc] >=
1271 Opts.msan_disambiguate_warning_threshold;
1272 }
1273
1274 /// Helper function to insert a warning at IRB's current insert point.
1275 void insertWarningFn(IRBuilder<> &IRB, Value *Origin) {
1276 if (!Origin)
1277 Origin = (Value *)IRB.getInt32(0);
1278 assert(Origin->getType()->isIntegerTy());
1279
1280 if (shouldDisambiguateWarningLocation(IRB.getCurrentDebugLocation())) {
1281 // Try to create additional origin with debug info of the last origin
1282 // instruction. It may provide additional information to the user.
1283 if (Instruction *OI = dyn_cast_or_null<Instruction>(Origin)) {
1284 assert(MS.TrackOrigins);
1285 auto NewDebugLoc = OI->getDebugLoc();
1286 // Origin update with missing or the same debug location provides no
1287 // additional value.
1288 if (NewDebugLoc && NewDebugLoc != IRB.getCurrentDebugLocation()) {
1289 // Insert update just before the check, so we call runtime only just
1290 // before the report.
1291 IRBuilder<> IRBOrigin(&*IRB.GetInsertPoint());
1292 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1293 Origin = updateOrigin(Origin, IRBOrigin);
1294 }
1295 }
1296 }
1297
1298 if (MS.CompileKernel || MS.TrackOrigins)
1299 IRB.CreateCall(MS.WarningFn, Origin)->setCannotMerge();
1300 else
1301 IRB.CreateCall(MS.WarningFn)->setCannotMerge();
1302 // FIXME: Insert UnreachableInst if !MS.Recover?
1303 // This may invalidate some of the following checks and needs to be done
1304 // at the very end.
1305 }
1306
1307 void materializeOneCheck(IRBuilder<> &IRB, Value *ConvertedShadow,
1308 Value *Origin) {
1309 const DataLayout &DL = F.getDataLayout();
1310 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1311 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1312 if (instrumentWithCalls(ConvertedShadow) && !MS.CompileKernel) {
1313 // ZExt cannot convert between vector and scalar
1314 ConvertedShadow = convertShadowToScalar(ConvertedShadow, IRB);
1315 Value *ConvertedShadow2 =
1316 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1317
1318 if (SizeIndex < kNumberOfAccessSizes) {
1319 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1320 CallBase *CB = IRB.CreateCall(
1321 Fn,
1322 {ConvertedShadow2,
1323 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1324 CB->addParamAttr(0, Attribute::ZExt);
1325 CB->addParamAttr(1, Attribute::ZExt);
1326 } else {
1327 FunctionCallee Fn = MS.MaybeWarningVarSizeFn;
1328 Value *ShadowAlloca = IRB.CreateAlloca(ConvertedShadow2->getType(), 0u);
1329 IRB.CreateStore(ConvertedShadow2, ShadowAlloca);
1330 unsigned ShadowSize = DL.getTypeAllocSize(ConvertedShadow2->getType());
1331 CallBase *CB = IRB.CreateCall(
1332 Fn,
1333 {ShadowAlloca, ConstantInt::get(IRB.getInt64Ty(), ShadowSize),
1334 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1335 CB->addParamAttr(1, Attribute::ZExt);
1336 CB->addParamAttr(2, Attribute::ZExt);
1337 }
1338 } else {
1339 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1341 Cmp, &*IRB.GetInsertPoint(),
1342 /* Unreachable */ !MS.Recover, MS.ColdCallWeights);
1343
1344 IRB.SetInsertPoint(CheckTerm);
1345 insertWarningFn(IRB, Origin);
1346 LLVM_DEBUG(dbgs() << " CHECK: " << *Cmp << "\n");
1347 }
1348 }
1349
1350 void materializeInstructionChecks(
1351 ArrayRef<ShadowOriginAndInsertPoint> InstructionChecks) {
1352 const DataLayout &DL = F.getDataLayout();
1353 // Disable combining in some cases. TrackOrigins checks each shadow to pick
1354 // correct origin.
1355 bool Combine = !MS.TrackOrigins;
1356 Instruction *Instruction = InstructionChecks.front().OrigIns;
1357 Value *Shadow = nullptr;
1358 for (const auto &ShadowData : InstructionChecks) {
1359 assert(ShadowData.OrigIns == Instruction);
1360 IRBuilder<> IRB(Instruction);
1361
1362 Value *ConvertedShadow = ShadowData.Shadow;
1363
1364 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1365 if (!Opts.msan_check_constant_shadow || ConstantShadow->isNullValue()) {
1366 // Skip, value is initialized or const shadow is ignored.
1367 continue;
1368 }
1369 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1370 // Report as the value is definitely uninitialized.
1371 insertWarningFn(IRB, ShadowData.Origin);
1372 if (!MS.Recover)
1373 return; // Always fail and stop here, not need to check the rest.
1374 // Skip entire instruction,
1375 continue;
1376 }
1377 // Fallback to runtime check, which still can be optimized out later.
1378 }
1379
1380 if (!Combine) {
1381 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1382 continue;
1383 }
1384
1385 if (!Shadow) {
1386 Shadow = ConvertedShadow;
1387 continue;
1388 }
1389
1390 Shadow = convertToBool(Shadow, IRB, "_mscmp");
1391 ConvertedShadow = convertToBool(ConvertedShadow, IRB, "_mscmp");
1392 Shadow = IRB.CreateOr(Shadow, ConvertedShadow, "_msor");
1393 }
1394
1395 if (Shadow) {
1396 assert(Combine);
1397 IRBuilder<> IRB(Instruction);
1398 materializeOneCheck(IRB, Shadow, nullptr);
1399 }
1400 }
1401
1402 static bool isAArch64SVCount(Type *Ty) {
1403 if (TargetExtType *TTy = dyn_cast<TargetExtType>(Ty))
1404 return TTy->getName() == "aarch64.svcount";
1405 return false;
1406 }
1407
1408 // This is intended to match the "AArch64 Predicate-as-Counter Type" (aka
1409 // 'target("aarch64.svcount")', but not e.g., <vscale x 4 x i32>.
1410 static bool isScalableNonVectorType(Type *Ty) {
1411 if (!isAArch64SVCount(Ty))
1412 LLVM_DEBUG(dbgs() << "isScalableNonVectorType: Unexpected type " << *Ty
1413 << "\n");
1414
1415 return Ty->isScalableTy() && !isa<VectorType>(Ty);
1416 }
1417
1418 void materializeChecks() {
1419#ifndef NDEBUG
1420 // For assert below.
1421 SmallPtrSet<Instruction *, 16> Done;
1422#endif
1423
1424 for (auto I = InstrumentationList.begin();
1425 I != InstrumentationList.end();) {
1426 auto OrigIns = I->OrigIns;
1427 // Checks are grouped by the original instruction. We call all
1428 // `insertShadowCheck` for an instruction at once.
1429 assert(Done.insert(OrigIns).second);
1430 auto J = std::find_if(I + 1, InstrumentationList.end(),
1431 [OrigIns](const ShadowOriginAndInsertPoint &R) {
1432 return OrigIns != R.OrigIns;
1433 });
1434 // Process all checks of instruction at once.
1435 materializeInstructionChecks(ArrayRef<ShadowOriginAndInsertPoint>(I, J));
1436 I = J;
1437 }
1438
1439 LLVM_DEBUG(dbgs() << "DONE:\n" << F);
1440 }
1441
1442 // Returns the last instruction in the new prologue
1443 void insertKmsanPrologue(IRBuilder<> &IRB) {
1444 Value *ContextState = IRB.CreateCall(MS.MsanGetContextStateFn, {});
1445 Constant *Zero = IRB.getInt32(0);
1446 MS.ParamTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1447 {Zero, IRB.getInt32(0)}, "param_shadow");
1448 MS.RetvalTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1449 {Zero, IRB.getInt32(1)}, "retval_shadow");
1450 MS.VAArgTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1451 {Zero, IRB.getInt32(2)}, "va_arg_shadow");
1452 MS.VAArgOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1453 {Zero, IRB.getInt32(3)}, "va_arg_origin");
1454 MS.VAArgOverflowSizeTLS =
1455 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1456 {Zero, IRB.getInt32(4)}, "va_arg_overflow_size");
1457 MS.ParamOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1458 {Zero, IRB.getInt32(5)}, "param_origin");
1459 MS.RetvalOriginTLS =
1460 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1461 {Zero, IRB.getInt32(6)}, "retval_origin");
1462 if (MS.TargetTriple.getArch() == Triple::systemz)
1463 MS.MsanMetadataAlloca = IRB.CreateAlloca(MS.MsanMetadata, 0u);
1464 }
1465
1466 /// Add MemorySanitizer instrumentation to a function.
1467 bool runOnFunction() {
1468 // Iterate all BBs in depth-first order and create shadow instructions
1469 // for all instructions (where applicable).
1470 // For PHI nodes we create dummy shadow PHIs which will be finalized later.
1471 for (BasicBlock *BB : depth_first(FnPrologueEnd->getParent()))
1472 visit(*BB);
1473
1474 // `visit` above only collects instructions. Process them after iterating
1475 // CFG to avoid requirement on CFG transformations.
1476 for (Instruction *I : Instructions)
1478
1479 // Finalize PHI nodes.
1480 for (PHINode *PN : ShadowPHINodes) {
1481 PHINode *PNS = cast<PHINode>(getShadow(PN));
1482 PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
1483 size_t NumValues = PN->getNumIncomingValues();
1484 for (size_t v = 0; v < NumValues; v++) {
1485 PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1486 if (PNO)
1487 PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1488 }
1489 }
1490
1491 VAHelper->finalizeInstrumentation();
1492
1493 // Poison llvm.lifetime.start intrinsics, if we haven't fallen back to
1494 // instrumenting only allocas.
1495 if (Opts.msan_handle_lifetime_intrinsics) {
1496 for (auto Item : LifetimeStartList) {
1497 instrumentAlloca(*Item.second, Item.first);
1498 AllocaSet.remove(Item.second);
1499 }
1500 }
1501 // Poison the allocas for which we didn't instrument the corresponding
1502 // lifetime intrinsics.
1503 for (AllocaInst *AI : AllocaSet)
1504 instrumentAlloca(*AI);
1505
1506 // Insert shadow value checks.
1507 materializeChecks();
1508
1509 // Delayed instrumentation of StoreInst.
1510 // This may not add new address checks.
1511 materializeStores();
1512
1513 return true;
1514 }
1515
1516 /// Compute the shadow type that corresponds to a given Value.
1517 Type *getShadowTy(Value *V) { return getShadowTy(V->getType()); }
1518
1519 /// Compute the shadow type that corresponds to a given Type.
1520 Type *getShadowTy(Type *OrigTy) {
1521 if (!OrigTy->isSized()) {
1522 return nullptr;
1523 }
1524 // For integer type, shadow is the same as the original type.
1525 // This may return weird-sized types like i1.
1526 if (IntegerType *IT = dyn_cast<IntegerType>(OrigTy))
1527 return IT;
1528 const DataLayout &DL = F.getDataLayout();
1529 if (VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
1530 uint32_t EltSize = DL.getTypeSizeInBits(VT->getElementType());
1531 return VectorType::get(IntegerType::get(*MS.C, EltSize),
1532 VT->getElementCount());
1533 }
1534 if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) {
1535 return ArrayType::get(getShadowTy(AT->getElementType()),
1536 AT->getNumElements());
1537 }
1538 if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
1540 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1541 Elements.push_back(getShadowTy(ST->getElementType(i)));
1542 StructType *Res = StructType::get(*MS.C, Elements, ST->isPacked());
1543 LLVM_DEBUG(dbgs() << "getShadowTy: " << *ST << " ===> " << *Res << "\n");
1544 return Res;
1545 }
1546 if (isScalableNonVectorType(OrigTy)) {
1547 LLVM_DEBUG(dbgs() << "getShadowTy: Scalable non-vector type: " << *OrigTy
1548 << "\n");
1549 return OrigTy;
1550 }
1551
1552 uint32_t TypeSize = DL.getTypeSizeInBits(OrigTy);
1553 return IntegerType::get(*MS.C, TypeSize);
1554 }
1555
1556 /// Extract combined shadow of struct elements as a bool
1557 Value *collapseStructShadow(StructType *Struct, Value *Shadow,
1558 IRBuilder<> &IRB) {
1559 Value *FalseVal = IRB.getIntN(/* width */ 1, /* value */ 0);
1560 Value *Aggregator = FalseVal;
1561
1562 for (unsigned Idx = 0; Idx < Struct->getNumElements(); Idx++) {
1563 // Combine by ORing together each element's bool shadow
1564 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1565 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1566
1567 if (Aggregator != FalseVal)
1568 Aggregator = IRB.CreateOr(Aggregator, ShadowBool);
1569 else
1570 Aggregator = ShadowBool;
1571 }
1572
1573 return Aggregator;
1574 }
1575
1576 // Extract combined shadow of array elements
1577 Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
1578 IRBuilder<> &IRB) {
1579 if (!Array->getNumElements())
1580 return IRB.getIntN(/* width */ 1, /* value */ 0);
1581
1582 Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
1583 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1584
1585 for (unsigned Idx = 1; Idx < Array->getNumElements(); Idx++) {
1586 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1587 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1588 Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
1589 }
1590 return Aggregator;
1591 }
1592
1593 /// Convert a shadow value to it's flattened variant. The resulting
1594 /// shadow may not necessarily have the same bit width as the input
1595 /// value, but it will always be comparable to zero.
1596 Value *convertShadowToScalar(Value *V, IRBuilder<> &IRB) {
1597 if (StructType *Struct = dyn_cast<StructType>(V->getType()))
1598 return collapseStructShadow(Struct, V, IRB);
1599 if (ArrayType *Array = dyn_cast<ArrayType>(V->getType()))
1600 return collapseArrayShadow(Array, V, IRB);
1601 if (isa<VectorType>(V->getType())) {
1602 if (isa<ScalableVectorType>(V->getType()))
1603 return convertShadowToScalar(IRB.CreateOrReduce(V), IRB);
1604 unsigned BitWidth =
1605 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1606 return IRB.CreateBitCast(V, IntegerType::get(*MS.C, BitWidth));
1607 }
1608 return V;
1609 }
1610
1611 // Convert a scalar value to an i1 by comparing with 0
1612 Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &name = "") {
1613 Type *VTy = V->getType();
1614 if (!VTy->isIntegerTy())
1615 return convertToBool(convertShadowToScalar(V, IRB), IRB, name);
1616 if (VTy->getIntegerBitWidth() == 1)
1617 // Just converting a bool to a bool, so do nothing.
1618 return V;
1619 return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), name);
1620 }
1621
1622 Type *ptrToIntPtrType(Type *PtrTy) const {
1623 if (VectorType *VectTy = dyn_cast<VectorType>(PtrTy)) {
1624 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1625 VectTy->getElementCount());
1626 }
1627 assert(PtrTy->isIntOrPtrTy());
1628 return MS.IntptrTy;
1629 }
1630
1631 Type *getPtrToShadowPtrType(Type *IntPtrTy, Type *ShadowTy) const {
1632 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1633 return VectorType::get(
1634 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1635 VectTy->getElementCount());
1636 }
1637 assert(IntPtrTy == MS.IntptrTy);
1638 return MS.PtrTy;
1639 }
1640
1641 Constant *constToIntPtr(Type *IntPtrTy, uint64_t C) const {
1642 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1644 VectTy->getElementCount(),
1645 constToIntPtr(VectTy->getElementType(), C));
1646 }
1647 assert(IntPtrTy == MS.IntptrTy);
1648 // TODO: Avoid implicit trunc?
1649 // See https://github.com/llvm/llvm-project/issues/112510.
1650 return ConstantInt::get(MS.IntptrTy, C, /*IsSigned=*/false,
1651 /*ImplicitTrunc=*/true);
1652 }
1653
1654 /// Returns the integer shadow offset that corresponds to a given
1655 /// application address, whereby:
1656 ///
1657 /// Offset = (Addr & ~AndMask) ^ XorMask
1658 /// Shadow = ShadowBase + Offset
1659 /// Origin = (OriginBase + Offset) & ~Alignment
1660 ///
1661 /// Note: for efficiency, many shadow mappings only require use the XorMask
1662 /// and OriginBase; the AndMask and ShadowBase are often zero.
1663 Value *getShadowPtrOffset(Value *Addr, IRBuilder<> &IRB) {
1664 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1665 Value *OffsetLong = IRB.CreatePointerCast(Addr, IntptrTy);
1666
1667 if (uint64_t AndMask = MS.MapParams->AndMask)
1668 OffsetLong = IRB.CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1669
1670 if (uint64_t XorMask = MS.MapParams->XorMask)
1671 OffsetLong = IRB.CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1672 return OffsetLong;
1673 }
1674
1675 /// Compute the shadow and origin addresses corresponding to a given
1676 /// application address.
1677 ///
1678 /// Shadow = ShadowBase + Offset
1679 /// Origin = (OriginBase + Offset) & ~3ULL
1680 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1681 /// a single pointee.
1682 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1683 std::pair<Value *, Value *>
1684 getShadowOriginPtrUserspace(Value *Addr, IRBuilder<> &IRB, Type *ShadowTy,
1685 MaybeAlign Alignment) {
1686 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1687 if (!VectTy) {
1688 assert(Addr->getType()->isPointerTy());
1689 } else {
1690 assert(VectTy->getElementType()->isPointerTy());
1691 }
1692 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1693 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1694 Value *ShadowLong = ShadowOffset;
1695 if (uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1696 ShadowLong =
1697 IRB.CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1698 }
1699 Value *ShadowPtr = IRB.CreateIntToPtr(
1700 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1701
1702 Value *OriginPtr = nullptr;
1703 if (MS.TrackOrigins) {
1704 Value *OriginLong = ShadowOffset;
1705 uint64_t OriginBase = MS.MapParams->OriginBase;
1706 if (OriginBase != 0)
1707 OriginLong =
1708 IRB.CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1709 if (!Alignment || *Alignment < kMinOriginAlignment) {
1711 OriginLong = IRB.CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1712 }
1713 OriginPtr = IRB.CreateIntToPtr(
1714 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1715 }
1716 return std::make_pair(ShadowPtr, OriginPtr);
1717 }
1718
1719 template <typename... ArgsTy>
1720 Value *createMetadataCall(IRBuilder<> &IRB, FunctionCallee Callee,
1721 ArgsTy... Args) {
1722 if (MS.TargetTriple.getArch() == Triple::systemz) {
1723 IRB.CreateCall(Callee,
1724 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1725 return IRB.CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1726 }
1727
1728 return IRB.CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1729 }
1730
1731 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(Value *Addr,
1732 IRBuilder<> &IRB,
1733 Type *ShadowTy,
1734 bool isStore) {
1735 Value *ShadowOriginPtrs;
1736 const DataLayout &DL = F.getDataLayout();
1737 TypeSize Size = DL.getTypeStoreSize(ShadowTy);
1738
1739 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size);
1740 Value *AddrCast = IRB.CreatePointerCast(Addr, MS.PtrTy);
1741 if (Getter) {
1742 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1743 } else {
1744 Value *SizeVal = ConstantInt::get(MS.IntptrTy, Size);
1745 ShadowOriginPtrs = createMetadataCall(
1746 IRB,
1747 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1748 AddrCast, SizeVal);
1749 }
1750 Value *ShadowPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 0);
1751 ShadowPtr = IRB.CreatePointerCast(ShadowPtr, MS.PtrTy);
1752 Value *OriginPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 1);
1753
1754 return std::make_pair(ShadowPtr, OriginPtr);
1755 }
1756
1757 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1758 /// a single pointee.
1759 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1760 std::pair<Value *, Value *> getShadowOriginPtrKernel(Value *Addr,
1761 IRBuilder<> &IRB,
1762 Type *ShadowTy,
1763 bool isStore) {
1764 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1765 if (!VectTy) {
1766 assert(Addr->getType()->isPointerTy());
1767 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy, isStore);
1768 }
1769
1770 // TODO: Support callbacs with vectors of addresses.
1771 unsigned NumElements = cast<FixedVectorType>(VectTy)->getNumElements();
1772 Value *ShadowPtrs = ConstantInt::getNullValue(
1773 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1774 Value *OriginPtrs = nullptr;
1775 if (MS.TrackOrigins)
1776 OriginPtrs = ConstantInt::getNullValue(
1777 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1778 for (unsigned i = 0; i < NumElements; ++i) {
1779 Value *OneAddr =
1780 IRB.CreateExtractElement(Addr, ConstantInt::get(IRB.getInt32Ty(), i));
1781 auto [ShadowPtr, OriginPtr] =
1782 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy, isStore);
1783
1784 ShadowPtrs = IRB.CreateInsertElement(
1785 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1786 if (MS.TrackOrigins)
1787 OriginPtrs = IRB.CreateInsertElement(
1788 OriginPtrs, OriginPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1789 }
1790 return {ShadowPtrs, OriginPtrs};
1791 }
1792
1793 std::pair<Value *, Value *> getShadowOriginPtr(Value *Addr, IRBuilder<> &IRB,
1794 Type *ShadowTy,
1795 MaybeAlign Alignment,
1796 bool isStore) {
1797 if (MS.CompileKernel)
1798 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy, isStore);
1799 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1800 }
1801
1802 /// Compute the shadow address for a given function argument.
1803 ///
1804 /// Shadow = ParamTLS+ArgOffset.
1805 Value *getShadowPtrForArgument(IRBuilder<> &IRB, int ArgOffset) {
1806 return IRB.CreatePtrAdd(MS.ParamTLS,
1807 ConstantInt::get(MS.IntptrTy, ArgOffset), "_msarg");
1808 }
1809
1810 /// Compute the origin address for a given function argument.
1811 Value *getOriginPtrForArgument(IRBuilder<> &IRB, int ArgOffset) {
1812 if (!MS.TrackOrigins)
1813 return nullptr;
1814 return IRB.CreatePtrAdd(MS.ParamOriginTLS,
1815 ConstantInt::get(MS.IntptrTy, ArgOffset),
1816 "_msarg_o");
1817 }
1818
1819 /// Compute the shadow address for a retval.
1820 Value *getShadowPtrForRetval(IRBuilder<> &IRB) {
1821 return IRB.CreatePointerCast(MS.RetvalTLS, IRB.getPtrTy(0), "_msret");
1822 }
1823
1824 /// Compute the origin address for a retval.
1825 Value *getOriginPtrForRetval() {
1826 // We keep a single origin for the entire retval. Might be too optimistic.
1827 return MS.RetvalOriginTLS;
1828 }
1829
1830 /// Set SV to be the shadow value for V.
1831 void setShadow(Value *V, Value *SV) {
1832 assert(!ShadowMap.count(V) && "Values may only have one shadow");
1833
1834 // getShadowTy(VoidType) == nullptr
1835 if (SV && !V->getType()->isVoidTy() && getShadowTy(V) != SV->getType()) {
1836 LLVM_DEBUG(dbgs() << "V: " << *V << "\n");
1837 LLVM_DEBUG(dbgs() << "SV: " << *SV << "\n");
1838 assert(getShadowTy(V) == SV->getType() &&
1839 "setShadow called with mismatching types");
1840 }
1841
1842 ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
1843 }
1844
1845 /// Set Origin to be the origin value for V.
1846 void setOrigin(Value *V, Value *Origin) {
1847 if (!MS.TrackOrigins)
1848 return;
1849 assert(!OriginMap.count(V) && "Values may only have one origin");
1850 LLVM_DEBUG(dbgs() << "ORIGIN: " << *V << " ==> " << *Origin << "\n");
1851 OriginMap[V] = Origin;
1852 }
1853
1854 Constant *getCleanShadow(Type *OrigTy) {
1855 Type *ShadowTy = getShadowTy(OrigTy);
1856 if (!ShadowTy)
1857 return nullptr;
1858 return Constant::getNullValue(ShadowTy);
1859 }
1860
1861 /// Create a clean shadow value for a given value.
1862 ///
1863 /// Clean shadow (all zeroes) means all bits of the value are defined
1864 /// (initialized).
1865 Constant *getCleanShadow(Value *V) { return getCleanShadow(V->getType()); }
1866
1867 /// Create a dirty shadow of a given shadow type.
1868 Constant *getPoisonedShadow(Type *ShadowTy) {
1869 assert(ShadowTy);
1870 if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
1871 return Constant::getAllOnesValue(ShadowTy);
1872 if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) {
1873 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
1874 getPoisonedShadow(AT->getElementType()));
1875 return ConstantArray::get(AT, Vals);
1876 }
1877 if (StructType *ST = dyn_cast<StructType>(ShadowTy)) {
1878 SmallVector<Constant *, 4> Vals;
1879 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1880 Vals.push_back(getPoisonedShadow(ST->getElementType(i)));
1881 return ConstantStruct::get(ST, Vals);
1882 }
1883 llvm_unreachable("Unexpected shadow type");
1884 }
1885
1886 /// Create a dirty shadow for a given value.
1887 Constant *getPoisonedShadow(Value *V) {
1888 Type *ShadowTy = getShadowTy(V);
1889 if (!ShadowTy)
1890 return nullptr;
1891 return getPoisonedShadow(ShadowTy);
1892 }
1893
1894 /// Create a clean (zero) origin.
1895 Value *getCleanOrigin() { return Constant::getNullValue(MS.OriginTy); }
1896
1897 /// Get the shadow value for a given Value.
1898 ///
1899 /// This function either returns the value set earlier with setShadow,
1900 /// or extracts if from ParamTLS (for function arguments).
1901 Value *getShadow(Value *V) {
1902 if (Instruction *I = dyn_cast<Instruction>(V)) {
1903 if (!PropagateShadow || I->getMetadata(LLVMContext::MD_nosanitize))
1904 return getCleanShadow(V);
1905 // For instructions the shadow is already stored in the map.
1906 Value *Shadow = ShadowMap[V];
1907 if (!Shadow) {
1908 LLVM_DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent()));
1909 assert(Shadow && "No shadow for a value");
1910 }
1911 return Shadow;
1912 }
1913 // Handle fully undefined values
1914 // (partially undefined constant vectors are handled later)
1915 if ([[maybe_unused]] UndefValue *U = dyn_cast<UndefValue>(V)) {
1916 Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
1917 : getCleanShadow(V);
1918 LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n");
1919 return AllOnes;
1920 }
1921 if (Argument *A = dyn_cast<Argument>(V)) {
1922 // For arguments we compute the shadow on demand and store it in the map.
1923 Value *&ShadowPtr = ShadowMap[V];
1924 if (ShadowPtr)
1925 return ShadowPtr;
1926 Function *F = A->getParent();
1927 IRBuilder<> EntryIRB(FnPrologueEnd);
1928 unsigned ArgOffset = 0;
1929 const DataLayout &DL = F->getDataLayout();
1930 for (auto &FArg : F->args()) {
1931 if (!FArg.getType()->isSized() || FArg.getType()->isScalableTy()) {
1932 LLVM_DEBUG(dbgs() << (FArg.getType()->isScalableTy()
1933 ? "vscale not fully supported\n"
1934 : "Arg is not sized\n"));
1935 if (A == &FArg) {
1936 ShadowPtr = getCleanShadow(V);
1937 setOrigin(A, getCleanOrigin());
1938 break;
1939 }
1940 continue;
1941 }
1942
1943 unsigned Size = FArg.hasByValAttr()
1944 ? DL.getTypeAllocSize(FArg.getParamByValType())
1945 : DL.getTypeAllocSize(FArg.getType());
1946
1947 if (A == &FArg) {
1948 bool Overflow = ArgOffset + Size > kParamTLSSize;
1949 if (FArg.hasByValAttr()) {
1950 // ByVal pointer itself has clean shadow. We copy the actual
1951 // argument shadow to the underlying memory.
1952 // Figure out maximal valid memcpy alignment.
1953 const Align ArgAlign = DL.getValueOrABITypeAlignment(
1954 FArg.getParamAlign(), FArg.getParamByValType());
1955 Value *CpShadowPtr, *CpOriginPtr;
1956 std::tie(CpShadowPtr, CpOriginPtr) =
1957 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
1958 /*isStore*/ true);
1959 if (!PropagateShadow || Overflow) {
1960 // ParamTLS overflow.
1961 EntryIRB.CreateMemSet(
1962 CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()),
1963 Size, ArgAlign);
1964 } else {
1965 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1966 const Align CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
1967 [[maybe_unused]] Value *Cpy = EntryIRB.CreateMemCpy(
1968 CpShadowPtr, CopyAlign, Base, CopyAlign, Size);
1969 LLVM_DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n");
1970
1971 if (MS.TrackOrigins) {
1972 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1973 // FIXME: OriginSize should be:
1974 // alignTo(V % kMinOriginAlignment + Size, kMinOriginAlignment)
1975 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
1976 EntryIRB.CreateMemCpy(
1977 CpOriginPtr,
1978 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginPtr,
1979 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
1980 OriginSize);
1981 }
1982 }
1983 }
1984
1985 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
1986 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
1987 ShadowPtr = getCleanShadow(V);
1988 setOrigin(A, getCleanOrigin());
1989 } else {
1990 // Shadow over TLS
1991 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1992 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg), Base,
1994 if (MS.TrackOrigins) {
1995 Value *OriginPtr = getOriginPtrForArgument(EntryIRB, ArgOffset);
1996 setOrigin(A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
1997 }
1998 }
2000 << " ARG: " << FArg << " ==> " << *ShadowPtr << "\n");
2001 break;
2002 }
2003
2004 ArgOffset += alignTo(Size, kShadowTLSAlignment);
2005 }
2006 assert(ShadowPtr && "Could not find shadow for an argument");
2007 return ShadowPtr;
2008 }
2009
2010 // Check for partially-undefined constant vectors
2011 // TODO: scalable vectors (this is hard because we do not have IRBuilder)
2012 if (isa<FixedVectorType>(V->getType()) && isa<Constant>(V) &&
2013 cast<Constant>(V)->containsUndefOrPoisonElement() && PropagateShadow &&
2014 PoisonUndefVectors) {
2015 unsigned NumElems = cast<FixedVectorType>(V->getType())->getNumElements();
2016 SmallVector<Constant *, 32> ShadowVector(NumElems);
2017 for (unsigned i = 0; i != NumElems; ++i) {
2018 Constant *Elem = cast<Constant>(V)->getAggregateElement(i);
2019 ShadowVector[i] = isa<UndefValue>(Elem) ? getPoisonedShadow(Elem)
2020 : getCleanShadow(Elem);
2021 }
2022
2023 Value *ShadowConstant = ConstantVector::get(ShadowVector);
2024 LLVM_DEBUG(dbgs() << "Partial undef constant vector: " << *V << " ==> "
2025 << *ShadowConstant << "\n");
2026
2027 return ShadowConstant;
2028 }
2029
2030 // TODO: partially-undefined constant arrays, structures, and nested types
2031
2032 // For everything else the shadow is zero.
2033 return getCleanShadow(V);
2034 }
2035
2036 /// Get the shadow for i-th argument of the instruction I.
2037 Value *getShadow(Instruction *I, int i) {
2038 return getShadow(I->getOperand(i));
2039 }
2040
2041 /// Get the origin for a value.
2042 Value *getOrigin(Value *V) {
2043 if (!MS.TrackOrigins)
2044 return nullptr;
2045 if (!PropagateShadow || isa<Constant>(V) || isa<InlineAsm>(V))
2046 return getCleanOrigin();
2048 "Unexpected value type in getOrigin()");
2049 if (Instruction *I = dyn_cast<Instruction>(V)) {
2050 if (I->getMetadata(LLVMContext::MD_nosanitize))
2051 return getCleanOrigin();
2052 }
2053 Value *Origin = OriginMap[V];
2054 assert(Origin && "Missing origin");
2055 return Origin;
2056 }
2057
2058 /// Get the origin for i-th argument of the instruction I.
2059 Value *getOrigin(Instruction *I, int i) {
2060 return getOrigin(I->getOperand(i));
2061 }
2062
2063 /// Remember the place where a shadow check should be inserted.
2064 ///
2065 /// This location will be later instrumented with a check that will print a
2066 /// UMR warning in runtime if the shadow value is not 0.
2067 void insertCheckShadow(Value *Shadow, Value *Origin, Instruction *OrigIns) {
2068 assert(Shadow);
2069 if (!InsertChecks)
2070 return;
2071
2072 if (!DebugCounter::shouldExecute(DebugInsertCheck)) {
2073 LLVM_DEBUG(dbgs() << "Skipping check of " << *Shadow << " before "
2074 << *OrigIns << "\n");
2075 return;
2076 }
2077
2078 Type *ShadowTy = Shadow->getType();
2079 if (isScalableNonVectorType(ShadowTy)) {
2080 LLVM_DEBUG(dbgs() << "Skipping check of scalable non-vector " << *Shadow
2081 << " before " << *OrigIns << "\n");
2082 return;
2083 }
2084#ifndef NDEBUG
2085 assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
2086 isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
2087 "Can only insert checks for integer, vector, and aggregate shadow "
2088 "types");
2089#endif
2090 InstrumentationList.push_back(
2091 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2092 }
2093
2094 /// Get shadow for value, and remember the place where a shadow check should
2095 /// be inserted.
2096 ///
2097 /// This location will be later instrumented with a check that will print a
2098 /// UMR warning in runtime if the value is not fully defined.
2099 void insertCheckShadowOf(Value *Val, Instruction *OrigIns) {
2100 assert(Val);
2101 Value *Shadow, *Origin;
2102 if (Opts.msan_check_constant_shadow) {
2103 Shadow = getShadow(Val);
2104 if (!Shadow)
2105 return;
2106 Origin = getOrigin(Val);
2107 } else {
2108 Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
2109 if (!Shadow)
2110 return;
2111 Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
2112 }
2113 insertCheckShadow(Shadow, Origin, OrigIns);
2114 }
2115
2117 switch (a) {
2118 case AtomicOrdering::NotAtomic:
2119 return AtomicOrdering::NotAtomic;
2120 case AtomicOrdering::Unordered:
2121 case AtomicOrdering::Monotonic:
2122 case AtomicOrdering::Release:
2123 return AtomicOrdering::Release;
2124 case AtomicOrdering::Acquire:
2125 case AtomicOrdering::AcquireRelease:
2126 return AtomicOrdering::AcquireRelease;
2127 case AtomicOrdering::SequentiallyConsistent:
2128 return AtomicOrdering::SequentiallyConsistent;
2129 }
2130 llvm_unreachable("Unknown ordering");
2131 }
2132
2133 Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
2134 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2135 uint32_t OrderingTable[NumOrderings] = {};
2136
2137 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2138 OrderingTable[(int)AtomicOrderingCABI::release] =
2139 (int)AtomicOrderingCABI::release;
2140 OrderingTable[(int)AtomicOrderingCABI::consume] =
2141 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2142 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2143 (int)AtomicOrderingCABI::acq_rel;
2144 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2145 (int)AtomicOrderingCABI::seq_cst;
2146
2147 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2148 }
2149
2151 switch (a) {
2152 case AtomicOrdering::NotAtomic:
2153 return AtomicOrdering::NotAtomic;
2154 case AtomicOrdering::Unordered:
2155 case AtomicOrdering::Monotonic:
2156 case AtomicOrdering::Acquire:
2157 return AtomicOrdering::Acquire;
2158 case AtomicOrdering::Release:
2159 case AtomicOrdering::AcquireRelease:
2160 return AtomicOrdering::AcquireRelease;
2161 case AtomicOrdering::SequentiallyConsistent:
2162 return AtomicOrdering::SequentiallyConsistent;
2163 }
2164 llvm_unreachable("Unknown ordering");
2165 }
2166
2167 Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
2168 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2169 uint32_t OrderingTable[NumOrderings] = {};
2170
2171 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2172 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2173 OrderingTable[(int)AtomicOrderingCABI::consume] =
2174 (int)AtomicOrderingCABI::acquire;
2175 OrderingTable[(int)AtomicOrderingCABI::release] =
2176 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2177 (int)AtomicOrderingCABI::acq_rel;
2178 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2179 (int)AtomicOrderingCABI::seq_cst;
2180
2181 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2182 }
2183
2184 // ------------------- Visitors.
2185 using InstVisitor<MemorySanitizerVisitor>::visit;
2186 void visit(Instruction &I) {
2187 if (I.getMetadata(LLVMContext::MD_nosanitize))
2188 return;
2189 // Don't want to visit if we're in the prologue
2190 if (isInPrologue(I))
2191 return;
2192 if (!DebugCounter::shouldExecute(DebugInstrumentInstruction)) {
2193 LLVM_DEBUG(dbgs() << "Skipping instruction: " << I << "\n");
2194 // We still need to set the shadow and origin to clean values.
2195 setShadow(&I, getCleanShadow(&I));
2196 setOrigin(&I, getCleanOrigin());
2197 return;
2198 }
2199
2200 Instructions.push_back(&I);
2201 }
2202
2203 /// Instrument LoadInst
2204 ///
2205 /// Loads the corresponding shadow and (optionally) origin.
2206 /// Optionally, checks that the load address is fully defined.
2207 void visitLoadInst(LoadInst &I) {
2208 assert(I.getType()->isSized() && "Load type must have size");
2209 assert(!I.getMetadata(LLVMContext::MD_nosanitize));
2210 NextNodeIRBuilder IRB(&I);
2211 Type *ShadowTy = getShadowTy(&I);
2212 Value *Addr = I.getPointerOperand();
2213 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
2214 const Align Alignment = I.getAlign();
2215 if (PropagateShadow) {
2216 std::tie(ShadowPtr, OriginPtr) =
2217 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
2218 setShadow(&I,
2219 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2220 } else {
2221 setShadow(&I, getCleanShadow(&I));
2222 }
2223
2224 if (Opts.msan_check_access_address)
2225 insertCheckShadowOf(I.getPointerOperand(), &I);
2226
2227 if (I.isAtomic())
2228 I.setOrdering(addAcquireOrdering(I.getOrdering()));
2229
2230 if (MS.TrackOrigins) {
2231 if (PropagateShadow) {
2232 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
2233 setOrigin(
2234 &I, IRB.CreateAlignedLoad(MS.OriginTy, OriginPtr, OriginAlignment));
2235 } else {
2236 setOrigin(&I, getCleanOrigin());
2237 }
2238 }
2239 }
2240
2241 /// Instrument StoreInst
2242 ///
2243 /// Stores the corresponding shadow and (optionally) origin.
2244 /// Optionally, checks that the store address is fully defined.
2245 void visitStoreInst(StoreInst &I) {
2246 StoreList.push_back(&I);
2247 if (Opts.msan_check_access_address)
2248 insertCheckShadowOf(I.getPointerOperand(), &I);
2249 }
2250
2251 void handleCASOrRMW(Instruction &I) {
2253
2254 IRBuilder<> IRB(&I);
2255 Value *Addr = I.getOperand(0);
2256 Value *Val = I.getOperand(1);
2257 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val), Align(1),
2258 /*isStore*/ true)
2259 .first;
2260
2261 if (Opts.msan_check_access_address)
2262 insertCheckShadowOf(Addr, &I);
2263
2264 // Only test the conditional argument of cmpxchg instruction.
2265 // The other argument can potentially be uninitialized, but we can not
2266 // detect this situation reliably without possible false positives.
2268 insertCheckShadowOf(Val, &I);
2269
2270 IRB.CreateStore(getCleanShadow(Val), ShadowPtr);
2271
2272 setShadow(&I, getCleanShadow(&I));
2273 setOrigin(&I, getCleanOrigin());
2274 }
2275
2276 void visitAtomicRMWInst(AtomicRMWInst &I) {
2277 handleCASOrRMW(I);
2278 I.setOrdering(addReleaseOrdering(I.getOrdering()));
2279 }
2280
2281 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
2282 handleCASOrRMW(I);
2283 I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
2284 }
2285
2286 /// Generic handler to compute shadow for == and != comparisons.
2287 ///
2288 /// This function is used by handleEqualityComparison and visitSwitchInst.
2289 ///
2290 /// Sometimes the comparison result is known even if some of the bits of the
2291 /// arguments are not.
2292 Value *propagateEqualityComparison(IRBuilder<> &IRB, Value *A, Value *B,
2293 Value *Sa, Value *Sb) {
2294 assert(getShadowTy(A) == Sa->getType());
2295 assert(getShadowTy(B) == Sb->getType());
2296
2297 // Get rid of pointers and vectors of pointers.
2298 // For ints (and vectors of ints), types of A and Sa match,
2299 // and this is a no-op.
2300 A = IRB.CreatePointerCast(A, Sa->getType());
2301 B = IRB.CreatePointerCast(B, Sb->getType());
2302
2303 // A == B <==> (C = A^B) == 0
2304 // A != B <==> (C = A^B) != 0
2305 // Sc = Sa | Sb
2306 Value *C = IRB.CreateXor(A, B);
2307 Value *Sc = IRB.CreateOr(Sa, Sb);
2308 // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
2309 // Result is defined if one of the following is true
2310 // * there is a defined 1 bit in C
2311 // * C is fully defined
2312 // Si = !(C & ~Sc) && Sc
2314 Value *MinusOne = Constant::getAllOnesValue(Sc->getType());
2315 Value *LHS = IRB.CreateICmpNE(Sc, Zero);
2316 Value *RHS =
2317 IRB.CreateICmpEQ(IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero);
2318 Value *Si = IRB.CreateAnd(LHS, RHS);
2319 Si->setName("_msprop_icmp");
2320
2321 return Si;
2322 }
2323
2324 // Instrument:
2325 // switch i32 %Val, label %else [ i32 0, label %A
2326 // i32 1, label %B
2327 // i32 2, label %C ]
2328 //
2329 // Typically, the switch input value (%Val) is fully initialized.
2330 //
2331 // Sometimes the compiler may convert (icmp + br) into a switch statement.
2332 // MSan allows icmp eq/ne with partly initialized inputs to still result in a
2333 // fully initialized output, if there exists a bit that is initialized in
2334 // both inputs with a differing value. For compatibility, we support this in
2335 // the switch instrumentation as well. Note that this edge case only applies
2336 // if the switch input value does not match *any* of the cases (matching any
2337 // of the cases requires an exact, fully initialized match).
2338 //
2339 // ShadowCases = 0
2340 // | propagateEqualityComparison(Val, 0)
2341 // | propagateEqualityComparison(Val, 1)
2342 // | propagateEqualityComparison(Val, 2))
2343 void visitSwitchInst(SwitchInst &SI) {
2344 IRBuilder<> IRB(&SI);
2345
2346 Value *Val = SI.getCondition();
2347 Value *ShadowVal = getShadow(Val);
2348 // TODO: add fast path - if the condition is fully initialized, we know
2349 // there is no UUM, without needing to consider the case values below.
2350
2351 // Some code (e.g., AMDGPUGenMCCodeEmitter.inc) has tens of thousands of
2352 // cases. This results in an extremely long chained expression for MSan's
2353 // switch instrumentation, which can cause the JumpThreadingPass to have a
2354 // stack overflow or excessive runtime. We limit the number of cases
2355 // considered, with the tradeoff of niche false negatives.
2356 // TODO: figure out a better solution.
2357 int casesToConsider = Opts.msan_switch_precision;
2358
2359 Value *ShadowCases = nullptr;
2360 for (auto Case : SI.cases()) {
2361 if (casesToConsider <= 0)
2362 break;
2363
2364 Value *Comparator = Case.getCaseValue();
2365 // TODO: some simplification is possible when comparing multiple cases
2366 // simultaneously.
2367 Value *ComparisonShadow = propagateEqualityComparison(
2368 IRB, Val, Comparator, ShadowVal, getShadow(Comparator));
2369
2370 if (ShadowCases)
2371 ShadowCases = IRB.CreateOr(ShadowCases, ComparisonShadow);
2372 else
2373 ShadowCases = ComparisonShadow;
2374
2375 casesToConsider--;
2376 }
2377
2378 if (ShadowCases)
2379 insertCheckShadow(ShadowCases, getOrigin(Val), &SI);
2380 }
2381
2382 // Vector manipulation.
2383 void visitExtractElementInst(ExtractElementInst &I) {
2384 insertCheckShadowOf(I.getOperand(1), &I);
2385 IRBuilder<> IRB(&I);
2386 setShadow(&I, IRB.CreateExtractElement(getShadow(&I, 0), I.getOperand(1),
2387 "_msprop"));
2388 setOrigin(&I, getOrigin(&I, 0));
2389 }
2390
2391 void visitInsertElementInst(InsertElementInst &I) {
2392 insertCheckShadowOf(I.getOperand(2), &I);
2393 IRBuilder<> IRB(&I);
2394 auto *Shadow0 = getShadow(&I, 0);
2395 auto *Shadow1 = getShadow(&I, 1);
2396 setShadow(&I, IRB.CreateInsertElement(Shadow0, Shadow1, I.getOperand(2),
2397 "_msprop"));
2398 setOriginForNaryOp(I);
2399 }
2400
2401 void visitShuffleVectorInst(ShuffleVectorInst &I) {
2402 IRBuilder<> IRB(&I);
2403 auto *Shadow0 = getShadow(&I, 0);
2404 auto *Shadow1 = getShadow(&I, 1);
2405 setShadow(&I, IRB.CreateShuffleVector(Shadow0, Shadow1, I.getShuffleMask(),
2406 "_msprop"));
2407 setOriginForNaryOp(I);
2408 }
2409
2410 // Casts.
2411 void visitSExtInst(SExtInst &I) {
2412 IRBuilder<> IRB(&I);
2413 setShadow(&I, IRB.CreateSExt(getShadow(&I, 0), I.getType(), "_msprop"));
2414 setOrigin(&I, getOrigin(&I, 0));
2415 }
2416
2417 void visitZExtInst(ZExtInst &I) {
2418 IRBuilder<> IRB(&I);
2419 setShadow(&I, IRB.CreateZExt(getShadow(&I, 0), I.getType(), "_msprop"));
2420 setOrigin(&I, getOrigin(&I, 0));
2421 }
2422
2423 void visitTruncInst(TruncInst &I) {
2424 IRBuilder<> IRB(&I);
2425 setShadow(&I, IRB.CreateTrunc(getShadow(&I, 0), I.getType(), "_msprop"));
2426 setOrigin(&I, getOrigin(&I, 0));
2427 }
2428
2429 void visitBitCastInst(BitCastInst &I) {
2430 // Special case: if this is the bitcast (there is exactly 1 allowed) between
2431 // a musttail call and a ret, don't instrument. New instructions are not
2432 // allowed after a musttail call.
2433 if (auto *CI = dyn_cast<CallInst>(I.getOperand(0)))
2434 if (CI->isMustTailCall())
2435 return;
2436 IRBuilder<> IRB(&I);
2437 setShadow(&I, IRB.CreateBitCast(getShadow(&I, 0), getShadowTy(&I)));
2438 setOrigin(&I, getOrigin(&I, 0));
2439 }
2440
2441 void visitAddrSpaceCastInst(AddrSpaceCastInst &I) {
2442 IRBuilder<> IRB(&I);
2443 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2444 "_msprop_addrspacecast"));
2445 setOrigin(&I, getOrigin(&I, 0));
2446 }
2447
2448 void visitPtrToIntInst(PtrToIntInst &I) {
2449 IRBuilder<> IRB(&I);
2450 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2451 "_msprop_ptrtoint"));
2452 setOrigin(&I, getOrigin(&I, 0));
2453 }
2454
2455 void visitPtrToAddrInst(PtrToAddrInst &I) {
2456 IRBuilder<> IRB(&I);
2457 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2458 "_msprop_ptrtoaddr"));
2459 setOrigin(&I, getOrigin(&I, 0));
2460 }
2461
2462 void visitIntToPtrInst(IntToPtrInst &I) {
2463 IRBuilder<> IRB(&I);
2464 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2465 "_msprop_inttoptr"));
2466 setOrigin(&I, getOrigin(&I, 0));
2467 }
2468
2469 /// Handle LLVM and NEON vector convert intrinsics.
2470 ///
2471 /// e.g., <4 x i32> @llvm.aarch64.neon.fcvtpu.v4i32.v4f32(<4 x float>)
2472 /// i32 @llvm.aarch64.neon.fcvtms.i32.f64 (double)
2473 /// <2 x i32> @fptoui (<2 x float>)
2474 /// i64 @llvm.fptosi.sat.i64.f64(double)
2475 ///
2476 /// Note that the size of input/output elements can differ e.g.,
2477 /// double @sitofp(i32)
2478 /// but the number of elements must be the same.
2479 ///
2480 /// For conversions to or from fixed-point, there is a trailing argument to
2481 /// indicate the fixed-point precision:
2482 /// - <4 x float> llvm.aarch64.neon.vcvtfxs2fp.v4f32.v4i32(<4 x i32>, i32)
2483 /// - <4 x i32> llvm.aarch64.neon.vcvtfp2fxu.v4i32.v4f32(<4 x float>, i32)
2484 ///
2485 /// For x86 SSE vector convert intrinsics, see
2486 /// handleSSEVectorConvertIntrinsic().
2487 void handleGenericVectorConvertIntrinsic(Instruction &I, bool FixedPoint) {
2488 [[maybe_unused]] unsigned NumArgs = I.getNumOperands();
2489 if (auto *CI = dyn_cast<CallInst>(&I))
2490 NumArgs = CI->arg_size();
2491
2492 if (FixedPoint) {
2493 assert(NumArgs == 2);
2494 Value *Precision = I.getOperand(1);
2495 insertCheckShadowOf(Precision, &I);
2496 } else {
2497 assert(NumArgs == 1);
2498 }
2499
2500 IRBuilder<> IRB(&I);
2501 Value *S0 = getShadow(&I, 0);
2502
2503 /// For scalars:
2504 /// Since they are converting from floating-point to integer, or between
2505 /// different width floating-point values, the output is:
2506 /// - fully uninitialized if *any* bit of the input is uninitialized
2507 /// - fully ininitialized if all bits of the input are ininitialized
2508 /// We apply the same principle on a per-field basis for vectors.
2509 Value *OutShadow = IRB.CreateSExt(IRB.CreateICmpNE(S0, getCleanShadow(S0)),
2510 getShadowTy(&I));
2511 setShadow(&I, OutShadow);
2512 setOriginForNaryOp(I);
2513 }
2514
2515 void visitFPToSIInst(CastInst &I) {
2516 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2517 }
2518 void visitFPToUIInst(CastInst &I) {
2519 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2520 }
2521 void visitSIToFPInst(CastInst &I) {
2522 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2523 }
2524 void visitUIToFPInst(CastInst &I) {
2525 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2526 }
2527
2528 void visitFPExtInst(CastInst &I) {
2529 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2530 }
2531 void visitFPTruncInst(CastInst &I) {
2532 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
2533 }
2534
2535 /// Generic handler to compute shadow for bitwise AND.
2536 ///
2537 /// This is used by 'visitAnd' but also as a primitive for other handlers.
2538 ///
2539 /// This code is precise: it implements the rule that "And" of an initialized
2540 /// zero bit always results in an initialized value:
2541 // 1&1 => 1; 0&1 => 0; p&1 => p;
2542 // 1&0 => 0; 0&0 => 0; p&0 => 0;
2543 // 1&p => p; 0&p => 0; p&p => p;
2544 //
2545 // S = (S1 & S2) | (V1 & S2) | (S1 & V2)
2546 Value *handleBitwiseAnd(IRBuilder<> &IRB, Value *V1, Value *V2, Value *S1,
2547 Value *S2) {
2548 // "The two arguments to the ‘and’ instruction must be integer or vector
2549 // of integer values. Both arguments must have identical types."
2550 //
2551 // We enforce this condition for all callers to handleBitwiseAnd(); callers
2552 // with non-integer types should call CreateAppToShadowCast() themselves.
2553 assert(V1->getType()->isIntOrIntVectorTy());
2554 assert(V1->getType() == V2->getType());
2555
2556 // Conveniently, getShadowTy() of Int/IntVector returns the original type.
2557 assert(V1->getType() == S1->getType());
2558 assert(V2->getType() == S2->getType());
2559
2560 Value *S1S2 = IRB.CreateAnd(S1, S2);
2561 Value *V1S2 = IRB.CreateAnd(V1, S2);
2562 Value *S1V2 = IRB.CreateAnd(S1, V2);
2563
2564 return IRB.CreateOr({S1S2, V1S2, S1V2});
2565 }
2566
2567 /// Handler for bitwise AND operator.
2568 void visitAnd(BinaryOperator &I) {
2569 IRBuilder<> IRB(&I);
2570 Value *V1 = I.getOperand(0);
2571 Value *V2 = I.getOperand(1);
2572 Value *S1 = getShadow(&I, 0);
2573 Value *S2 = getShadow(&I, 1);
2574
2575 Value *OutShadow = handleBitwiseAnd(IRB, V1, V2, S1, S2);
2576
2577 setShadow(&I, OutShadow);
2578 setOriginForNaryOp(I);
2579 }
2580
2581 void visitOr(BinaryOperator &I) {
2582 IRBuilder<> IRB(&I);
2583 // "Or" of 1 and a poisoned value results in unpoisoned value:
2584 // 1|1 => 1; 0|1 => 1; p|1 => 1;
2585 // 1|0 => 1; 0|0 => 0; p|0 => p;
2586 // 1|p => 1; 0|p => p; p|p => p;
2587 //
2588 // S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2)
2589 //
2590 // If the "disjoint OR" property is violated, the result is poison, and
2591 // hence the entire shadow is uninitialized:
2592 // S = S | SignExt(V1 & V2 != 0)
2593 Value *S1 = getShadow(&I, 0);
2594 Value *S2 = getShadow(&I, 1);
2595 Value *V1 = I.getOperand(0);
2596 Value *V2 = I.getOperand(1);
2597
2598 // "The two arguments to the ‘or’ instruction must be integer or vector
2599 // of integer values. Both arguments must have identical types."
2600 assert(V1->getType()->isIntOrIntVectorTy());
2601 assert(V1->getType() == V2->getType());
2602
2603 // Conveniently, getShadowTy() of Int/IntVector returns the original type.
2604 assert(V1->getType() == S1->getType());
2605 assert(V2->getType() == S2->getType());
2606
2607 Value *NotV1 = IRB.CreateNot(V1);
2608 Value *NotV2 = IRB.CreateNot(V2);
2609
2610 Value *S1S2 = IRB.CreateAnd(S1, S2);
2611 Value *S2NotV1 = IRB.CreateAnd(NotV1, S2);
2612 Value *S1NotV2 = IRB.CreateAnd(S1, NotV2);
2613
2614 Value *S = IRB.CreateOr({S1S2, S2NotV1, S1NotV2});
2615
2616 if (Opts.msan_precise_disjoint_or &&
2617 cast<PossiblyDisjointInst>(&I)->isDisjoint()) {
2618 Value *V1V2 = IRB.CreateAnd(V1, V2);
2619 Value *DisjointOrShadow = IRB.CreateSExt(
2620 IRB.CreateICmpNE(V1V2, getCleanShadow(V1V2)), V1V2->getType());
2621 S = IRB.CreateOr(S, DisjointOrShadow, "_ms_disjoint");
2622 }
2623
2624 setShadow(&I, S);
2625 setOriginForNaryOp(I);
2626 }
2627
2628 /// Default propagation of shadow and/or origin.
2629 ///
2630 /// This class implements the general case of shadow propagation, used in all
2631 /// cases where we don't know and/or don't care about what the operation
2632 /// actually does. It converts all input shadow values to a common type
2633 /// (extending or truncating as necessary), and bitwise OR's them.
2634 ///
2635 /// This is much cheaper than inserting checks (i.e. requiring inputs to be
2636 /// fully initialized), and less prone to false positives.
2637 ///
2638 /// This class also implements the general case of origin propagation. For a
2639 /// Nary operation, result origin is set to the origin of an argument that is
2640 /// not entirely initialized. If there is more than one such arguments, the
2641 /// rightmost of them is picked. It does not matter which one is picked if all
2642 /// arguments are initialized.
2643 template <bool CombineShadow> class Combiner {
2644 Value *Shadow = nullptr;
2645 Value *Origin = nullptr;
2646 IRBuilder<> &IRB;
2647 MemorySanitizerVisitor *MSV;
2648
2649 public:
2650 Combiner(MemorySanitizerVisitor *MSV, IRBuilder<> &IRB)
2651 : IRB(IRB), MSV(MSV) {}
2652
2653 /// Add a pair of shadow and origin values to the mix.
2654 Combiner &Add(Value *OpShadow, Value *OpOrigin) {
2655 if (CombineShadow) {
2656 assert(OpShadow);
2657 if (!Shadow)
2658 Shadow = OpShadow;
2659 else {
2660 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2661 Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop");
2662 }
2663 }
2664
2665 if (MSV->MS.TrackOrigins) {
2666 assert(OpOrigin);
2667 if (!Origin) {
2668 Origin = OpOrigin;
2669 } else {
2670 Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
2671 // No point in adding something that might result in 0 origin value.
2672 if (!ConstOrigin || !ConstOrigin->isNullValue()) {
2673 Value *Cond = MSV->convertToBool(OpShadow, IRB);
2674 Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
2675 }
2676 }
2677 }
2678 return *this;
2679 }
2680
2681 /// Add an application value to the mix.
2682 Combiner &Add(Value *V) {
2683 Value *OpShadow = MSV->getShadow(V);
2684 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : nullptr;
2685 return Add(OpShadow, OpOrigin);
2686 }
2687
2688 /// Set the current combined values as the given instruction's shadow
2689 /// and origin.
2690 void Done(Instruction *I) {
2691 if (CombineShadow) {
2692 assert(Shadow);
2693 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
2694 MSV->setShadow(I, Shadow);
2695 }
2696 if (MSV->MS.TrackOrigins) {
2697 assert(Origin);
2698 MSV->setOrigin(I, Origin);
2699 }
2700 }
2701
2702 /// Store the current combined value at the specified origin
2703 /// location.
2704 void DoneAndStoreOrigin(TypeSize TS, Value *OriginPtr) {
2705 if (MSV->MS.TrackOrigins) {
2706 assert(Origin);
2707 MSV->paintOrigin(IRB, Origin, OriginPtr, TS, kMinOriginAlignment);
2708 }
2709 }
2710 };
2711
2712 using ShadowAndOriginCombiner = Combiner<true>;
2713 using OriginCombiner = Combiner<false>;
2714
2715 /// Propagate origin for arbitrary operation.
2716 void setOriginForNaryOp(Instruction &I) {
2717 if (!MS.TrackOrigins)
2718 return;
2719 IRBuilder<> IRB(&I);
2720 OriginCombiner OC(this, IRB);
2721 for (Use &Op : I.operands())
2722 OC.Add(Op.get());
2723 OC.Done(&I);
2724 }
2725
2726 size_t VectorOrPrimitiveTypeSizeInBits(Type *Ty) {
2727 assert(!(Ty->isVectorTy() && Ty->getScalarType()->isPointerTy()) &&
2728 "Vector of pointers is not a valid shadow type");
2729 return Ty->isVectorTy() ? cast<FixedVectorType>(Ty)->getNumElements() *
2731 : Ty->getPrimitiveSizeInBits();
2732 }
2733
2734 /// Cast between two shadow types, extending or truncating as
2735 /// necessary.
2736 Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
2737 bool Signed = false) {
2738 Type *srcTy = V->getType();
2739 if (srcTy == dstTy)
2740 return V;
2741 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2742 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2743 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2744 return IRB.CreateICmpNE(V, getCleanShadow(V));
2745
2746 if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
2747 return IRB.CreateIntCast(V, dstTy, Signed);
2748 if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
2749 cast<VectorType>(dstTy)->getElementCount() ==
2750 cast<VectorType>(srcTy)->getElementCount())
2751 return IRB.CreateIntCast(V, dstTy, Signed);
2752 Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
2753 Value *V2 =
2754 IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
2755 return IRB.CreateBitCast(V2, dstTy);
2756 // TODO: handle struct types.
2757 }
2758
2759 /// Cast an application value to the type of its own shadow.
2760 Value *CreateAppToShadowCast(IRBuilder<> &IRB, Value *V) {
2761 Type *ShadowTy = getShadowTy(V);
2762 if (V->getType() == ShadowTy)
2763 return V;
2764 if (V->getType()->isPtrOrPtrVectorTy())
2765 return IRB.CreatePtrToInt(V, ShadowTy);
2766 else
2767 return IRB.CreateBitCast(V, ShadowTy);
2768 }
2769
2770 /// Propagate shadow for arbitrary operation.
2771 void handleShadowOr(Instruction &I) {
2772 IRBuilder<> IRB(&I);
2773 ShadowAndOriginCombiner SC(this, IRB);
2774 for (Use &Op : I.operands())
2775 SC.Add(Op.get());
2776 SC.Done(&I);
2777 }
2778
2779 // Perform a bitwise OR on the horizontal pairs (or other specified grouping)
2780 // of elements.
2781 //
2782 // For example, suppose we have:
2783 // VectorA: <a0, a1, a2, a3, a4, a5>
2784 // VectorB: <b0, b1, b2, b3, b4, b5>
2785 // ReductionFactor: 3
2786 // Shards: 1
2787 // The output would be:
2788 // <a0|a1|a2, a3|a4|a5, b0|b1|b2, b3|b4|b5>
2789 //
2790 // If we have:
2791 // VectorA: <a0, a1, a2, a3, a4, a5, a6, a7>
2792 // VectorB: <b0, b1, b2, b3, b4, b5, b6, b7>
2793 // ReductionFactor: 2
2794 // Shards: 2
2795 // then a and be each have 2 "shards", resulting in the output being
2796 // interleaved:
2797 // <a0|a1, a2|a3, b0|b1, b2|b3, a4|a5, a6|a7, b4|b5, b6|b7>
2798 //
2799 // This is convenient for instrumenting horizontal add/sub.
2800 // For bitwise OR on "vertical" pairs, see maybeHandleSimpleNomemIntrinsic().
2801 Value *horizontalReduce(IntrinsicInst &I, unsigned ReductionFactor,
2802 unsigned Shards, Value *VectorA, Value *VectorB) {
2803 assert(isa<FixedVectorType>(VectorA->getType()));
2804 unsigned NumElems =
2805 cast<FixedVectorType>(VectorA->getType())->getNumElements();
2806
2807 [[maybe_unused]] unsigned TotalNumElems = NumElems;
2808 if (VectorB) {
2809 assert(VectorA->getType() == VectorB->getType());
2810 TotalNumElems *= 2;
2811 }
2812
2813 assert(NumElems % (ReductionFactor * Shards) == 0);
2814
2815 Value *Or = nullptr;
2816
2817 IRBuilder<> IRB(&I);
2818 for (unsigned i = 0; i < ReductionFactor; i++) {
2819 SmallVector<int, 16> Mask;
2820
2821 for (unsigned j = 0; j < Shards; j++) {
2822 unsigned Offset = NumElems / Shards * j;
2823
2824 for (unsigned X = 0; X < NumElems / Shards; X += ReductionFactor)
2825 Mask.push_back(Offset + X + i);
2826
2827 if (VectorB) {
2828 for (unsigned X = 0; X < NumElems / Shards; X += ReductionFactor)
2829 Mask.push_back(NumElems + Offset + X + i);
2830 }
2831 }
2832
2833 Value *Masked;
2834 if (VectorB)
2835 Masked = IRB.CreateShuffleVector(VectorA, VectorB, Mask);
2836 else
2837 Masked = IRB.CreateShuffleVector(VectorA, Mask);
2838
2839 if (Or)
2840 Or = IRB.CreateOr(Or, Masked);
2841 else
2842 Or = Masked;
2843 }
2844
2845 return Or;
2846 }
2847
2848 /// Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
2849 /// fields.
2850 ///
2851 /// e.g., <2 x i32> @llvm.aarch64.neon.saddlp.v2i32.v4i16(<4 x i16>)
2852 /// <16 x i8> @llvm.aarch64.neon.addp.v16i8(<16 x i8>, <16 x i8>)
2853 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &I, unsigned Shards) {
2854 assert(I.arg_size() == 1 || I.arg_size() == 2);
2855
2856 assert(I.getType()->isVectorTy());
2857 assert(I.getArgOperand(0)->getType()->isVectorTy());
2858
2859 [[maybe_unused]] FixedVectorType *ParamType =
2860 cast<FixedVectorType>(I.getArgOperand(0)->getType());
2861 assert((I.arg_size() != 2) ||
2862 (ParamType == cast<FixedVectorType>(I.getArgOperand(1)->getType())));
2863 [[maybe_unused]] FixedVectorType *ReturnType =
2864 cast<FixedVectorType>(I.getType());
2865 assert(ParamType->getNumElements() * I.arg_size() ==
2866 2 * ReturnType->getNumElements());
2867
2868 IRBuilder<> IRB(&I);
2869
2870 // Horizontal OR of shadow
2871 Value *FirstArgShadow = getShadow(&I, 0);
2872 Value *SecondArgShadow = nullptr;
2873 if (I.arg_size() == 2)
2874 SecondArgShadow = getShadow(&I, 1);
2875
2876 Value *OrShadow = horizontalReduce(I, /*ReductionFactor=*/2, Shards,
2877 FirstArgShadow, SecondArgShadow);
2878
2879 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
2880
2881 setShadow(&I, OrShadow);
2882 setOriginForNaryOp(I);
2883 }
2884
2885 /// Propagate shadow for 1- or 2-vector intrinsics that combine adjacent
2886 /// fields, with the parameters reinterpreted to have elements of a specified
2887 /// width. For example:
2888 /// @llvm.x86.ssse3.phadd.w(<1 x i64> [[VAR1]], <1 x i64> [[VAR2]])
2889 /// conceptually operates on
2890 /// (<4 x i16> [[VAR1]], <4 x i16> [[VAR2]])
2891 /// and can be handled with ReinterpretElemWidth == 16.
2892 void handlePairwiseShadowOrIntrinsic(IntrinsicInst &I, unsigned Shards,
2893 int ReinterpretElemWidth) {
2894 assert(I.arg_size() == 1 || I.arg_size() == 2);
2895
2896 assert(I.getType()->isVectorTy());
2897 assert(I.getArgOperand(0)->getType()->isVectorTy());
2898
2899 FixedVectorType *ParamType =
2900 cast<FixedVectorType>(I.getArgOperand(0)->getType());
2901 assert((I.arg_size() != 2) ||
2902 (ParamType == cast<FixedVectorType>(I.getArgOperand(1)->getType())));
2903
2904 [[maybe_unused]] FixedVectorType *ReturnType =
2905 cast<FixedVectorType>(I.getType());
2906 assert(ParamType->getNumElements() * I.arg_size() ==
2907 2 * ReturnType->getNumElements());
2908
2909 IRBuilder<> IRB(&I);
2910
2911 FixedVectorType *ReinterpretShadowTy = nullptr;
2912 assert(isAligned(Align(ReinterpretElemWidth),
2913 ParamType->getPrimitiveSizeInBits()));
2914 ReinterpretShadowTy = FixedVectorType::get(
2915 IRB.getIntNTy(ReinterpretElemWidth),
2916 ParamType->getPrimitiveSizeInBits() / ReinterpretElemWidth);
2917
2918 // Horizontal OR of shadow
2919 Value *FirstArgShadow = getShadow(&I, 0);
2920 FirstArgShadow = IRB.CreateBitCast(FirstArgShadow, ReinterpretShadowTy);
2921
2922 // If we had two parameters each with an odd number of elements, the total
2923 // number of elements is even, but we have never seen this in extant
2924 // instruction sets, so we enforce that each parameter must have an even
2925 // number of elements.
2927 Align(2),
2928 cast<FixedVectorType>(FirstArgShadow->getType())->getNumElements()));
2929
2930 Value *SecondArgShadow = nullptr;
2931 if (I.arg_size() == 2) {
2932 SecondArgShadow = getShadow(&I, 1);
2933 SecondArgShadow = IRB.CreateBitCast(SecondArgShadow, ReinterpretShadowTy);
2934 }
2935
2936 Value *OrShadow = horizontalReduce(I, /*ReductionFactor=*/2, Shards,
2937 FirstArgShadow, SecondArgShadow);
2938
2939 OrShadow = CreateShadowCast(IRB, OrShadow, getShadowTy(&I));
2940
2941 setShadow(&I, OrShadow);
2942 setOriginForNaryOp(I);
2943 }
2944
2945 void visitFNeg(UnaryOperator &I) { handleShadowOr(I); }
2946
2947 // Handle multiplication by constant.
2948 //
2949 // Handle a special case of multiplication by constant that may have one or
2950 // more zeros in the lower bits. This makes corresponding number of lower bits
2951 // of the result zero as well. We model it by shifting the other operand
2952 // shadow left by the required number of bits. Effectively, we transform
2953 // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B).
2954 // We use multiplication by 2**N instead of shift to cover the case of
2955 // multiplication by 0, which may occur in some elements of a vector operand.
2956 void handleMulByConstant(BinaryOperator &I, Constant *ConstArg,
2957 Value *OtherArg) {
2958 Constant *ShadowMul;
2959 Type *Ty = ConstArg->getType();
2960 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
2961 unsigned NumElements = cast<FixedVectorType>(VTy)->getNumElements();
2962 Type *EltTy = VTy->getElementType();
2964 for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
2965 if (ConstantInt *Elt =
2967 const APInt &V = Elt->getValue();
2968 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
2969 Elements.push_back(ConstantInt::get(EltTy, V2));
2970 } else {
2971 Elements.push_back(ConstantInt::get(EltTy, 1));
2972 }
2973 }
2974 ShadowMul = ConstantVector::get(Elements);
2975 } else {
2976 if (ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg)) {
2977 const APInt &V = Elt->getValue();
2978 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
2979 ShadowMul = ConstantInt::get(Ty, V2);
2980 } else {
2981 ShadowMul = ConstantInt::get(Ty, 1);
2982 }
2983 }
2984
2985 IRBuilder<> IRB(&I);
2986 setShadow(&I,
2987 IRB.CreateMul(getShadow(OtherArg), ShadowMul, "msprop_mul_cst"));
2988 setOrigin(&I, getOrigin(OtherArg));
2989 }
2990
2991 void visitMul(BinaryOperator &I) {
2992 Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
2993 Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
2994 if (constOp0 && !constOp1)
2995 handleMulByConstant(I, constOp0, I.getOperand(1));
2996 else if (constOp1 && !constOp0)
2997 handleMulByConstant(I, constOp1, I.getOperand(0));
2998 else
2999 handleShadowOr(I);
3000 }
3001
3002 void visitFAdd(BinaryOperator &I) { handleShadowOr(I); }
3003 void visitFSub(BinaryOperator &I) { handleShadowOr(I); }
3004 void visitFMul(BinaryOperator &I) { handleShadowOr(I); }
3005 void visitAdd(BinaryOperator &I) { handleShadowOr(I); }
3006 void visitSub(BinaryOperator &I) { handleShadowOr(I); }
3007 void visitXor(BinaryOperator &I) { handleShadowOr(I); }
3008
3009 void handleIntegerDiv(Instruction &I) {
3010 IRBuilder<> IRB(&I);
3011 // Strict on the second argument.
3012 insertCheckShadowOf(I.getOperand(1), &I);
3013 setShadow(&I, getShadow(&I, 0));
3014 setOrigin(&I, getOrigin(&I, 0));
3015 }
3016
3017 void visitUDiv(BinaryOperator &I) { handleIntegerDiv(I); }
3018 void visitSDiv(BinaryOperator &I) { handleIntegerDiv(I); }
3019 void visitURem(BinaryOperator &I) { handleIntegerDiv(I); }
3020 void visitSRem(BinaryOperator &I) { handleIntegerDiv(I); }
3021
3022 // Floating point division is side-effect free. We can not require that the
3023 // divisor is fully initialized and must propagate shadow. See PR37523.
3024 void visitFDiv(BinaryOperator &I) { handleShadowOr(I); }
3025 void visitFRem(BinaryOperator &I) { handleShadowOr(I); }
3026
3027 /// Instrument == and != comparisons.
3028 ///
3029 /// Sometimes the comparison result is known even if some of the bits of the
3030 /// arguments are not.
3031 void handleEqualityComparison(ICmpInst &I) {
3032 IRBuilder<> IRB(&I);
3033 Value *A = I.getOperand(0);
3034 Value *B = I.getOperand(1);
3035 Value *Sa = getShadow(A);
3036 Value *Sb = getShadow(B);
3037
3038 Value *Si = propagateEqualityComparison(IRB, A, B, Sa, Sb);
3039
3040 setShadow(&I, Si);
3041 setOriginForNaryOp(I);
3042 }
3043
3044 /// Instrument relational comparisons.
3045 ///
3046 /// This function does exact shadow propagation for all relational
3047 /// comparisons of integers, pointers and vectors of those.
3048 /// FIXME: output seems suboptimal when one of the operands is a constant
3049 void handleRelationalComparisonExact(ICmpInst &I) {
3050 IRBuilder<> IRB(&I);
3051 Value *A = I.getOperand(0);
3052 Value *B = I.getOperand(1);
3053 Value *Sa = getShadow(A);
3054 Value *Sb = getShadow(B);
3055
3056 // Get rid of pointers and vectors of pointers.
3057 // For ints (and vectors of ints), types of A and Sa match,
3058 // and this is a no-op.
3059 A = IRB.CreatePointerCast(A, Sa->getType());
3060 B = IRB.CreatePointerCast(B, Sb->getType());
3061
3062 // Let [a0, a1] be the interval of possible values of A, taking into account
3063 // its undefined bits. Let [b0, b1] be the interval of possible values of B.
3064 // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
3065 bool IsSigned = I.isSigned();
3066
3067 auto GetMinMaxUnsigned = [&](Value *V, Value *S) {
3068 if (IsSigned) {
3069 // Sign-flip to map from signed range to unsigned range. Relation A vs B
3070 // should be preserved, if checked with `getUnsignedPredicate()`.
3071 // Relationship between Amin, Amax, Bmin, Bmax also will not be
3072 // affected, as they are created by effectively adding/substructing from
3073 // A (or B) a value, derived from shadow, with no overflow, either
3074 // before or after sign flip.
3075 APInt MinVal =
3076 APInt::getSignedMinValue(V->getType()->getScalarSizeInBits());
3077 V = IRB.CreateXor(V, ConstantInt::get(V->getType(), MinVal));
3078 }
3079 // Minimize undefined bits.
3080 Value *Min = IRB.CreateAnd(V, IRB.CreateNot(S));
3081 Value *Max = IRB.CreateOr(V, S);
3082 return std::make_pair(Min, Max);
3083 };
3084
3085 auto [Amin, Amax] = GetMinMaxUnsigned(A, Sa);
3086 auto [Bmin, Bmax] = GetMinMaxUnsigned(B, Sb);
3087 Value *S1 = IRB.CreateICmp(I.getUnsignedPredicate(), Amin, Bmax);
3088 Value *S2 = IRB.CreateICmp(I.getUnsignedPredicate(), Amax, Bmin);
3089
3090 Value *Si = IRB.CreateXor(S1, S2);
3091 setShadow(&I, Si);
3092 setOriginForNaryOp(I);
3093 }
3094
3095 /// Instrument signed relational comparisons.
3096 ///
3097 /// Handle sign bit tests: x<0, x>=0, x<=-1, x>-1 by propagating the highest
3098 /// bit of the shadow. Everything else is delegated to handleShadowOr().
3099 void handleSignedRelationalComparison(ICmpInst &I) {
3100 Constant *constOp;
3101 Value *op = nullptr;
3103 if ((constOp = dyn_cast<Constant>(I.getOperand(1)))) {
3104 op = I.getOperand(0);
3105 pre = I.getPredicate();
3106 } else if ((constOp = dyn_cast<Constant>(I.getOperand(0)))) {
3107 op = I.getOperand(1);
3108 pre = I.getSwappedPredicate();
3109 } else {
3110 handleShadowOr(I);
3111 return;
3112 }
3113
3114 if ((constOp->isNullValue() &&
3115 (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) ||
3116 (constOp->isAllOnesValue() &&
3117 (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE))) {
3118 IRBuilder<> IRB(&I);
3119 Value *Shadow = IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op),
3120 "_msprop_icmp_s");
3121 setShadow(&I, Shadow);
3122 setOrigin(&I, getOrigin(op));
3123 } else {
3124 handleShadowOr(I);
3125 }
3126 }
3127
3128 void visitICmpInst(ICmpInst &I) {
3129 if (!Opts.msan_handle_icmp) {
3130 handleShadowOr(I);
3131 return;
3132 }
3133 if (I.isEquality()) {
3134 handleEqualityComparison(I);
3135 return;
3136 }
3137
3138 assert(I.isRelational());
3139 if (Opts.msan_handle_icmp_exact) {
3140 handleRelationalComparisonExact(I);
3141 return;
3142 }
3143 if (I.isSigned()) {
3144 handleSignedRelationalComparison(I);
3145 return;
3146 }
3147
3148 assert(I.isUnsigned());
3149 if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
3150 handleRelationalComparisonExact(I);
3151 return;
3152 }
3153
3154 handleShadowOr(I);
3155 }
3156
3157 void visitFCmpInst(FCmpInst &I) { handleShadowOr(I); }
3158
3159 void handleShift(BinaryOperator &I) {
3160 IRBuilder<> IRB(&I);
3161 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3162 // Otherwise perform the same shift on S1.
3163 Value *S1 = getShadow(&I, 0);
3164 Value *S2 = getShadow(&I, 1);
3165 Value *S2Conv =
3166 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
3167 Value *V2 = I.getOperand(1);
3168 Value *Shift = IRB.CreateBinOp(I.getOpcode(), S1, V2);
3169 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3170 setOriginForNaryOp(I);
3171 }
3172
3173 void visitShl(BinaryOperator &I) { handleShift(I); }
3174 void visitAShr(BinaryOperator &I) { handleShift(I); }
3175 void visitLShr(BinaryOperator &I) { handleShift(I); }
3176
3177 void handleFunnelShift(IntrinsicInst &I) {
3178 IRBuilder<> IRB(&I);
3179 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3180 // Otherwise perform the same shift on S0 and S1.
3181 Value *S0 = getShadow(&I, 0);
3182 Value *S1 = getShadow(&I, 1);
3183 Value *S2 = getShadow(&I, 2);
3184 Value *S2Conv =
3185 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
3186 Value *V2 = I.getOperand(2);
3187 Value *Shift = IRB.CreateIntrinsic(I.getIntrinsicID(), S2Conv->getType(),
3188 {S0, S1, V2});
3189 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3190 setOriginForNaryOp(I);
3191 }
3192
3193 // Instrument bit manipulation intrinsics.
3194 // All of these intrinsics are Z = I(SRC, MASK)
3195 // where the types of all operands and the result match.
3196 // The following instrumentation happens to work for all of them:
3197 // Sz = I(Ssrc, MASK) | (sext (Smask != 0))
3198 void handleGenericBitManipulation(IntrinsicInst &I) {
3199 IRBuilder<> IRB(&I);
3200 Type *ShadowTy = getShadowTy(&I);
3201
3202 // If any bit of the mask operand is poisoned, then the whole thing is.
3203 Value *SMask = getShadow(&I, 1);
3204 SMask = IRB.CreateSExt(IRB.CreateICmpNE(SMask, getCleanShadow(ShadowTy)),
3205 ShadowTy);
3206 // Apply the same intrinsic to the shadow of the first operand.
3207 Value *S;
3208 if (Function *Func = I.getCalledFunction())
3209 S = IRB.CreateCall(Func, {getShadow(&I, 0), I.getOperand(1)});
3210 else
3211 S = IRB.CreateIntrinsic(I.getIntrinsicID(), ShadowTy,
3212 {getShadow(&I, 0), I.getOperand(1)});
3213
3214 setShadow(&I, IRB.CreateOr(SMask, S));
3215 setOriginForNaryOp(I);
3216 }
3217
3218 /// Instrument llvm.memmove
3219 ///
3220 /// At this point we don't know if llvm.memmove will be inlined or not.
3221 /// If we don't instrument it and it gets inlined,
3222 /// our interceptor will not kick in and we will lose the memmove.
3223 /// If we instrument the call here, but it does not get inlined,
3224 /// we will memmove the shadow twice: which is bad in case
3225 /// of overlapping regions. So, we simply lower the intrinsic to a call.
3226 ///
3227 /// Similar situation exists for memcpy and memset.
3228 void visitMemMoveInst(MemMoveInst &I) {
3229 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
3230 IRBuilder<> IRB(&I);
3231 IRB.CreateCall(MS.MemmoveFn,
3232 {I.getArgOperand(0), I.getArgOperand(1),
3233 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3235 }
3236
3237 /// Instrument memcpy
3238 ///
3239 /// Similar to memmove: avoid copying shadow twice. This is somewhat
3240 /// unfortunate as it may slowdown small constant memcpys.
3241 /// FIXME: consider doing manual inline for small constant sizes and proper
3242 /// alignment.
3243 ///
3244 /// Note: This also handles memcpy.inline, which promises no calls to external
3245 /// functions as an optimization. However, with instrumentation enabled this
3246 /// is difficult to promise; additionally, we know that the MSan runtime
3247 /// exists and provides __msan_memcpy(). Therefore, we assume that with
3248 /// instrumentation it's safe to turn memcpy.inline into a call to
3249 /// __msan_memcpy(). Should this be wrong, such as when implementing memcpy()
3250 /// itself, instrumentation should be disabled with the no_sanitize attribute.
3251 void visitMemCpyInst(MemCpyInst &I) {
3252 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
3253 IRBuilder<> IRB(&I);
3254 IRB.CreateCall(MS.MemcpyFn,
3255 {I.getArgOperand(0), I.getArgOperand(1),
3256 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3258 }
3259
3260 // Same as memcpy.
3261 void visitMemSetInst(MemSetInst &I) {
3262 IRBuilder<> IRB(&I);
3263 IRB.CreateCall(
3264 MS.MemsetFn,
3265 {I.getArgOperand(0),
3266 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
3267 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
3269 }
3270
3271 void visitVAStartInst(VAStartInst &I) { VAHelper->visitVAStartInst(I); }
3272
3273 void visitVACopyInst(VACopyInst &I) { VAHelper->visitVACopyInst(I); }
3274
3275 /// Handle vector store-like intrinsics.
3276 ///
3277 /// Instrument intrinsics that look like a simple SIMD store: writes memory,
3278 /// has 1 pointer argument and 1 vector argument, returns void.
3279 bool handleVectorStoreIntrinsic(IntrinsicInst &I) {
3280 assert(I.arg_size() == 2);
3281
3282 IRBuilder<> IRB(&I);
3283 Value *Addr = I.getArgOperand(0);
3284 Value *Shadow = getShadow(&I, 1);
3285 Value *ShadowPtr, *OriginPtr;
3286
3287 // We don't know the pointer alignment (could be unaligned SSE store!).
3288 // Have to assume to worst case.
3289 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3290 Addr, IRB, Shadow->getType(), Align(1), /*isStore*/ true);
3291 IRB.CreateAlignedStore(Shadow, ShadowPtr, Align(1));
3292
3293 if (Opts.msan_check_access_address)
3294 insertCheckShadowOf(Addr, &I);
3295
3296 // FIXME: factor out common code from materializeStores
3297 if (MS.TrackOrigins)
3298 IRB.CreateStore(getOrigin(&I, 1), OriginPtr);
3299 return true;
3300 }
3301
3302 /// Handle vector load-like intrinsics.
3303 ///
3304 /// Instrument intrinsics that look like a simple SIMD load: reads memory,
3305 /// has 1 pointer argument, returns a vector.
3306 bool handleVectorLoadIntrinsic(IntrinsicInst &I) {
3307 assert(I.arg_size() == 1);
3308
3309 IRBuilder<> IRB(&I);
3310 Value *Addr = I.getArgOperand(0);
3311
3312 Type *ShadowTy = getShadowTy(&I);
3313 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
3314 if (PropagateShadow) {
3315 // We don't know the pointer alignment (could be unaligned SSE load!).
3316 // Have to assume to worst case.
3317 const Align Alignment = Align(1);
3318 std::tie(ShadowPtr, OriginPtr) =
3319 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
3320 setShadow(&I,
3321 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
3322 } else {
3323 setShadow(&I, getCleanShadow(&I));
3324 }
3325
3326 if (Opts.msan_check_access_address)
3327 insertCheckShadowOf(Addr, &I);
3328
3329 if (MS.TrackOrigins) {
3330 if (PropagateShadow)
3331 setOrigin(&I, IRB.CreateLoad(MS.OriginTy, OriginPtr));
3332 else
3333 setOrigin(&I, getCleanOrigin());
3334 }
3335 return true;
3336 }
3337
3338 /// Handle (SIMD arithmetic)-like intrinsics.
3339 ///
3340 /// Instrument intrinsics with any number of arguments of the same type [*],
3341 /// equal to the return type, plus a specified number of trailing flags of
3342 /// any type.
3343 ///
3344 /// [*] The type should be simple (no aggregates or pointers; vectors are
3345 /// fine).
3346 ///
3347 /// Caller guarantees that this intrinsic does not access memory.
3348 ///
3349 /// TODO: "horizontal"/"pairwise" intrinsics are often incorrectly matched by
3350 /// by this handler. See horizontalReduce().
3351 ///
3352 /// TODO: permutation intrinsics are also often incorrectly matched.
3353 [[maybe_unused]] bool
3354 maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I,
3355 unsigned int trailingFlags) {
3356 Type *RetTy = I.getType();
3357 if (!(RetTy->isIntOrIntVectorTy() || RetTy->isFPOrFPVectorTy()))
3358 return false;
3359
3360 unsigned NumArgOperands = I.arg_size();
3361 assert(NumArgOperands >= trailingFlags);
3362 for (unsigned i = 0; i < NumArgOperands - trailingFlags; ++i) {
3363 Type *Ty = I.getArgOperand(i)->getType();
3364 if (Ty != RetTy)
3365 return false;
3366 }
3367
3368 IRBuilder<> IRB(&I);
3369 ShadowAndOriginCombiner SC(this, IRB);
3370 for (unsigned i = 0; i < NumArgOperands; ++i)
3371 SC.Add(I.getArgOperand(i));
3372 SC.Done(&I);
3373
3374 return true;
3375 }
3376
3377 /// Returns whether it was able to heuristically instrument unknown
3378 /// intrinsics.
3379 ///
3380 /// The main purpose of this code is to do something reasonable with all
3381 /// random intrinsics we might encounter, most importantly - SIMD intrinsics.
3382 /// We recognize several classes of intrinsics by their argument types and
3383 /// ModRefBehaviour and apply special instrumentation when we are reasonably
3384 /// sure that we know what the intrinsic does.
3385 ///
3386 /// We special-case intrinsics where this approach fails. See llvm.bswap
3387 /// handling as an example of that.
3388 bool maybeHandleUnknownIntrinsicUnlogged(IntrinsicInst &I) {
3389 unsigned NumArgOperands = I.arg_size();
3390 if (NumArgOperands == 0)
3391 return false;
3392
3393 if (NumArgOperands == 2 && I.getArgOperand(0)->getType()->isPointerTy() &&
3394 I.getArgOperand(1)->getType()->isVectorTy() &&
3395 I.getType()->isVoidTy() && !I.onlyReadsMemory()) {
3396 // This looks like a vector store.
3397 return handleVectorStoreIntrinsic(I);
3398 }
3399
3400 if (NumArgOperands == 1 && I.getArgOperand(0)->getType()->isPointerTy() &&
3401 I.getType()->isVectorTy() && I.onlyReadsMemory()) {
3402 // This looks like a vector load.
3403 return handleVectorLoadIntrinsic(I);
3404 }
3405
3406 if (I.doesNotAccessMemory())
3407 if (maybeHandleSimpleNomemIntrinsic(I, /*trailingFlags=*/0))
3408 return true;
3409
3410 // FIXME: detect and handle SSE maskstore/maskload?
3411 // Some cases are now handled in handleAVXMasked{Load,Store}.
3412 return false;
3413 }
3414
3415 bool maybeHandleUnknownIntrinsic(IntrinsicInst &I) {
3416 if (maybeHandleUnknownIntrinsicUnlogged(I)) {
3417 if (Opts.msan_dump_heuristic_instructions)
3418 dumpInst(I, "Heuristic");
3419
3420 LLVM_DEBUG(dbgs() << "UNKNOWN INSTRUCTION HANDLED HEURISTICALLY: " << I
3421 << "\n");
3422 return true;
3423 } else
3424 return false;
3425 }
3426
3427 void handleInvariantGroup(IntrinsicInst &I) {
3428 setShadow(&I, getShadow(&I, 0));
3429 setOrigin(&I, getOrigin(&I, 0));
3430 }
3431
3432 void handleLifetimeStart(IntrinsicInst &I) {
3433 if (!PoisonStack)
3434 return;
3435 AllocaInst *AI = dyn_cast<AllocaInst>(I.getArgOperand(0));
3436 if (AI)
3437 LifetimeStartList.push_back(std::make_pair(&I, AI));
3438 }
3439
3440 void handleBswap(IntrinsicInst &I) {
3441 IRBuilder<> IRB(&I);
3442 Value *Op = I.getArgOperand(0);
3443 Type *OpType = Op->getType();
3444 setShadow(&I, IRB.CreateIntrinsic(Intrinsic::bswap, ArrayRef(&OpType, 1),
3445 getShadow(Op)));
3446 setOrigin(&I, getOrigin(Op));
3447 }
3448
3449 // Uninitialized bits are ok if they appear after the leading/trailing 0's
3450 // and a 1. If the input is all zero, it is fully initialized iff
3451 // !is_zero_poison.
3452 //
3453 // e.g., for ctlz, with little-endian, if 0/1 are initialized bits with
3454 // concrete value 0/1, and ? is an uninitialized bit:
3455 // - 0001 0??? is fully initialized
3456 // - 000? ???? is fully uninitialized (*)
3457 // - ???? ???? is fully uninitialized
3458 // - 0000 0000 is fully uninitialized if is_zero_poison,
3459 // fully initialized otherwise
3460 //
3461 // (*) TODO: arguably, since the number of zeros is in the range [3, 8], we
3462 // only need to poison 4 bits.
3463 //
3464 // OutputShadow =
3465 // ((ConcreteZerosCount >= ShadowZerosCount) && !AllZeroShadow)
3466 // || (is_zero_poison && AllZeroSrc)
3467 void handleCountLeadingTrailingZeros(IntrinsicInst &I) {
3468 IRBuilder<> IRB(&I);
3469 Value *Src = I.getArgOperand(0);
3470 Value *SrcShadow = getShadow(Src);
3471
3472 Value *False = IRB.getInt1(false);
3473 Value *ConcreteZerosCount = IRB.CreateIntrinsic(
3474 I.getType(), I.getIntrinsicID(), {Src, /*is_zero_poison=*/False});
3475 Value *ShadowZerosCount = IRB.CreateIntrinsic(
3476 I.getType(), I.getIntrinsicID(), {SrcShadow, /*is_zero_poison=*/False});
3477
3478 Value *CompareConcreteZeros = IRB.CreateICmpUGE(
3479 ConcreteZerosCount, ShadowZerosCount, "_mscz_cmp_zeros");
3480
3481 Value *NotAllZeroShadow =
3482 IRB.CreateIsNotNull(SrcShadow, "_mscz_shadow_not_null");
3483 Value *OutputShadow =
3484 IRB.CreateAnd(CompareConcreteZeros, NotAllZeroShadow, "_mscz_main");
3485
3486 // If zero poison is requested, mix in with the shadow
3487 Constant *IsZeroPoison = cast<Constant>(I.getOperand(1));
3488 if (!IsZeroPoison->isNullValue()) {
3489 Value *BoolZeroPoison = IRB.CreateIsNull(Src, "_mscz_bzp");
3490 OutputShadow = IRB.CreateOr(OutputShadow, BoolZeroPoison, "_mscz_bs");
3491 }
3492
3493 OutputShadow = IRB.CreateSExt(OutputShadow, getShadowTy(Src), "_mscz_os");
3494
3495 setShadow(&I, OutputShadow);
3496 setOriginForNaryOp(I);
3497 }
3498
3499 /// Some instructions have additional zero-elements in the return type
3500 /// e.g., <16 x i8> @llvm.x86.avx512.mask.pmov.qb.512(<8 x i64>, ...)
3501 ///
3502 /// This function will return a vector type with the same number of elements
3503 /// as the input, but same per-element width as the return value e.g.,
3504 /// <8 x i8>.
3505 FixedVectorType *maybeShrinkVectorShadowType(Value *Src, IntrinsicInst &I) {
3506 assert(isa<FixedVectorType>(getShadowTy(&I)));
3507 FixedVectorType *ShadowType = cast<FixedVectorType>(getShadowTy(&I));
3508
3509 // TODO: generalize beyond 2x?
3510 if (ShadowType->getElementCount() ==
3511 cast<VectorType>(Src->getType())->getElementCount() * 2)
3512 ShadowType = FixedVectorType::getHalfElementsVectorType(ShadowType);
3513
3514 assert(ShadowType->getElementCount() ==
3515 cast<VectorType>(Src->getType())->getElementCount());
3516
3517 return ShadowType;
3518 }
3519
3520 /// Doubles the length of a vector shadow (extending with zeros) if necessary
3521 /// to match the length of the shadow for the instruction.
3522 /// If scalar types of the vectors are different, it will use the type of the
3523 /// input vector.
3524 /// This is more type-safe than CreateShadowCast().
3525 Value *maybeExtendVectorShadowWithZeros(Value *Shadow, IntrinsicInst &I) {
3526 IRBuilder<> IRB(&I);
3528 assert(isa<FixedVectorType>(I.getType()));
3529
3530 Value *FullShadow = getCleanShadow(&I);
3531 unsigned ShadowNumElems =
3532 cast<FixedVectorType>(Shadow->getType())->getNumElements();
3533 unsigned FullShadowNumElems =
3534 cast<FixedVectorType>(FullShadow->getType())->getNumElements();
3535
3536 assert((ShadowNumElems == FullShadowNumElems) ||
3537 (ShadowNumElems * 2 == FullShadowNumElems));
3538
3539 if (ShadowNumElems == FullShadowNumElems) {
3540 FullShadow = Shadow;
3541 } else {
3542 // TODO: generalize beyond 2x?
3543 SmallVector<int, 32> ShadowMask(FullShadowNumElems);
3544 std::iota(ShadowMask.begin(), ShadowMask.end(), 0);
3545
3546 // Append zeros
3547 FullShadow =
3548 IRB.CreateShuffleVector(Shadow, getCleanShadow(Shadow), ShadowMask);
3549 }
3550
3551 return FullShadow;
3552 }
3553
3554 /// Handle x86 SSE vector conversion.
3555 ///
3556 /// e.g., single-precision to half-precision conversion:
3557 /// <8 x i16> @llvm.x86.vcvtps2ph.256(<8 x float> %a0, i32 0)
3558 /// <8 x i16> @llvm.x86.vcvtps2ph.128(<4 x float> %a0, i32 0)
3559 ///
3560 /// floating-point to integer:
3561 /// <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float>)
3562 /// <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double>)
3563 ///
3564 /// Note: if the output has more elements, they are zero-initialized (and
3565 /// therefore the shadow will also be initialized).
3566 ///
3567 /// This differs from handleSSEVectorConvertIntrinsic() because it
3568 /// propagates uninitialized shadow (instead of checking the shadow).
3569 void handleSSEVectorConvertIntrinsicByProp(IntrinsicInst &I,
3570 bool HasRoundingMode) {
3571 if (HasRoundingMode) {
3572 assert(I.arg_size() == 2);
3573 [[maybe_unused]] Value *RoundingMode = I.getArgOperand(1);
3574 assert(RoundingMode->getType()->isIntegerTy());
3575 } else {
3576 assert(I.arg_size() == 1);
3577 }
3578
3579 Value *Src = I.getArgOperand(0);
3580 assert(Src->getType()->isVectorTy());
3581
3582 // The return type might have more elements than the input.
3583 // Temporarily shrink the return type's number of elements.
3584 VectorType *ShadowType = maybeShrinkVectorShadowType(Src, I);
3585
3586 IRBuilder<> IRB(&I);
3587 Value *S0 = getShadow(&I, 0);
3588
3589 /// For scalars:
3590 /// Since they are converting to and/or from floating-point, the output is:
3591 /// - fully uninitialized if *any* bit of the input is uninitialized
3592 /// - fully ininitialized if all bits of the input are ininitialized
3593 /// We apply the same principle on a per-field basis for vectors.
3594 Value *Shadow =
3595 IRB.CreateSExt(IRB.CreateICmpNE(S0, getCleanShadow(S0)), ShadowType);
3596
3597 // The return type might have more elements than the input.
3598 // Extend the return type back to its original width if necessary.
3599 Value *FullShadow = maybeExtendVectorShadowWithZeros(Shadow, I);
3600
3601 setShadow(&I, FullShadow);
3602 setOriginForNaryOp(I);
3603 }
3604
3605 // Instrument x86 SSE vector convert intrinsic.
3606 //
3607 // This function instruments intrinsics like cvtsi2ss:
3608 // %Out = int_xxx_cvtyyy(%ConvertOp)
3609 // or
3610 // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp)
3611 // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same
3612 // number \p Out elements, and (if has 2 arguments) copies the rest of the
3613 // elements from \p CopyOp.
3614 // In most cases conversion involves floating-point value which may trigger a
3615 // hardware exception when not fully initialized. For this reason we require
3616 // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise.
3617 // We copy the shadow of \p CopyOp[NumUsedElements:] to \p
3618 // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
3619 // return a fully initialized value.
3620 //
3621 // For Arm NEON vector convert intrinsics, see
3622 // handleNEONVectorConvertIntrinsic().
3623 void handleSSEVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
3624 bool HasRoundingMode = false) {
3625 IRBuilder<> IRB(&I);
3626 Value *CopyOp, *ConvertOp;
3627
3628 assert((!HasRoundingMode ||
3629 isa<ConstantInt>(I.getArgOperand(I.arg_size() - 1))) &&
3630 "Invalid rounding mode");
3631
3632 switch (I.arg_size() - HasRoundingMode) {
3633 case 2:
3634 CopyOp = I.getArgOperand(0);
3635 ConvertOp = I.getArgOperand(1);
3636 break;
3637 case 1:
3638 ConvertOp = I.getArgOperand(0);
3639 CopyOp = nullptr;
3640 break;
3641 default:
3642 llvm_unreachable("Cvt intrinsic with unsupported number of arguments.");
3643 }
3644
3645 // The first *NumUsedElements* elements of ConvertOp are converted to the
3646 // same number of output elements. The rest of the output is copied from
3647 // CopyOp, or (if not available) filled with zeroes.
3648 // Combine shadow for elements of ConvertOp that are used in this operation,
3649 // and insert a check.
3650 // FIXME: consider propagating shadow of ConvertOp, at least in the case of
3651 // int->any conversion.
3652 Value *ConvertShadow = getShadow(ConvertOp);
3653 Value *AggShadow = nullptr;
3654 if (ConvertOp->getType()->isVectorTy()) {
3655 AggShadow = IRB.CreateExtractElement(
3656 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
3657 for (int i = 1; i < NumUsedElements; ++i) {
3658 Value *MoreShadow = IRB.CreateExtractElement(
3659 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), i));
3660 AggShadow = IRB.CreateOr(AggShadow, MoreShadow);
3661 }
3662 } else {
3663 AggShadow = ConvertShadow;
3664 }
3665 assert(AggShadow->getType()->isIntegerTy());
3666 insertCheckShadow(AggShadow, getOrigin(ConvertOp), &I);
3667
3668 // Build result shadow by zero-filling parts of CopyOp shadow that come from
3669 // ConvertOp.
3670 if (CopyOp) {
3671 assert(CopyOp->getType() == I.getType());
3672 assert(CopyOp->getType()->isVectorTy());
3673 Value *ResultShadow = getShadow(CopyOp);
3674 Type *EltTy = cast<VectorType>(ResultShadow->getType())->getElementType();
3675 for (int i = 0; i < NumUsedElements; ++i) {
3676 ResultShadow = IRB.CreateInsertElement(
3677 ResultShadow, ConstantInt::getNullValue(EltTy),
3678 ConstantInt::get(IRB.getInt32Ty(), i));
3679 }
3680 setShadow(&I, ResultShadow);
3681 setOrigin(&I, getOrigin(CopyOp));
3682 } else {
3683 setShadow(&I, getCleanShadow(&I));
3684 setOrigin(&I, getCleanOrigin());
3685 }
3686 }
3687
3688 // Given a scalar or vector, extract lower 64 bits (or less), and return all
3689 // zeroes if it is zero, and all ones otherwise.
3690 Value *Lower64ShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3691 if (S->getType()->isVectorTy())
3692 S = CreateShadowCast(IRB, S, IRB.getInt64Ty(), /* Signed */ true);
3693 assert(S->getType()->getPrimitiveSizeInBits() <= 64);
3694 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3695 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3696 }
3697
3698 // Given a vector, extract its first element, and return all
3699 // zeroes if it is zero, and all ones otherwise.
3700 Value *LowerElementShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3701 Value *S1 = IRB.CreateExtractElement(S, (uint64_t)0);
3702 Value *S2 = IRB.CreateICmpNE(S1, getCleanShadow(S1));
3703 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3704 }
3705
3706 Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) {
3707 Type *T = S->getType();
3708 assert(T->isVectorTy());
3709 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3710 return IRB.CreateSExt(S2, T);
3711 }
3712
3713 // Instrument vector shift intrinsic.
3714 //
3715 // This function instruments intrinsics like int_x86_avx2_psll_w.
3716 // Intrinsic shifts %In by %ShiftSize bits.
3717 // %ShiftSize may be a vector. In that case the lower 64 bits determine shift
3718 // size, and the rest is ignored. Behavior is defined even if shift size is
3719 // greater than register (or field) width.
3720 void handleVectorShiftIntrinsic(IntrinsicInst &I, bool Variable) {
3721 assert(I.arg_size() == 2);
3722 IRBuilder<> IRB(&I);
3723 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3724 // Otherwise perform the same shift on S1.
3725 Value *S1 = getShadow(&I, 0);
3726 Value *S2 = getShadow(&I, 1);
3727 Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
3728 : Lower64ShadowExtend(IRB, S2, getShadowTy(&I));
3729 Value *V1 = I.getOperand(0);
3730 Value *V2 = I.getOperand(1);
3731 Value *Shift = IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(),
3732 {IRB.CreateBitCast(S1, V1->getType()), V2});
3733 Shift = IRB.CreateBitCast(Shift, getShadowTy(&I));
3734 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3735 setOriginForNaryOp(I);
3736 }
3737
3738 // Get an MMX-sized (64-bit) vector type, or optionally, other sized
3739 // vectors.
3740 Type *getMMXVectorTy(unsigned EltSizeInBits,
3741 unsigned X86_MMXSizeInBits = 64) {
3742 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3743 "Illegal MMX vector element size");
3744 return FixedVectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
3745 X86_MMXSizeInBits / EltSizeInBits);
3746 }
3747
3748 // Returns a signed counterpart for an (un)signed-saturate-and-pack
3749 // intrinsic.
3750 Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
3751 switch (id) {
3752 case Intrinsic::x86_sse2_packsswb_128:
3753 case Intrinsic::x86_sse2_packuswb_128:
3754 return Intrinsic::x86_sse2_packsswb_128;
3755
3756 case Intrinsic::x86_sse2_packssdw_128:
3757 case Intrinsic::x86_sse41_packusdw:
3758 return Intrinsic::x86_sse2_packssdw_128;
3759
3760 case Intrinsic::x86_avx2_packsswb:
3761 case Intrinsic::x86_avx2_packuswb:
3762 return Intrinsic::x86_avx2_packsswb;
3763
3764 case Intrinsic::x86_avx2_packssdw:
3765 case Intrinsic::x86_avx2_packusdw:
3766 return Intrinsic::x86_avx2_packssdw;
3767
3768 case Intrinsic::x86_mmx_packsswb:
3769 case Intrinsic::x86_mmx_packuswb:
3770 return Intrinsic::x86_mmx_packsswb;
3771
3772 case Intrinsic::x86_mmx_packssdw:
3773 return Intrinsic::x86_mmx_packssdw;
3774
3775 case Intrinsic::x86_avx512_packssdw_512:
3776 case Intrinsic::x86_avx512_packusdw_512:
3777 return Intrinsic::x86_avx512_packssdw_512;
3778
3779 case Intrinsic::x86_avx512_packsswb_512:
3780 case Intrinsic::x86_avx512_packuswb_512:
3781 return Intrinsic::x86_avx512_packsswb_512;
3782
3783 default:
3784 llvm_unreachable("unexpected intrinsic id");
3785 }
3786 }
3787
3788 // Instrument vector pack intrinsic.
3789 //
3790 // This function instruments intrinsics like x86_mmx_packsswb, that
3791 // packs elements of 2 input vectors into half as many bits with saturation.
3792 // Shadow is propagated with the signed variant of the same intrinsic applied
3793 // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
3794 // MMXEltSizeInBits is used only for x86mmx arguments.
3795 //
3796 // TODO: consider using GetMinMaxUnsigned() to handle saturation precisely
3797 void handleVectorPackIntrinsic(IntrinsicInst &I,
3798 unsigned MMXEltSizeInBits = 0) {
3799 assert(I.arg_size() == 2);
3800 IRBuilder<> IRB(&I);
3801 Value *S1 = getShadow(&I, 0);
3802 Value *S2 = getShadow(&I, 1);
3803 assert(S1->getType()->isVectorTy());
3804
3805 // SExt and ICmpNE below must apply to individual elements of input vectors.
3806 // In case of x86mmx arguments, cast them to appropriate vector types and
3807 // back.
3808 Type *T =
3809 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) : S1->getType();
3810 if (MMXEltSizeInBits) {
3811 S1 = IRB.CreateBitCast(S1, T);
3812 S2 = IRB.CreateBitCast(S2, T);
3813 }
3814 Value *S1_ext =
3816 Value *S2_ext =
3818 if (MMXEltSizeInBits) {
3819 S1_ext = IRB.CreateBitCast(S1_ext, getMMXVectorTy(64));
3820 S2_ext = IRB.CreateBitCast(S2_ext, getMMXVectorTy(64));
3821 }
3822
3823 Value *S = IRB.CreateIntrinsic(getSignedPackIntrinsic(I.getIntrinsicID()),
3824 {S1_ext, S2_ext}, /*FMFSource=*/nullptr,
3825 "_msprop_vector_pack");
3826 if (MMXEltSizeInBits)
3827 S = IRB.CreateBitCast(S, getShadowTy(&I));
3828 setShadow(&I, S);
3829 setOriginForNaryOp(I);
3830 }
3831
3832 // Convert `Mask` into `<n x i1>`.
3833 Constant *createDppMask(unsigned Width, unsigned Mask) {
3834 SmallVector<Constant *, 4> R(Width);
3835 for (auto &M : R) {
3836 M = ConstantInt::getBool(F.getContext(), Mask & 1);
3837 Mask >>= 1;
3838 }
3839 return ConstantVector::get(R);
3840 }
3841
3842 // Calculate output shadow as array of booleans `<n x i1>`, assuming if any
3843 // arg is poisoned, entire dot product is poisoned.
3844 Value *findDppPoisonedOutput(IRBuilder<> &IRB, Value *S, unsigned SrcMask,
3845 unsigned DstMask) {
3846 const unsigned Width =
3847 cast<FixedVectorType>(S->getType())->getNumElements();
3848
3849 S = IRB.CreateSelect(createDppMask(Width, SrcMask), S,
3851 Value *SElem = IRB.CreateOrReduce(S);
3852 Value *IsClean = IRB.CreateIsNull(SElem, "_msdpp");
3853 Value *DstMaskV = createDppMask(Width, DstMask);
3854
3855 return IRB.CreateSelect(
3856 IsClean, Constant::getNullValue(DstMaskV->getType()), DstMaskV);
3857 }
3858
3859 // See `Intel Intrinsics Guide` for `_dp_p*` instructions.
3860 //
3861 // 2 and 4 element versions produce single scalar of dot product, and then
3862 // puts it into elements of output vector, selected by 4 lowest bits of the
3863 // mask. Top 4 bits of the mask control which elements of input to use for dot
3864 // product.
3865 //
3866 // 8 element version mask still has only 4 bit for input, and 4 bit for output
3867 // mask. According to the spec it just operates as 4 element version on first
3868 // 4 elements of inputs and output, and then on last 4 elements of inputs and
3869 // output.
3870 void handleDppIntrinsic(IntrinsicInst &I) {
3871 IRBuilder<> IRB(&I);
3872
3873 Value *S0 = getShadow(&I, 0);
3874 Value *S1 = getShadow(&I, 1);
3875 Value *S = IRB.CreateOr(S0, S1);
3876
3877 const unsigned Width =
3878 cast<FixedVectorType>(S->getType())->getNumElements();
3879 assert(Width == 2 || Width == 4 || Width == 8);
3880
3881 const unsigned Mask = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
3882 const unsigned SrcMask = Mask >> 4;
3883 const unsigned DstMask = Mask & 0xf;
3884
3885 // Calculate shadow as `<n x i1>`.
3886 Value *SI1 = findDppPoisonedOutput(IRB, S, SrcMask, DstMask);
3887 if (Width == 8) {
3888 // First 4 elements of shadow are already calculated. `makeDppShadow`
3889 // operats on 32 bit masks, so we can just shift masks, and repeat.
3890 SI1 = IRB.CreateOr(
3891 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3892 }
3893 // Extend to real size of shadow, poisoning either all or none bits of an
3894 // element.
3895 S = IRB.CreateSExt(SI1, S->getType(), "_msdpp");
3896
3897 setShadow(&I, S);
3898 setOriginForNaryOp(I);
3899 }
3900
3901 Value *convertBlendvToSelectMask(IRBuilder<> &IRB, Value *C) {
3902 C = CreateAppToShadowCast(IRB, C);
3903 FixedVectorType *FVT = cast<FixedVectorType>(C->getType());
3904 unsigned ElSize = FVT->getElementType()->getPrimitiveSizeInBits();
3905 C = IRB.CreateAShr(C, ElSize - 1);
3906 FVT = FixedVectorType::get(IRB.getInt1Ty(), FVT->getNumElements());
3907 return IRB.CreateTrunc(C, FVT);
3908 }
3909
3910 // `blendv(f, t, c)` is effectively `select(c[top_bit], t, f)`.
3911 void handleBlendvIntrinsic(IntrinsicInst &I) {
3912 Value *C = I.getOperand(2);
3913 Value *T = I.getOperand(1);
3914 Value *F = I.getOperand(0);
3915
3916 Value *Sc = getShadow(&I, 2);
3917 Value *Oc = MS.TrackOrigins ? getOrigin(C) : nullptr;
3918
3919 {
3920 IRBuilder<> IRB(&I);
3921 // Extract top bit from condition and its shadow.
3922 C = convertBlendvToSelectMask(IRB, C);
3923 Sc = convertBlendvToSelectMask(IRB, Sc);
3924
3925 setShadow(C, Sc);
3926 setOrigin(C, Oc);
3927 }
3928
3929 handleSelectLikeInst(I, C, T, F);
3930 }
3931
3932 // Instrument sum-of-absolute-differences intrinsic.
3933 void handleVectorSadIntrinsic(IntrinsicInst &I, bool IsMMX = false) {
3934 const unsigned SignificantBitsPerResultElement = 16;
3935 Type *ResTy = IsMMX ? IntegerType::get(*MS.C, 64) : I.getType();
3936 unsigned ZeroBitsPerResultElement =
3937 ResTy->getScalarSizeInBits() - SignificantBitsPerResultElement;
3938
3939 IRBuilder<> IRB(&I);
3940 auto *Shadow0 = getShadow(&I, 0);
3941 auto *Shadow1 = getShadow(&I, 1);
3942 Value *S = IRB.CreateOr(Shadow0, Shadow1);
3943 S = IRB.CreateBitCast(S, ResTy);
3944 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
3945 ResTy);
3946 S = IRB.CreateLShr(S, ZeroBitsPerResultElement);
3947 S = IRB.CreateBitCast(S, getShadowTy(&I));
3948 setShadow(&I, S);
3949 setOriginForNaryOp(I);
3950 }
3951
3952 // Instrument dot-product / multiply-add(-accumulate)? intrinsics.
3953 //
3954 // e.g., Two operands:
3955 // <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a, <8 x i16> %b)
3956 //
3957 // Two operands which require an EltSizeInBits override:
3958 // <1 x i64> @llvm.x86.mmx.pmadd.wd(<1 x i64> %a, <1 x i64> %b)
3959 //
3960 // Three operands:
3961 // <4 x i32> @llvm.x86.avx512.vpdpbusd.128
3962 // (<4 x i32> %s, <16 x i8> %a, <16 x i8> %b)
3963 // <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16
3964 // (<2 x float> %acc, <4 x bfloat> %a, <4 x bfloat> %b)
3965 // (these are equivalent to multiply-add on %a and %b, followed by
3966 // adding/"accumulating" %s. "Accumulation" stores the result in one
3967 // of the source registers, but this accumulate vs. add distinction
3968 // is lost when dealing with LLVM intrinsics.)
3969 //
3970 // ZeroPurifies means that multiplying a known-zero with an uninitialized
3971 // value results in an initialized value. This is applicable for integer
3972 // multiplication, but not floating-point (counter-example: NaN).
3973 void handleVectorDotProductIntrinsic(IntrinsicInst &I,
3974 unsigned ReductionFactor,
3975 bool ZeroPurifies,
3976 unsigned EltSizeInBits,
3977 enum OddOrEvenLanes Lanes) {
3978 IRBuilder<> IRB(&I);
3979
3980 [[maybe_unused]] FixedVectorType *ReturnType =
3981 cast<FixedVectorType>(I.getType());
3982 assert(isa<FixedVectorType>(ReturnType));
3983
3984 // Vectors A and B, and shadows
3985 Value *Va = nullptr;
3986 Value *Vb = nullptr;
3987 Value *Sa = nullptr;
3988 Value *Sb = nullptr;
3989
3990 assert(I.arg_size() == 2 || I.arg_size() == 3);
3991 if (I.arg_size() == 2) {
3992 assert(Lanes == kBothLanes);
3993
3994 Va = I.getOperand(0);
3995 Vb = I.getOperand(1);
3996
3997 Sa = getShadow(&I, 0);
3998 Sb = getShadow(&I, 1);
3999 } else if (I.arg_size() == 3) {
4000 // Operand 0 is the accumulator. We will deal with that below.
4001 Va = I.getOperand(1);
4002 Vb = I.getOperand(2);
4003
4004 Sa = getShadow(&I, 1);
4005 Sb = getShadow(&I, 2);
4006
4007 if (Lanes == kEvenLanes || Lanes == kOddLanes) {
4008 // Convert < S0, S1, S2, S3, S4, S5, S6, S7 >
4009 // to < S0, S0, S2, S2, S4, S4, S6, S6 > (if even)
4010 // to < S1, S1, S3, S3, S5, S5, S7, S7 > (if odd)
4011 //
4012 // Note: for aarch64.neon.bfmlalb/t, the odd/even-indexed values are
4013 // zeroed, not duplicated. However, for shadow propagation, this
4014 // distinction is unimportant because Step 1 below will squeeze
4015 // each pair of elements (e.g., [S0, S0]) into a single bit, and
4016 // we only care if it is fully initialized.
4017
4018 FixedVectorType *InputShadowType = cast<FixedVectorType>(Sa->getType());
4019 unsigned Width = InputShadowType->getNumElements();
4020
4021 Sa = IRB.CreateShuffleVector(
4022 Sa, getPclmulMask(Width, /*OddElements=*/Lanes == kOddLanes));
4023 Sb = IRB.CreateShuffleVector(
4024 Sb, getPclmulMask(Width, /*OddElements=*/Lanes == kOddLanes));
4025 }
4026 }
4027
4028 FixedVectorType *ParamType = cast<FixedVectorType>(Va->getType());
4029 assert(ParamType == Vb->getType());
4030
4031 assert(ParamType->getPrimitiveSizeInBits() ==
4032 ReturnType->getPrimitiveSizeInBits());
4033
4034 if (I.arg_size() == 3) {
4035 [[maybe_unused]] auto *AccumulatorType =
4036 cast<FixedVectorType>(I.getOperand(0)->getType());
4037 assert(AccumulatorType == ReturnType);
4038 }
4039
4040 FixedVectorType *ImplicitReturnType =
4041 cast<FixedVectorType>(getShadowTy(ReturnType));
4042 // Step 1: instrument multiplication of corresponding vector elements
4043 if (EltSizeInBits) {
4044 ImplicitReturnType = cast<FixedVectorType>(
4045 getMMXVectorTy(EltSizeInBits * ReductionFactor,
4046 ParamType->getPrimitiveSizeInBits()));
4047 ParamType = cast<FixedVectorType>(
4048 getMMXVectorTy(EltSizeInBits, ParamType->getPrimitiveSizeInBits()));
4049
4050 Va = IRB.CreateBitCast(Va, ParamType);
4051 Vb = IRB.CreateBitCast(Vb, ParamType);
4052
4053 Sa = IRB.CreateBitCast(Sa, getShadowTy(ParamType));
4054 Sb = IRB.CreateBitCast(Sb, getShadowTy(ParamType));
4055 } else {
4056 assert(ParamType->getNumElements() ==
4057 ReturnType->getNumElements() * ReductionFactor);
4058 }
4059
4060 // Each element of the vector is represented by a single bit (poisoned or
4061 // not) e.g., <8 x i1>.
4062 Value *SaNonZero = IRB.CreateIsNotNull(Sa);
4063 Value *SbNonZero = IRB.CreateIsNotNull(Sb);
4064 Value *And;
4065 if (ZeroPurifies) {
4066 // Multiplying an *initialized* zero by an uninitialized element results
4067 // in an initialized zero element.
4068 //
4069 // This is analogous to bitwise AND, where "AND" of 0 and a poisoned value
4070 // results in an unpoisoned value.
4071 Value *VaInt = Va;
4072 Value *VbInt = Vb;
4073 if (!Va->getType()->isIntegerTy()) {
4074 VaInt = CreateAppToShadowCast(IRB, Va);
4075 VbInt = CreateAppToShadowCast(IRB, Vb);
4076 }
4077
4078 // We check for non-zero on a per-element basis, not per-bit.
4079 Value *VaNonZero = IRB.CreateIsNotNull(VaInt);
4080 Value *VbNonZero = IRB.CreateIsNotNull(VbInt);
4081
4082 And = handleBitwiseAnd(IRB, VaNonZero, VbNonZero, SaNonZero, SbNonZero);
4083 } else {
4084 And = IRB.CreateOr({SaNonZero, SbNonZero});
4085 }
4086
4087 // Extend <8 x i1> to <8 x i16>.
4088 // (The real pmadd intrinsic would have computed intermediate values of
4089 // <8 x i32>, but that is irrelevant for our shadow purposes because we
4090 // consider each element to be either fully initialized or fully
4091 // uninitialized.)
4092 And = IRB.CreateSExt(And, Sa->getType());
4093
4094 // Step 2: instrument horizontal add
4095 // We don't need bit-precise horizontalReduce because we only want to check
4096 // if each pair/quad of elements is fully zero.
4097 // Cast to <4 x i32>.
4098 Value *Horizontal = IRB.CreateBitCast(And, ImplicitReturnType);
4099
4100 // Compute <4 x i1>, then extend back to <4 x i32>.
4101 Value *OutShadow = IRB.CreateSExt(
4102 IRB.CreateICmpNE(Horizontal,
4103 Constant::getNullValue(Horizontal->getType())),
4104 ImplicitReturnType);
4105
4106 // Cast it back to the required fake return type (if MMX: <1 x i64>; for
4107 // AVX, it is already correct).
4108 if (EltSizeInBits)
4109 OutShadow = CreateShadowCast(IRB, OutShadow, getShadowTy(&I));
4110
4111 // Step 3 (if applicable): instrument accumulator
4112 if (I.arg_size() == 3)
4113 OutShadow = IRB.CreateOr(OutShadow, getShadow(&I, 0));
4114
4115 setShadow(&I, OutShadow);
4116 setOriginForNaryOp(I);
4117 }
4118
4119 // Instrument compare-packed intrinsic.
4120 //
4121 // x86 has the predicate as the third operand, which is ImmArg e.g.,
4122 // - <4 x double> @llvm.x86.avx.cmp.pd.256(<4 x double>, <4 x double>, i8)
4123 // - <2 x double> @llvm.x86.sse2.cmp.pd(<2 x double>, <2 x double>, i8)
4124 //
4125 // while Arm has separate intrinsics for >= and > e.g.,
4126 // - <2 x i32> @llvm.aarch64.neon.facge.v2i32.v2f32
4127 // (<2 x float> %A, <2 x float>)
4128 // - <2 x i32> @llvm.aarch64.neon.facgt.v2i32.v2f32
4129 // (<2 x float> %A, <2 x float>)
4130 //
4131 // Bonus: this also handles scalar cases e.g.,
4132 // - i32 @llvm.aarch64.neon.facgt.i32.f32(float %A, float %B)
4133 void handleVectorComparePackedIntrinsic(IntrinsicInst &I,
4134 bool PredicateAsOperand) {
4135 if (PredicateAsOperand) {
4136 assert(I.arg_size() == 3);
4137 assert(I.paramHasAttr(2, Attribute::ImmArg));
4138 } else
4139 assert(I.arg_size() == 2);
4140
4141 IRBuilder<> IRB(&I);
4142
4143 // Basically, an or followed by sext(icmp ne 0) to end up with all-zeros or
4144 // all-ones shadow.
4145 Type *ResTy = getShadowTy(&I);
4146 auto *Shadow0 = getShadow(&I, 0);
4147 auto *Shadow1 = getShadow(&I, 1);
4148 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
4149 Value *S = IRB.CreateSExt(
4150 IRB.CreateICmpNE(S0, Constant::getNullValue(ResTy)), ResTy);
4151 setShadow(&I, S);
4152 setOriginForNaryOp(I);
4153 }
4154
4155 // Instrument compare-scalar intrinsic.
4156 // This handles both cmp* intrinsics which return the result in the first
4157 // element of a vector, and comi* which return the result as i32.
4158 void handleVectorCompareScalarIntrinsic(IntrinsicInst &I) {
4159 IRBuilder<> IRB(&I);
4160 auto *Shadow0 = getShadow(&I, 0);
4161 auto *Shadow1 = getShadow(&I, 1);
4162 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
4163 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&I));
4164 setShadow(&I, S);
4165 setOriginForNaryOp(I);
4166 }
4167
4168 // Instrument generic vector reduction intrinsics
4169 // by ORing together all their fields.
4170 //
4171 // If AllowShadowCast is true, the return type does not need to be the same
4172 // type as the fields
4173 // e.g., declare i32 @llvm.aarch64.neon.uaddv.i32.v16i8(<16 x i8>)
4174 void handleVectorReduceIntrinsic(IntrinsicInst &I, bool AllowShadowCast) {
4175 assert(I.arg_size() == 1);
4176
4177 IRBuilder<> IRB(&I);
4178 Value *S = IRB.CreateOrReduce(getShadow(&I, 0));
4179 if (AllowShadowCast)
4180 S = CreateShadowCast(IRB, S, getShadowTy(&I));
4181 else
4182 assert(S->getType() == getShadowTy(&I));
4183 setShadow(&I, S);
4184 setOriginForNaryOp(I);
4185 }
4186
4187 // Similar to handleVectorReduceIntrinsic but with an initial starting value.
4188 // e.g., call float @llvm.vector.reduce.fadd.f32.v2f32(float %a0, <2 x float>
4189 // %a1)
4190 // shadow = shadow[a0] | shadow[a1.0] | shadow[a1.1]
4191 //
4192 // The type of the return value, initial starting value, and elements of the
4193 // vector must be identical.
4194 void handleVectorReduceWithStarterIntrinsic(IntrinsicInst &I) {
4195 assert(I.arg_size() == 2);
4196
4197 IRBuilder<> IRB(&I);
4198 Value *Shadow0 = getShadow(&I, 0);
4199 Value *Shadow1 = IRB.CreateOrReduce(getShadow(&I, 1));
4200 assert(Shadow0->getType() == Shadow1->getType());
4201 Value *S = IRB.CreateOr(Shadow0, Shadow1);
4202 assert(S->getType() == getShadowTy(&I));
4203 setShadow(&I, S);
4204 setOriginForNaryOp(I);
4205 }
4206
4207 // e.g., <4 x i32> @llvm.vector.partial.reduce.add (<4 x i32>, <8 x i32>)
4208 // acc addends
4209 // <4 x fp16> @llvm.vector.partial.reduce.fadd(<4 x fp16>, <8 x fp16>)
4210 // acc addends
4211 //
4212 // output[i] = acc[i] + addend[i] + addend[i+4]
4213 //
4214 // We approximate this as "all-or-nothing" for each element of the vector
4215 // i.e., even a single uninitialized bit in acc[i], addend[i], or
4216 // addend[i+4] will make output[i] fully uninitialized.
4217 //
4218 // By converting each vector element to a single value (0 or 1) representing
4219 // whether it is uninitialized, we can apply vector.partial.reduce.add to
4220 // compute the output shadow.
4221 //
4222 // N.B. this function is ready for scalable vectors, but its dependencies
4223 // are not.
4224 void handleVectorPartialReduceAddIntrinsic(IntrinsicInst &I) {
4225 IRBuilder<> IRB(&I);
4226
4227 assert(I.arg_size() == 2);
4228 [[maybe_unused]] Value *Accumulator = I.getArgOperand(0);
4229 [[maybe_unused]] Value *Addends = I.getArgOperand(1);
4230 assert(isa<VectorType>(Accumulator->getType()));
4231 assert(isa<VectorType>(Addends->getType()));
4232
4233 assert(I.getType() == Accumulator->getType());
4234
4235 assert(cast<VectorType>(Addends->getType())->getElementType() ==
4236 cast<VectorType>(I.getType())->getElementType());
4237 assert(cast<VectorType>(Addends->getType())
4238 ->getElementCount()
4239 .isKnownMultipleOf(
4240 cast<VectorType>(I.getType())->getElementCount()));
4241
4242 // e.g., <4 x i32>, <8 x i32>
4243 Value *SAcc = getShadow(&I, 0);
4244 Value *SAdd = getShadow(&I, 1);
4245
4246 // All-or-nothing shadows
4247 // e.g., <4 x i1>, <8 x i1>
4248 SAcc = IRB.CreateICmpNE(SAcc, getCleanShadow(SAcc));
4249 SAdd = IRB.CreateICmpNE(SAdd, getCleanShadow(SAdd));
4250
4251 // If we applied vector.partial.reduce.add to (<M x i1>, <N x i1>) shadows,
4252 // the sums might wrap around. Zero-extend to avoid this.
4253 // 16-bit for each sum (up to 65535) ought to be enough for anybody.
4254 SAcc = IRB.CreateZExt(
4255 SAcc,
4256 VectorType::get(IRB.getInt16Ty(),
4257 cast<VectorType>(SAcc->getType())->getElementCount()));
4258 SAdd = IRB.CreateZExt(
4259 SAdd,
4260 VectorType::get(IRB.getInt16Ty(),
4261 cast<VectorType>(SAdd->getType())->getElementCount()));
4262
4263 Value *SOutput = IRB.CreateIntrinsic(
4264 SAcc->getType(), Intrinsic::vector_partial_reduce_add, {SAcc, SAdd});
4265
4266 SOutput = IRB.CreateSExt(IRB.CreateICmpNE(SOutput, getCleanShadow(SOutput)),
4267 getShadowTy(&I));
4268
4269 setShadow(&I, SOutput);
4270 setOriginForNaryOp(I);
4271 }
4272
4273 // Instrument vector.reduce.or intrinsic.
4274 // Valid (non-poisoned) set bits in the operand pull low the
4275 // corresponding shadow bits.
4276 void handleVectorReduceOrIntrinsic(IntrinsicInst &I) {
4277 assert(I.arg_size() == 1);
4278
4279 IRBuilder<> IRB(&I);
4280 Value *OperandShadow = getShadow(&I, 0);
4281 Value *OperandUnsetBits = IRB.CreateNot(I.getOperand(0));
4282 Value *OperandUnsetOrPoison = IRB.CreateOr(OperandUnsetBits, OperandShadow);
4283 // Bit N is clean if any field's bit N is 1 and unpoison
4284 Value *OutShadowMask = IRB.CreateAndReduce(OperandUnsetOrPoison);
4285 // Otherwise, it is clean if every field's bit N is unpoison
4286 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
4287 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
4288
4289 setShadow(&I, S);
4290 setOrigin(&I, getOrigin(&I, 0));
4291 }
4292
4293 // Instrument vector.reduce.and intrinsic.
4294 // Valid (non-poisoned) unset bits in the operand pull down the
4295 // corresponding shadow bits.
4296 void handleVectorReduceAndIntrinsic(IntrinsicInst &I) {
4297 assert(I.arg_size() == 1);
4298
4299 IRBuilder<> IRB(&I);
4300 Value *OperandShadow = getShadow(&I, 0);
4301 Value *OperandSetOrPoison = IRB.CreateOr(I.getOperand(0), OperandShadow);
4302 // Bit N is clean if any field's bit N is 0 and unpoison
4303 Value *OutShadowMask = IRB.CreateAndReduce(OperandSetOrPoison);
4304 // Otherwise, it is clean if every field's bit N is unpoison
4305 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
4306 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
4307
4308 setShadow(&I, S);
4309 setOrigin(&I, getOrigin(&I, 0));
4310 }
4311
4312 void handleStmxcsr(IntrinsicInst &I) {
4313 IRBuilder<> IRB(&I);
4314 Value *Addr = I.getArgOperand(0);
4315 Type *Ty = IRB.getInt32Ty();
4316 Value *ShadowPtr =
4317 getShadowOriginPtr(Addr, IRB, Ty, Align(1), /*isStore*/ true).first;
4318
4319 IRB.CreateStore(getCleanShadow(Ty), ShadowPtr);
4320
4321 if (Opts.msan_check_access_address)
4322 insertCheckShadowOf(Addr, &I);
4323 }
4324
4325 void handleLdmxcsr(IntrinsicInst &I) {
4326 if (!InsertChecks)
4327 return;
4328
4329 IRBuilder<> IRB(&I);
4330 Value *Addr = I.getArgOperand(0);
4331 Type *Ty = IRB.getInt32Ty();
4332 const Align Alignment = Align(1);
4333 Value *ShadowPtr, *OriginPtr;
4334 std::tie(ShadowPtr, OriginPtr) =
4335 getShadowOriginPtr(Addr, IRB, Ty, Alignment, /*isStore*/ false);
4336
4337 if (Opts.msan_check_access_address)
4338 insertCheckShadowOf(Addr, &I);
4339
4340 Value *Shadow = IRB.CreateAlignedLoad(Ty, ShadowPtr, Alignment, "_ldmxcsr");
4341 Value *Origin = MS.TrackOrigins ? IRB.CreateLoad(MS.OriginTy, OriginPtr)
4342 : getCleanOrigin();
4343 insertCheckShadow(Shadow, Origin, &I);
4344 }
4345
4346 void handleMaskedExpandLoad(IntrinsicInst &I) {
4347 IRBuilder<> IRB(&I);
4348 Value *Ptr = I.getArgOperand(0);
4349 MaybeAlign Align = I.getParamAlign(0);
4350 Value *Mask = I.getArgOperand(1);
4351 Value *PassThru = I.getArgOperand(2);
4352
4353 if (Opts.msan_check_access_address) {
4354 insertCheckShadowOf(Ptr, &I);
4355 insertCheckShadowOf(Mask, &I);
4356 }
4357
4358 if (!PropagateShadow) {
4359 setShadow(&I, getCleanShadow(&I));
4360 setOrigin(&I, getCleanOrigin());
4361 return;
4362 }
4363
4364 Type *ShadowTy = getShadowTy(&I);
4365 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
4366 auto [ShadowPtr, OriginPtr] =
4367 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align, /*isStore*/ false);
4368
4369 Value *Shadow =
4370 IRB.CreateMaskedExpandLoad(ShadowTy, ShadowPtr, Align, Mask,
4371 getShadow(PassThru), "_msmaskedexpload");
4372
4373 setShadow(&I, Shadow);
4374
4375 // TODO: Store origins.
4376 setOrigin(&I, getCleanOrigin());
4377 }
4378
4379 void handleMaskedCompressStore(IntrinsicInst &I) {
4380 IRBuilder<> IRB(&I);
4381 Value *Values = I.getArgOperand(0);
4382 Value *Ptr = I.getArgOperand(1);
4383 MaybeAlign Align = I.getParamAlign(1);
4384 Value *Mask = I.getArgOperand(2);
4385
4386 if (Opts.msan_check_access_address) {
4387 insertCheckShadowOf(Ptr, &I);
4388 insertCheckShadowOf(Mask, &I);
4389 }
4390
4391 Value *Shadow = getShadow(Values);
4392 Type *ElementShadowTy =
4393 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
4394 auto [ShadowPtr, OriginPtrs] =
4395 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align, /*isStore*/ true);
4396
4397 IRB.CreateMaskedCompressStore(Shadow, ShadowPtr, Align, Mask);
4398
4399 // TODO: Store origins.
4400 }
4401
4402 void handleMaskedGather(IntrinsicInst &I) {
4403 IRBuilder<> IRB(&I);
4404 Value *Ptrs = I.getArgOperand(0);
4405 const Align Alignment = I.getParamAlign(0).valueOrOne();
4406 Value *Mask = I.getArgOperand(1);
4407 Value *PassThru = I.getArgOperand(2);
4408
4409 Type *PtrsShadowTy = getShadowTy(Ptrs);
4410 if (Opts.msan_check_access_address) {
4411 insertCheckShadowOf(Mask, &I);
4412 Value *MaskedPtrShadow = IRB.CreateSelect(
4413 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
4414 "_msmaskedptrs");
4415 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &I);
4416 }
4417
4418 if (!PropagateShadow) {
4419 setShadow(&I, getCleanShadow(&I));
4420 setOrigin(&I, getCleanOrigin());
4421 return;
4422 }
4423
4424 Type *ShadowTy = getShadowTy(&I);
4425 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
4426 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4427 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ false);
4428
4429 Value *Shadow =
4430 IRB.CreateMaskedGather(ShadowTy, ShadowPtrs, Alignment, Mask,
4431 getShadow(PassThru), "_msmaskedgather");
4432
4433 setShadow(&I, Shadow);
4434
4435 // TODO: Store origins.
4436 setOrigin(&I, getCleanOrigin());
4437 }
4438
4439 void handleMaskedScatter(IntrinsicInst &I) {
4440 IRBuilder<> IRB(&I);
4441 Value *Values = I.getArgOperand(0);
4442 Value *Ptrs = I.getArgOperand(1);
4443 const Align Alignment = I.getParamAlign(1).valueOrOne();
4444 Value *Mask = I.getArgOperand(2);
4445
4446 Type *PtrsShadowTy = getShadowTy(Ptrs);
4447 if (Opts.msan_check_access_address) {
4448 insertCheckShadowOf(Mask, &I);
4449 Value *MaskedPtrShadow = IRB.CreateSelect(
4450 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
4451 "_msmaskedptrs");
4452 insertCheckShadow(MaskedPtrShadow, getOrigin(Ptrs), &I);
4453 }
4454
4455 Value *Shadow = getShadow(Values);
4456 Type *ElementShadowTy =
4457 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
4458 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
4459 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ true);
4460
4461 IRB.CreateMaskedScatter(Shadow, ShadowPtrs, Alignment, Mask);
4462
4463 // TODO: Store origin.
4464 }
4465
4466 // Intrinsic::masked_store
4467 //
4468 // Note: handleAVXMaskedStore handles AVX/AVX2 variants, though AVX512 masked
4469 // stores are lowered to Intrinsic::masked_store.
4470 void handleMaskedStore(IntrinsicInst &I) {
4471 IRBuilder<> IRB(&I);
4472 Value *V = I.getArgOperand(0);
4473 Value *Ptr = I.getArgOperand(1);
4474 const Align Alignment = I.getParamAlign(1).valueOrOne();
4475 Value *Mask = I.getArgOperand(2);
4476 Value *Shadow = getShadow(V);
4477
4478 if (Opts.msan_check_access_address) {
4479 insertCheckShadowOf(Ptr, &I);
4480 insertCheckShadowOf(Mask, &I);
4481 }
4482
4483 Value *ShadowPtr;
4484 Value *OriginPtr;
4485 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
4486 Ptr, IRB, Shadow->getType(), Alignment, /*isStore*/ true);
4487
4488 IRB.CreateMaskedStore(Shadow, ShadowPtr, Alignment, Mask);
4489
4490 if (!MS.TrackOrigins)
4491 return;
4492
4493 auto &DL = F.getDataLayout();
4494 paintOrigin(IRB, getOrigin(V), OriginPtr,
4495 DL.getTypeStoreSize(Shadow->getType()),
4496 std::max(Alignment, kMinOriginAlignment));
4497 }
4498
4499 // Intrinsic::masked_load
4500 //
4501 // Note: handleAVXMaskedLoad handles AVX/AVX2 variants, though AVX512 masked
4502 // loads are lowered to Intrinsic::masked_load.
4503 void handleMaskedLoad(IntrinsicInst &I) {
4504 IRBuilder<> IRB(&I);
4505 Value *Ptr = I.getArgOperand(0);
4506 const Align Alignment = I.getParamAlign(0).valueOrOne();
4507 Value *Mask = I.getArgOperand(1);
4508 Value *PassThru = I.getArgOperand(2);
4509
4510 if (Opts.msan_check_access_address) {
4511 insertCheckShadowOf(Ptr, &I);
4512 insertCheckShadowOf(Mask, &I);
4513 }
4514
4515 if (!PropagateShadow) {
4516 setShadow(&I, getCleanShadow(&I));
4517 setOrigin(&I, getCleanOrigin());
4518 return;
4519 }
4520
4521 Type *ShadowTy = getShadowTy(&I);
4522 Value *ShadowPtr, *OriginPtr;
4523 std::tie(ShadowPtr, OriginPtr) =
4524 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment, /*isStore*/ false);
4525 setShadow(&I, IRB.CreateMaskedLoad(ShadowTy, ShadowPtr, Alignment, Mask,
4526 getShadow(PassThru), "_msmaskedld"));
4527
4528 if (!MS.TrackOrigins)
4529 return;
4530
4531 // Choose between PassThru's and the loaded value's origins.
4532 Value *MaskedPassThruShadow = IRB.CreateAnd(
4533 getShadow(PassThru), IRB.CreateSExt(IRB.CreateNeg(Mask), ShadowTy));
4534
4535 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB, "_mscmp");
4536
4537 Value *PtrOrigin = IRB.CreateLoad(MS.OriginTy, OriginPtr);
4538 Value *Origin = IRB.CreateSelect(NotNull, getOrigin(PassThru), PtrOrigin);
4539
4540 setOrigin(&I, Origin);
4541 }
4542
4543 // e.g., <4 x i32> @llvm.masked.udiv.v4i32(<4 x i32> %dividend,
4544 // <4 x i32> %divisor,
4545 // <4 x i1> %mask)
4546 //
4547 // As handleIntegerDiv(), but per-lane: strict on the divisor and propagating
4548 // the dividend, both only on the enabled lanes. Disabled lanes cannot cause
4549 // undefined behaviour, and their result is poison.
4550 void handleMaskedIntegerDivRem(IntrinsicInst &I) {
4551 assert(I.arg_size() == 3);
4552 IRBuilder<> IRB(&I);
4553 Value *Dividend = I.getArgOperand(0);
4554 Value *Divisor = I.getArgOperand(1);
4555 Value *Mask = I.getArgOperand(2);
4556
4557 insertCheckShadowOf(Mask, &I);
4558
4559 Value *MaskedDivisorShadow = IRB.CreateSelect(
4560 Mask, getShadow(Divisor), getCleanShadow(Divisor), "_msmaskeddivisor");
4561 insertCheckShadow(MaskedDivisorShadow, getOrigin(Divisor), &I);
4562
4563 if (!PropagateShadow) {
4564 setShadow(&I, getCleanShadow(&I));
4565 setOrigin(&I, getCleanOrigin());
4566 return;
4567 }
4568
4569 setShadow(&I, IRB.CreateSelect(Mask, getShadow(Dividend),
4570 getPoisonedShadow(&I), "_msmaskeddiv"));
4571 setOrigin(&I, getOrigin(Dividend));
4572 }
4573
4574 // e.g., i32 @llvm.experimental.vector.extract.last.active.v4i32(
4575 // <4 x i32> %data, <4 x i1> %mask, i32 %passthru)
4576 void handleVectorExtractLastActive(IntrinsicInst &I) {
4577 assert(I.arg_size() == 3);
4578 IRBuilder<> IRB(&I);
4579 Value *Data = I.getArgOperand(0);
4580 Value *Mask = I.getArgOperand(1);
4581 Value *PassThru = I.getArgOperand(2);
4582
4583 assert(isa<VectorType>(Data->getType()));
4584 assert(isa<VectorType>(Mask->getType()));
4585 assert(!isa<VectorType>(PassThru->getType()));
4586 assert(!isa<VectorType>(I.getType()));
4587 assert(I.getType() == PassThru->getType());
4588 assert(cast<VectorType>(Data->getType())->getElementType() == I.getType());
4589 assert(cast<VectorType>(Mask->getType())->getElementType() ==
4590 IRB.getInt1Ty());
4591 assert(cast<VectorType>(Data->getType())->getElementCount() ==
4592 cast<VectorType>(Mask->getType())->getElementCount());
4593
4594 insertCheckShadowOf(Mask, &I);
4595
4596 if (!PropagateShadow) {
4597 setShadow(&I, getCleanShadow(&I));
4598 setOrigin(&I, getCleanOrigin());
4599 return;
4600 }
4601
4602 Value *DataShadow = getShadow(Data);
4603 Value *Shadow = IRB.CreateIntrinsic(
4604 Intrinsic::experimental_vector_extract_last_active,
4605 {DataShadow->getType()}, {DataShadow, Mask, getShadow(PassThru)},
4606 /*FMFSource=*/{}, "_msprop_vector_extract_last_active");
4607 setShadow(&I, Shadow);
4608
4609 if (MS.TrackOrigins) {
4610 Value *AnyActive = IRB.CreateOrReduce(Mask);
4611 setOrigin(&I, IRB.CreateSelect(AnyActive, getOrigin(Data),
4612 getOrigin(PassThru)));
4613 }
4614 }
4615
4616 // e.g., void @llvm.x86.avx.maskstore.ps.256(ptr, <8 x i32>, <8 x float>)
4617 // dst mask src
4618 //
4619 // AVX512 masked stores are lowered to Intrinsic::masked_load and are handled
4620 // by handleMaskedStore.
4621 //
4622 // This function handles AVX and AVX2 masked stores; these use the MSBs of a
4623 // vector of integers, unlike the LLVM masked intrinsics, which require a
4624 // vector of booleans. X86InstCombineIntrinsic.cpp::simplifyX86MaskedLoad
4625 // mentions that the x86 backend does not know how to efficiently convert
4626 // from a vector of booleans back into the AVX mask format; therefore, they
4627 // (and we) do not reduce AVX/AVX2 masked intrinsics into LLVM masked
4628 // intrinsics.
4629 void handleAVXMaskedStore(IntrinsicInst &I) {
4630 assert(I.arg_size() == 3);
4631
4632 IRBuilder<> IRB(&I);
4633
4634 Value *Dst = I.getArgOperand(0);
4635 assert(Dst->getType()->isPointerTy() && "Destination is not a pointer!");
4636
4637 Value *Mask = I.getArgOperand(1);
4638 assert(isa<VectorType>(Mask->getType()) && "Mask is not a vector!");
4639
4640 Value *Src = I.getArgOperand(2);
4641 assert(isa<VectorType>(Src->getType()) && "Source is not a vector!");
4642
4643 const Align Alignment = Align(1);
4644
4645 Value *SrcShadow = getShadow(Src);
4646
4647 if (Opts.msan_check_access_address) {
4648 insertCheckShadowOf(Dst, &I);
4649 insertCheckShadowOf(Mask, &I);
4650 }
4651
4652 Value *DstShadowPtr;
4653 Value *DstOriginPtr;
4654 std::tie(DstShadowPtr, DstOriginPtr) = getShadowOriginPtr(
4655 Dst, IRB, SrcShadow->getType(), Alignment, /*isStore*/ true);
4656
4657 SmallVector<Value *, 2> ShadowArgs;
4658 ShadowArgs.append(1, DstShadowPtr);
4659 ShadowArgs.append(1, Mask);
4660 // The intrinsic may require floating-point but shadows can be arbitrary
4661 // bit patterns, of which some would be interpreted as "invalid"
4662 // floating-point values (NaN etc.); we assume the intrinsic will happily
4663 // copy them.
4664 ShadowArgs.append(1, IRB.CreateBitCast(SrcShadow, Src->getType()));
4665
4666 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4667 IRB.getVoidTy(), I.getIntrinsicID(), ShadowArgs);
4668 setShadow(&I, CI);
4669
4670 if (!MS.TrackOrigins)
4671 return;
4672
4673 // Approximation only
4674 auto &DL = F.getDataLayout();
4675 paintOrigin(IRB, getOrigin(Src), DstOriginPtr,
4676 DL.getTypeStoreSize(SrcShadow->getType()),
4677 std::max(Alignment, kMinOriginAlignment));
4678 }
4679
4680 // e.g., <8 x float> @llvm.x86.avx.maskload.ps.256(ptr, <8 x i32>)
4681 // return src mask
4682 //
4683 // Masked-off values are replaced with 0, which conveniently also represents
4684 // initialized memory.
4685 //
4686 // AVX512 masked stores are lowered to Intrinsic::masked_load and are handled
4687 // by handleMaskedStore.
4688 //
4689 // We do not combine this with handleMaskedLoad; see comment in
4690 // handleAVXMaskedStore for the rationale.
4691 //
4692 // This is subtly different than handleIntrinsicByApplyingToShadow(I, 1)
4693 // because we need to apply getShadowOriginPtr, not getShadow, to the first
4694 // parameter.
4695 void handleAVXMaskedLoad(IntrinsicInst &I) {
4696 assert(I.arg_size() == 2);
4697
4698 IRBuilder<> IRB(&I);
4699
4700 Value *Src = I.getArgOperand(0);
4701 assert(Src->getType()->isPointerTy() && "Source is not a pointer!");
4702
4703 Value *Mask = I.getArgOperand(1);
4704 assert(isa<VectorType>(Mask->getType()) && "Mask is not a vector!");
4705
4706 const Align Alignment = Align(1);
4707
4708 if (Opts.msan_check_access_address) {
4709 insertCheckShadowOf(Mask, &I);
4710 }
4711
4712 Type *SrcShadowTy = getShadowTy(Src);
4713 Value *SrcShadowPtr, *SrcOriginPtr;
4714 std::tie(SrcShadowPtr, SrcOriginPtr) =
4715 getShadowOriginPtr(Src, IRB, SrcShadowTy, Alignment, /*isStore*/ false);
4716
4717 SmallVector<Value *, 2> ShadowArgs;
4718 ShadowArgs.append(1, SrcShadowPtr);
4719 ShadowArgs.append(1, Mask);
4720
4721 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4722 I.getType(), I.getIntrinsicID(), ShadowArgs);
4723 // The AVX masked load intrinsics do not have integer variants. We use the
4724 // floating-point variants, which will happily copy the shadows even if
4725 // they are interpreted as "invalid" floating-point values (NaN etc.).
4726 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4727
4728 if (!MS.TrackOrigins)
4729 return;
4730
4731 // The "pass-through" value is always zero (initialized). To the extent
4732 // that that results in initialized aligned 4-byte chunks, the origin value
4733 // is ignored. It is therefore correct to simply copy the origin from src.
4734 Value *PtrSrcOrigin = IRB.CreateLoad(MS.OriginTy, SrcOriginPtr);
4735 setOrigin(&I, PtrSrcOrigin);
4736 }
4737
4738 // Test whether the mask indices are initialized, only checking the bits that
4739 // are actually used.
4740 //
4741 // e.g., if Idx is <32 x i16>, only (log2(32) == 5) bits of each index are
4742 // used/checked.
4743 void maskedCheckAVXIndexShadow(IRBuilder<> &IRB, Value *Idx, Instruction *I) {
4744 assert(isFixedIntVector(Idx));
4745 auto IdxVectorSize =
4746 cast<FixedVectorType>(Idx->getType())->getNumElements();
4747 assert(isPowerOf2_64(IdxVectorSize));
4748
4749 // Compiler isn't smart enough, let's help it
4750 if (isa<Constant>(Idx))
4751 return;
4752
4753 auto *IdxShadow = getShadow(Idx);
4754 Value *Truncated = IRB.CreateTrunc(
4755 IdxShadow,
4756 FixedVectorType::get(Type::getIntNTy(*MS.C, Log2_64(IdxVectorSize)),
4757 IdxVectorSize));
4758 insertCheckShadow(Truncated, getOrigin(Idx), I);
4759 }
4760
4761 // Instrument AVX permutation intrinsic.
4762 // We apply the same permutation (argument index 1) to the shadow.
4763 void handleAVXVpermilvar(IntrinsicInst &I) {
4764 IRBuilder<> IRB(&I);
4765 Value *Shadow = getShadow(&I, 0);
4766 maskedCheckAVXIndexShadow(IRB, I.getArgOperand(1), &I);
4767
4768 // Shadows are integer-ish types but some intrinsics require a
4769 // different (e.g., floating-point) type.
4770 Shadow = IRB.CreateBitCast(Shadow, I.getArgOperand(0)->getType());
4771 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4772 I.getType(), I.getIntrinsicID(), {Shadow, I.getArgOperand(1)});
4773
4774 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4775 setOriginForNaryOp(I);
4776 }
4777
4778 // Instrument AVX permutation intrinsic.
4779 // We apply the same permutation (argument index 1) to the shadows.
4780 void handleAVXVpermi2var(IntrinsicInst &I) {
4781 assert(I.arg_size() == 3);
4782 assert(isa<FixedVectorType>(I.getArgOperand(0)->getType()));
4783 assert(isa<FixedVectorType>(I.getArgOperand(1)->getType()));
4784 assert(isa<FixedVectorType>(I.getArgOperand(2)->getType()));
4785 [[maybe_unused]] auto ArgVectorSize =
4786 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4787 assert(cast<FixedVectorType>(I.getArgOperand(1)->getType())
4788 ->getNumElements() == ArgVectorSize);
4789 assert(cast<FixedVectorType>(I.getArgOperand(2)->getType())
4790 ->getNumElements() == ArgVectorSize);
4791 assert(I.getArgOperand(0)->getType() == I.getArgOperand(2)->getType());
4792 assert(I.getType() == I.getArgOperand(0)->getType());
4793 assert(I.getArgOperand(1)->getType()->isIntOrIntVectorTy());
4794 IRBuilder<> IRB(&I);
4795 Value *AShadow = getShadow(&I, 0);
4796 Value *Idx = I.getArgOperand(1);
4797 Value *BShadow = getShadow(&I, 2);
4798
4799 maskedCheckAVXIndexShadow(IRB, Idx, &I);
4800
4801 // Shadows are integer-ish types but some intrinsics require a
4802 // different (e.g., floating-point) type.
4803 AShadow = IRB.CreateBitCast(AShadow, I.getArgOperand(0)->getType());
4804 BShadow = IRB.CreateBitCast(BShadow, I.getArgOperand(2)->getType());
4805 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
4806 I.getType(), I.getIntrinsicID(), {AShadow, Idx, BShadow});
4807 setShadow(&I, IRB.CreateBitCast(CI, getShadowTy(&I)));
4808 setOriginForNaryOp(I);
4809 }
4810
4811 [[maybe_unused]] static bool isFixedIntVectorTy(const Type *T) {
4812 return isa<FixedVectorType>(T) && T->isIntOrIntVectorTy();
4813 }
4814
4815 [[maybe_unused]] static bool isFixedFPVectorTy(const Type *T) {
4816 return isa<FixedVectorType>(T) && T->isFPOrFPVectorTy();
4817 }
4818
4819 [[maybe_unused]] static bool isFixedIntVector(const Value *V) {
4820 return isFixedIntVectorTy(V->getType());
4821 }
4822
4823 [[maybe_unused]] static bool isFixedFPVector(const Value *V) {
4824 return isFixedFPVectorTy(V->getType());
4825 }
4826
4827 // e.g., <16 x i32> @llvm.x86.avx512.mask.cvtps2dq.512
4828 // (<16 x float> a, <16 x i32> writethru, i16 mask,
4829 // i32 rounding)
4830 //
4831 // Inconveniently, some similar intrinsics have a different operand order:
4832 // <16 x i16> @llvm.x86.avx512.mask.vcvtps2ph.512
4833 // (<16 x float> a, i32 rounding, <16 x i16> writethru,
4834 // i16 mask)
4835 //
4836 // If the return type has more elements than A, the excess elements are
4837 // zeroed (and the corresponding shadow is initialized).
4838 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.128
4839 // (<4 x float> a, i32 rounding, <8 x i16> writethru,
4840 // i8 mask)
4841 //
4842 // dst[i] = mask[i] ? convert(a[i]) : writethru[i]
4843 // dst_shadow[i] = mask[i] ? all_or_nothing(a_shadow[i]) : writethru_shadow[i]
4844 // where all_or_nothing(x) is fully uninitialized if x has any
4845 // uninitialized bits
4846 void handleAVX512VectorConvertFPToInt(IntrinsicInst &I, bool LastMask) {
4847 IRBuilder<> IRB(&I);
4848
4849 assert(I.arg_size() == 4);
4850 Value *A = I.getOperand(0);
4851 Value *WriteThrough;
4852 Value *Mask;
4854 if (LastMask) {
4855 WriteThrough = I.getOperand(2);
4856 Mask = I.getOperand(3);
4857 RoundingMode = I.getOperand(1);
4858 } else {
4859 WriteThrough = I.getOperand(1);
4860 Mask = I.getOperand(2);
4861 RoundingMode = I.getOperand(3);
4862 }
4863
4864 assert(isFixedFPVector(A));
4865 assert(isFixedIntVector(WriteThrough));
4866
4867 unsigned ANumElements =
4868 cast<FixedVectorType>(A->getType())->getNumElements();
4869 [[maybe_unused]] unsigned WriteThruNumElements =
4870 cast<FixedVectorType>(WriteThrough->getType())->getNumElements();
4871 assert(ANumElements == WriteThruNumElements ||
4872 ANumElements * 2 == WriteThruNumElements);
4873
4874 assert(Mask->getType()->isIntegerTy());
4875 unsigned MaskNumElements = Mask->getType()->getScalarSizeInBits();
4876 assert(ANumElements == MaskNumElements ||
4877 ANumElements * 2 == MaskNumElements);
4878
4879 assert(WriteThruNumElements == MaskNumElements);
4880
4881 // Some bits of the mask may be unused, though it's unusual to have partly
4882 // uninitialized bits.
4883 insertCheckShadowOf(Mask, &I);
4884
4885 assert(RoundingMode->getType()->isIntegerTy());
4886 // Only some bits of the rounding mode are used, though it's very
4887 // unusual to have uninitialized bits there (more commonly, it's a
4888 // constant).
4889 insertCheckShadowOf(RoundingMode, &I);
4890
4891 assert(I.getType() == WriteThrough->getType());
4892
4893 Value *AShadow = getShadow(A);
4894 AShadow = maybeExtendVectorShadowWithZeros(AShadow, I);
4895
4896 if (ANumElements * 2 == MaskNumElements) {
4897 // Ensure that the irrelevant bits of the mask are zero, hence selecting
4898 // from the zeroed shadow instead of the writethrough's shadow.
4899 Mask =
4900 IRB.CreateTrunc(Mask, IRB.getIntNTy(ANumElements), "_ms_mask_trunc");
4901 Mask =
4902 IRB.CreateZExt(Mask, IRB.getIntNTy(MaskNumElements), "_ms_mask_zext");
4903 }
4904
4905 // Convert i16 mask to <16 x i1>
4906 Mask = IRB.CreateBitCast(
4907 Mask, FixedVectorType::get(IRB.getInt1Ty(), MaskNumElements),
4908 "_ms_mask_bitcast");
4909
4910 /// For floating-point to integer conversion, the output is:
4911 /// - fully uninitialized if *any* bit of the input is uninitialized
4912 /// - fully ininitialized if all bits of the input are ininitialized
4913 /// We apply the same principle on a per-element basis for vectors.
4914 ///
4915 /// We use the scalar width of the return type instead of A's.
4916 AShadow = IRB.CreateSExt(
4917 IRB.CreateICmpNE(AShadow, getCleanShadow(AShadow->getType())),
4918 getShadowTy(&I), "_ms_a_shadow");
4919
4920 Value *WriteThroughShadow = getShadow(WriteThrough);
4921 Value *Shadow = IRB.CreateSelect(Mask, AShadow, WriteThroughShadow,
4922 "_ms_writethru_select");
4923
4924 setShadow(&I, Shadow);
4925 setOriginForNaryOp(I);
4926 }
4927
4928 static SmallVector<int, 8> getPclmulMask(unsigned Width, bool OddElements) {
4929 SmallVector<int, 8> Mask;
4930 for (unsigned X = OddElements ? 1 : 0; X < Width; X += 2) {
4931 Mask.append(2, X);
4932 }
4933 return Mask;
4934 }
4935
4936 // Instrument pclmul intrinsics.
4937 // These intrinsics operate either on odd or on even elements of the input
4938 // vectors, depending on the constant in the 3rd argument, ignoring the rest.
4939 // Replace the unused elements with copies of the used ones, ex:
4940 // (0, 1, 2, 3) -> (0, 0, 2, 2) (even case)
4941 // or
4942 // (0, 1, 2, 3) -> (1, 1, 3, 3) (odd case)
4943 // and then apply the usual shadow combining logic.
4944 void handlePclmulIntrinsic(IntrinsicInst &I) {
4945 IRBuilder<> IRB(&I);
4946 unsigned Width =
4947 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4948 assert(isa<ConstantInt>(I.getArgOperand(2)) &&
4949 "pclmul 3rd operand must be a constant");
4950 unsigned Imm = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
4951 Value *Shuf0 = IRB.CreateShuffleVector(getShadow(&I, 0),
4952 getPclmulMask(Width, Imm & 0x01));
4953 Value *Shuf1 = IRB.CreateShuffleVector(getShadow(&I, 1),
4954 getPclmulMask(Width, Imm & 0x10));
4955 ShadowAndOriginCombiner SOC(this, IRB);
4956 SOC.Add(Shuf0, getOrigin(&I, 0));
4957 SOC.Add(Shuf1, getOrigin(&I, 1));
4958 SOC.Done(&I);
4959 }
4960
4961 // Instrument _mm_*_sd|ss intrinsics
4962 void handleUnarySdSsIntrinsic(IntrinsicInst &I) {
4963 IRBuilder<> IRB(&I);
4964 unsigned Width =
4965 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4966 Value *First = getShadow(&I, 0);
4967 Value *Second = getShadow(&I, 1);
4968 // First element of second operand, remaining elements of first operand
4969 SmallVector<int, 16> Mask;
4970 Mask.push_back(Width);
4971 for (unsigned i = 1; i < Width; i++)
4972 Mask.push_back(i);
4973 Value *Shadow = IRB.CreateShuffleVector(First, Second, Mask);
4974
4975 setShadow(&I, Shadow);
4976 setOriginForNaryOp(I);
4977 }
4978
4979 void handleVtestIntrinsic(IntrinsicInst &I) {
4980 IRBuilder<> IRB(&I);
4981 Value *Shadow0 = getShadow(&I, 0);
4982 Value *Shadow1 = getShadow(&I, 1);
4983 Value *Or = IRB.CreateOr(Shadow0, Shadow1);
4984 Value *NZ = IRB.CreateICmpNE(Or, Constant::getNullValue(Or->getType()));
4985 Value *Scalar = convertShadowToScalar(NZ, IRB);
4986 Value *Shadow = IRB.CreateZExt(Scalar, getShadowTy(&I));
4987
4988 setShadow(&I, Shadow);
4989 setOriginForNaryOp(I);
4990 }
4991
4992 void handleBinarySdSsIntrinsic(IntrinsicInst &I) {
4993 IRBuilder<> IRB(&I);
4994 unsigned Width =
4995 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
4996 Value *First = getShadow(&I, 0);
4997 Value *Second = getShadow(&I, 1);
4998 Value *OrShadow = IRB.CreateOr(First, Second);
4999 // First element of both OR'd together, remaining elements of first operand
5000 SmallVector<int, 16> Mask;
5001 Mask.push_back(Width);
5002 for (unsigned i = 1; i < Width; i++)
5003 Mask.push_back(i);
5004 Value *Shadow = IRB.CreateShuffleVector(First, OrShadow, Mask);
5005
5006 setShadow(&I, Shadow);
5007 setOriginForNaryOp(I);
5008 }
5009
5010 // _mm_round_ps / _mm_round_ps.
5011 // Similar to maybeHandleSimpleNomemIntrinsic except
5012 // the second argument is guaranteed to be a constant integer.
5013 void handleRoundPdPsIntrinsic(IntrinsicInst &I) {
5014 assert(I.getArgOperand(0)->getType() == I.getType());
5015 assert(I.arg_size() == 2);
5016 assert(isa<ConstantInt>(I.getArgOperand(1)));
5017
5018 IRBuilder<> IRB(&I);
5019 ShadowAndOriginCombiner SC(this, IRB);
5020 SC.Add(I.getArgOperand(0));
5021 SC.Done(&I);
5022 }
5023
5024 // Instrument @llvm.abs intrinsic.
5025 //
5026 // e.g., i32 @llvm.abs.i32 (i32 <Src>, i1 <is_int_min_poison>)
5027 // <4 x i32> @llvm.abs.v4i32(<4 x i32> <Src>, i1 <is_int_min_poison>)
5028 void handleAbsIntrinsic(IntrinsicInst &I) {
5029 assert(I.arg_size() == 2);
5030 Value *Src = I.getArgOperand(0);
5031 Value *IsIntMinPoison = I.getArgOperand(1);
5032
5033 assert(I.getType()->isIntOrIntVectorTy());
5034
5035 assert(Src->getType() == I.getType());
5036
5037 assert(IsIntMinPoison->getType()->isIntegerTy());
5038 assert(IsIntMinPoison->getType()->getIntegerBitWidth() == 1);
5039
5040 IRBuilder<> IRB(&I);
5041 Value *SrcShadow = getShadow(Src);
5042
5043 APInt MinVal =
5044 APInt::getSignedMinValue(Src->getType()->getScalarSizeInBits());
5045 Value *MinValVec = ConstantInt::get(Src->getType(), MinVal);
5046 Value *SrcIsMin = IRB.CreateICmp(CmpInst::ICMP_EQ, Src, MinValVec);
5047
5048 Value *PoisonedShadow = getPoisonedShadow(Src);
5049 Value *PoisonedIfIntMinShadow =
5050 IRB.CreateSelect(SrcIsMin, PoisonedShadow, SrcShadow);
5051 Value *Shadow =
5052 IRB.CreateSelect(IsIntMinPoison, PoisonedIfIntMinShadow, SrcShadow);
5053
5054 setShadow(&I, Shadow);
5055 setOrigin(&I, getOrigin(&I, 0));
5056 }
5057
5058 void handleIsFpClass(IntrinsicInst &I) {
5059 IRBuilder<> IRB(&I);
5060 Value *Shadow = getShadow(&I, 0);
5061 setShadow(&I, IRB.CreateICmpNE(Shadow, getCleanShadow(Shadow)));
5062 setOrigin(&I, getOrigin(&I, 0));
5063 }
5064
5065 void handleArithmeticWithOverflow(IntrinsicInst &I) {
5066 IRBuilder<> IRB(&I);
5067 Value *Shadow0 = getShadow(&I, 0);
5068 Value *Shadow1 = getShadow(&I, 1);
5069 Value *ShadowElt0 = IRB.CreateOr(Shadow0, Shadow1);
5070 Value *ShadowElt1 =
5071 IRB.CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
5072
5073 Value *Shadow = PoisonValue::get(getShadowTy(&I));
5074 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt0, 0);
5075 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt1, 1);
5076
5077 setShadow(&I, Shadow);
5078 setOriginForNaryOp(I);
5079 }
5080
5081 void handleModfOrSincos(IntrinsicInst &I) {
5082 IRBuilder<> IRB(&I);
5083 Value *ArgShadow = getShadow(&I, 0);
5084 Value *Shadow = PoisonValue::get(getShadowTy(&I));
5085 Shadow = IRB.CreateInsertValue(Shadow, ArgShadow, 0);
5086 Shadow = IRB.CreateInsertValue(Shadow, ArgShadow, 1);
5087 setShadow(&I, Shadow);
5088 setOrigin(&I, getOrigin(&I, 0));
5089 }
5090
5091 Value *extractLowerShadow(IRBuilder<> &IRB, Value *V) {
5092 assert(isa<FixedVectorType>(V->getType()));
5093 assert(cast<FixedVectorType>(V->getType())->getNumElements() > 0);
5094 Value *Shadow = getShadow(V);
5095 return IRB.CreateExtractElement(Shadow,
5096 ConstantInt::get(IRB.getInt32Ty(), 0));
5097 }
5098
5099 // Handle llvm.x86.avx512.mask.pmov{,s,us}.*.{128,256,512}
5100 //
5101 // e.g., call <16 x i8> @llvm.x86.avx512.mask.pmov.qb.512
5102 // (<8 x i64>, <16 x i8>, i8)
5103 // A WriteThru Mask
5104 //
5105 // call <16 x i8> @llvm.x86.avx512.mask.pmovs.db.512
5106 // (<16 x i32>, <16 x i8>, i16)
5107 //
5108 // Dst[i] = Mask[i] ? truncate_or_saturate(A[i]) : WriteThru[i]
5109 // Dst_shadow[i] = Mask[i] ? truncate(A_shadow[i]) : WriteThru_shadow[i]
5110 //
5111 // If Dst has more elements than A, the excess elements are zeroed (and the
5112 // corresponding shadow is initialized).
5113 //
5114 // Note: for PMOV (truncation), handleIntrinsicByApplyingToShadow is precise
5115 // and is much faster than this handler.
5116 void handleAVX512VectorDownConvert(IntrinsicInst &I) {
5117 IRBuilder<> IRB(&I);
5118
5119 assert(I.arg_size() == 3);
5120 Value *A = I.getOperand(0);
5121 Value *WriteThrough = I.getOperand(1);
5122 Value *Mask = I.getOperand(2);
5123
5124 assert(isFixedIntVector(A));
5125 assert(isFixedIntVector(WriteThrough));
5126
5127 unsigned ANumElements =
5128 cast<FixedVectorType>(A->getType())->getNumElements();
5129 unsigned OutputNumElements =
5130 cast<FixedVectorType>(WriteThrough->getType())->getNumElements();
5131 assert(ANumElements == OutputNumElements ||
5132 ANumElements * 2 == OutputNumElements);
5133 // N.B. some PMOV{,S,US} instructions have a 4x or even 8x ratio in the
5134 // number of elements e.g.,
5135 // <16 x i8> @llvm.x86.avx512.mask.pmovs.qb.256
5136 // (<4 x i64>, <16 x i8>, i8)
5137 // <16 x i8> @llvm.x86.avx512.mask.pmovs.qb.128
5138 // (<2 x i64>, <16 x i8>, i8)
5139 // However, we currently handle those elsewhere.
5140
5141 assert(Mask->getType()->isIntegerTy());
5142 insertCheckShadowOf(Mask, &I);
5143
5144 // The mask has 1 bit per element of A, but a minimum of 8 bits.
5145 if (Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5146 Mask = IRB.CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5147 assert(Mask->getType()->getScalarSizeInBits() == ANumElements);
5148
5149 assert(I.getType() == WriteThrough->getType());
5150
5151 // Widen the mask, if necessary, to have one bit per element of the output
5152 // vector.
5153 // We want the extra bits to have '1's, so that the CreateSelect will
5154 // select the values from AShadow instead of WriteThroughShadow ("maskless"
5155 // versions of the intrinsics are sometimes implemented using an all-1's
5156 // mask and an undefined value for WriteThroughShadow). We accomplish this
5157 // by using bitwise NOT before and after the ZExt.
5158 if (ANumElements != OutputNumElements) {
5159 Mask = IRB.CreateNot(Mask);
5160 Mask = IRB.CreateZExt(Mask, Type::getIntNTy(*MS.C, OutputNumElements),
5161 "_ms_widen_mask");
5162 Mask = IRB.CreateNot(Mask);
5163 }
5164 Mask = IRB.CreateBitCast(
5165 Mask, FixedVectorType::get(IRB.getInt1Ty(), OutputNumElements));
5166
5167 Value *AShadow = getShadow(A);
5168
5169 // The return type might have more elements than the input.
5170 // Temporarily shrink the return type's number of elements.
5171 VectorType *ShadowType = maybeShrinkVectorShadowType(A, I);
5172
5173 // PMOV truncates; PMOVS/PMOVUS uses signed/unsigned saturation.
5174 // This handler treats them all as truncation, which leads to some rare
5175 // false positives in the cases where the truncated bytes could
5176 // unambiguously saturate the value e.g., if A = ??????10 ????????
5177 // (big-endian), the unsigned saturated byte conversion is 11111111 i.e.,
5178 // fully defined, but the truncated byte is ????????.
5179 //
5180 // TODO: use GetMinMaxUnsigned() to handle saturation precisely.
5181 AShadow = IRB.CreateTrunc(AShadow, ShadowType, "_ms_trunc_shadow");
5182 AShadow = maybeExtendVectorShadowWithZeros(AShadow, I);
5183
5184 Value *WriteThroughShadow = getShadow(WriteThrough);
5185
5186 Value *Shadow = IRB.CreateSelect(Mask, AShadow, WriteThroughShadow);
5187 setShadow(&I, Shadow);
5188 setOriginForNaryOp(I);
5189 }
5190
5191 // Handle llvm.x86.avx512.* instructions that take vector(s) of floating-point
5192 // values and perform an operation whose shadow propagation should be handled
5193 // as all-or-nothing [*], with masking provided by a vector and a mask
5194 // supplied as an integer.
5195 //
5196 // [*] if all bits of a vector element are initialized, the output is fully
5197 // initialized; otherwise, the output is fully uninitialized
5198 //
5199 // e.g., <16 x float> @llvm.x86.avx512.rsqrt14.ps.512
5200 // (<16 x float>, <16 x float>, i16)
5201 // A WriteThru Mask
5202 //
5203 // <2 x double> @llvm.x86.avx512.rcp14.pd.128
5204 // (<2 x double>, <2 x double>, i8)
5205 // A WriteThru Mask
5206 //
5207 // <8 x double> @llvm.x86.avx512.mask.rndscale.pd.512
5208 // (<8 x double>, i32, <8 x double>, i8, i32)
5209 // A Imm WriteThru Mask Rounding
5210 //
5211 // <16 x float> @llvm.x86.avx512.mask.scalef.ps.512
5212 // (<16 x float>, <16 x float>, <16 x float>, i16, i32)
5213 // WriteThru A B Mask Rnd
5214 //
5215 // All operands other than A, B, ..., and WriteThru (e.g., Mask, Imm,
5216 // Rounding) must be fully initialized.
5217 //
5218 // Dst[i] = Mask[i] ? some_op(A[i], B[i], ...)
5219 // : WriteThru[i]
5220 // Dst_shadow[i] = Mask[i] ? all_or_nothing(A_shadow[i] | B_shadow[i] | ...)
5221 // : WriteThru_shadow[i]
5222 void handleAVX512VectorGenericMaskedFP(IntrinsicInst &I,
5223 SmallVector<unsigned, 4> DataIndices,
5224 unsigned WriteThruIndex,
5225 unsigned MaskIndex) {
5226 IRBuilder<> IRB(&I);
5227
5228 unsigned NumArgs = I.arg_size();
5229
5230 assert(WriteThruIndex < NumArgs);
5231 assert(MaskIndex < NumArgs);
5232 assert(WriteThruIndex != MaskIndex);
5233 Value *WriteThru = I.getOperand(WriteThruIndex);
5234
5235 unsigned OutputNumElements =
5236 cast<FixedVectorType>(WriteThru->getType())->getNumElements();
5237
5238 assert(DataIndices.size() > 0);
5239
5240 bool isData[16] = {false};
5241 assert(NumArgs <= 16);
5242 for (unsigned i : DataIndices) {
5243 assert(i < NumArgs);
5244 assert(i != WriteThruIndex);
5245 assert(i != MaskIndex);
5246
5247 isData[i] = true;
5248
5249 Value *A = I.getOperand(i);
5250 assert(isFixedFPVector(A));
5251 [[maybe_unused]] unsigned ANumElements =
5252 cast<FixedVectorType>(A->getType())->getNumElements();
5253 assert(ANumElements == OutputNumElements);
5254 }
5255
5256 Value *Mask = I.getOperand(MaskIndex);
5257
5258 assert(isFixedFPVector(WriteThru));
5259
5260 for (unsigned i = 0; i < NumArgs; ++i) {
5261 if (!isData[i] && i != WriteThruIndex) {
5262 // Imm, Mask, Rounding etc. are "control" data, hence we require that
5263 // they be fully initialized.
5264 assert(I.getOperand(i)->getType()->isIntegerTy());
5265 insertCheckShadowOf(I.getOperand(i), &I);
5266 }
5267 }
5268
5269 // The mask has 1 bit per element of A, but a minimum of 8 bits.
5270 if (Mask->getType()->getScalarSizeInBits() == 8 && OutputNumElements < 8)
5271 Mask = IRB.CreateTrunc(Mask, Type::getIntNTy(*MS.C, OutputNumElements));
5272 assert(Mask->getType()->getScalarSizeInBits() == OutputNumElements);
5273
5274 assert(I.getType() == WriteThru->getType());
5275
5276 Mask = IRB.CreateBitCast(
5277 Mask, FixedVectorType::get(IRB.getInt1Ty(), OutputNumElements));
5278
5279 Value *DataShadow = nullptr;
5280 for (unsigned i : DataIndices) {
5281 Value *A = I.getOperand(i);
5282 if (DataShadow)
5283 DataShadow = IRB.CreateOr(DataShadow, getShadow(A));
5284 else
5285 DataShadow = getShadow(A);
5286 }
5287
5288 // All-or-nothing shadow
5289 DataShadow =
5290 IRB.CreateSExt(IRB.CreateICmpNE(DataShadow, getCleanShadow(DataShadow)),
5291 DataShadow->getType());
5292
5293 Value *WriteThruShadow = getShadow(WriteThru);
5294
5295 Value *Shadow = IRB.CreateSelect(Mask, DataShadow, WriteThruShadow);
5296 setShadow(&I, Shadow);
5297
5298 setOriginForNaryOp(I);
5299 }
5300
5301 // AVX512 Floating-Point Classification
5302 //
5303 // e.g.,
5304 // - < 8 x i1> @llvm.x86.avx512.fpclass.pd.512
5305 // (<8 x double> %input, i32 %classifiers)
5306 // - <16 x i1> @llvm.x86.avx512.fpclass.ps.512
5307 // (<16 x float> %input, i32 %classifiers)
5308 void handleAVX512FPClass(IntrinsicInst &I) {
5309 IRBuilder<> IRB(&I);
5310
5311 assert(I.arg_size() == 2);
5312
5313 Value *Input = I.getOperand(0);
5314 assert(isFixedFPVector(Input));
5315 [[maybe_unused]] FixedVectorType *InputType = cast<FixedVectorType>(Input->getType());
5316
5317 Value *Classifiers = I.getOperand(1);
5318 assert(isa<ConstantInt>(Classifiers));
5319 // No shadow check needed for constants
5320
5321 assert(isFixedIntVectorTy(I.getType()));
5322 FixedVectorType *OutputType = cast<FixedVectorType>(I.getType());
5323 assert(OutputType->getScalarSizeInBits() == 1);
5324
5325 assert(OutputType->getNumElements() == InputType->getNumElements());
5326
5327 Value *OutputShadow;
5328 if (cast<ConstantInt>(Classifiers)->isZero())
5329 // Each bit specifies whether a particular classifier is enabled.
5330 // If Classifiers == 0, the output is trivially known to be zero, thus
5331 // the output is fully initialized.
5332 OutputShadow = getCleanShadow(OutputType);
5333 else
5334 // Approximate each bit of the output shadow based on whether the
5335 // corresponding input element is fully initialized. It is only
5336 // approximate because some classifications do not rely on all bits of
5337 // the input element.
5338 OutputShadow = IRB.CreateICmpNE(getShadow(Input), getCleanShadow(Input));
5339
5340 setShadow(&I, OutputShadow);
5341
5342 setOriginForNaryOp(I);
5343 }
5344
5345 // For sh.* compiler intrinsics:
5346 // llvm.x86.avx512fp16.mask.{add/sub/mul/div/max/min}.sh.round
5347 // (<8 x half>, <8 x half>, <8 x half>, i8, i32)
5348 // A B WriteThru Mask RoundingMode
5349 //
5350 // DstShadow[0] = Mask[0] ? (AShadow[0] | BShadow[0]) : WriteThruShadow[0]
5351 // DstShadow[1..7] = AShadow[1..7]
5352 void visitGenericScalarHalfwordInst(IntrinsicInst &I) {
5353 IRBuilder<> IRB(&I);
5354
5355 assert(I.arg_size() == 5);
5356 Value *A = I.getOperand(0);
5357 Value *B = I.getOperand(1);
5358 Value *WriteThrough = I.getOperand(2);
5359 Value *Mask = I.getOperand(3);
5360 Value *RoundingMode = I.getOperand(4);
5361
5362 // Technically, we could probably just check whether the LSB is
5363 // initialized, but intuitively it feels like a partly uninitialized mask
5364 // is unintended, and we should warn the user immediately.
5365 insertCheckShadowOf(Mask, &I);
5366 insertCheckShadowOf(RoundingMode, &I);
5367
5368 assert(isa<FixedVectorType>(A->getType()));
5369 unsigned NumElements =
5370 cast<FixedVectorType>(A->getType())->getNumElements();
5371 assert(NumElements == 8);
5372 assert(A->getType() == B->getType());
5373 assert(B->getType() == WriteThrough->getType());
5374 assert(Mask->getType()->getPrimitiveSizeInBits() == NumElements);
5375 assert(RoundingMode->getType()->isIntegerTy());
5376
5377 Value *ALowerShadow = extractLowerShadow(IRB, A);
5378 Value *BLowerShadow = extractLowerShadow(IRB, B);
5379
5380 Value *ABLowerShadow = IRB.CreateOr(ALowerShadow, BLowerShadow);
5381
5382 Value *WriteThroughLowerShadow = extractLowerShadow(IRB, WriteThrough);
5383
5384 Mask = IRB.CreateBitCast(
5385 Mask, FixedVectorType::get(IRB.getInt1Ty(), NumElements));
5386 Value *MaskLower =
5387 IRB.CreateExtractElement(Mask, ConstantInt::get(IRB.getInt32Ty(), 0));
5388
5389 Value *AShadow = getShadow(A);
5390 Value *DstLowerShadow =
5391 IRB.CreateSelect(MaskLower, ABLowerShadow, WriteThroughLowerShadow);
5392 Value *DstShadow = IRB.CreateInsertElement(
5393 AShadow, DstLowerShadow, ConstantInt::get(IRB.getInt32Ty(), 0),
5394 "_msprop");
5395
5396 setShadow(&I, DstShadow);
5397 setOriginForNaryOp(I);
5398 }
5399
5400 // Approximately handle AVX Galois Field Affine Transformation
5401 //
5402 // e.g.,
5403 // <16 x i8> @llvm.x86.vgf2p8affineqb.128(<16 x i8>, <16 x i8>, i8)
5404 // <32 x i8> @llvm.x86.vgf2p8affineqb.256(<32 x i8>, <32 x i8>, i8)
5405 // <64 x i8> @llvm.x86.vgf2p8affineqb.512(<64 x i8>, <64 x i8>, i8)
5406 // Out A x b
5407 // where A and x are packed matrices, b is a vector,
5408 // Out = A * x + b in GF(2)
5409 //
5410 // Multiplication in GF(2) is equivalent to bitwise AND. However, the matrix
5411 // computation also includes a parity calculation.
5412 //
5413 // For the bitwise AND of bits V1 and V2, the exact shadow is:
5414 // Out_Shadow = (V1_Shadow & V2_Shadow)
5415 // | (V1 & V2_Shadow)
5416 // | (V1_Shadow & V2 )
5417 //
5418 // We approximate the shadow of gf2p8affineqb using:
5419 // Out_Shadow = gf2p8affineqb(x_Shadow, A_shadow, 0)
5420 // | gf2p8affineqb(x, A_shadow, 0)
5421 // | gf2p8affineqb(x_Shadow, A, 0)
5422 // | set1_epi8(b_Shadow)
5423 //
5424 // This approximation has false negatives: if an intermediate dot-product
5425 // contains an even number of 1's, the parity is 0.
5426 // It has no false positives.
5427 void handleAVXGF2P8Affine(IntrinsicInst &I) {
5428 IRBuilder<> IRB(&I);
5429
5430 assert(I.arg_size() == 3);
5431 Value *A = I.getOperand(0);
5432 Value *X = I.getOperand(1);
5433 Value *B = I.getOperand(2);
5434
5435 assert(isFixedIntVector(A));
5436 assert(cast<VectorType>(A->getType())
5437 ->getElementType()
5438 ->getScalarSizeInBits() == 8);
5439
5440 assert(A->getType() == X->getType());
5441
5442 assert(B->getType()->isIntegerTy());
5443 assert(B->getType()->getScalarSizeInBits() == 8);
5444
5445 assert(I.getType() == A->getType());
5446
5447 Value *AShadow = getShadow(A);
5448 Value *XShadow = getShadow(X);
5449 Value *BZeroShadow = getCleanShadow(B);
5450
5451 Value *AShadowXShadow = IRB.CreateIntrinsic(
5452 I.getType(), I.getIntrinsicID(), {XShadow, AShadow, BZeroShadow});
5453 Value *AShadowX = IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(),
5454 {X, AShadow, BZeroShadow});
5455 Value *XShadowA = IRB.CreateIntrinsic(I.getType(), I.getIntrinsicID(),
5456 {XShadow, A, BZeroShadow});
5457
5458 unsigned NumElements = cast<FixedVectorType>(I.getType())->getNumElements();
5459 Value *BShadow = getShadow(B);
5460 Value *BBroadcastShadow = getCleanShadow(AShadow);
5461 // There is no LLVM IR intrinsic for _mm512_set1_epi8.
5462 // This loop generates a lot of LLVM IR, which we expect that CodeGen will
5463 // lower appropriately (e.g., VPBROADCASTB).
5464 // Besides, b is often a constant, in which case it is fully initialized.
5465 for (unsigned i = 0; i < NumElements; i++)
5466 BBroadcastShadow = IRB.CreateInsertElement(BBroadcastShadow, BShadow, i);
5467
5468 setShadow(&I, IRB.CreateOr(
5469 {AShadowXShadow, AShadowX, XShadowA, BBroadcastShadow}));
5470 setOriginForNaryOp(I);
5471 }
5472
5473 // Handle Arm NEON vector load intrinsics (vld*).
5474 //
5475 // The WithLane instructions (ld[234]lane) are similar to:
5476 // call {<4 x i32>, <4 x i32>, <4 x i32>}
5477 // @llvm.aarch64.neon.ld3lane.v4i32.p0
5478 // (<4 x i32> %L1, <4 x i32> %L2, <4 x i32> %L3, i64 %lane, ptr
5479 // %A)
5480 //
5481 // The non-WithLane instructions (ld[234], ld1x[234], ld[234]r) are similar
5482 // to:
5483 // call {<8 x i8>, <8 x i8>} @llvm.aarch64.neon.ld2.v8i8.p0(ptr %A)
5484 void handleNEONVectorLoad(IntrinsicInst &I, bool WithLane) {
5485 unsigned int numArgs = I.arg_size();
5486
5487 // Return type is a struct of vectors of integers or floating-point
5488 assert(I.getType()->isStructTy());
5489 [[maybe_unused]] StructType *RetTy = cast<StructType>(I.getType());
5490 assert(RetTy->getNumElements() > 0);
5492 RetTy->getElementType(0)->isFPOrFPVectorTy());
5493 for (unsigned int i = 0; i < RetTy->getNumElements(); i++)
5494 assert(RetTy->getElementType(i) == RetTy->getElementType(0));
5495
5496 if (WithLane) {
5497 // 2, 3 or 4 vectors, plus lane number, plus input pointer
5498 assert(4 <= numArgs && numArgs <= 6);
5499
5500 // Return type is a struct of the input vectors
5501 assert(RetTy->getNumElements() + 2 == numArgs);
5502 for (unsigned int i = 0; i < RetTy->getNumElements(); i++)
5503 assert(I.getArgOperand(i)->getType() == RetTy->getElementType(0));
5504 } else {
5505 assert(numArgs == 1);
5506 }
5507
5508 IRBuilder<> IRB(&I);
5509
5510 SmallVector<Value *, 6> ShadowArgs;
5511 if (WithLane) {
5512 for (unsigned int i = 0; i < numArgs - 2; i++)
5513 ShadowArgs.push_back(getShadow(I.getArgOperand(i)));
5514
5515 // Lane number, passed verbatim
5516 Value *LaneNumber = I.getArgOperand(numArgs - 2);
5517 ShadowArgs.push_back(LaneNumber);
5518
5519 // TODO: blend shadow of lane number into output shadow?
5520 insertCheckShadowOf(LaneNumber, &I);
5521 }
5522
5523 Value *Src = I.getArgOperand(numArgs - 1);
5524 assert(Src->getType()->isPointerTy() && "Source is not a pointer!");
5525
5526 Type *SrcShadowTy = getShadowTy(Src);
5527 auto [SrcShadowPtr, SrcOriginPtr] =
5528 getShadowOriginPtr(Src, IRB, SrcShadowTy, Align(1), /*isStore*/ false);
5529 ShadowArgs.push_back(SrcShadowPtr);
5530
5531 // The NEON vector load instructions handled by this function all have
5532 // integer variants. It is easier to use those rather than trying to cast
5533 // a struct of vectors of floats into a struct of vectors of integers.
5534 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
5535 getShadowTy(&I), I.getIntrinsicID(), ShadowArgs);
5536 setShadow(&I, CI);
5537
5538 if (!MS.TrackOrigins)
5539 return;
5540
5541 Value *PtrSrcOrigin = IRB.CreateLoad(MS.OriginTy, SrcOriginPtr);
5542 setOrigin(&I, PtrSrcOrigin);
5543 }
5544
5545 /// Handle Arm NEON vector store intrinsics (vst{2,3,4}, vst1x_{2,3,4},
5546 /// and vst{2,3,4}lane).
5547 ///
5548 /// Arm NEON vector store intrinsics have the output address (pointer) as the
5549 /// last argument, with the initial arguments being the inputs (and lane
5550 /// number for vst{2,3,4}lane). They return void.
5551 ///
5552 /// - st4 interleaves the output e.g., st4 (inA, inB, inC, inD, outP) writes
5553 /// abcdabcdabcdabcd... into *outP
5554 /// - st1_x4 is non-interleaved e.g., st1_x4 (inA, inB, inC, inD, outP)
5555 /// writes aaaa...bbbb...cccc...dddd... into *outP
5556 /// - st4lane has arguments of (inA, inB, inC, inD, lane, outP)
5557 /// These instructions can all be instrumented with essentially the same
5558 /// MSan logic, simply by applying the corresponding intrinsic to the shadow.
5559 void handleNEONVectorStoreIntrinsic(IntrinsicInst &I, bool useLane) {
5560 IRBuilder<> IRB(&I);
5561
5562 // Don't use getNumOperands() because it includes the callee
5563 int numArgOperands = I.arg_size();
5564
5565 // The last arg operand is the output (pointer)
5566 assert(numArgOperands >= 1);
5567 Value *Addr = I.getArgOperand(numArgOperands - 1);
5568 assert(Addr->getType()->isPointerTy());
5569 int skipTrailingOperands = 1;
5570
5571 if (Opts.msan_check_access_address)
5572 insertCheckShadowOf(Addr, &I);
5573
5574 // Second-last operand is the lane number (for vst{2,3,4}lane)
5575 if (useLane) {
5576 skipTrailingOperands++;
5577 assert(numArgOperands >= static_cast<int>(skipTrailingOperands));
5579 I.getArgOperand(numArgOperands - skipTrailingOperands)->getType()));
5580 }
5581
5582 SmallVector<Value *, 8> ShadowArgs;
5583 // All the initial operands are the inputs
5584 for (int i = 0; i < numArgOperands - skipTrailingOperands; i++) {
5585 assert(isa<FixedVectorType>(I.getArgOperand(i)->getType()));
5586 Value *Shadow = getShadow(&I, i);
5587 ShadowArgs.append(1, Shadow);
5588 }
5589
5590 // MSan's GetShadowTy assumes the LHS is the type we want the shadow for
5591 // e.g., for:
5592 // [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to i128
5593 // we know the type of the output (and its shadow) is <16 x i8>.
5594 //
5595 // Arm NEON VST is unusual because the last argument is the output address:
5596 // define void @st2_16b(<16 x i8> %A, <16 x i8> %B, ptr %P) {
5597 // call void @llvm.aarch64.neon.st2.v16i8.p0
5598 // (<16 x i8> [[A]], <16 x i8> [[B]], ptr [[P]])
5599 // and we have no type information about P's operand. We must manually
5600 // compute the type (<16 x i8> x 2).
5601 FixedVectorType *OutputVectorTy = FixedVectorType::get(
5602 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getElementType(),
5603 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements() *
5604 (numArgOperands - skipTrailingOperands));
5605 Type *OutputShadowTy = getShadowTy(OutputVectorTy);
5606
5607 if (useLane)
5608 ShadowArgs.append(1,
5609 I.getArgOperand(numArgOperands - skipTrailingOperands));
5610
5611 Value *OutputShadowPtr, *OutputOriginPtr;
5612 // AArch64 NEON does not need alignment (unless OS requires it)
5613 std::tie(OutputShadowPtr, OutputOriginPtr) = getShadowOriginPtr(
5614 Addr, IRB, OutputShadowTy, Align(1), /*isStore*/ true);
5615 ShadowArgs.append(1, OutputShadowPtr);
5616
5617 CallInst *CI = IRB.CreateIntrinsicWithoutFolding(
5618 IRB.getVoidTy(), I.getIntrinsicID(), ShadowArgs);
5619 setShadow(&I, CI);
5620
5621 if (MS.TrackOrigins) {
5622 // TODO: if we modelled the vst* instruction more precisely, we could
5623 // more accurately track the origins (e.g., if both inputs are
5624 // uninitialized for vst2, we currently blame the second input, even
5625 // though part of the output depends only on the first input).
5626 //
5627 // This is particularly imprecise for vst{2,3,4}lane, since only one
5628 // lane of each input is actually copied to the output.
5629 OriginCombiner OC(this, IRB);
5630 for (int i = 0; i < numArgOperands - skipTrailingOperands; i++)
5631 OC.Add(I.getArgOperand(i));
5632
5633 const DataLayout &DL = F.getDataLayout();
5634 OC.DoneAndStoreOrigin(DL.getTypeStoreSize(OutputVectorTy),
5635 OutputOriginPtr);
5636 }
5637 }
5638
5639 // Integer matrix multiplication:
5640 // - <4 x i32> @llvm.aarch64.neon.{s,u,us}mmla.v4i32.v16i8
5641 // (<4 x i32> %R, <16 x i8> %A, <16 x i8> %B)
5642 // - <4 x i32> is a 2x2 matrix
5643 // - <16 x i8> %A and %B are 2x8 and 8x2 matrices respectively
5644 //
5645 // Floating-point matrix multiplication:
5646 // - <4 x float> @llvm.aarch64.neon.bfmmla
5647 // (<4 x float> %R, <8 x bfloat> %A, <8 x bfloat> %B)
5648 // - <4 x float> is a 2x2 matrix
5649 // - <8 x bfloat> %A and %B are 2x4 and 4x2 matrices respectively
5650 //
5651 // The general shadow propagation approach is:
5652 // 1) get the shadows of the input matrices %A and %B
5653 // 2) map each shadow value to 0x1 if the corresponding value is fully
5654 // initialized, and 0x0 otherwise
5655 // 3) perform a matrix multiplication on the shadows of %A and %B [*].
5656 // The output will be a 2x2 matrix. For each element, a value of 0x8
5657 // (for {s,u,us}mmla) or 0x4 (for bfmmla) means all the corresponding
5658 // inputs were clean; if so, set the shadow to zero, otherwise set to -1.
5659 // 4) blend in the shadow of %R
5660 //
5661 // [*] Since shadows are integral, the obvious approach is to always apply
5662 // ummla to the shadows. Unfortunately, Armv8.2+bf16 supports bfmmla,
5663 // but not ummla. Thus, for bfmmla, our instrumentation reuses bfmmla.
5664 //
5665 // TODO: consider allowing multiplication of zero with an uninitialized value
5666 // to result in an initialized value.
5667 void handleNEONMatrixMultiply(IntrinsicInst &I) {
5668 IRBuilder<> IRB(&I);
5669
5670 assert(I.arg_size() == 3);
5671 Value *R = I.getArgOperand(0);
5672 Value *A = I.getArgOperand(1);
5673 Value *B = I.getArgOperand(2);
5674
5675 assert(I.getType() == R->getType());
5676
5677 assert(isa<FixedVectorType>(R->getType()));
5678 assert(isa<FixedVectorType>(A->getType()));
5679 assert(isa<FixedVectorType>(B->getType()));
5680
5681 FixedVectorType *RTy = cast<FixedVectorType>(R->getType());
5682 FixedVectorType *ATy = cast<FixedVectorType>(A->getType());
5683 FixedVectorType *BTy = cast<FixedVectorType>(B->getType());
5684 assert(ATy->getElementType() == BTy->getElementType());
5685
5686 if (RTy->getElementType()->isIntegerTy()) {
5687 // <4 x i32> @llvm.aarch64.neon.ummla.v4i32.v16i8
5688 // (<4 x i32> %R, <16 x i8> %X, <16 x i8> %Y)
5689 assert(RTy == FixedVectorType::get(IntegerType::get(*MS.C, 32), 4));
5690 assert(ATy == FixedVectorType::get(IntegerType::get(*MS.C, 8), 16));
5691 assert(BTy == FixedVectorType::get(IntegerType::get(*MS.C, 8), 16));
5692 } else {
5693 // <4 x float> @llvm.aarch64.neon.bfmmla
5694 // (<4 x float> %R, <8 x bfloat> %X, <8 x bfloat> %Y)
5695 assert(RTy == FixedVectorType::get(Type::getFloatTy(*MS.C), 4));
5696 assert(ATy == FixedVectorType::get(Type::getBFloatTy(*MS.C), 8));
5697 assert(BTy == FixedVectorType::get(Type::getBFloatTy(*MS.C), 8));
5698 }
5699
5700 Value *ShadowR = getShadow(&I, 0);
5701 Value *ShadowA = getShadow(&I, 1);
5702 Value *ShadowB = getShadow(&I, 2);
5703
5704 Value *ShadowAB;
5705 Value *FullyInit;
5706
5707 if (RTy->getElementType()->isIntegerTy()) {
5708 // If the value is fully initialized, the shadow will be 000...001.
5709 // Otherwise, the shadow will be all zero.
5710 // (This is the opposite of how we typically handle shadows.)
5711 ShadowA = IRB.CreateZExt(IRB.CreateICmpEQ(ShadowA, getCleanShadow(ATy)),
5712 getShadowTy(ATy));
5713 ShadowB = IRB.CreateZExt(IRB.CreateICmpEQ(ShadowB, getCleanShadow(BTy)),
5714 getShadowTy(BTy));
5715 // TODO: the CreateSelect approach used below for floating-point is more
5716 // generic than CreateZExt. Investigate whether it is worthwhile
5717 // unifying the two approaches.
5718
5719 ShadowAB = IRB.CreateIntrinsic(RTy, Intrinsic::aarch64_neon_ummla,
5720 {getCleanShadow(RTy), ShadowA, ShadowB});
5721
5722 // ummla multiplies a 2x8 matrix with an 8x2 matrix. If all entries of the
5723 // input matrices are equal to 0x1, all entries of the output matrix will
5724 // be 0x8.
5725 FullyInit = ConstantVector::getSplat(
5726 RTy->getElementCount(), ConstantInt::get(RTy->getElementType(), 0x8));
5727
5728 ShadowAB = IRB.CreateICmpNE(ShadowAB, FullyInit);
5729 } else {
5731 ATy->getElementCount(), ConstantFP::get(ATy->getElementType(), 0));
5733 ATy->getElementCount(), ConstantFP::get(ATy->getElementType(), 1));
5734
5735 // As per the integer case, if the shadow is clean, we store 0x1,
5736 // otherwise we store 0x0 (the opposite of usual shadow arithmetic).
5737 ShadowA = IRB.CreateSelect(IRB.CreateICmpEQ(ShadowA, getCleanShadow(ATy)),
5738 ABOnes, ABZeros);
5739 ShadowB = IRB.CreateSelect(IRB.CreateICmpEQ(ShadowB, getCleanShadow(BTy)),
5740 ABOnes, ABZeros);
5741
5743 RTy->getElementCount(), ConstantFP::get(RTy->getElementType(), 0));
5744
5745 ShadowAB = IRB.CreateIntrinsic(RTy, Intrinsic::aarch64_neon_bfmmla,
5746 {RZeros, ShadowA, ShadowB});
5747
5748 // bfmmla multiplies a 2x4 matrix with an 4x2 matrix. If all entries of
5749 // the input matrices are equal to 0x1, all entries of the output matrix
5750 // will be 4.0. (To avoid floating-point error, we check if each entry
5751 // < 3.5.)
5752 FullyInit = ConstantVector::getSplat(
5753 RTy->getElementCount(), ConstantFP::get(RTy->getElementType(), 3.5));
5754
5755 // FCmpULT: "yields true if either operand is a QNAN or op1 is less than"
5756 // op2"
5757 ShadowAB = IRB.CreateFCmpULT(ShadowAB, FullyInit);
5758 }
5759
5760 ShadowR = IRB.CreateICmpNE(ShadowR, getCleanShadow(RTy));
5761 ShadowR = IRB.CreateOr(ShadowAB, ShadowR);
5762
5763 setShadow(&I, IRB.CreateSExt(ShadowR, getShadowTy(RTy)));
5764
5765 setOriginForNaryOp(I);
5766 }
5767
5768 /// Handle intrinsics by applying the intrinsic to the shadows.
5769 ///
5770 /// For example, this can be applied to the Arm NEON vector table intrinsics
5771 /// (tbl{1,2,3,4}).
5772 ///
5773 /// Typically, shadowIntrinsicID will be specified by the caller to be
5774 /// I.getIntrinsicID(), but the caller can choose to replace it with another
5775 /// intrinsic of the same type.
5776 ///
5777 /// The trailing arguments are passed verbatim to the intrinsic, though any
5778 /// uninitialized trailing arguments can also taint the shadow e.g., for an
5779 /// intrinsic with one trailing verbatim argument:
5780 /// out = intrinsic(var1, var2, opType)
5781 /// we compute:
5782 /// shadow[out] =
5783 /// intrinsic(shadow[var1], shadow[var2], opType) | shadow[opType]
5784 ///
5785 /// If an intrinsic is called with floating-point arguments, we will
5786 /// typically cast the shadows to floating-point, apply the intrinsic [*],
5787 /// then cast the result back to integer/shadow.
5788 ///
5789 /// In cases where we know the intrinsic is compatible with integer
5790 /// arguments, 'forceIntegerIntrinsic' will apply the integer variant, even
5791 /// if the arguments are floating-point, thus avoiding unnecessary casts
5792 /// e.g., if I is:
5793 /// <16 x float> @llvm.x86.avx512.mask.compress
5794 /// (<16 x float>, <16 x float>, <16 x i1> %mask)
5795 /// we would prefer to compute the shadows using:
5796 /// <16 x i32> @llvm.x86.avx512.mask.compress
5797 /// (<16 x i32>, <16 x i32>, <16 x i1> %mask)
5798 ///
5799 /// [*] CAUTION: this assumes that the intrinsic will handle arbitrary
5800 /// bit-patterns (for example, if the intrinsic accepts floats
5801 /// for var1, we require that it doesn't care if inputs are
5802 /// NaNs).
5803 ///
5804 /// The origin is approximated using setOriginForNaryOp.
5805 void handleIntrinsicByApplyingToShadow(IntrinsicInst &I,
5806 Intrinsic::ID shadowIntrinsicID,
5807 unsigned int trailingVerbatimArgs,
5808 bool forceIntegerIntrinsic) {
5809 IRBuilder<> IRB(&I);
5810
5811 assert(trailingVerbatimArgs < I.arg_size());
5812
5813 SmallVector<Value *, 8> ShadowArgs;
5814 // Don't use getNumOperands() because it includes the callee
5815 for (unsigned int i = 0; i < I.arg_size() - trailingVerbatimArgs; i++) {
5816 Value *Shadow = getShadow(&I, i);
5817
5818 if (forceIntegerIntrinsic)
5819 ShadowArgs.push_back(Shadow);
5820 else
5821 ShadowArgs.push_back(
5822 IRB.CreateBitCast(Shadow, I.getArgOperand(i)->getType()));
5823 }
5824
5825 for (unsigned int i = I.arg_size() - trailingVerbatimArgs; i < I.arg_size();
5826 i++) {
5827 Value *Arg = I.getArgOperand(i);
5828 if (forceIntegerIntrinsic)
5830 ShadowArgs.push_back(Arg);
5831 }
5832
5833 Value *CombinedShadow;
5834 if (forceIntegerIntrinsic) {
5835 CombinedShadow =
5836 IRB.CreateIntrinsic(getShadowTy(&I), shadowIntrinsicID, ShadowArgs);
5837 } else {
5838 Value *CI =
5839 IRB.CreateIntrinsic(I.getType(), shadowIntrinsicID, ShadowArgs);
5840 CombinedShadow = IRB.CreateBitCast(CI, getShadowTy(&I));
5841 }
5842
5843 // Combine the computed shadow with the shadow of trailing args
5844 for (unsigned int i = I.arg_size() - trailingVerbatimArgs; i < I.arg_size();
5845 i++) {
5846 Value *Shadow =
5847 CreateShadowCast(IRB, getShadow(&I, i), CombinedShadow->getType());
5848 CombinedShadow = IRB.CreateOr(Shadow, CombinedShadow, "_msprop");
5849 }
5850
5851 setShadow(&I, CombinedShadow);
5852
5853 setOriginForNaryOp(I);
5854 }
5855
5856 // Approximation only
5857 //
5858 // e.g., <16 x i8> @llvm.aarch64.neon.pmull64(i64, i64)
5859 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst &I) {
5860 assert(I.arg_size() == 2);
5861
5862 handleShadowOr(I);
5863 }
5864
5865 // Handles:
5866 // <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane
5867 // (<4 x half>, <8 x i8>, <16 x i8>, i32)
5868 // accumulator A B lane
5869 //
5870 // <8 x half> @llvm.aarch64.neon.fp8.fdot2.lane
5871 // (<8 x half>, <16 x i8>, <16 x i8>, i32)
5872 // <2 x float> @llvm.aarch64.neon.fp8.fdot4.lane
5873 // (<2 x float>, <8 x i8>, <16 x i8>, i32)
5874 // <4 x float> @llvm.aarch64.neon.fp8.fdot4.lane
5875 // (<4 x float>, <16 x i8>, <16 x i8>, i32)
5876 //
5877 // The lane specifies which pair (fdot2) or quad (fdot4) of numbers to
5878 // extract from B, which is then splatted before being used in the dot
5879 // products e.g., for
5880 // <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane:
5881 // (<4 x half>, <8 x i8>, <16 x i8>, 1)
5882 //
5883 // acc[0] acc[1] acc[2] acc[3]
5884 // + + + + + + + +
5885 // A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7]
5886 // * * * * * * * *
5887 // B[2] B[3] B[2] B[3] B[2] B[3] B[2] B[3]
5888 //
5889 // Notice that if any bit of B[2] or B[3] is uninitialized, every accumulator
5890 // value will become tainted; we approximate this by marking the output as
5891 // fully uninitialized. This permits a 'Select' optimization.
5892 //
5893 // This function is separate from handleVectorDotProductIntrinsic(), because
5894 // the non-overlapping features (e.g., odd/even lanes vs. numbered lanes,
5895 // ZeroPurifies, EltSizeInBits) and optimizations make clean code reuse
5896 // difficult.
5897 void handleNEONDotProductLaneIntrinsic(IntrinsicInst &I,
5898 unsigned ReductionFactor) {
5899 IRBuilder<> IRB(&I);
5900 assert(I.arg_size() == 4);
5901
5902 [[maybe_unused]] Value *VAcc = I.getOperand(0);
5903 [[maybe_unused]] Value *Va = I.getOperand(1);
5904 [[maybe_unused]] Value *Vb = I.getOperand(2);
5905 Value *Lane = I.getOperand(3);
5906
5908 assert(VAcc->getType() == I.getType());
5909
5912 I.getType()->getPrimitiveSizeInBits());
5913
5914 assert(cast<FixedVectorType>(Va->getType())->getNumElements() ==
5915 cast<FixedVectorType>(I.getType())->getNumElements() *
5916 ReductionFactor);
5917
5919 // Deliberately not strict equality
5921 I.getType()->getPrimitiveSizeInBits());
5922
5923 assert(Lane->getType()->isIntegerTy());
5924
5925 // (<4 x 16>, <8 x i8>, <16 x i8>)
5926 // SAcc Sa Sb
5927 Value *SAcc = getShadow(&I, 0);
5928 Value *Sa = getShadow(&I, 1);
5929 Value *Sb = getShadow(&I, 2);
5930
5931 // Cast the shadows to:
5932 // (<4 x i16>, <4 x i16>, <8 x i16>)
5933 // SAcc Sa Sb
5934 Sa = IRB.CreateBitCast(Sa, SAcc->getType());
5935 Sb = IRB.CreateBitCast(
5936 Sb, FixedVectorType::getWithSizeAndScalar(
5938 cast<FixedVectorType>(SAcc->getType())->getElementType()));
5939
5940 // All-or-nothing shadows
5941 Sa =
5942 IRB.CreateSExt(IRB.CreateICmpNE(Sa, getCleanShadow(Sa)), Sa->getType());
5943
5944 // Extract the specific lane from Sb to get i16, then turn it into a single
5945 // bit representing if it is fully initialized.
5946 Sb = IRB.CreateExtractElement(Sb, Lane);
5947 Value *SbClean = IRB.CreateIsNull(Sb);
5948
5949 Value *SOutput = IRB.CreateOr(SAcc, Sa);
5950
5951 // Select is cheaper than broadcasting Sb into <4 x i16>.
5952 SOutput = IRB.CreateSelect(SbClean, SOutput, getPoisonedShadow(SOutput));
5953
5954 setShadow(&I, SOutput);
5955 setOriginForNaryOp(I);
5956 }
5957
5958 bool maybeHandleCrossPlatformIntrinsic(IntrinsicInst &I) {
5959 switch (I.getIntrinsicID()) {
5960 case Intrinsic::uadd_with_overflow:
5961 case Intrinsic::sadd_with_overflow:
5962 case Intrinsic::usub_with_overflow:
5963 case Intrinsic::ssub_with_overflow:
5964 case Intrinsic::umul_with_overflow:
5965 case Intrinsic::smul_with_overflow:
5966 handleArithmeticWithOverflow(I);
5967 break;
5968 case Intrinsic::modf:
5969 case Intrinsic::sincos:
5970 case Intrinsic::sincospi:
5971 handleModfOrSincos(I);
5972 break;
5973 case Intrinsic::abs:
5974 handleAbsIntrinsic(I);
5975 break;
5976 case Intrinsic::bitreverse:
5977 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
5978 /*trailingVerbatimArgs=*/0,
5979 /*forceIntegerIntrinsic=*/false);
5980 break;
5981 case Intrinsic::is_fpclass:
5982 handleIsFpClass(I);
5983 break;
5984 case Intrinsic::lifetime_start:
5985 handleLifetimeStart(I);
5986 break;
5987 case Intrinsic::launder_invariant_group:
5988 handleInvariantGroup(I);
5989 break;
5990 case Intrinsic::bswap:
5991 handleBswap(I);
5992 break;
5993 case Intrinsic::ctlz:
5994 case Intrinsic::cttz:
5995 handleCountLeadingTrailingZeros(I);
5996 break;
5997 case Intrinsic::masked_compressstore:
5998 handleMaskedCompressStore(I);
5999 break;
6000 case Intrinsic::masked_expandload:
6001 handleMaskedExpandLoad(I);
6002 break;
6003 case Intrinsic::masked_gather:
6004 handleMaskedGather(I);
6005 break;
6006 case Intrinsic::masked_scatter:
6007 handleMaskedScatter(I);
6008 break;
6009 case Intrinsic::masked_store:
6010 handleMaskedStore(I);
6011 break;
6012 case Intrinsic::masked_load:
6013 handleMaskedLoad(I);
6014 break;
6015 case Intrinsic::masked_udiv:
6016 case Intrinsic::masked_sdiv:
6017 case Intrinsic::masked_urem:
6018 case Intrinsic::masked_srem:
6019 handleMaskedIntegerDivRem(I);
6020 break;
6021 case Intrinsic::vector_reduce_and:
6022 handleVectorReduceAndIntrinsic(I);
6023 break;
6024 case Intrinsic::vector_reduce_or:
6025 handleVectorReduceOrIntrinsic(I);
6026 break;
6027
6028 case Intrinsic::vector_reduce_add:
6029 case Intrinsic::vector_reduce_xor:
6030 case Intrinsic::vector_reduce_mul:
6031 // Signed/Unsigned Min/Max
6032 // TODO: handling similarly to AND/OR may be more precise.
6033 case Intrinsic::vector_reduce_smax:
6034 case Intrinsic::vector_reduce_smin:
6035 case Intrinsic::vector_reduce_umax:
6036 case Intrinsic::vector_reduce_umin:
6037 // TODO: this has no false positives, but arguably we should check that all
6038 // the bits are initialized.
6039 case Intrinsic::vector_reduce_fmax:
6040 case Intrinsic::vector_reduce_fmin:
6041 handleVectorReduceIntrinsic(I, /*AllowShadowCast=*/false);
6042 break;
6043
6044 case Intrinsic::vector_reduce_fadd:
6045 case Intrinsic::vector_reduce_fmul:
6046 handleVectorReduceWithStarterIntrinsic(I);
6047 break;
6048
6049 // e.g., <4 x i32> @llvm.vector.partial.reduce.add(<4 x i32>, <8 x i32>)
6050 case Intrinsic::vector_partial_reduce_add:
6051 case Intrinsic::vector_partial_reduce_fadd:
6052 handleVectorPartialReduceAddIntrinsic(I);
6053 break;
6054
6055 case Intrinsic::experimental_vector_extract_last_active:
6056 handleVectorExtractLastActive(I);
6057 break;
6058
6059 case Intrinsic::scmp:
6060 case Intrinsic::ucmp: {
6061 handleShadowOr(I);
6062 break;
6063 }
6064
6065 case Intrinsic::fshl:
6066 case Intrinsic::fshr:
6067 handleFunnelShift(I);
6068 break;
6069
6070 case Intrinsic::pdep:
6071 case Intrinsic::pext:
6072 handleGenericBitManipulation(I);
6073 break;
6074
6075 case Intrinsic::is_constant:
6076 // The result of llvm.is.constant() is always defined.
6077 setShadow(&I, getCleanShadow(&I));
6078 setOrigin(&I, getCleanOrigin());
6079 break;
6080
6081 // The non-saturating versions are handled by visitFPTo[US]IInst().
6082 //
6083 // N.B. some platform-specific intrinsics, such as AArch64 fcvtz[us], are
6084 // lowered to these cross-platform intrinsics.
6085 case Intrinsic::fptosi_sat:
6086 case Intrinsic::fptoui_sat:
6087 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
6088 break;
6089
6090 // e.g.,
6091 // notail call void (...) @llvm.fake.use(i64 %x)
6092 // notail call void (...) @llvm.fake.use(i32 %y)
6093 // notail call void (...) @llvm.fake.use(ptr %z)
6094 case Intrinsic::fake_use:
6095 assert(I.getType()->isVoidTy());
6096 // fake_uses aren't real, they can't hurt you. If the use isn't real, it
6097 // can't be a real use-of-uninitialized memory. Silently skip over
6098 // fake_use.
6099 return true;
6100
6101 default:
6102 return false;
6103 }
6104
6105 return true;
6106 }
6107
6108 bool maybeHandleX86SIMDIntrinsic(IntrinsicInst &I) {
6109 switch (I.getIntrinsicID()) {
6110 case Intrinsic::x86_sse_stmxcsr:
6111 handleStmxcsr(I);
6112 break;
6113 case Intrinsic::x86_sse_ldmxcsr:
6114 handleLdmxcsr(I);
6115 break;
6116
6117 // Convert Scalar Double Precision Floating-Point Value
6118 // to Unsigned Doubleword Integer
6119 // etc.
6120 case Intrinsic::x86_avx512_vcvtsd2usi64:
6121 case Intrinsic::x86_avx512_vcvtsd2usi32:
6122 case Intrinsic::x86_avx512_vcvtss2usi64:
6123 case Intrinsic::x86_avx512_vcvtss2usi32:
6124 case Intrinsic::x86_avx512_cvttss2usi64:
6125 case Intrinsic::x86_avx512_cvttss2usi:
6126 case Intrinsic::x86_avx512_cvttsd2usi64:
6127 case Intrinsic::x86_avx512_cvttsd2usi:
6128 case Intrinsic::x86_avx512_cvtusi2ss:
6129 case Intrinsic::x86_avx512_cvtusi642sd:
6130 case Intrinsic::x86_avx512_cvtusi642ss:
6131 handleSSEVectorConvertIntrinsic(I, 1, true);
6132 break;
6133 case Intrinsic::x86_sse2_cvtsd2si64:
6134 case Intrinsic::x86_sse2_cvtsd2si:
6135 case Intrinsic::x86_sse2_cvtsd2ss:
6136 case Intrinsic::x86_sse2_cvttsd2si64:
6137 case Intrinsic::x86_sse2_cvttsd2si:
6138 case Intrinsic::x86_sse_cvtss2si64:
6139 case Intrinsic::x86_sse_cvtss2si:
6140 case Intrinsic::x86_sse_cvttss2si64:
6141 case Intrinsic::x86_sse_cvttss2si:
6142 handleSSEVectorConvertIntrinsic(I, 1);
6143 break;
6144 case Intrinsic::x86_sse_cvtps2pi:
6145 case Intrinsic::x86_sse_cvttps2pi:
6146 handleSSEVectorConvertIntrinsic(I, 2);
6147 break;
6148
6149 // TODO:
6150 // <1 x i64> @llvm.x86.sse.cvtpd2pi(<2 x double>)
6151 // <2 x double> @llvm.x86.sse.cvtpi2pd(<1 x i64>)
6152 // <4 x float> @llvm.x86.sse.cvtpi2ps(<4 x float>, <1 x i64>)
6153
6154 case Intrinsic::x86_vcvtps2ph_128:
6155 case Intrinsic::x86_vcvtps2ph_256: {
6156 handleSSEVectorConvertIntrinsicByProp(I, /*HasRoundingMode=*/true);
6157 break;
6158 }
6159
6160 // Convert Packed Single Precision Floating-Point Values
6161 // to Packed Signed Doubleword Integer Values
6162 //
6163 // <16 x i32> @llvm.x86.avx512.mask.cvtps2dq.512
6164 // (<16 x float>, <16 x i32>, i16, i32)
6165 case Intrinsic::x86_avx512_mask_cvtps2dq_512:
6166 handleAVX512VectorConvertFPToInt(I, /*LastMask=*/false);
6167 break;
6168
6169 // Convert Packed Double Precision Floating-Point Values
6170 // to Packed Single Precision Floating-Point Values
6171 case Intrinsic::x86_sse2_cvtpd2ps:
6172 case Intrinsic::x86_sse2_cvtps2dq:
6173 case Intrinsic::x86_sse2_cvtpd2dq:
6174 case Intrinsic::x86_sse2_cvttps2dq:
6175 case Intrinsic::x86_sse2_cvttpd2dq:
6176 case Intrinsic::x86_avx_cvt_pd2_ps_256:
6177 case Intrinsic::x86_avx_cvt_ps2dq_256:
6178 case Intrinsic::x86_avx_cvt_pd2dq_256:
6179 case Intrinsic::x86_avx_cvtt_ps2dq_256:
6180 case Intrinsic::x86_avx_cvtt_pd2dq_256: {
6181 handleSSEVectorConvertIntrinsicByProp(I, /*HasRoundingMode=*/false);
6182 break;
6183 }
6184
6185 // Convert Single-Precision FP Value to 16-bit FP Value
6186 // <16 x i16> @llvm.x86.avx512.mask.vcvtps2ph.512
6187 // (<16 x float>, i32, <16 x i16>, i16)
6188 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.128
6189 // (<4 x float>, i32, <8 x i16>, i8)
6190 // <8 x i16> @llvm.x86.avx512.mask.vcvtps2ph.256
6191 // (<8 x float>, i32, <8 x i16>, i8)
6192 case Intrinsic::x86_avx512_mask_vcvtps2ph_512:
6193 case Intrinsic::x86_avx512_mask_vcvtps2ph_256:
6194 case Intrinsic::x86_avx512_mask_vcvtps2ph_128:
6195 handleAVX512VectorConvertFPToInt(I, /*LastMask=*/true);
6196 break;
6197
6198 // Shift Packed Data (Left Logical, Right Arithmetic, Right Logical)
6199 case Intrinsic::x86_avx512_psll_w_512:
6200 case Intrinsic::x86_avx512_psll_d_512:
6201 case Intrinsic::x86_avx512_psll_q_512:
6202 case Intrinsic::x86_avx512_pslli_w_512:
6203 case Intrinsic::x86_avx512_pslli_d_512:
6204 case Intrinsic::x86_avx512_pslli_q_512:
6205 case Intrinsic::x86_avx512_psrl_w_512:
6206 case Intrinsic::x86_avx512_psrl_d_512:
6207 case Intrinsic::x86_avx512_psrl_q_512:
6208 case Intrinsic::x86_avx512_psra_w_512:
6209 case Intrinsic::x86_avx512_psra_d_512:
6210 case Intrinsic::x86_avx512_psra_q_512:
6211 case Intrinsic::x86_avx512_psrli_w_512:
6212 case Intrinsic::x86_avx512_psrli_d_512:
6213 case Intrinsic::x86_avx512_psrli_q_512:
6214 case Intrinsic::x86_avx512_psrai_w_512:
6215 case Intrinsic::x86_avx512_psrai_d_512:
6216 case Intrinsic::x86_avx512_psrai_q_512:
6217 case Intrinsic::x86_avx512_psra_q_256:
6218 case Intrinsic::x86_avx512_psra_q_128:
6219 case Intrinsic::x86_avx512_psrai_q_256:
6220 case Intrinsic::x86_avx512_psrai_q_128:
6221 case Intrinsic::x86_avx2_psll_w:
6222 case Intrinsic::x86_avx2_psll_d:
6223 case Intrinsic::x86_avx2_psll_q:
6224 case Intrinsic::x86_avx2_pslli_w:
6225 case Intrinsic::x86_avx2_pslli_d:
6226 case Intrinsic::x86_avx2_pslli_q:
6227 case Intrinsic::x86_avx2_psrl_w:
6228 case Intrinsic::x86_avx2_psrl_d:
6229 case Intrinsic::x86_avx2_psrl_q:
6230 case Intrinsic::x86_avx2_psra_w:
6231 case Intrinsic::x86_avx2_psra_d:
6232 case Intrinsic::x86_avx2_psrli_w:
6233 case Intrinsic::x86_avx2_psrli_d:
6234 case Intrinsic::x86_avx2_psrli_q:
6235 case Intrinsic::x86_avx2_psrai_w:
6236 case Intrinsic::x86_avx2_psrai_d:
6237 case Intrinsic::x86_sse2_psll_w:
6238 case Intrinsic::x86_sse2_psll_d:
6239 case Intrinsic::x86_sse2_psll_q:
6240 case Intrinsic::x86_sse2_pslli_w:
6241 case Intrinsic::x86_sse2_pslli_d:
6242 case Intrinsic::x86_sse2_pslli_q:
6243 case Intrinsic::x86_sse2_psrl_w:
6244 case Intrinsic::x86_sse2_psrl_d:
6245 case Intrinsic::x86_sse2_psrl_q:
6246 case Intrinsic::x86_sse2_psra_w:
6247 case Intrinsic::x86_sse2_psra_d:
6248 case Intrinsic::x86_sse2_psrli_w:
6249 case Intrinsic::x86_sse2_psrli_d:
6250 case Intrinsic::x86_sse2_psrli_q:
6251 case Intrinsic::x86_sse2_psrai_w:
6252 case Intrinsic::x86_sse2_psrai_d:
6253 case Intrinsic::x86_mmx_psll_w:
6254 case Intrinsic::x86_mmx_psll_d:
6255 case Intrinsic::x86_mmx_psll_q:
6256 case Intrinsic::x86_mmx_pslli_w:
6257 case Intrinsic::x86_mmx_pslli_d:
6258 case Intrinsic::x86_mmx_pslli_q:
6259 case Intrinsic::x86_mmx_psrl_w:
6260 case Intrinsic::x86_mmx_psrl_d:
6261 case Intrinsic::x86_mmx_psrl_q:
6262 case Intrinsic::x86_mmx_psra_w:
6263 case Intrinsic::x86_mmx_psra_d:
6264 case Intrinsic::x86_mmx_psrli_w:
6265 case Intrinsic::x86_mmx_psrli_d:
6266 case Intrinsic::x86_mmx_psrli_q:
6267 case Intrinsic::x86_mmx_psrai_w:
6268 case Intrinsic::x86_mmx_psrai_d:
6269 handleVectorShiftIntrinsic(I, /* Variable */ false);
6270 break;
6271 case Intrinsic::x86_avx2_psllv_d:
6272 case Intrinsic::x86_avx2_psllv_d_256:
6273 case Intrinsic::x86_avx512_psllv_d_512:
6274 case Intrinsic::x86_avx2_psllv_q:
6275 case Intrinsic::x86_avx2_psllv_q_256:
6276 case Intrinsic::x86_avx512_psllv_q_512:
6277 case Intrinsic::x86_avx2_psrlv_d:
6278 case Intrinsic::x86_avx2_psrlv_d_256:
6279 case Intrinsic::x86_avx512_psrlv_d_512:
6280 case Intrinsic::x86_avx2_psrlv_q:
6281 case Intrinsic::x86_avx2_psrlv_q_256:
6282 case Intrinsic::x86_avx512_psrlv_q_512:
6283 case Intrinsic::x86_avx2_psrav_d:
6284 case Intrinsic::x86_avx2_psrav_d_256:
6285 case Intrinsic::x86_avx512_psrav_d_512:
6286 case Intrinsic::x86_avx512_psrav_q_128:
6287 case Intrinsic::x86_avx512_psrav_q_256:
6288 case Intrinsic::x86_avx512_psrav_q_512:
6289 handleVectorShiftIntrinsic(I, /* Variable */ true);
6290 break;
6291
6292 // Pack with Signed/Unsigned Saturation
6293 case Intrinsic::x86_sse2_packsswb_128:
6294 case Intrinsic::x86_sse2_packssdw_128:
6295 case Intrinsic::x86_sse2_packuswb_128:
6296 case Intrinsic::x86_sse41_packusdw:
6297 case Intrinsic::x86_avx2_packsswb:
6298 case Intrinsic::x86_avx2_packssdw:
6299 case Intrinsic::x86_avx2_packuswb:
6300 case Intrinsic::x86_avx2_packusdw:
6301 // e.g., <64 x i8> @llvm.x86.avx512.packsswb.512
6302 // (<32 x i16> %a, <32 x i16> %b)
6303 // <32 x i16> @llvm.x86.avx512.packssdw.512
6304 // (<16 x i32> %a, <16 x i32> %b)
6305 // Note: AVX512 masked variants are auto-upgraded by LLVM.
6306 case Intrinsic::x86_avx512_packsswb_512:
6307 case Intrinsic::x86_avx512_packssdw_512:
6308 case Intrinsic::x86_avx512_packuswb_512:
6309 case Intrinsic::x86_avx512_packusdw_512:
6310 handleVectorPackIntrinsic(I);
6311 break;
6312
6313 case Intrinsic::x86_sse41_pblendvb:
6314 case Intrinsic::x86_sse41_blendvpd:
6315 case Intrinsic::x86_sse41_blendvps:
6316 case Intrinsic::x86_avx_blendv_pd_256:
6317 case Intrinsic::x86_avx_blendv_ps_256:
6318 case Intrinsic::x86_avx2_pblendvb:
6319 handleBlendvIntrinsic(I);
6320 break;
6321
6322 case Intrinsic::x86_avx_dp_ps_256:
6323 case Intrinsic::x86_sse41_dppd:
6324 case Intrinsic::x86_sse41_dpps:
6325 handleDppIntrinsic(I);
6326 break;
6327
6328 case Intrinsic::x86_mmx_packsswb:
6329 case Intrinsic::x86_mmx_packuswb:
6330 handleVectorPackIntrinsic(I, 16);
6331 break;
6332
6333 case Intrinsic::x86_mmx_packssdw:
6334 handleVectorPackIntrinsic(I, 32);
6335 break;
6336
6337 case Intrinsic::x86_mmx_psad_bw:
6338 handleVectorSadIntrinsic(I, true);
6339 break;
6340 case Intrinsic::x86_sse2_psad_bw:
6341 case Intrinsic::x86_avx2_psad_bw:
6342 handleVectorSadIntrinsic(I);
6343 break;
6344
6345 // Multiply and Add Packed Words
6346 // < 4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16>, <8 x i16>)
6347 // < 8 x i32> @llvm.x86.avx2.pmadd.wd(<16 x i16>, <16 x i16>)
6348 // <16 x i32> @llvm.x86.avx512.pmaddw.d.512(<32 x i16>, <32 x i16>)
6349 //
6350 // Multiply and Add Packed Signed and Unsigned Bytes
6351 // < 8 x i16> @llvm.x86.ssse3.pmadd.ub.sw.128(<16 x i8>, <16 x i8>)
6352 // <16 x i16> @llvm.x86.avx2.pmadd.ub.sw(<32 x i8>, <32 x i8>)
6353 // <32 x i16> @llvm.x86.avx512.pmaddubs.w.512(<64 x i8>, <64 x i8>)
6354 //
6355 // These intrinsics are auto-upgraded into non-masked forms:
6356 // < 4 x i32> @llvm.x86.avx512.mask.pmaddw.d.128
6357 // (<8 x i16>, <8 x i16>, <4 x i32>, i8)
6358 // < 8 x i32> @llvm.x86.avx512.mask.pmaddw.d.256
6359 // (<16 x i16>, <16 x i16>, <8 x i32>, i8)
6360 // <16 x i32> @llvm.x86.avx512.mask.pmaddw.d.512
6361 // (<32 x i16>, <32 x i16>, <16 x i32>, i16)
6362 // < 8 x i16> @llvm.x86.avx512.mask.pmaddubs.w.128
6363 // (<16 x i8>, <16 x i8>, <8 x i16>, i8)
6364 // <16 x i16> @llvm.x86.avx512.mask.pmaddubs.w.256
6365 // (<32 x i8>, <32 x i8>, <16 x i16>, i16)
6366 // <32 x i16> @llvm.x86.avx512.mask.pmaddubs.w.512
6367 // (<64 x i8>, <64 x i8>, <32 x i16>, i32)
6368 case Intrinsic::x86_sse2_pmadd_wd:
6369 case Intrinsic::x86_avx2_pmadd_wd:
6370 case Intrinsic::x86_avx512_pmaddw_d_512:
6371 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
6372 case Intrinsic::x86_avx2_pmadd_ub_sw:
6373 case Intrinsic::x86_avx512_pmaddubs_w_512:
6374 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6375 /*ZeroPurifies=*/true,
6376 /*EltSizeInBits=*/0,
6377 /*Lanes=*/kBothLanes);
6378 break;
6379
6380 // <1 x i64> @llvm.x86.ssse3.pmadd.ub.sw(<1 x i64>, <1 x i64>)
6381 case Intrinsic::x86_ssse3_pmadd_ub_sw:
6382 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6383 /*ZeroPurifies=*/true,
6384 /*EltSizeInBits=*/8,
6385 /*Lanes=*/kBothLanes);
6386 break;
6387
6388 // <1 x i64> @llvm.x86.mmx.pmadd.wd(<1 x i64>, <1 x i64>)
6389 case Intrinsic::x86_mmx_pmadd_wd:
6390 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6391 /*ZeroPurifies=*/true,
6392 /*EltSizeInBits=*/16,
6393 /*Lanes=*/kBothLanes);
6394 break;
6395
6396 // BFloat16 multiply-add to single-precision
6397 // <4 x float> llvm.aarch64.neon.bfmlalt
6398 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6399 case Intrinsic::aarch64_neon_bfmlalt:
6400 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6401 /*ZeroPurifies=*/false,
6402 /*EltSizeInBits=*/0,
6403 /*Lanes=*/kOddLanes);
6404 break;
6405
6406 // <4 x float> llvm.aarch64.neon.bfmlalb
6407 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6408 case Intrinsic::aarch64_neon_bfmlalb:
6409 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6410 /*ZeroPurifies=*/false,
6411 /*EltSizeInBits=*/0,
6412 /*Lanes=*/kEvenLanes);
6413 break;
6414
6415 // AVX Vector Neural Network Instructions: bytes
6416 //
6417 // Multiply and Add Signed Bytes
6418 // < 4 x i32> @llvm.x86.avx2.vpdpbssd.128
6419 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6420 // < 8 x i32> @llvm.x86.avx2.vpdpbssd.256
6421 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6422 // <16 x i32> @llvm.x86.avx10.vpdpbssd.512
6423 // (<16 x i32>, <64 x i8>, <64 x i8>)
6424 //
6425 // Multiply and Add Signed Bytes With Saturation
6426 // < 4 x i32> @llvm.x86.avx2.vpdpbssds.128
6427 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6428 // < 8 x i32> @llvm.x86.avx2.vpdpbssds.256
6429 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6430 // <16 x i32> @llvm.x86.avx10.vpdpbssds.512
6431 // (<16 x i32>, <64 x i8>, <64 x i8>)
6432 //
6433 // Multiply and Add Signed and Unsigned Bytes
6434 // < 4 x i32> @llvm.x86.avx2.vpdpbsud.128
6435 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6436 // < 8 x i32> @llvm.x86.avx2.vpdpbsud.256
6437 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6438 // <16 x i32> @llvm.x86.avx10.vpdpbsud.512
6439 // (<16 x i32>, <64 x i8>, <64 x i8>)
6440 //
6441 // Multiply and Add Signed and Unsigned Bytes With Saturation
6442 // < 4 x i32> @llvm.x86.avx2.vpdpbsuds.128
6443 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6444 // < 8 x i32> @llvm.x86.avx2.vpdpbsuds.256
6445 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6446 // <16 x i32> @llvm.x86.avx512.vpdpbusds.512
6447 // (<16 x i32>, <64 x i8>, <64 x i8>)
6448 //
6449 // Multiply and Add Unsigned and Signed Bytes
6450 // < 4 x i32> @llvm.x86.avx512.vpdpbusd.128
6451 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6452 // < 8 x i32> @llvm.x86.avx512.vpdpbusd.256
6453 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6454 // <16 x i32> @llvm.x86.avx512.vpdpbusd.512
6455 // (<16 x i32>, <64 x i8>, <64 x i8>)
6456 //
6457 // Multiply and Add Unsigned and Signed Bytes With Saturation
6458 // < 4 x i32> @llvm.x86.avx512.vpdpbusds.128
6459 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6460 // < 8 x i32> @llvm.x86.avx512.vpdpbusds.256
6461 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6462 // <16 x i32> @llvm.x86.avx10.vpdpbsuds.512
6463 // (<16 x i32>, <64 x i8>, <64 x i8>)
6464 //
6465 // Multiply and Add Unsigned Bytes
6466 // < 4 x i32> @llvm.x86.avx2.vpdpbuud.128
6467 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6468 // < 8 x i32> @llvm.x86.avx2.vpdpbuud.256
6469 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6470 // <16 x i32> @llvm.x86.avx10.vpdpbuud.512
6471 // (<16 x i32>, <64 x i8>, <64 x i8>)
6472 //
6473 // Multiply and Add Unsigned Bytes With Saturation
6474 // < 4 x i32> @llvm.x86.avx2.vpdpbuuds.128
6475 // (< 4 x i32>, <16 x i8>, <16 x i8>)
6476 // < 8 x i32> @llvm.x86.avx2.vpdpbuuds.256
6477 // (< 8 x i32>, <32 x i8>, <32 x i8>)
6478 // <16 x i32> @llvm.x86.avx10.vpdpbuuds.512
6479 // (<16 x i32>, <64 x i8>, <64 x i8>)
6480 //
6481 // These intrinsics are auto-upgraded into non-masked forms:
6482 // <4 x i32> @llvm.x86.avx512.mask.vpdpbusd.128
6483 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6484 // <4 x i32> @llvm.x86.avx512.maskz.vpdpbusd.128
6485 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6486 // <8 x i32> @llvm.x86.avx512.mask.vpdpbusd.256
6487 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6488 // <8 x i32> @llvm.x86.avx512.maskz.vpdpbusd.256
6489 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6490 // <16 x i32> @llvm.x86.avx512.mask.vpdpbusd.512
6491 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6492 // <16 x i32> @llvm.x86.avx512.maskz.vpdpbusd.512
6493 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6494 //
6495 // <4 x i32> @llvm.x86.avx512.mask.vpdpbusds.128
6496 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6497 // <4 x i32> @llvm.x86.avx512.maskz.vpdpbusds.128
6498 // (<4 x i32>, <16 x i8>, <16 x i8>, i8)
6499 // <8 x i32> @llvm.x86.avx512.mask.vpdpbusds.256
6500 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6501 // <8 x i32> @llvm.x86.avx512.maskz.vpdpbusds.256
6502 // (<8 x i32>, <32 x i8>, <32 x i8>, i8)
6503 // <16 x i32> @llvm.x86.avx512.mask.vpdpbusds.512
6504 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6505 // <16 x i32> @llvm.x86.avx512.maskz.vpdpbusds.512
6506 // (<16 x i32>, <64 x i8>, <64 x i8>, i16)
6507 case Intrinsic::x86_avx512_vpdpbusd_128:
6508 case Intrinsic::x86_avx512_vpdpbusd_256:
6509 case Intrinsic::x86_avx512_vpdpbusd_512:
6510 case Intrinsic::x86_avx512_vpdpbusds_128:
6511 case Intrinsic::x86_avx512_vpdpbusds_256:
6512 case Intrinsic::x86_avx512_vpdpbusds_512:
6513 case Intrinsic::x86_avx2_vpdpbssd_128:
6514 case Intrinsic::x86_avx2_vpdpbssd_256:
6515 case Intrinsic::x86_avx10_vpdpbssd_512:
6516 case Intrinsic::x86_avx2_vpdpbssds_128:
6517 case Intrinsic::x86_avx2_vpdpbssds_256:
6518 case Intrinsic::x86_avx10_vpdpbssds_512:
6519 case Intrinsic::x86_avx2_vpdpbsud_128:
6520 case Intrinsic::x86_avx2_vpdpbsud_256:
6521 case Intrinsic::x86_avx10_vpdpbsud_512:
6522 case Intrinsic::x86_avx2_vpdpbsuds_128:
6523 case Intrinsic::x86_avx2_vpdpbsuds_256:
6524 case Intrinsic::x86_avx10_vpdpbsuds_512:
6525 case Intrinsic::x86_avx2_vpdpbuud_128:
6526 case Intrinsic::x86_avx2_vpdpbuud_256:
6527 case Intrinsic::x86_avx10_vpdpbuud_512:
6528 case Intrinsic::x86_avx2_vpdpbuuds_128:
6529 case Intrinsic::x86_avx2_vpdpbuuds_256:
6530 case Intrinsic::x86_avx10_vpdpbuuds_512:
6531 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
6532 /*ZeroPurifies=*/true,
6533 /*EltSizeInBits=*/0,
6534 /*Lanes=*/kBothLanes);
6535 break;
6536
6537 // AVX Vector Neural Network Instructions: words
6538 //
6539 // Multiply and Add Signed Word Integers
6540 // < 4 x i32> @llvm.x86.avx512.vpdpwssd.128
6541 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6542 // < 8 x i32> @llvm.x86.avx512.vpdpwssd.256
6543 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6544 // <16 x i32> @llvm.x86.avx512.vpdpwssd.512
6545 // (<16 x i32>, <32 x i16>, <32 x i16>)
6546 //
6547 // Multiply and Add Signed Word Integers With Saturation
6548 // < 4 x i32> @llvm.x86.avx512.vpdpwssds.128
6549 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6550 // < 8 x i32> @llvm.x86.avx512.vpdpwssds.256
6551 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6552 // <16 x i32> @llvm.x86.avx512.vpdpwssds.512
6553 // (<16 x i32>, <32 x i16>, <32 x i16>)
6554 //
6555 // Multiply and Add Signed and Unsigned Word Integers
6556 // < 4 x i32> @llvm.x86.avx2.vpdpwsud.128
6557 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6558 // < 8 x i32> @llvm.x86.avx2.vpdpwsud.256
6559 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6560 // <16 x i32> @llvm.x86.avx10.vpdpwsud.512
6561 // (<16 x i32>, <32 x i16>, <32 x i16>)
6562 //
6563 // Multiply and Add Signed and Unsigned Word Integers With Saturation
6564 // < 4 x i32> @llvm.x86.avx2.vpdpwsuds.128
6565 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6566 // < 8 x i32> @llvm.x86.avx2.vpdpwsuds.256
6567 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6568 // <16 x i32> @llvm.x86.avx10.vpdpwsuds.512
6569 // (<16 x i32>, <32 x i16>, <32 x i16>)
6570 //
6571 // Multiply and Add Unsigned and Signed Word Integers
6572 // < 4 x i32> @llvm.x86.avx2.vpdpwusd.128
6573 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6574 // < 8 x i32> @llvm.x86.avx2.vpdpwusd.256
6575 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6576 // <16 x i32> @llvm.x86.avx10.vpdpwusd.512
6577 // (<16 x i32>, <32 x i16>, <32 x i16>)
6578 //
6579 // Multiply and Add Unsigned and Signed Word Integers With Saturation
6580 // < 4 x i32> @llvm.x86.avx2.vpdpwusds.128
6581 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6582 // < 8 x i32> @llvm.x86.avx2.vpdpwusds.256
6583 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6584 // <16 x i32> @llvm.x86.avx10.vpdpwusds.512
6585 // (<16 x i32>, <32 x i16>, <32 x i16>)
6586 //
6587 // Multiply and Add Unsigned and Unsigned Word Integers
6588 // < 4 x i32> @llvm.x86.avx2.vpdpwuud.128
6589 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6590 // < 8 x i32> @llvm.x86.avx2.vpdpwuud.256
6591 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6592 // <16 x i32> @llvm.x86.avx10.vpdpwuud.512
6593 // (<16 x i32>, <32 x i16>, <32 x i16>)
6594 //
6595 // Multiply and Add Unsigned and Unsigned Word Integers With Saturation
6596 // < 4 x i32> @llvm.x86.avx2.vpdpwuuds.128
6597 // (< 4 x i32>, < 8 x i16>, < 8 x i16>)
6598 // < 8 x i32> @llvm.x86.avx2.vpdpwuuds.256
6599 // (< 8 x i32>, <16 x i16>, <16 x i16>)
6600 // <16 x i32> @llvm.x86.avx10.vpdpwuuds.512
6601 // (<16 x i32>, <32 x i16>, <32 x i16>)
6602 //
6603 // These intrinsics are auto-upgraded into non-masked forms:
6604 // <4 x i32> @llvm.x86.avx512.mask.vpdpwssd.128
6605 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6606 // <4 x i32> @llvm.x86.avx512.maskz.vpdpwssd.128
6607 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6608 // <8 x i32> @llvm.x86.avx512.mask.vpdpwssd.256
6609 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6610 // <8 x i32> @llvm.x86.avx512.maskz.vpdpwssd.256
6611 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6612 // <16 x i32> @llvm.x86.avx512.mask.vpdpwssd.512
6613 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6614 // <16 x i32> @llvm.x86.avx512.maskz.vpdpwssd.512
6615 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6616 //
6617 // <4 x i32> @llvm.x86.avx512.mask.vpdpwssds.128
6618 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6619 // <4 x i32> @llvm.x86.avx512.maskz.vpdpwssds.128
6620 // (<4 x i32>, <8 x i16>, <8 x i16>, i8)
6621 // <8 x i32> @llvm.x86.avx512.mask.vpdpwssds.256
6622 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6623 // <8 x i32> @llvm.x86.avx512.maskz.vpdpwssds.256
6624 // (<8 x i32>, <16 x i16>, <16 x i16>, i8)
6625 // <16 x i32> @llvm.x86.avx512.mask.vpdpwssds.512
6626 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6627 // <16 x i32> @llvm.x86.avx512.maskz.vpdpwssds.512
6628 // (<16 x i32>, <32 x i16>, <32 x i16>, i16)
6629 case Intrinsic::x86_avx512_vpdpwssd_128:
6630 case Intrinsic::x86_avx512_vpdpwssd_256:
6631 case Intrinsic::x86_avx512_vpdpwssd_512:
6632 case Intrinsic::x86_avx512_vpdpwssds_128:
6633 case Intrinsic::x86_avx512_vpdpwssds_256:
6634 case Intrinsic::x86_avx512_vpdpwssds_512:
6635 case Intrinsic::x86_avx2_vpdpwsud_128:
6636 case Intrinsic::x86_avx2_vpdpwsud_256:
6637 case Intrinsic::x86_avx10_vpdpwsud_512:
6638 case Intrinsic::x86_avx2_vpdpwsuds_128:
6639 case Intrinsic::x86_avx2_vpdpwsuds_256:
6640 case Intrinsic::x86_avx10_vpdpwsuds_512:
6641 case Intrinsic::x86_avx2_vpdpwusd_128:
6642 case Intrinsic::x86_avx2_vpdpwusd_256:
6643 case Intrinsic::x86_avx10_vpdpwusd_512:
6644 case Intrinsic::x86_avx2_vpdpwusds_128:
6645 case Intrinsic::x86_avx2_vpdpwusds_256:
6646 case Intrinsic::x86_avx10_vpdpwusds_512:
6647 case Intrinsic::x86_avx2_vpdpwuud_128:
6648 case Intrinsic::x86_avx2_vpdpwuud_256:
6649 case Intrinsic::x86_avx10_vpdpwuud_512:
6650 case Intrinsic::x86_avx2_vpdpwuuds_128:
6651 case Intrinsic::x86_avx2_vpdpwuuds_256:
6652 case Intrinsic::x86_avx10_vpdpwuuds_512:
6653 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6654 /*ZeroPurifies=*/true,
6655 /*EltSizeInBits=*/0,
6656 /*Lanes=*/kBothLanes);
6657 break;
6658
6659 // Dot Product of BF16 Pairs Accumulated Into Packed Single
6660 // Precision
6661 // <4 x float> @llvm.x86.avx512bf16.dpbf16ps.128
6662 // (<4 x float>, <8 x bfloat>, <8 x bfloat>)
6663 // <8 x float> @llvm.x86.avx512bf16.dpbf16ps.256
6664 // (<8 x float>, <16 x bfloat>, <16 x bfloat>)
6665 // <16 x float> @llvm.x86.avx512bf16.dpbf16ps.512
6666 // (<16 x float>, <32 x bfloat>, <32 x bfloat>)
6667 case Intrinsic::x86_avx512bf16_dpbf16ps_128:
6668 case Intrinsic::x86_avx512bf16_dpbf16ps_256:
6669 case Intrinsic::x86_avx512bf16_dpbf16ps_512:
6670 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
6671 /*ZeroPurifies=*/false,
6672 /*EltSizeInBits=*/0,
6673 /*Lanes=*/kBothLanes);
6674 break;
6675
6676 case Intrinsic::x86_sse_cmp_ss:
6677 case Intrinsic::x86_sse2_cmp_sd:
6678 case Intrinsic::x86_sse_comieq_ss:
6679 case Intrinsic::x86_sse_comilt_ss:
6680 case Intrinsic::x86_sse_comile_ss:
6681 case Intrinsic::x86_sse_comigt_ss:
6682 case Intrinsic::x86_sse_comige_ss:
6683 case Intrinsic::x86_sse_comineq_ss:
6684 case Intrinsic::x86_sse_ucomieq_ss:
6685 case Intrinsic::x86_sse_ucomilt_ss:
6686 case Intrinsic::x86_sse_ucomile_ss:
6687 case Intrinsic::x86_sse_ucomigt_ss:
6688 case Intrinsic::x86_sse_ucomige_ss:
6689 case Intrinsic::x86_sse_ucomineq_ss:
6690 case Intrinsic::x86_sse2_comieq_sd:
6691 case Intrinsic::x86_sse2_comilt_sd:
6692 case Intrinsic::x86_sse2_comile_sd:
6693 case Intrinsic::x86_sse2_comigt_sd:
6694 case Intrinsic::x86_sse2_comige_sd:
6695 case Intrinsic::x86_sse2_comineq_sd:
6696 case Intrinsic::x86_sse2_ucomieq_sd:
6697 case Intrinsic::x86_sse2_ucomilt_sd:
6698 case Intrinsic::x86_sse2_ucomile_sd:
6699 case Intrinsic::x86_sse2_ucomigt_sd:
6700 case Intrinsic::x86_sse2_ucomige_sd:
6701 case Intrinsic::x86_sse2_ucomineq_sd:
6702 handleVectorCompareScalarIntrinsic(I);
6703 break;
6704
6705 case Intrinsic::x86_avx_cmp_pd_256:
6706 case Intrinsic::x86_avx_cmp_ps_256:
6707 case Intrinsic::x86_sse2_cmp_pd:
6708 case Intrinsic::x86_sse_cmp_ps:
6709 handleVectorComparePackedIntrinsic(I, /*PredicateAsOperand=*/true);
6710 break;
6711
6712 case Intrinsic::x86_bmi_bextr_32:
6713 case Intrinsic::x86_bmi_bextr_64:
6714 case Intrinsic::x86_bmi_bzhi_32:
6715 case Intrinsic::x86_bmi_bzhi_64:
6716 handleGenericBitManipulation(I);
6717 break;
6718
6719 case Intrinsic::x86_pclmulqdq:
6720 case Intrinsic::x86_pclmulqdq_256:
6721 case Intrinsic::x86_pclmulqdq_512:
6722 handlePclmulIntrinsic(I);
6723 break;
6724
6725 case Intrinsic::x86_avx_round_pd_256:
6726 case Intrinsic::x86_avx_round_ps_256:
6727 case Intrinsic::x86_sse41_round_pd:
6728 case Intrinsic::x86_sse41_round_ps:
6729 handleRoundPdPsIntrinsic(I);
6730 break;
6731
6732 case Intrinsic::x86_sse41_round_sd:
6733 case Intrinsic::x86_sse41_round_ss:
6734 handleUnarySdSsIntrinsic(I);
6735 break;
6736
6737 case Intrinsic::x86_sse2_max_sd:
6738 case Intrinsic::x86_sse_max_ss:
6739 case Intrinsic::x86_sse2_min_sd:
6740 case Intrinsic::x86_sse_min_ss:
6741 handleBinarySdSsIntrinsic(I);
6742 break;
6743
6744 case Intrinsic::x86_avx_vtestc_pd:
6745 case Intrinsic::x86_avx_vtestc_pd_256:
6746 case Intrinsic::x86_avx_vtestc_ps:
6747 case Intrinsic::x86_avx_vtestc_ps_256:
6748 case Intrinsic::x86_avx_vtestnzc_pd:
6749 case Intrinsic::x86_avx_vtestnzc_pd_256:
6750 case Intrinsic::x86_avx_vtestnzc_ps:
6751 case Intrinsic::x86_avx_vtestnzc_ps_256:
6752 case Intrinsic::x86_avx_vtestz_pd:
6753 case Intrinsic::x86_avx_vtestz_pd_256:
6754 case Intrinsic::x86_avx_vtestz_ps:
6755 case Intrinsic::x86_avx_vtestz_ps_256:
6756 case Intrinsic::x86_avx_ptestc_256:
6757 case Intrinsic::x86_avx_ptestnzc_256:
6758 case Intrinsic::x86_avx_ptestz_256:
6759 case Intrinsic::x86_sse41_ptestc:
6760 case Intrinsic::x86_sse41_ptestnzc:
6761 case Intrinsic::x86_sse41_ptestz:
6762 handleVtestIntrinsic(I);
6763 break;
6764
6765 // Packed Horizontal Add/Subtract
6766 case Intrinsic::x86_ssse3_phadd_w:
6767 case Intrinsic::x86_ssse3_phadd_w_128:
6768 case Intrinsic::x86_ssse3_phsub_w:
6769 case Intrinsic::x86_ssse3_phsub_w_128:
6770 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6771 /*ReinterpretElemWidth=*/16);
6772 break;
6773
6774 case Intrinsic::x86_avx2_phadd_w:
6775 case Intrinsic::x86_avx2_phsub_w:
6776 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6777 /*ReinterpretElemWidth=*/16);
6778 break;
6779
6780 // Packed Horizontal Add/Subtract
6781 case Intrinsic::x86_ssse3_phadd_d:
6782 case Intrinsic::x86_ssse3_phadd_d_128:
6783 case Intrinsic::x86_ssse3_phsub_d:
6784 case Intrinsic::x86_ssse3_phsub_d_128:
6785 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6786 /*ReinterpretElemWidth=*/32);
6787 break;
6788
6789 case Intrinsic::x86_avx2_phadd_d:
6790 case Intrinsic::x86_avx2_phsub_d:
6791 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6792 /*ReinterpretElemWidth=*/32);
6793 break;
6794
6795 // Packed Horizontal Add/Subtract and Saturate
6796 case Intrinsic::x86_ssse3_phadd_sw:
6797 case Intrinsic::x86_ssse3_phadd_sw_128:
6798 case Intrinsic::x86_ssse3_phsub_sw:
6799 case Intrinsic::x86_ssse3_phsub_sw_128:
6800 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1,
6801 /*ReinterpretElemWidth=*/16);
6802 break;
6803
6804 case Intrinsic::x86_avx2_phadd_sw:
6805 case Intrinsic::x86_avx2_phsub_sw:
6806 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2,
6807 /*ReinterpretElemWidth=*/16);
6808 break;
6809
6810 // Packed Single/Double Precision Floating-Point Horizontal Add
6811 case Intrinsic::x86_sse3_hadd_ps:
6812 case Intrinsic::x86_sse3_hadd_pd:
6813 case Intrinsic::x86_sse3_hsub_ps:
6814 case Intrinsic::x86_sse3_hsub_pd:
6815 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1);
6816 break;
6817
6818 case Intrinsic::x86_avx_hadd_pd_256:
6819 case Intrinsic::x86_avx_hadd_ps_256:
6820 case Intrinsic::x86_avx_hsub_pd_256:
6821 case Intrinsic::x86_avx_hsub_ps_256:
6822 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/2);
6823 break;
6824
6825 case Intrinsic::x86_avx_maskstore_ps:
6826 case Intrinsic::x86_avx_maskstore_pd:
6827 case Intrinsic::x86_avx_maskstore_ps_256:
6828 case Intrinsic::x86_avx_maskstore_pd_256:
6829 case Intrinsic::x86_avx2_maskstore_d:
6830 case Intrinsic::x86_avx2_maskstore_q:
6831 case Intrinsic::x86_avx2_maskstore_d_256:
6832 case Intrinsic::x86_avx2_maskstore_q_256: {
6833 handleAVXMaskedStore(I);
6834 break;
6835 }
6836
6837 case Intrinsic::x86_avx_maskload_ps:
6838 case Intrinsic::x86_avx_maskload_pd:
6839 case Intrinsic::x86_avx_maskload_ps_256:
6840 case Intrinsic::x86_avx_maskload_pd_256:
6841 case Intrinsic::x86_avx2_maskload_d:
6842 case Intrinsic::x86_avx2_maskload_q:
6843 case Intrinsic::x86_avx2_maskload_d_256:
6844 case Intrinsic::x86_avx2_maskload_q_256: {
6845 handleAVXMaskedLoad(I);
6846 break;
6847 }
6848
6849 // Packed
6850 case Intrinsic::x86_avx512fp16_add_ph_512:
6851 case Intrinsic::x86_avx512fp16_sub_ph_512:
6852 case Intrinsic::x86_avx512fp16_mul_ph_512:
6853 case Intrinsic::x86_avx512fp16_div_ph_512:
6854 case Intrinsic::x86_avx512fp16_max_ph_512:
6855 case Intrinsic::x86_avx512fp16_min_ph_512:
6856 case Intrinsic::x86_avx512_min_ps_512:
6857 case Intrinsic::x86_avx512_min_pd_512:
6858 case Intrinsic::x86_avx512_max_ps_512:
6859 case Intrinsic::x86_avx512_max_pd_512: {
6860 // These AVX512 variants contain the rounding mode as a trailing flag.
6861 // Earlier variants do not have a trailing flag and are already handled
6862 // by maybeHandleSimpleNomemIntrinsic(I, 0) via
6863 // maybeHandleUnknownIntrinsic.
6864 [[maybe_unused]] bool Success =
6865 maybeHandleSimpleNomemIntrinsic(I, /*trailingFlags=*/1);
6866 assert(Success);
6867 break;
6868 }
6869
6870 case Intrinsic::x86_avx_vpermilvar_pd:
6871 case Intrinsic::x86_avx_vpermilvar_pd_256:
6872 case Intrinsic::x86_avx512_vpermilvar_pd_512:
6873 case Intrinsic::x86_avx_vpermilvar_ps:
6874 case Intrinsic::x86_avx_vpermilvar_ps_256:
6875 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
6876 handleAVXVpermilvar(I);
6877 break;
6878 }
6879
6880 case Intrinsic::x86_avx512_vpermi2var_d_128:
6881 case Intrinsic::x86_avx512_vpermi2var_d_256:
6882 case Intrinsic::x86_avx512_vpermi2var_d_512:
6883 case Intrinsic::x86_avx512_vpermi2var_hi_128:
6884 case Intrinsic::x86_avx512_vpermi2var_hi_256:
6885 case Intrinsic::x86_avx512_vpermi2var_hi_512:
6886 case Intrinsic::x86_avx512_vpermi2var_pd_128:
6887 case Intrinsic::x86_avx512_vpermi2var_pd_256:
6888 case Intrinsic::x86_avx512_vpermi2var_pd_512:
6889 case Intrinsic::x86_avx512_vpermi2var_ps_128:
6890 case Intrinsic::x86_avx512_vpermi2var_ps_256:
6891 case Intrinsic::x86_avx512_vpermi2var_ps_512:
6892 case Intrinsic::x86_avx512_vpermi2var_q_128:
6893 case Intrinsic::x86_avx512_vpermi2var_q_256:
6894 case Intrinsic::x86_avx512_vpermi2var_q_512:
6895 case Intrinsic::x86_avx512_vpermi2var_qi_128:
6896 case Intrinsic::x86_avx512_vpermi2var_qi_256:
6897 case Intrinsic::x86_avx512_vpermi2var_qi_512:
6898 handleAVXVpermi2var(I);
6899 break;
6900
6901 // Packed Shuffle
6902 // llvm.x86.sse.pshuf.w(<1 x i64>, i8)
6903 // llvm.x86.ssse3.pshuf.b(<1 x i64>, <1 x i64>)
6904 // llvm.x86.ssse3.pshuf.b.128(<16 x i8>, <16 x i8>)
6905 // llvm.x86.avx2.pshuf.b(<32 x i8>, <32 x i8>)
6906 // llvm.x86.avx512.pshuf.b.512(<64 x i8>, <64 x i8>)
6907 //
6908 // The following intrinsics are auto-upgraded:
6909 // llvm.x86.sse2.pshuf.d(<4 x i32>, i8)
6910 // llvm.x86.sse2.gpshufh.w(<8 x i16>, i8)
6911 // llvm.x86.sse2.pshufl.w(<8 x i16>, i8)
6912 case Intrinsic::x86_avx2_pshuf_b:
6913 case Intrinsic::x86_sse_pshuf_w:
6914 case Intrinsic::x86_ssse3_pshuf_b_128:
6915 case Intrinsic::x86_ssse3_pshuf_b:
6916 case Intrinsic::x86_avx512_pshuf_b_512:
6917 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
6918 /*trailingVerbatimArgs=*/1,
6919 /*forceIntegerIntrinsic=*/false);
6920 break;
6921
6922 // AVX512 PMOV: Packed MOV, with truncation
6923 // Precisely handled by applying the same intrinsic to the shadow
6924 case Intrinsic::x86_avx512_mask_pmov_dw_128:
6925 case Intrinsic::x86_avx512_mask_pmov_db_128:
6926 case Intrinsic::x86_avx512_mask_pmov_qb_128:
6927 case Intrinsic::x86_avx512_mask_pmov_qw_128:
6928 case Intrinsic::x86_avx512_mask_pmov_qd_128:
6929 case Intrinsic::x86_avx512_mask_pmov_wb_128:
6930 case Intrinsic::x86_avx512_mask_pmov_dw_256:
6931 case Intrinsic::x86_avx512_mask_pmov_db_256:
6932 case Intrinsic::x86_avx512_mask_pmov_qb_256:
6933 case Intrinsic::x86_avx512_mask_pmov_qw_256:
6934 case Intrinsic::x86_avx512_mask_pmov_dw_512:
6935 case Intrinsic::x86_avx512_mask_pmov_db_512:
6936 case Intrinsic::x86_avx512_mask_pmov_qb_512:
6937 case Intrinsic::x86_avx512_mask_pmov_qw_512: {
6938 // Intrinsic::x86_avx512_mask_pmov_{qd,wb}_{256,512} were removed in
6939 // f608dc1f5775ee880e8ea30e2d06ab5a4a935c22
6940 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
6941 /*trailingVerbatimArgs=*/1,
6942 /*forceIntegerIntrinsic=*/false);
6943 break;
6944 }
6945
6946 // AVX512 PMOV{S,US}: Packed MOV, with signed/unsigned saturation
6947 // Approximately handled using the corresponding truncation intrinsic
6948 // TODO: improve handleAVX512VectorDownConvert to precisely model saturation
6949 case Intrinsic::x86_avx512_mask_pmovs_dw_512:
6950 case Intrinsic::x86_avx512_mask_pmovus_dw_512: {
6951 handleIntrinsicByApplyingToShadow(
6952 I, Intrinsic::x86_avx512_mask_pmov_dw_512,
6953 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6954 break;
6955 }
6956
6957 case Intrinsic::x86_avx512_mask_pmovs_dw_256:
6958 case Intrinsic::x86_avx512_mask_pmovus_dw_256:
6959 handleIntrinsicByApplyingToShadow(
6960 I, Intrinsic::x86_avx512_mask_pmov_dw_256,
6961 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6962 break;
6963
6964 case Intrinsic::x86_avx512_mask_pmovs_dw_128:
6965 case Intrinsic::x86_avx512_mask_pmovus_dw_128:
6966 handleIntrinsicByApplyingToShadow(
6967 I, Intrinsic::x86_avx512_mask_pmov_dw_128,
6968 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6969 break;
6970
6971 case Intrinsic::x86_avx512_mask_pmovs_db_512:
6972 case Intrinsic::x86_avx512_mask_pmovus_db_512: {
6973 handleIntrinsicByApplyingToShadow(
6974 I, Intrinsic::x86_avx512_mask_pmov_db_512,
6975 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6976 break;
6977 }
6978
6979 case Intrinsic::x86_avx512_mask_pmovs_db_256:
6980 case Intrinsic::x86_avx512_mask_pmovus_db_256:
6981 handleIntrinsicByApplyingToShadow(
6982 I, Intrinsic::x86_avx512_mask_pmov_db_256,
6983 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6984 break;
6985
6986 case Intrinsic::x86_avx512_mask_pmovs_db_128:
6987 case Intrinsic::x86_avx512_mask_pmovus_db_128:
6988 handleIntrinsicByApplyingToShadow(
6989 I, Intrinsic::x86_avx512_mask_pmov_db_128,
6990 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6991 break;
6992
6993 case Intrinsic::x86_avx512_mask_pmovs_qb_512:
6994 case Intrinsic::x86_avx512_mask_pmovus_qb_512: {
6995 handleIntrinsicByApplyingToShadow(
6996 I, Intrinsic::x86_avx512_mask_pmov_qb_512,
6997 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
6998 break;
6999 }
7000
7001 case Intrinsic::x86_avx512_mask_pmovs_qb_256:
7002 case Intrinsic::x86_avx512_mask_pmovus_qb_256:
7003 handleIntrinsicByApplyingToShadow(
7004 I, Intrinsic::x86_avx512_mask_pmov_qb_256,
7005 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7006 break;
7007
7008 case Intrinsic::x86_avx512_mask_pmovs_qb_128:
7009 case Intrinsic::x86_avx512_mask_pmovus_qb_128:
7010 handleIntrinsicByApplyingToShadow(
7011 I, Intrinsic::x86_avx512_mask_pmov_qb_128,
7012 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7013 break;
7014
7015 case Intrinsic::x86_avx512_mask_pmovs_qw_512:
7016 case Intrinsic::x86_avx512_mask_pmovus_qw_512: {
7017 handleIntrinsicByApplyingToShadow(
7018 I, Intrinsic::x86_avx512_mask_pmov_qw_512,
7019 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7020 break;
7021 }
7022
7023 case Intrinsic::x86_avx512_mask_pmovs_qw_256:
7024 case Intrinsic::x86_avx512_mask_pmovus_qw_256:
7025 handleIntrinsicByApplyingToShadow(
7026 I, Intrinsic::x86_avx512_mask_pmov_qw_256,
7027 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7028 break;
7029
7030 case Intrinsic::x86_avx512_mask_pmovs_qw_128:
7031 case Intrinsic::x86_avx512_mask_pmovus_qw_128:
7032 handleIntrinsicByApplyingToShadow(
7033 I, Intrinsic::x86_avx512_mask_pmov_qw_128,
7034 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7035 break;
7036
7037 case Intrinsic::x86_avx512_mask_pmovs_qd_128:
7038 case Intrinsic::x86_avx512_mask_pmovus_qd_128:
7039 handleIntrinsicByApplyingToShadow(
7040 I, Intrinsic::x86_avx512_mask_pmov_qd_128,
7041 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7042 break;
7043
7044 case Intrinsic::x86_avx512_mask_pmovs_wb_128:
7045 case Intrinsic::x86_avx512_mask_pmovus_wb_128:
7046 handleIntrinsicByApplyingToShadow(
7047 I, Intrinsic::x86_avx512_mask_pmov_wb_128,
7048 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7049 break;
7050
7051 case Intrinsic::x86_avx512_mask_pmovs_qd_256:
7052 case Intrinsic::x86_avx512_mask_pmovus_qd_256:
7053 case Intrinsic::x86_avx512_mask_pmovs_wb_256:
7054 case Intrinsic::x86_avx512_mask_pmovus_wb_256:
7055 case Intrinsic::x86_avx512_mask_pmovs_qd_512:
7056 case Intrinsic::x86_avx512_mask_pmovus_qd_512:
7057 case Intrinsic::x86_avx512_mask_pmovs_wb_512:
7058 case Intrinsic::x86_avx512_mask_pmovus_wb_512: {
7059 // Since Intrinsic::x86_avx512_mask_pmov_{qd,wb}_{256,512} do not exist,
7060 // we cannot use handleIntrinsicByApplyingToShadow. Instead, we call the
7061 // slow-path handler.
7062 handleAVX512VectorDownConvert(I);
7063 break;
7064 }
7065
7066 // e.g.,
7067 // <16 x float> @llvm.x86.avx512.mask.compress
7068 // (<16 x float> %data, <16 x float> %passthru,
7069 // <16 x i1> %mask)
7070 // <16 x i32> @llvm.x86.avx512.mask.compress
7071 // (<16 x i32> %data, <16 x i32> %passthru,
7072 // <16 x i1> %mask)
7073 case Intrinsic::x86_avx512_mask_compress:
7074 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
7075 /*trailingVerbatimArgs=*/1,
7076 /*forceIntegerIntrinsic=*/true);
7077 break;
7078
7079 // AVX512/AVX10 Reciprocal
7080 // <16 x float> @llvm.x86.avx512.rsqrt14.ps.512
7081 // (<16 x float>, <16 x float>, i16)
7082 // <8 x float> @llvm.x86.avx512.rsqrt14.ps.256
7083 // (<8 x float>, <8 x float>, i8)
7084 // <4 x float> @llvm.x86.avx512.rsqrt14.ps.128
7085 // (<4 x float>, <4 x float>, i8)
7086 //
7087 // <8 x double> @llvm.x86.avx512.rsqrt14.pd.512
7088 // (<8 x double>, <8 x double>, i8)
7089 // <4 x double> @llvm.x86.avx512.rsqrt14.pd.256
7090 // (<4 x double>, <4 x double>, i8)
7091 // <2 x double> @llvm.x86.avx512.rsqrt14.pd.128
7092 // (<2 x double>, <2 x double>, i8)
7093 //
7094 // <32 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.512
7095 // (<32 x bfloat>, <32 x bfloat>, i32)
7096 // <16 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.256
7097 // (<16 x bfloat>, <16 x bfloat>, i16)
7098 // <8 x bfloat> @llvm.x86.avx10.mask.rsqrt.bf16.128
7099 // (<8 x bfloat>, <8 x bfloat>, i8)
7100 //
7101 // <32 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.512
7102 // (<32 x half>, <32 x half>, i32)
7103 // <16 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.256
7104 // (<16 x half>, <16 x half>, i16)
7105 // <8 x half> @llvm.x86.avx512fp16.mask.rsqrt.ph.128
7106 // (<8 x half>, <8 x half>, i8)
7107 //
7108 // TODO: 3-operand variants are not handled:
7109 // <2 x double> @llvm.x86.avx512.rsqrt14.sd
7110 // (<2 x double>, <2 x double>, <2 x double>, i8)
7111 // <4 x float> @llvm.x86.avx512.rsqrt14.ss
7112 // (<4 x float>, <4 x float>, <4 x float>, i8)
7113 // <8 x half> @llvm.x86.avx512fp16.mask.rsqrt.sh
7114 // (<8 x half>, <8 x half>, <8 x half>, i8)
7115 case Intrinsic::x86_avx512_rsqrt14_ps_512:
7116 case Intrinsic::x86_avx512_rsqrt14_ps_256:
7117 case Intrinsic::x86_avx512_rsqrt14_ps_128:
7118 case Intrinsic::x86_avx512_rsqrt14_pd_512:
7119 case Intrinsic::x86_avx512_rsqrt14_pd_256:
7120 case Intrinsic::x86_avx512_rsqrt14_pd_128:
7121 case Intrinsic::x86_avx10_mask_rsqrt_bf16_512:
7122 case Intrinsic::x86_avx10_mask_rsqrt_bf16_256:
7123 case Intrinsic::x86_avx10_mask_rsqrt_bf16_128:
7124 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_512:
7125 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_256:
7126 case Intrinsic::x86_avx512fp16_mask_rsqrt_ph_128:
7127 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7128 /*WriteThruIndex=*/1,
7129 /*MaskIndex=*/2);
7130 break;
7131
7132 // AVX512/AVX10 Reciprocal Square Root
7133 // <16 x float> @llvm.x86.avx512.rcp14.ps.512
7134 // (<16 x float>, <16 x float>, i16)
7135 // <8 x float> @llvm.x86.avx512.rcp14.ps.256
7136 // (<8 x float>, <8 x float>, i8)
7137 // <4 x float> @llvm.x86.avx512.rcp14.ps.128
7138 // (<4 x float>, <4 x float>, i8)
7139 //
7140 // <8 x double> @llvm.x86.avx512.rcp14.pd.512
7141 // (<8 x double>, <8 x double>, i8)
7142 // <4 x double> @llvm.x86.avx512.rcp14.pd.256
7143 // (<4 x double>, <4 x double>, i8)
7144 // <2 x double> @llvm.x86.avx512.rcp14.pd.128
7145 // (<2 x double>, <2 x double>, i8)
7146 //
7147 // <32 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.512
7148 // (<32 x bfloat>, <32 x bfloat>, i32)
7149 // <16 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.256
7150 // (<16 x bfloat>, <16 x bfloat>, i16)
7151 // <8 x bfloat> @llvm.x86.avx10.mask.rcp.bf16.128
7152 // (<8 x bfloat>, <8 x bfloat>, i8)
7153 //
7154 // <32 x half> @llvm.x86.avx512fp16.mask.rcp.ph.512
7155 // (<32 x half>, <32 x half>, i32)
7156 // <16 x half> @llvm.x86.avx512fp16.mask.rcp.ph.256
7157 // (<16 x half>, <16 x half>, i16)
7158 // <8 x half> @llvm.x86.avx512fp16.mask.rcp.ph.128
7159 // (<8 x half>, <8 x half>, i8)
7160 //
7161 // TODO: 3-operand variants are not handled:
7162 // <2 x double> @llvm.x86.avx512.rcp14.sd
7163 // (<2 x double>, <2 x double>, <2 x double>, i8)
7164 // <4 x float> @llvm.x86.avx512.rcp14.ss
7165 // (<4 x float>, <4 x float>, <4 x float>, i8)
7166 // <8 x half> @llvm.x86.avx512fp16.mask.rcp.sh
7167 // (<8 x half>, <8 x half>, <8 x half>, i8)
7168 case Intrinsic::x86_avx512_rcp14_ps_512:
7169 case Intrinsic::x86_avx512_rcp14_ps_256:
7170 case Intrinsic::x86_avx512_rcp14_ps_128:
7171 case Intrinsic::x86_avx512_rcp14_pd_512:
7172 case Intrinsic::x86_avx512_rcp14_pd_256:
7173 case Intrinsic::x86_avx512_rcp14_pd_128:
7174 case Intrinsic::x86_avx10_mask_rcp_bf16_512:
7175 case Intrinsic::x86_avx10_mask_rcp_bf16_256:
7176 case Intrinsic::x86_avx10_mask_rcp_bf16_128:
7177 case Intrinsic::x86_avx512fp16_mask_rcp_ph_512:
7178 case Intrinsic::x86_avx512fp16_mask_rcp_ph_256:
7179 case Intrinsic::x86_avx512fp16_mask_rcp_ph_128:
7180 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7181 /*WriteThruIndex=*/1,
7182 /*MaskIndex=*/2);
7183 break;
7184
7185 // <32 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.512
7186 // (<32 x half>, i32, <32 x half>, i32, i32)
7187 // <16 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.256
7188 // (<16 x half>, i32, <16 x half>, i32, i16)
7189 // <8 x half> @llvm.x86.avx512fp16.mask.rndscale.ph.128
7190 // (<8 x half>, i32, <8 x half>, i32, i8)
7191 //
7192 // <16 x float> @llvm.x86.avx512.mask.rndscale.ps.512
7193 // (<16 x float>, i32, <16 x float>, i16, i32)
7194 // <8 x float> @llvm.x86.avx512.mask.rndscale.ps.256
7195 // (<8 x float>, i32, <8 x float>, i8)
7196 // <4 x float> @llvm.x86.avx512.mask.rndscale.ps.128
7197 // (<4 x float>, i32, <4 x float>, i8)
7198 //
7199 // <8 x double> @llvm.x86.avx512.mask.rndscale.pd.512
7200 // (<8 x double>, i32, <8 x double>, i8, i32)
7201 // A Imm WriteThru Mask Rounding
7202 // <4 x double> @llvm.x86.avx512.mask.rndscale.pd.256
7203 // (<4 x double>, i32, <4 x double>, i8)
7204 // <2 x double> @llvm.x86.avx512.mask.rndscale.pd.128
7205 // (<2 x double>, i32, <2 x double>, i8)
7206 // A Imm WriteThru Mask
7207 //
7208 // <32 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.512
7209 // (<32 x bfloat>, i32, <32 x bfloat>, i32)
7210 // <16 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.256
7211 // (<16 x bfloat>, i32, <16 x bfloat>, i16)
7212 // <8 x bfloat> @llvm.x86.avx10.mask.rndscale.bf16.128
7213 // (<8 x bfloat>, i32, <8 x bfloat>, i8)
7214 //
7215 // Not supported: three vectors
7216 // - <8 x half> @llvm.x86.avx512fp16.mask.rndscale.sh
7217 // (<8 x half>, <8 x half>,<8 x half>, i8, i32, i32)
7218 // - <4 x float> @llvm.x86.avx512.mask.rndscale.ss
7219 // (<4 x float>, <4 x float>, <4 x float>, i8, i32, i32)
7220 // - <2 x double> @llvm.x86.avx512.mask.rndscale.sd
7221 // (<2 x double>, <2 x double>, <2 x double>, i8, i32,
7222 // i32)
7223 // A B WriteThru Mask Imm
7224 // Rounding
7225 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_512:
7226 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_256:
7227 case Intrinsic::x86_avx512fp16_mask_rndscale_ph_128:
7228 case Intrinsic::x86_avx512_mask_rndscale_ps_512:
7229 case Intrinsic::x86_avx512_mask_rndscale_ps_256:
7230 case Intrinsic::x86_avx512_mask_rndscale_ps_128:
7231 case Intrinsic::x86_avx512_mask_rndscale_pd_512:
7232 case Intrinsic::x86_avx512_mask_rndscale_pd_256:
7233 case Intrinsic::x86_avx512_mask_rndscale_pd_128:
7234 case Intrinsic::x86_avx10_mask_rndscale_bf16_512:
7235 case Intrinsic::x86_avx10_mask_rndscale_bf16_256:
7236 case Intrinsic::x86_avx10_mask_rndscale_bf16_128:
7237 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0},
7238 /*WriteThruIndex=*/2,
7239 /*MaskIndex=*/3);
7240 break;
7241
7242 // AVX512 Vector Scale Float* Packed
7243 //
7244 // < 8 x double> @llvm.x86.avx512.mask.scalef.pd.512
7245 // (<8 x double>, <8 x double>, <8 x double>, i8, i32)
7246 // A B WriteThru Msk Round
7247 // < 4 x double> @llvm.x86.avx512.mask.scalef.pd.256
7248 // (<4 x double>, <4 x double>, <4 x double>, i8)
7249 // < 2 x double> @llvm.x86.avx512.mask.scalef.pd.128
7250 // (<2 x double>, <2 x double>, <2 x double>, i8)
7251 //
7252 // <16 x float> @llvm.x86.avx512.mask.scalef.ps.512
7253 // (<16 x float>, <16 x float>, <16 x float>, i16, i32)
7254 // < 8 x float> @llvm.x86.avx512.mask.scalef.ps.256
7255 // (<8 x float>, <8 x float>, <8 x float>, i8)
7256 // < 4 x float> @llvm.x86.avx512.mask.scalef.ps.128
7257 // (<4 x float>, <4 x float>, <4 x float>, i8)
7258 //
7259 // <32 x half> @llvm.x86.avx512fp16.mask.scalef.ph.512
7260 // (<32 x half>, <32 x half>, <32 x half>, i32, i32)
7261 // <16 x half> @llvm.x86.avx512fp16.mask.scalef.ph.256
7262 // (<16 x half>, <16 x half>, <16 x half>, i16)
7263 // < 8 x half> @llvm.x86.avx512fp16.mask.scalef.ph.128
7264 // (<8 x half>, <8 x half>, <8 x half>, i8)
7265 //
7266 // TODO: AVX10
7267 // <32 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.512
7268 // (<32 x bfloat>, <32 x bfloat>, <32 x bfloat>, i32)
7269 // <16 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.256
7270 // (<16 x bfloat>, <16 x bfloat>, <16 x bfloat>, i16)
7271 // < 8 x bfloat> @llvm.x86.avx10.mask.scalef.bf16.128
7272 // (<8 x bfloat>, <8 x bfloat>, <8 x bfloat>, i8)
7273 case Intrinsic::x86_avx512_mask_scalef_pd_512:
7274 case Intrinsic::x86_avx512_mask_scalef_pd_256:
7275 case Intrinsic::x86_avx512_mask_scalef_pd_128:
7276 case Intrinsic::x86_avx512_mask_scalef_ps_512:
7277 case Intrinsic::x86_avx512_mask_scalef_ps_256:
7278 case Intrinsic::x86_avx512_mask_scalef_ps_128:
7279 case Intrinsic::x86_avx512fp16_mask_scalef_ph_512:
7280 case Intrinsic::x86_avx512fp16_mask_scalef_ph_256:
7281 case Intrinsic::x86_avx512fp16_mask_scalef_ph_128:
7282 // The AVX512 512-bit operand variants have an extra operand (the
7283 // Rounding mode). The extra operand, if present, will be
7284 // automatically checked by the handler.
7285 handleAVX512VectorGenericMaskedFP(I, /*DataIndices=*/{0, 1},
7286 /*WriteThruIndex=*/2,
7287 /*MaskIndex=*/3);
7288 break;
7289
7290 // TODO: AVX512 Vector Scale Float* Scalar
7291 //
7292 // This is different from the Packed variant, because some bits are copied,
7293 // and some bits are zeroed.
7294 //
7295 // < 4 x float> @llvm.x86.avx512.mask.scalef.ss
7296 // (<4 x float>, <4 x float>, <4 x float>, i8, i32)
7297 //
7298 // < 2 x double> @llvm.x86.avx512.mask.scalef.sd
7299 // (<2 x double>, <2 x double>, <2 x double>, i8, i32)
7300 //
7301 // < 8 x half> @llvm.x86.avx512fp16.mask.scalef.sh
7302 // (<8 x half>, <8 x half>, <8 x half>, i8, i32)
7303
7304 // AVX512 FP16 Arithmetic
7305 case Intrinsic::x86_avx512fp16_mask_add_sh_round:
7306 case Intrinsic::x86_avx512fp16_mask_sub_sh_round:
7307 case Intrinsic::x86_avx512fp16_mask_mul_sh_round:
7308 case Intrinsic::x86_avx512fp16_mask_div_sh_round:
7309 case Intrinsic::x86_avx512fp16_mask_max_sh_round:
7310 case Intrinsic::x86_avx512fp16_mask_min_sh_round: {
7311 visitGenericScalarHalfwordInst(I);
7312 break;
7313 }
7314
7315 // AVX512 Floating-Point Classification
7316 // - <8 x i1> @llvm.x86.avx512.fpclass.pd.512(<8 x double>, i32)
7317 // - <16 x i1> @llvm.x86.avx512.fpclass.ps.512(<16 x float>, i32)
7318 case Intrinsic::x86_avx512_fpclass_pd_512:
7319 case Intrinsic::x86_avx512_fpclass_ps_512:
7320 handleAVX512FPClass(I);
7321 break;
7322
7323 // AVX Galois Field New Instructions
7324 case Intrinsic::x86_vgf2p8affineqb_128:
7325 case Intrinsic::x86_vgf2p8affineqb_256:
7326 case Intrinsic::x86_vgf2p8affineqb_512:
7327 handleAVXGF2P8Affine(I);
7328 break;
7329
7330 default:
7331 return false;
7332 }
7333
7334 return true;
7335 }
7336
7337 bool maybeHandleArmSIMDIntrinsic(IntrinsicInst &I) {
7338 switch (I.getIntrinsicID()) {
7339 // Two operands e.g.,
7340 // - <8 x i8> @llvm.aarch64.neon.rshrn.v8i8 (<8 x i16>, i32)
7341 // - <4 x i16> @llvm.aarch64.neon.uqrshl.v4i16(<4 x i16>, <4 x i16>)
7342 case Intrinsic::aarch64_neon_rshrn:
7343 case Intrinsic::aarch64_neon_sqrshl:
7344 case Intrinsic::aarch64_neon_sqrshrn:
7345 case Intrinsic::aarch64_neon_sqrshrun:
7346 case Intrinsic::aarch64_neon_sqshl:
7347 case Intrinsic::aarch64_neon_sqshlu:
7348 case Intrinsic::aarch64_neon_sqshrn:
7349 case Intrinsic::aarch64_neon_sqshrun:
7350 case Intrinsic::aarch64_neon_srshl:
7351 case Intrinsic::aarch64_neon_sshl:
7352 case Intrinsic::aarch64_neon_uqrshl:
7353 case Intrinsic::aarch64_neon_uqrshrn:
7354 case Intrinsic::aarch64_neon_uqshl:
7355 case Intrinsic::aarch64_neon_uqshrn:
7356 case Intrinsic::aarch64_neon_urshl:
7357 case Intrinsic::aarch64_neon_ushl:
7358 handleVectorShiftIntrinsic(I, /* Variable */ false);
7359 break;
7360
7361 // Vector Shift Left/Right and Insert
7362 //
7363 // Three operands e.g.,
7364 // - <4 x i16> @llvm.aarch64.neon.vsli.v4i16
7365 // (<4 x i16> %a, <4 x i16> %b, i32 %n)
7366 // - <16 x i8> @llvm.aarch64.neon.vsri.v16i8
7367 // (<16 x i8> %a, <16 x i8> %b, i32 %n)
7368 //
7369 // %b is shifted by %n bits, and the "missing" bits are filled in with %a
7370 // (instead of zero-extending/sign-extending).
7371 case Intrinsic::aarch64_neon_vsli:
7372 case Intrinsic::aarch64_neon_vsri:
7373 handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
7374 /*trailingVerbatimArgs=*/1,
7375 /*forceIntegerIntrinsic=*/false);
7376 break;
7377
7378 // TODO: handling max/min similarly to AND/OR may be more precise
7379 // Floating-Point Maximum/Minimum Pairwise
7380 case Intrinsic::aarch64_neon_fmaxp:
7381 case Intrinsic::aarch64_neon_fminp:
7382 // Floating-Point Maximum/Minimum Number Pairwise
7383 case Intrinsic::aarch64_neon_fmaxnmp:
7384 case Intrinsic::aarch64_neon_fminnmp:
7385 // Signed/Unsigned Maximum/Minimum Pairwise
7386 case Intrinsic::aarch64_neon_smaxp:
7387 case Intrinsic::aarch64_neon_sminp:
7388 case Intrinsic::aarch64_neon_umaxp:
7389 case Intrinsic::aarch64_neon_uminp:
7390 // Add Pairwise
7391 case Intrinsic::aarch64_neon_addp:
7392 // Floating-point Add Pairwise
7393 case Intrinsic::aarch64_neon_faddp:
7394 // Add Long Pairwise
7395 case Intrinsic::aarch64_neon_saddlp:
7396 case Intrinsic::aarch64_neon_uaddlp: {
7397 handlePairwiseShadowOrIntrinsic(I, /*Shards=*/1);
7398 break;
7399 }
7400
7401 // Floating-point Convert to integer, rounding to nearest with ties to Away
7402 case Intrinsic::aarch64_neon_fcvtas:
7403 case Intrinsic::aarch64_neon_fcvtau:
7404 // Floating-point convert to integer, rounding toward minus infinity
7405 case Intrinsic::aarch64_neon_fcvtms:
7406 case Intrinsic::aarch64_neon_fcvtmu:
7407 // Floating-point convert to integer, rounding to nearest with ties to even
7408 case Intrinsic::aarch64_neon_fcvtns:
7409 case Intrinsic::aarch64_neon_fcvtnu:
7410 // Floating-point convert to integer, rounding toward plus infinity
7411 case Intrinsic::aarch64_neon_fcvtps:
7412 case Intrinsic::aarch64_neon_fcvtpu:
7413 // Floating-point Convert to integer, rounding toward Zero
7414 case Intrinsic::aarch64_neon_fcvtzs:
7415 case Intrinsic::aarch64_neon_fcvtzu:
7416 // Floating-point convert to lower precision narrow, rounding to odd
7417 case Intrinsic::aarch64_neon_fcvtxn:
7418 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/false);
7419 break;
7420
7421 // Vector Conversions Between Fixed-Point and Floating-Point
7422 case Intrinsic::aarch64_neon_vcvtfxs2fp:
7423 case Intrinsic::aarch64_neon_vcvtfp2fxs:
7424 case Intrinsic::aarch64_neon_vcvtfxu2fp:
7425 case Intrinsic::aarch64_neon_vcvtfp2fxu:
7426 handleGenericVectorConvertIntrinsic(I, /*FixedPoint=*/true);
7427 break;
7428
7429 // TODO: bfloat conversions
7430 // - bfloat @llvm.aarch64.neon.bfcvt(float)
7431 // - <8 x bfloat> @llvm.aarch64.neon.bfcvtn(<4 x float>)
7432 // - <8 x bfloat> @llvm.aarch64.neon.bfcvtn2(<8 x bfloat>, <4 x float>)
7433
7434 // Add reduction to scalar
7435 case Intrinsic::aarch64_neon_faddv:
7436 case Intrinsic::aarch64_neon_saddv:
7437 case Intrinsic::aarch64_neon_uaddv:
7438 // Signed/Unsigned min/max (Vector)
7439 // TODO: handling similarly to AND/OR may be more precise.
7440 case Intrinsic::aarch64_neon_smaxv:
7441 case Intrinsic::aarch64_neon_sminv:
7442 case Intrinsic::aarch64_neon_umaxv:
7443 case Intrinsic::aarch64_neon_uminv:
7444 // Floating-point min/max (vector)
7445 // The f{min,max}"nm"v variants handle NaN differently than f{min,max}v,
7446 // but our shadow propagation is the same.
7447 case Intrinsic::aarch64_neon_fmaxv:
7448 case Intrinsic::aarch64_neon_fminv:
7449 case Intrinsic::aarch64_neon_fmaxnmv:
7450 case Intrinsic::aarch64_neon_fminnmv:
7451 // Sum long across vector
7452 case Intrinsic::aarch64_neon_saddlv:
7453 case Intrinsic::aarch64_neon_uaddlv:
7454 handleVectorReduceIntrinsic(I, /*AllowShadowCast=*/true);
7455 break;
7456
7457 case Intrinsic::aarch64_neon_ld1x2:
7458 case Intrinsic::aarch64_neon_ld1x3:
7459 case Intrinsic::aarch64_neon_ld1x4:
7460 case Intrinsic::aarch64_neon_ld2:
7461 case Intrinsic::aarch64_neon_ld3:
7462 case Intrinsic::aarch64_neon_ld4:
7463 case Intrinsic::aarch64_neon_ld2r:
7464 case Intrinsic::aarch64_neon_ld3r:
7465 case Intrinsic::aarch64_neon_ld4r: {
7466 handleNEONVectorLoad(I, /*WithLane=*/false);
7467 break;
7468 }
7469
7470 case Intrinsic::aarch64_neon_ld2lane:
7471 case Intrinsic::aarch64_neon_ld3lane:
7472 case Intrinsic::aarch64_neon_ld4lane: {
7473 handleNEONVectorLoad(I, /*WithLane=*/true);
7474 break;
7475 }
7476
7477 // Saturating extract narrow
7478 case Intrinsic::aarch64_neon_sqxtn:
7479 case Intrinsic::aarch64_neon_sqxtun:
7480 case Intrinsic::aarch64_neon_uqxtn:
7481 // These only have one argument, but we (ab)use handleShadowOr because it
7482 // does work on single argument intrinsics and will typecast the shadow
7483 // (and update the origin).
7484 handleShadowOr(I);
7485 break;
7486
7487 case Intrinsic::aarch64_neon_st1x2:
7488 case Intrinsic::aarch64_neon_st1x3:
7489 case Intrinsic::aarch64_neon_st1x4:
7490 case Intrinsic::aarch64_neon_st2:
7491 case Intrinsic::aarch64_neon_st3:
7492 case Intrinsic::aarch64_neon_st4: {
7493 handleNEONVectorStoreIntrinsic(I, false);
7494 break;
7495 }
7496
7497 case Intrinsic::aarch64_neon_st2lane:
7498 case Intrinsic::aarch64_neon_st3lane:
7499 case Intrinsic::aarch64_neon_st4lane: {
7500 handleNEONVectorStoreIntrinsic(I, true);
7501 break;
7502 }
7503
7504 // Arm NEON vector table intrinsics have the source/table register(s) as
7505 // arguments, followed by the index register. They return the output.
7506 //
7507 // 'TBL writes a zero if an index is out-of-range, while TBX leaves the
7508 // original value unchanged in the destination register.'
7509 // Conveniently, zero denotes a clean shadow, which means out-of-range
7510 // indices for TBL will initialize the user data with zero and also clean
7511 // the shadow. (For TBX, neither the user data nor the shadow will be
7512 // updated, which is also correct.)
7513 case Intrinsic::aarch64_neon_tbl1:
7514 case Intrinsic::aarch64_neon_tbl2:
7515 case Intrinsic::aarch64_neon_tbl3:
7516 case Intrinsic::aarch64_neon_tbl4:
7517 case Intrinsic::aarch64_neon_tbx1:
7518 case Intrinsic::aarch64_neon_tbx2:
7519 case Intrinsic::aarch64_neon_tbx3:
7520 case Intrinsic::aarch64_neon_tbx4: {
7521 // The last trailing argument (index register) should be handled verbatim
7522 handleIntrinsicByApplyingToShadow(
7523 I, /*shadowIntrinsicID=*/I.getIntrinsicID(),
7524 /*trailingVerbatimArgs=*/1, /*forceIntegerIntrinsic=*/false);
7525 break;
7526 }
7527
7528 case Intrinsic::aarch64_neon_fmulx:
7529 case Intrinsic::aarch64_neon_pmul:
7530 case Intrinsic::aarch64_neon_pmull:
7531 case Intrinsic::aarch64_neon_smull:
7532 case Intrinsic::aarch64_neon_pmull64:
7533 case Intrinsic::aarch64_neon_umull: {
7534 handleNEONVectorMultiplyIntrinsic(I);
7535 break;
7536 }
7537
7538 case Intrinsic::aarch64_neon_smmla:
7539 case Intrinsic::aarch64_neon_ummla:
7540 case Intrinsic::aarch64_neon_usmmla:
7541 case Intrinsic::aarch64_neon_bfmmla:
7542 handleNEONMatrixMultiply(I);
7543 break;
7544
7545 // <2 x i32> @llvm.aarch64.neon.{u,s,us}dot.v2i32.v8i8
7546 // (<2 x i32> %acc, <8 x i8> %a, <8 x i8> %b)
7547 // <4 x i32> @llvm.aarch64.neon.{u,s,us}dot.v4i32.v16i8
7548 // (<4 x i32> %acc, <16 x i8> %a, <16 x i8> %b)
7549 case Intrinsic::aarch64_neon_sdot:
7550 case Intrinsic::aarch64_neon_udot:
7551 case Intrinsic::aarch64_neon_usdot:
7552 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
7553 /*ZeroPurifies=*/true,
7554 /*EltSizeInBits=*/0,
7555 /*Lanes=*/kBothLanes);
7556 break;
7557
7558 // <2 x float> @llvm.aarch64.neon.bfdot.v2f32.v4bf16
7559 // (<2 x float> %acc, <4 x bfloat> %a, <4 x bfloat> %b)
7560 // <4 x float> @llvm.aarch64.neon.bfdot.v4f32.v8bf16
7561 // (<4 x float> %acc, <8 x bfloat> %a, <8 x bfloat> %b)
7562 case Intrinsic::aarch64_neon_bfdot:
7563 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
7564 /*ZeroPurifies=*/false,
7565 /*EltSizeInBits=*/0,
7566 /*Lanes=*/kBothLanes);
7567 break;
7568
7569 // <4 x half > @llvm.aarch64.neon.fp8.fdot2
7570 // (<4 x half >, < 8 x i8>, < 8 x i8>)
7571 // <8 x half > @llvm.aarch64.neon.fp8.fdot2
7572 // (<8 x half >, <16 x i8>, <16 x i8>)
7573 //
7574 // N.B. although the multiplicands are i8, they are actually fp8, thus
7575 // ZeroPurifies is not applicable.
7576 case Intrinsic::aarch64_neon_fp8_fdot2:
7577 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/2,
7578 /*ZeroPurifies=*/false,
7579 /*EltSizeInBits=*/0,
7580 /*Lanes=*/kBothLanes);
7581 break;
7582
7583 // <2 x float> @llvm.aarch64.neon.fp8.fdot4
7584 // (<2 x float>, < 8 x i8>, < 8 x i8>)
7585 // <4 x float> @llvm.aarch64.neon.fp8.fdot4
7586 // (<4 x float>, <16 x i8>, <16 x i8>)
7587 //
7588 // N.B. although the multiplicands are i8, they are actually fp8, thus
7589 // ZeroPurifies is not applicable.
7590 case Intrinsic::aarch64_neon_fp8_fdot4:
7591 handleVectorDotProductIntrinsic(I, /*ReductionFactor=*/4,
7592 /*ZeroPurifies=*/false,
7593 /*EltSizeInBits=*/0,
7594 /*Lanes=*/kBothLanes);
7595 break;
7596
7597 // <4 x half> @llvm.aarch64.neon.fp8.fdot2.lane
7598 // (<4 x half>, <8 x i8>, <16 x i8>, i32)
7599 // <8 x half> @llvm.aarch64.neon.fp8.fdot2.lane
7600 // (<8 x half>, <16 x i8>, <16 x i8>, i32)
7601 case Intrinsic::aarch64_neon_fp8_fdot2_lane:
7602 handleNEONDotProductLaneIntrinsic(I, /*ReductionFactor=*/2);
7603 break;
7604
7605 // <2 x float> @llvm.aarch64.neon.fp8.fdot4.lane
7606 // (<2 x float>, <8 x i8>, <16 x i8>, i32)
7607 // <4 x float> @llvm.aarch64.neon.fp8.fdot4.lane
7608 // (<4 x float>, <16 x i8>, <16 x i8>, i32)
7609 case Intrinsic::aarch64_neon_fp8_fdot4_lane:
7610 handleNEONDotProductLaneIntrinsic(I, /*ReductionFactor=*/4);
7611 break;
7612
7613 // Floating-Point Absolute Compare Greater Than/Equal
7614 case Intrinsic::aarch64_neon_facge:
7615 case Intrinsic::aarch64_neon_facgt:
7616 handleVectorComparePackedIntrinsic(I, /*PredicateAsOperand=*/false);
7617 break;
7618
7619 default:
7620 return false;
7621 }
7622
7623 return true;
7624 }
7625
7626 void visitIntrinsicInst(IntrinsicInst &I) {
7627 if (maybeHandleCrossPlatformIntrinsic(I))
7628 return;
7629
7630 if (maybeHandleX86SIMDIntrinsic(I))
7631 return;
7632
7633 if (maybeHandleArmSIMDIntrinsic(I))
7634 return;
7635
7636 if (maybeHandleUnknownIntrinsic(I))
7637 return;
7638
7639 visitInstruction(I);
7640 }
7641
7642 void visitLibAtomicLoad(CallBase &CB) {
7643 // Since we use getNextNode here, we can't have CB terminate the BB.
7644 assert(isa<CallInst>(CB));
7645
7646 IRBuilder<> IRB(&CB);
7647 Value *Size = CB.getArgOperand(0);
7648 Value *SrcPtr = CB.getArgOperand(1);
7649 Value *DstPtr = CB.getArgOperand(2);
7650 Value *Ordering = CB.getArgOperand(3);
7651 // Convert the call to have at least Acquire ordering to make sure
7652 // the shadow operations aren't reordered before it.
7653 Value *NewOrdering =
7654 IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
7655 CB.setArgOperand(3, NewOrdering);
7656
7657 NextNodeIRBuilder NextIRB(&CB);
7658 Value *SrcShadowPtr, *SrcOriginPtr;
7659 std::tie(SrcShadowPtr, SrcOriginPtr) =
7660 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
7661 /*isStore*/ false);
7662 Value *DstShadowPtr =
7663 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
7664 /*isStore*/ true)
7665 .first;
7666
7667 NextIRB.CreateMemCpy(DstShadowPtr, Align(1), SrcShadowPtr, Align(1), Size);
7668 if (MS.TrackOrigins) {
7669 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
7671 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
7672 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
7673 }
7674 }
7675
7676 void visitLibAtomicStore(CallBase &CB) {
7677 IRBuilder<> IRB(&CB);
7678 Value *Size = CB.getArgOperand(0);
7679 Value *DstPtr = CB.getArgOperand(2);
7680 Value *Ordering = CB.getArgOperand(3);
7681 // Convert the call to have at least Release ordering to make sure
7682 // the shadow operations aren't reordered after it.
7683 Value *NewOrdering =
7684 IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
7685 CB.setArgOperand(3, NewOrdering);
7686
7687 Value *DstShadowPtr =
7688 getShadowOriginPtr(DstPtr, IRB, IRB.getInt8Ty(), Align(1),
7689 /*isStore*/ true)
7690 .first;
7691
7692 // Atomic store always paints clean shadow/origin. See file header.
7693 IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
7694 Align(1));
7695 }
7696
7697 void visitCallBase(CallBase &CB) {
7698 assert(!CB.getMetadata(LLVMContext::MD_nosanitize));
7699 if (CB.isInlineAsm()) {
7700 // For inline asm (either a call to asm function, or callbr instruction),
7701 // do the usual thing: check argument shadow and mark all outputs as
7702 // clean. Note that any side effects of the inline asm that are not
7703 // immediately visible in its constraints are not handled.
7704 if (Opts.msan_handle_asm_conservative)
7705 visitAsmInstruction(CB);
7706 else
7707 visitInstruction(CB);
7708 return;
7709 }
7710 LibFunc LF = TLI->getLibFunc(CB);
7711 if (LF != NotLibFunc) {
7712 // libatomic.a functions need to have special handling because there isn't
7713 // a good way to intercept them or compile the library with
7714 // instrumentation.
7715 switch (LF) {
7716 case LibFunc_atomic_load:
7717 if (!isa<CallInst>(CB)) {
7718 llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
7719 "Ignoring!\n";
7720 break;
7721 }
7722 visitLibAtomicLoad(CB);
7723 return;
7724 case LibFunc_atomic_store:
7725 visitLibAtomicStore(CB);
7726 return;
7727 default:
7728 break;
7729 }
7730 }
7731
7732 if (auto *Call = dyn_cast<CallInst>(&CB)) {
7733 assert(!isa<IntrinsicInst>(Call) && "intrinsics are handled elsewhere");
7734
7735 // We are going to insert code that relies on the fact that the callee
7736 // will become a non-readonly function after it is instrumented by us. To
7737 // prevent this code from being optimized out, mark that function
7738 // non-readonly in advance.
7739 // TODO: We can likely do better than dropping memory() completely here.
7740 AttributeMask B;
7741 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
7742
7744 if (Function *Func = Call->getCalledFunction()) {
7745 Func->removeFnAttrs(B);
7746 }
7747
7749 }
7750 IRBuilder<> IRB(&CB);
7751 bool MayCheckCall = MS.EagerChecks;
7752 if (Function *Func = CB.getCalledFunction()) {
7753 // __sanitizer_unaligned_{load,store} functions may be called by users
7754 // and always expects shadows in the TLS. So don't check them.
7755 MayCheckCall &= !Func->getName().starts_with("__sanitizer_unaligned_");
7756 }
7757
7758 unsigned ArgOffset = 0;
7759 LLVM_DEBUG(dbgs() << " CallSite: " << CB << "\n");
7760 for (const auto &[i, A] : llvm::enumerate(CB.args())) {
7761 if (!A->getType()->isSized()) {
7762 LLVM_DEBUG(dbgs() << "Arg " << i << " is not sized: " << CB << "\n");
7763 continue;
7764 }
7765
7766 if (A->getType()->isScalableTy()) {
7767 LLVM_DEBUG(dbgs() << "Arg " << i << " is vscale: " << CB << "\n");
7768 // Handle as noundef, but don't reserve tls slots.
7769 insertCheckShadowOf(A, &CB);
7770 continue;
7771 }
7772
7773 unsigned Size = 0;
7774 const DataLayout &DL = F.getDataLayout();
7775
7776 bool ByVal = CB.isByValArgument(i);
7777 bool NoUndef = CB.paramHasAttr(i, Attribute::NoUndef);
7778 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
7779
7780 if (EagerCheck) {
7781 insertCheckShadowOf(A, &CB);
7782 Size = DL.getTypeAllocSize(A->getType());
7783 } else {
7784 [[maybe_unused]] Value *Store = nullptr;
7785 // Compute the Shadow for arg even if it is ByVal, because
7786 // in that case getShadow() will copy the actual arg shadow to
7787 // __msan_param_tls.
7788 Value *ArgShadow = getShadow(A);
7789 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
7790 LLVM_DEBUG(dbgs() << " Arg#" << i << ": " << *A
7791 << " Shadow: " << *ArgShadow << "\n");
7792 if (ByVal) {
7793 // ByVal requires some special handling as it's too big for a single
7794 // load
7795 assert(A->getType()->isPointerTy() &&
7796 "ByVal argument is not a pointer!");
7797 Size = DL.getTypeAllocSize(CB.getParamByValType(i));
7798 if (ArgOffset + Size > kParamTLSSize)
7799 break;
7800 const MaybeAlign ParamAlignment(CB.getParamAlign(i));
7801 MaybeAlign Alignment = std::nullopt;
7802 if (ParamAlignment)
7803 Alignment = std::min(*ParamAlignment, kShadowTLSAlignment);
7804 Value *AShadowPtr, *AOriginPtr;
7805 std::tie(AShadowPtr, AOriginPtr) =
7806 getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
7807 /*isStore*/ false);
7808 if (!PropagateShadow) {
7809 Store = IRB.CreateMemSet(ArgShadowBase,
7811 Size, Alignment);
7812 } else {
7813 Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr,
7814 Alignment, Size);
7815 if (MS.TrackOrigins) {
7816 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
7817 // FIXME: OriginSize should be:
7818 // alignTo(A % kMinOriginAlignment + Size, kMinOriginAlignment)
7819 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
7820 IRB.CreateMemCpy(
7821 ArgOriginBase,
7822 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
7823 AOriginPtr,
7824 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginSize);
7825 }
7826 }
7827 } else {
7828 // Any other parameters mean we need bit-grained tracking of uninit
7829 // data
7830 Size = DL.getTypeAllocSize(A->getType());
7831 if (ArgOffset + Size > kParamTLSSize)
7832 break;
7833 Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
7835 Constant *Cst = dyn_cast<Constant>(ArgShadow);
7836 if (MS.TrackOrigins && !(Cst && Cst->isNullValue())) {
7837 IRB.CreateStore(getOrigin(A),
7838 getOriginPtrForArgument(IRB, ArgOffset));
7839 }
7840 }
7841 assert(Store != nullptr);
7842 LLVM_DEBUG(dbgs() << " Param:" << *Store << "\n");
7843 }
7844 assert(Size != 0);
7845 ArgOffset += alignTo(Size, kShadowTLSAlignment);
7846 }
7847 LLVM_DEBUG(dbgs() << " done with call args\n");
7848
7849 FunctionType *FT = CB.getFunctionType();
7850 if (FT->isVarArg()) {
7851 VAHelper->visitCallBase(CB, IRB);
7852 }
7853
7854 // Now, get the shadow for the RetVal.
7855 if (!CB.getType()->isSized())
7856 return;
7857 // Don't emit the epilogue for musttail call returns.
7858 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
7859 return;
7860
7861 if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
7862 setShadow(&CB, getCleanShadow(&CB));
7863 setOrigin(&CB, getCleanOrigin());
7864 return;
7865 }
7866
7867 IRBuilder<> IRBBefore(&CB);
7868 // Until we have full dynamic coverage, make sure the retval shadow is 0.
7869 Value *Base = getShadowPtrForRetval(IRBBefore);
7870 IRBBefore.CreateAlignedStore(getCleanShadow(&CB), Base,
7872 BasicBlock::iterator NextInsn;
7873 if (isa<CallInst>(CB)) {
7874 NextInsn = ++CB.getIterator();
7875 assert(NextInsn != CB.getParent()->end());
7876 } else {
7877 BasicBlock *NormalDest = cast<InvokeInst>(CB).getNormalDest();
7878 if (!NormalDest->getSinglePredecessor()) {
7879 // FIXME: this case is tricky, so we are just conservative here.
7880 // Perhaps we need to split the edge between this BB and NormalDest,
7881 // but a naive attempt to use SplitEdge leads to a crash.
7882 setShadow(&CB, getCleanShadow(&CB));
7883 setOrigin(&CB, getCleanOrigin());
7884 return;
7885 }
7886 // FIXME: NextInsn is likely in a basic block that has not been visited
7887 // yet. Anything inserted there will be instrumented by MSan later!
7888 NextInsn = NormalDest->getFirstInsertionPt();
7889 assert(NextInsn != NormalDest->end() &&
7890 "Could not find insertion point for retval shadow load");
7891 }
7892 IRBuilder<> IRBAfter(&*NextInsn);
7893 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
7894 getShadowTy(&CB), getShadowPtrForRetval(IRBAfter), kShadowTLSAlignment,
7895 "_msret");
7896 setShadow(&CB, RetvalShadow);
7897 if (MS.TrackOrigins)
7898 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy, getOriginPtrForRetval()));
7899 }
7900
7901 bool isAMustTailRetVal(Value *RetVal) {
7902 if (auto *I = dyn_cast<BitCastInst>(RetVal)) {
7903 RetVal = I->getOperand(0);
7904 }
7905 if (auto *I = dyn_cast<CallInst>(RetVal)) {
7906 return I->isMustTailCall();
7907 }
7908 return false;
7909 }
7910
7911 void visitReturnInst(ReturnInst &I) {
7912 IRBuilder<> IRB(&I);
7913 Value *RetVal = I.getReturnValue();
7914 if (!RetVal)
7915 return;
7916 // Don't emit the epilogue for musttail call returns.
7917 if (isAMustTailRetVal(RetVal))
7918 return;
7919 Value *ShadowPtr = getShadowPtrForRetval(IRB);
7920 bool HasNoUndef = F.hasRetAttribute(Attribute::NoUndef);
7921 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
7922 // FIXME: Consider using SpecialCaseList to specify a list of functions that
7923 // must always return fully initialized values. For now, we hardcode "main".
7924 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (F.getName() == "main");
7925
7926 Value *Shadow = getShadow(RetVal);
7927 bool StoreOrigin = true;
7928 if (EagerCheck) {
7929 insertCheckShadowOf(RetVal, &I);
7930 Shadow = getCleanShadow(RetVal);
7931 StoreOrigin = false;
7932 }
7933
7934 // The caller may still expect information passed over TLS if we pass our
7935 // check
7936 if (StoreShadow) {
7937 IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
7938 if (MS.TrackOrigins && StoreOrigin)
7939 IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
7940 }
7941 }
7942
7943 void visitPHINode(PHINode &I) {
7944 IRBuilder<> IRB(&I);
7945 if (!PropagateShadow) {
7946 setShadow(&I, getCleanShadow(&I));
7947 setOrigin(&I, getCleanOrigin());
7948 return;
7949 }
7950
7951 ShadowPHINodes.push_back(&I);
7952 setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
7953 "_msphi_s"));
7954 if (MS.TrackOrigins)
7955 setOrigin(
7956 &I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(), "_msphi_o"));
7957 }
7958
7959 Value *getLocalVarIdptr(AllocaInst &I) {
7960 ConstantInt *IntConst =
7961 ConstantInt::get(Type::getInt32Ty((*F.getParent()).getContext()), 0);
7962 return new GlobalVariable(*F.getParent(), IntConst->getType(),
7963 /*isConstant=*/false, GlobalValue::PrivateLinkage,
7964 IntConst);
7965 }
7966
7967 Value *getLocalVarDescription(AllocaInst &I) {
7968 return createPrivateConstGlobalForString(*F.getParent(), I.getName());
7969 }
7970
7971 void poisonAllocaUserspace(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
7972 if (PoisonStack && Opts.msan_poison_stack_with_call) {
7973 IRB.CreateCall(MS.MsanPoisonStackFn, {&I, Len});
7974 } else {
7975 Value *ShadowBase, *OriginBase;
7976 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
7977 &I, IRB, IRB.getInt8Ty(), Align(1), /*isStore*/ true);
7978
7979 Value *PoisonValue =
7980 IRB.getInt8(PoisonStack ? Opts.msan_poison_stack_pattern : 0);
7981 IRB.CreateMemSet(ShadowBase, PoisonValue, Len, I.getAlign());
7982 }
7983
7984 if (PoisonStack && MS.TrackOrigins) {
7985 Value *Idptr = getLocalVarIdptr(I);
7986 if (Opts.msan_print_stack_names) {
7987 Value *Descr = getLocalVarDescription(I);
7988 IRB.CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
7989 {&I, Len, Idptr, Descr});
7990 } else {
7991 IRB.CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
7992 }
7993 }
7994 }
7995
7996 void poisonAllocaKmsan(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
7997 Value *Descr = getLocalVarDescription(I);
7998 if (PoisonStack) {
7999 IRB.CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
8000 } else {
8001 IRB.CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
8002 }
8003 }
8004
8005 void instrumentAlloca(AllocaInst &I, Instruction *InsPoint = nullptr) {
8006 if (!InsPoint)
8007 InsPoint = &I;
8008 NextNodeIRBuilder IRB(InsPoint);
8009 Value *Len = IRB.CreateAllocationSize(MS.IntptrTy, &I);
8010
8011 if (MS.CompileKernel)
8012 poisonAllocaKmsan(I, IRB, Len);
8013 else
8014 poisonAllocaUserspace(I, IRB, Len);
8015 }
8016
8017 void visitAllocaInst(AllocaInst &I) {
8018 setShadow(&I, getCleanShadow(&I));
8019 setOrigin(&I, getCleanOrigin());
8020 // We'll get to this alloca later unless it's poisoned at the corresponding
8021 // llvm.lifetime.start.
8022 AllocaSet.insert(&I);
8023 }
8024
8025 void visitSelectInst(SelectInst &I) {
8026 // a = select b, c, d
8027 Value *B = I.getCondition();
8028 Value *C = I.getTrueValue();
8029 Value *D = I.getFalseValue();
8030
8031 handleSelectLikeInst(I, B, C, D);
8032 }
8033
8034 void handleSelectLikeInst(Instruction &I, Value *B, Value *C, Value *D) {
8035 IRBuilder<> IRB(&I);
8036
8037 Value *Sb = getShadow(B);
8038 Value *Sc = getShadow(C);
8039 Value *Sd = getShadow(D);
8040
8041 Value *Ob = MS.TrackOrigins ? getOrigin(B) : nullptr;
8042 Value *Oc = MS.TrackOrigins ? getOrigin(C) : nullptr;
8043 Value *Od = MS.TrackOrigins ? getOrigin(D) : nullptr;
8044
8045 // Result shadow if condition shadow is 0.
8046 Value *Sa0 = IRB.CreateSelect(B, Sc, Sd);
8047 Value *Sa1;
8048 if (I.getType()->isAggregateType()) {
8049 // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do
8050 // an extra "select". This results in much more compact IR.
8051 // Sa = select Sb, poisoned, (select b, Sc, Sd)
8052 Sa1 = getPoisonedShadow(getShadowTy(I.getType()));
8053 } else if (isScalableNonVectorType(I.getType())) {
8054 // This is intended to handle target("aarch64.svcount"), which can't be
8055 // handled in the else branch because of incompatibility with CreateXor
8056 // ("The supported LLVM operations on this type are limited to load,
8057 // store, phi, select and alloca instructions").
8058
8059 // TODO: this currently underapproximates. Use Arm SVE EOR in the else
8060 // branch as needed instead.
8061 Sa1 = getCleanShadow(getShadowTy(I.getType()));
8062 } else {
8063 // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ]
8064 // If Sb (condition is poisoned), look for bits in c and d that are equal
8065 // and both unpoisoned.
8066 // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd.
8067
8068 // Cast arguments to shadow-compatible type.
8069 C = CreateAppToShadowCast(IRB, C);
8070 D = CreateAppToShadowCast(IRB, D);
8071
8072 // Result shadow if condition shadow is 1.
8073 Sa1 = IRB.CreateOr({IRB.CreateXor(C, D), Sc, Sd});
8074 }
8075 Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
8076 setShadow(&I, Sa);
8077 if (MS.TrackOrigins) {
8078 // Origins are always i32, so any vector conditions must be flattened.
8079 // FIXME: consider tracking vector origins for app vectors?
8080 if (B->getType()->isVectorTy()) {
8081 B = convertToBool(B, IRB);
8082 Sb = convertToBool(Sb, IRB);
8083 }
8084 // a = select b, c, d
8085 // Oa = Sb ? Ob : (b ? Oc : Od)
8086 setOrigin(&I, IRB.CreateSelect(Sb, Ob, IRB.CreateSelect(B, Oc, Od)));
8087 }
8088 }
8089
8090 void visitLandingPadInst(LandingPadInst &I) {
8091 // Do nothing.
8092 // See https://github.com/google/sanitizers/issues/504
8093 setShadow(&I, getCleanShadow(&I));
8094 setOrigin(&I, getCleanOrigin());
8095 }
8096
8097 void visitCatchSwitchInst(CatchSwitchInst &I) {
8098 setShadow(&I, getCleanShadow(&I));
8099 setOrigin(&I, getCleanOrigin());
8100 }
8101
8102 void visitFuncletPadInst(FuncletPadInst &I) {
8103 setShadow(&I, getCleanShadow(&I));
8104 setOrigin(&I, getCleanOrigin());
8105 }
8106
8107 void visitGetElementPtrInst(GetElementPtrInst &I) { handleShadowOr(I); }
8108
8109 void visitExtractValueInst(ExtractValueInst &I) {
8110 IRBuilder<> IRB(&I);
8111 Value *Agg = I.getAggregateOperand();
8112 LLVM_DEBUG(dbgs() << "ExtractValue: " << I << "\n");
8113 Value *AggShadow = getShadow(Agg);
8114 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
8115 Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
8116 LLVM_DEBUG(dbgs() << " ResShadow: " << *ResShadow << "\n");
8117 setShadow(&I, ResShadow);
8118 setOriginForNaryOp(I);
8119 }
8120
8121 void visitInsertValueInst(InsertValueInst &I) {
8122 IRBuilder<> IRB(&I);
8123 LLVM_DEBUG(dbgs() << "InsertValue: " << I << "\n");
8124 Value *AggShadow = getShadow(I.getAggregateOperand());
8125 Value *InsShadow = getShadow(I.getInsertedValueOperand());
8126 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
8127 LLVM_DEBUG(dbgs() << " InsShadow: " << *InsShadow << "\n");
8128 Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
8129 LLVM_DEBUG(dbgs() << " Res: " << *Res << "\n");
8130 setShadow(&I, Res);
8131 setOriginForNaryOp(I);
8132 }
8133
8134 void dumpInst(Instruction &I, const Twine &Prefix) {
8135 // Instruction name only
8136 // For intrinsics, the full/overloaded name is used
8137 //
8138 // e.g., "call llvm.aarch64.neon.uqsub.v16i8"
8139 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
8140 errs() << "ZZZ:" << Prefix << " call "
8141 << CI->getCalledFunction()->getName() << "\n";
8142 } else {
8143 errs() << "ZZZ:" << Prefix << " " << I.getOpcodeName() << "\n";
8144 }
8145
8146 // Instruction prototype (including return type and parameter types)
8147 // For intrinsics, we use the base/non-overloaded name
8148 //
8149 // e.g., "call <16 x i8> @llvm.aarch64.neon.uqsub(<16 x i8>, <16 x i8>)"
8150 unsigned NumOperands = I.getNumOperands();
8151 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
8152 errs() << "YYY:" << Prefix << " call " << *I.getType() << " @";
8153
8154 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI))
8155 errs() << Intrinsic::getBaseName(II->getIntrinsicID());
8156 else
8157 errs() << CI->getCalledFunction()->getName();
8158
8159 errs() << "(";
8160
8161 // The last operand of a CallInst is the function itself.
8162 NumOperands--;
8163 } else
8164 errs() << "YYY:" << Prefix << " " << *I.getType() << " "
8165 << I.getOpcodeName() << "(";
8166
8167 for (size_t i = 0; i < NumOperands; i++) {
8168 if (i > 0)
8169 errs() << ", ";
8170
8171 errs() << *(I.getOperand(i)->getType());
8172 }
8173
8174 errs() << ")\n";
8175
8176 // Full instruction, including types and operand values
8177 // For intrinsics, the full/overloaded name is used
8178 //
8179 // e.g., "%vqsubq_v.i15 = call noundef <16 x i8>
8180 // @llvm.aarch64.neon.uqsub.v16i8(<16 x i8> %vext21.i,
8181 // <16 x i8> splat (i8 1)), !dbg !66"
8182 errs() << "QQQ:" << Prefix << " " << I << "\n";
8183 }
8184
8185 void visitResumeInst(ResumeInst &I) {
8186 LLVM_DEBUG(dbgs() << "Resume: " << I << "\n");
8187 // Nothing to do here.
8188 }
8189
8190 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
8191 LLVM_DEBUG(dbgs() << "CleanupReturn: " << CRI << "\n");
8192 // Nothing to do here.
8193 }
8194
8195 void visitCatchReturnInst(CatchReturnInst &CRI) {
8196 LLVM_DEBUG(dbgs() << "CatchReturn: " << CRI << "\n");
8197 // Nothing to do here.
8198 }
8199
8200 void instrumentAsmArgument(Value *Operand, Type *ElemTy, Instruction &I,
8201 IRBuilder<> &IRB, const DataLayout &DL,
8202 bool isOutput) {
8203 // For each assembly argument, we check its value for being initialized.
8204 // If the argument is a pointer, we assume it points to a single element
8205 // of the corresponding type (or to a 8-byte word, if the type is unsized).
8206 // Each such pointer is instrumented with a call to the runtime library.
8207 Type *OpType = Operand->getType();
8208 // Check the operand value itself.
8209 insertCheckShadowOf(Operand, &I);
8210 if (!OpType->isPointerTy() || !isOutput) {
8211 assert(!isOutput);
8212 return;
8213 }
8214 if (!ElemTy->isSized())
8215 return;
8216 auto Size = DL.getTypeStoreSize(ElemTy);
8217 Value *SizeVal = IRB.CreateTypeSize(MS.IntptrTy, Size);
8218 if (MS.CompileKernel) {
8219 IRB.CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
8220 } else {
8221 // ElemTy, derived from elementtype(), does not encode the alignment of
8222 // the pointer. Conservatively assume that the shadow memory is unaligned.
8223 // When Size is large, avoid StoreInst as it would expand to many
8224 // instructions.
8225 auto [ShadowPtr, _] =
8226 getShadowOriginPtrUserspace(Operand, IRB, IRB.getInt8Ty(), Align(1));
8227 if (Size <= 32)
8228 IRB.CreateAlignedStore(getCleanShadow(ElemTy), ShadowPtr, Align(1));
8229 else
8230 IRB.CreateMemSet(ShadowPtr, ConstantInt::getNullValue(IRB.getInt8Ty()),
8231 SizeVal, Align(1));
8232 }
8233 }
8234
8235 /// Get the number of output arguments returned by pointers.
8236 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
8237 int NumRetOutputs = 0;
8238 int NumOutputs = 0;
8239 Type *RetTy = cast<Value>(CB)->getType();
8240 if (!RetTy->isVoidTy()) {
8241 // Register outputs are returned via the CallInst return value.
8242 auto *ST = dyn_cast<StructType>(RetTy);
8243 if (ST)
8244 NumRetOutputs = ST->getNumElements();
8245 else
8246 NumRetOutputs = 1;
8247 }
8248 InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
8249 for (const InlineAsm::ConstraintInfo &Info : Constraints) {
8250 switch (Info.Type) {
8252 NumOutputs++;
8253 break;
8254 default:
8255 break;
8256 }
8257 }
8258 return NumOutputs - NumRetOutputs;
8259 }
8260
8261 void visitAsmInstruction(Instruction &I) {
8262 // Conservative inline assembly handling: check for poisoned shadow of
8263 // asm() arguments, then unpoison the result and all the memory locations
8264 // pointed to by those arguments.
8265 // An inline asm() statement in C++ contains lists of input and output
8266 // arguments used by the assembly code. These are mapped to operands of the
8267 // CallInst as follows:
8268 // - nR register outputs ("=r) are returned by value in a single structure
8269 // (SSA value of the CallInst);
8270 // - nO other outputs ("=m" and others) are returned by pointer as first
8271 // nO operands of the CallInst;
8272 // - nI inputs ("r", "m" and others) are passed to CallInst as the
8273 // remaining nI operands.
8274 // The total number of asm() arguments in the source is nR+nO+nI, and the
8275 // corresponding CallInst has nO+nI+1 operands (the last operand is the
8276 // function to be called).
8277 const DataLayout &DL = F.getDataLayout();
8278 CallBase *CB = cast<CallBase>(&I);
8279 IRBuilder<> IRB(&I);
8280 InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
8281 int OutputArgs = getNumOutputArgs(IA, CB);
8282 // The last operand of a CallInst is the function itself.
8283 int NumOperands = CB->getNumOperands() - 1;
8284
8285 // Check input arguments. Doing so before unpoisoning output arguments, so
8286 // that we won't overwrite uninit values before checking them.
8287 for (int i = OutputArgs; i < NumOperands; i++) {
8288 Value *Operand = CB->getOperand(i);
8289 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
8290 /*isOutput*/ false);
8291 }
8292 // Unpoison output arguments. This must happen before the actual InlineAsm
8293 // call, so that the shadow for memory published in the asm() statement
8294 // remains valid.
8295 for (int i = 0; i < OutputArgs; i++) {
8296 Value *Operand = CB->getOperand(i);
8297 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
8298 /*isOutput*/ true);
8299 }
8300
8301 setShadow(&I, getCleanShadow(&I));
8302 setOrigin(&I, getCleanOrigin());
8303 }
8304
8305 void visitFreezeInst(FreezeInst &I) {
8306 // Freeze always returns a fully defined value.
8307 setShadow(&I, getCleanShadow(&I));
8308 setOrigin(&I, getCleanOrigin());
8309 }
8310
8311 void visitInstruction(Instruction &I) {
8312 // Everything else: stop propagating and check for poisoned shadow.
8313 if (Opts.msan_dump_strict_instructions)
8314 dumpInst(I, "Strict");
8315 LLVM_DEBUG(dbgs() << "DEFAULT: " << I << "\n");
8316 for (size_t i = 0, n = I.getNumOperands(); i < n; i++) {
8317 Value *Operand = I.getOperand(i);
8318 if (Operand->getType()->isSized())
8319 insertCheckShadowOf(Operand, &I);
8320 }
8321 setShadow(&I, getCleanShadow(&I));
8322 setOrigin(&I, getCleanOrigin());
8323 }
8324};
8325
8326struct VarArgHelperBase : public VarArgHelper {
8327 Function &F;
8328 MemorySanitizer &MS;
8329 MemorySanitizerVisitor &MSV;
8330 SmallVector<CallInst *, 16> VAStartInstrumentationList;
8331 const unsigned VAListTagSize;
8332
8333 VarArgHelperBase(Function &F, MemorySanitizer &MS,
8334 MemorySanitizerVisitor &MSV, unsigned VAListTagSize)
8335 : F(F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
8336
8337 Value *getShadowAddrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
8338 Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
8339 return IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
8340 }
8341
8342 /// Compute the shadow address for a given va_arg.
8343 Value *getShadowPtrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
8344 return IRB.CreatePtrAdd(
8345 MS.VAArgTLS, ConstantInt::get(MS.IntptrTy, ArgOffset), "_msarg_va_s");
8346 }
8347
8348 /// Compute the shadow address for a given va_arg.
8349 Value *getShadowPtrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset,
8350 unsigned ArgSize) {
8351 // Make sure we don't overflow __msan_va_arg_tls.
8352 if (ArgOffset + ArgSize > kParamTLSSize)
8353 return nullptr;
8354 return getShadowPtrForVAArgument(IRB, ArgOffset);
8355 }
8356
8357 /// Compute the origin address for a given va_arg.
8358 Value *getOriginPtrForVAArgument(IRBuilder<> &IRB, int ArgOffset) {
8359 // getOriginPtrForVAArgument() is always called after
8360 // getShadowPtrForVAArgument(), so __msan_va_arg_origin_tls can never
8361 // overflow.
8362 return IRB.CreatePtrAdd(MS.VAArgOriginTLS,
8363 ConstantInt::get(MS.IntptrTy, ArgOffset),
8364 "_msarg_va_o");
8365 }
8366
8367 void CleanUnusedTLS(IRBuilder<> &IRB, Value *ShadowBase,
8368 unsigned BaseOffset) {
8369 // The tails of __msan_va_arg_tls is not large enough to fit full
8370 // value shadow, but it will be copied to backup anyway. Make it
8371 // clean.
8372 if (BaseOffset >= kParamTLSSize)
8373 return;
8374 Value *TailSize =
8375 ConstantInt::getSigned(IRB.getInt32Ty(), kParamTLSSize - BaseOffset);
8376 IRB.CreateMemSet(ShadowBase, ConstantInt::getNullValue(IRB.getInt8Ty()),
8377 TailSize, Align(8));
8378 }
8379
8380 void unpoisonVAListTagForInst(IntrinsicInst &I) {
8381 IRBuilder<> IRB(&I);
8382 Value *VAListTag = I.getArgOperand(0);
8383 const Align Alignment = Align(8);
8384 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
8385 VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
8386 // Unpoison the whole __va_list_tag.
8387 IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
8388 VAListTagSize, Alignment, false);
8389 }
8390
8391 void visitVAStartInst(VAStartInst &I) override {
8392 if (F.getCallingConv() == CallingConv::Win64)
8393 return;
8394 VAStartInstrumentationList.push_back(&I);
8395 unpoisonVAListTagForInst(I);
8396 }
8397
8398 void visitVACopyInst(VACopyInst &I) override {
8399 if (F.getCallingConv() == CallingConv::Win64)
8400 return;
8401 unpoisonVAListTagForInst(I);
8402 }
8403};
8404
8405/// AMD64-specific implementation of VarArgHelper.
8406struct VarArgAMD64Helper : public VarArgHelperBase {
8407 // An unfortunate workaround for asymmetric lowering of va_arg stuff.
8408 // See a comment in visitCallBase for more details.
8409 static const unsigned AMD64GpEndOffset = 48; // AMD64 ABI Draft 0.99.6 p3.5.7
8410 static const unsigned AMD64FpEndOffsetSSE = 176;
8411 // If SSE is disabled, fp_offset in va_list is zero.
8412 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
8413
8414 unsigned AMD64FpEndOffset;
8415 AllocaInst *VAArgTLSCopy = nullptr;
8416 AllocaInst *VAArgTLSOriginCopy = nullptr;
8417 Value *VAArgOverflowSize = nullptr;
8418
8419 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8420
8421 VarArgAMD64Helper(Function &F, MemorySanitizer &MS,
8422 MemorySanitizerVisitor &MSV)
8423 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/24) {
8424 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
8425 for (const auto &Attr : F.getAttributes().getFnAttrs()) {
8426 if (Attr.isStringAttribute() &&
8427 (Attr.getKindAsString() == "target-features")) {
8428 if (Attr.getValueAsString().contains("-sse"))
8429 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
8430 break;
8431 }
8432 }
8433 }
8434
8435 ArgKind classifyArgument(Value *arg) {
8436 // A very rough approximation of X86_64 argument classification rules.
8437 Type *T = arg->getType();
8438 if (T->isX86_FP80Ty())
8439 return AK_Memory;
8440 if (T->isFPOrFPVectorTy())
8441 return AK_FloatingPoint;
8442 if (T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64)
8443 return AK_GeneralPurpose;
8444 if (T->isPointerTy())
8445 return AK_GeneralPurpose;
8446 return AK_Memory;
8447 }
8448
8449 // For VarArg functions, store the argument shadow in an ABI-specific format
8450 // that corresponds to va_list layout.
8451 // We do this because Clang lowers va_arg in the frontend, and this pass
8452 // only sees the low level code that deals with va_list internals.
8453 // A much easier alternative (provided that Clang emits va_arg instructions)
8454 // would have been to associate each live instance of va_list with a copy of
8455 // MSanParamTLS, and extract shadow on va_arg() call in the argument list
8456 // order.
8457 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8458 unsigned GpOffset = 0;
8459 unsigned FpOffset = AMD64GpEndOffset;
8460 unsigned OverflowOffset = AMD64FpEndOffset;
8461 const DataLayout &DL = F.getDataLayout();
8462
8463 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8464 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8465 bool IsByVal = CB.isByValArgument(ArgNo);
8466 if (IsByVal) {
8467 // ByVal arguments always go to the overflow area.
8468 // Fixed arguments passed through the overflow area will be stepped
8469 // over by va_start, so don't count them towards the offset.
8470 if (IsFixed)
8471 continue;
8472 assert(A->getType()->isPointerTy());
8473 Type *RealTy = CB.getParamByValType(ArgNo);
8474 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
8475 uint64_t AlignedSize = alignTo(ArgSize, 8);
8476 unsigned BaseOffset = OverflowOffset;
8477 Value *ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8478 Value *OriginBase = nullptr;
8479 if (MS.TrackOrigins)
8480 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8481 OverflowOffset += AlignedSize;
8482
8483 if (OverflowOffset > kParamTLSSize) {
8484 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8485 continue; // We have no space to copy shadow there.
8486 }
8487
8488 Value *ShadowPtr, *OriginPtr;
8489 std::tie(ShadowPtr, OriginPtr) =
8490 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), kShadowTLSAlignment,
8491 /*isStore*/ false);
8492 IRB.CreateMemCpy(ShadowBase, kShadowTLSAlignment, ShadowPtr,
8493 kShadowTLSAlignment, ArgSize);
8494 if (MS.TrackOrigins)
8495 IRB.CreateMemCpy(OriginBase, kShadowTLSAlignment, OriginPtr,
8496 kShadowTLSAlignment, ArgSize);
8497 } else {
8498 ArgKind AK = classifyArgument(A);
8499 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
8500 AK = AK_Memory;
8501 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
8502 AK = AK_Memory;
8503 Value *ShadowBase, *OriginBase = nullptr;
8504 switch (AK) {
8505 case AK_GeneralPurpose:
8506 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
8507 if (MS.TrackOrigins)
8508 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
8509 GpOffset += 8;
8510 assert(GpOffset <= kParamTLSSize);
8511 break;
8512 case AK_FloatingPoint:
8513 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
8514 if (MS.TrackOrigins)
8515 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
8516 FpOffset += 16;
8517 assert(FpOffset <= kParamTLSSize);
8518 break;
8519 case AK_Memory:
8520 if (IsFixed)
8521 continue;
8522 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8523 uint64_t AlignedSize = alignTo(ArgSize, 8);
8524 unsigned BaseOffset = OverflowOffset;
8525 ShadowBase = getShadowPtrForVAArgument(IRB, OverflowOffset);
8526 if (MS.TrackOrigins) {
8527 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
8528 }
8529 OverflowOffset += AlignedSize;
8530 if (OverflowOffset > kParamTLSSize) {
8531 // We have no space to copy shadow there.
8532 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
8533 continue;
8534 }
8535 }
8536 // Take fixed arguments into account for GpOffset and FpOffset,
8537 // but don't actually store shadows for them.
8538 // TODO(glider): don't call get*PtrForVAArgument() for them.
8539 if (IsFixed)
8540 continue;
8541 Value *Shadow = MSV.getShadow(A);
8542 IRB.CreateAlignedStore(Shadow, ShadowBase, kShadowTLSAlignment);
8543 if (MS.TrackOrigins) {
8544 Value *Origin = MSV.getOrigin(A);
8545 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
8546 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
8548 }
8549 }
8550 }
8551 Constant *OverflowSize =
8552 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
8553 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8554 }
8555
8556 void finalizeInstrumentation() override {
8557 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8558 "finalizeInstrumentation called twice");
8559 if (!VAStartInstrumentationList.empty()) {
8560 // If there is a va_start in this function, make a backup copy of
8561 // va_arg_tls somewhere in the function entry block.
8562 IRBuilder<> IRB(MSV.FnPrologueEnd);
8563 VAArgOverflowSize =
8564 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8565 Value *CopySize = IRB.CreateAdd(
8566 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
8567 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8568 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8569 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8570 CopySize, kShadowTLSAlignment, false);
8571
8572 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8573 Intrinsic::umin, CopySize,
8574 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
8575 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8576 kShadowTLSAlignment, SrcSize);
8577 if (MS.TrackOrigins) {
8578 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8579 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
8580 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
8581 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
8582 }
8583 }
8584
8585 // Instrument va_start.
8586 // Copy va_list shadow from the backup copy of the TLS contents.
8587 for (CallInst *OrigInst : VAStartInstrumentationList) {
8588 NextNodeIRBuilder IRB(OrigInst);
8589 Value *VAListTag = OrigInst->getArgOperand(0);
8590
8591 Value *RegSaveAreaPtrPtr =
8592 IRB.CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 16));
8593 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
8594 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8595 const Align Alignment = Align(16);
8596 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8597 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8598 Alignment, /*isStore*/ true);
8599 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
8600 AMD64FpEndOffset);
8601 if (MS.TrackOrigins)
8602 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
8603 Alignment, AMD64FpEndOffset);
8604 Value *OverflowArgAreaPtrPtr =
8605 IRB.CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, 8));
8606 Value *OverflowArgAreaPtr =
8607 IRB.CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
8608 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
8609 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
8610 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
8611 Alignment, /*isStore*/ true);
8612 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
8613 AMD64FpEndOffset);
8614 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
8615 VAArgOverflowSize);
8616 if (MS.TrackOrigins) {
8617 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
8618 AMD64FpEndOffset);
8619 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
8620 VAArgOverflowSize);
8621 }
8622 }
8623 }
8624};
8625
8626/// AArch64-specific implementation of VarArgHelper.
8627struct VarArgAArch64Helper : public VarArgHelperBase {
8628 static const unsigned kAArch64GrArgSize = 64;
8629 static const unsigned kAArch64VrArgSize = 128;
8630
8631 static const unsigned AArch64GrBegOffset = 0;
8632 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
8633 // Make VR space aligned to 16 bytes.
8634 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
8635 static const unsigned AArch64VrEndOffset =
8636 AArch64VrBegOffset + kAArch64VrArgSize;
8637 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
8638
8639 AllocaInst *VAArgTLSCopy = nullptr;
8640 Value *VAArgOverflowSize = nullptr;
8641
8642 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
8643
8644 VarArgAArch64Helper(Function &F, MemorySanitizer &MS,
8645 MemorySanitizerVisitor &MSV)
8646 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/32) {}
8647
8648 // A very rough approximation of aarch64 argument classification rules.
8649 std::pair<ArgKind, uint64_t> classifyArgument(Type *T) {
8650 if (T->isIntOrPtrTy() && T->getPrimitiveSizeInBits() <= 64)
8651 return {AK_GeneralPurpose, 1};
8652 if (T->isFloatingPointTy() && T->getPrimitiveSizeInBits() <= 128)
8653 return {AK_FloatingPoint, 1};
8654
8655 if (T->isArrayTy()) {
8656 auto R = classifyArgument(T->getArrayElementType());
8657 R.second *= T->getScalarType()->getArrayNumElements();
8658 return R;
8659 }
8660
8661 if (const FixedVectorType *FV = dyn_cast<FixedVectorType>(T)) {
8662 auto R = classifyArgument(FV->getScalarType());
8663 R.second *= FV->getNumElements();
8664 return R;
8665 }
8666
8667 LLVM_DEBUG(errs() << "Unknown vararg type: " << *T << "\n");
8668 return {AK_Memory, 0};
8669 }
8670
8671 // The instrumentation stores the argument shadow in a non ABI-specific
8672 // format because it does not know which argument is named (since Clang,
8673 // like x86_64 case, lowers the va_args in the frontend and this pass only
8674 // sees the low level code that deals with va_list internals).
8675 // The first seven GR registers are saved in the first 56 bytes of the
8676 // va_arg tls arra, followed by the first 8 FP/SIMD registers, and then
8677 // the remaining arguments.
8678 // Using constant offset within the va_arg TLS array allows fast copy
8679 // in the finalize instrumentation.
8680 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8681 unsigned GrOffset = AArch64GrBegOffset;
8682 unsigned VrOffset = AArch64VrBegOffset;
8683 unsigned OverflowOffset = AArch64VAEndOffset;
8684
8685 const DataLayout &DL = F.getDataLayout();
8686 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8687 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8688 auto [AK, RegNum] = classifyArgument(A->getType());
8689 if (AK == AK_GeneralPurpose &&
8690 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
8691 AK = AK_Memory;
8692 if (AK == AK_FloatingPoint &&
8693 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
8694 AK = AK_Memory;
8695 Value *Base;
8696 switch (AK) {
8697 case AK_GeneralPurpose:
8698 Base = getShadowPtrForVAArgument(IRB, GrOffset);
8699 GrOffset += 8 * RegNum;
8700 break;
8701 case AK_FloatingPoint:
8702 Base = getShadowPtrForVAArgument(IRB, VrOffset);
8703 VrOffset += 16 * RegNum;
8704 break;
8705 case AK_Memory:
8706 // Don't count fixed arguments in the overflow area - va_start will
8707 // skip right over them.
8708 if (IsFixed)
8709 continue;
8710 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8711 uint64_t AlignedSize = alignTo(ArgSize, 8);
8712 unsigned BaseOffset = OverflowOffset;
8713 Base = getShadowPtrForVAArgument(IRB, BaseOffset);
8714 OverflowOffset += AlignedSize;
8715 if (OverflowOffset > kParamTLSSize) {
8716 // We have no space to copy shadow there.
8717 CleanUnusedTLS(IRB, Base, BaseOffset);
8718 continue;
8719 }
8720 break;
8721 }
8722 // Count Gp/Vr fixed arguments to their respective offsets, but don't
8723 // bother to actually store a shadow.
8724 if (IsFixed)
8725 continue;
8726 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
8727 }
8728 Constant *OverflowSize =
8729 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
8730 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
8731 }
8732
8733 // Retrieve a va_list field of 'void*' size.
8734 Value *getVAField64(IRBuilder<> &IRB, Value *VAListTag, int offset) {
8735 Value *SaveAreaPtrPtr =
8736 IRB.CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8737 return IRB.CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
8738 }
8739
8740 // Retrieve a va_list field of 'int' size.
8741 Value *getVAField32(IRBuilder<> &IRB, Value *VAListTag, int offset) {
8742 Value *SaveAreaPtr =
8743 IRB.CreatePtrAdd(VAListTag, ConstantInt::get(MS.IntptrTy, offset));
8744 Value *SaveArea32 = IRB.CreateLoad(IRB.getInt32Ty(), SaveAreaPtr);
8745 return IRB.CreateSExt(SaveArea32, MS.IntptrTy);
8746 }
8747
8748 void finalizeInstrumentation() override {
8749 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
8750 "finalizeInstrumentation called twice");
8751 if (!VAStartInstrumentationList.empty()) {
8752 // If there is a va_start in this function, make a backup copy of
8753 // va_arg_tls somewhere in the function entry block.
8754 IRBuilder<> IRB(MSV.FnPrologueEnd);
8755 VAArgOverflowSize =
8756 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8757 Value *CopySize = IRB.CreateAdd(
8758 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
8759 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8760 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8761 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8762 CopySize, kShadowTLSAlignment, false);
8763
8764 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8765 Intrinsic::umin, CopySize,
8766 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
8767 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8768 kShadowTLSAlignment, SrcSize);
8769 }
8770
8771 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
8772 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
8773
8774 // Instrument va_start, copy va_list shadow from the backup copy of
8775 // the TLS contents.
8776 for (CallInst *OrigInst : VAStartInstrumentationList) {
8777 NextNodeIRBuilder IRB(OrigInst);
8778
8779 Value *VAListTag = OrigInst->getArgOperand(0);
8780
8781 // The variadic ABI for AArch64 creates two areas to save the incoming
8782 // argument registers (one for 64-bit general register xn-x7 and another
8783 // for 128-bit FP/SIMD vn-v7).
8784 // We need then to propagate the shadow arguments on both regions
8785 // 'va::__gr_top + va::__gr_offs' and 'va::__vr_top + va::__vr_offs'.
8786 // The remaining arguments are saved on shadow for 'va::stack'.
8787 // One caveat is it requires only to propagate the non-named arguments,
8788 // however on the call site instrumentation 'all' the arguments are
8789 // saved. So to copy the shadow values from the va_arg TLS array
8790 // we need to adjust the offset for both GR and VR fields based on
8791 // the __{gr,vr}_offs value (since they are stores based on incoming
8792 // named arguments).
8793 Type *RegSaveAreaPtrTy = IRB.getPtrTy();
8794
8795 // Read the stack pointer from the va_list.
8796 Value *StackSaveAreaPtr =
8797 IRB.CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
8798
8799 // Read both the __gr_top and __gr_off and add them up.
8800 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
8801 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
8802
8803 Value *GrRegSaveAreaPtr = IRB.CreateIntToPtr(
8804 IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
8805
8806 // Read both the __vr_top and __vr_off and add them up.
8807 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
8808 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
8809
8810 Value *VrRegSaveAreaPtr = IRB.CreateIntToPtr(
8811 IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
8812
8813 // It does not know how many named arguments is being used and, on the
8814 // callsite all the arguments were saved. Since __gr_off is defined as
8815 // '0 - ((8 - named_gr) * 8)', the idea is to just propagate the variadic
8816 // argument by ignoring the bytes of shadow from named arguments.
8817 Value *GrRegSaveAreaShadowPtrOff =
8818 IRB.CreateAdd(GrArgSize, GrOffSaveArea);
8819
8820 Value *GrRegSaveAreaShadowPtr =
8821 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8822 Align(8), /*isStore*/ true)
8823 .first;
8824
8825 Value *GrSrcPtr =
8826 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy, GrRegSaveAreaShadowPtrOff);
8827 Value *GrCopySize = IRB.CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
8828
8829 IRB.CreateMemCpy(GrRegSaveAreaShadowPtr, Align(8), GrSrcPtr, Align(8),
8830 GrCopySize);
8831
8832 // Again, but for FP/SIMD values.
8833 Value *VrRegSaveAreaShadowPtrOff =
8834 IRB.CreateAdd(VrArgSize, VrOffSaveArea);
8835
8836 Value *VrRegSaveAreaShadowPtr =
8837 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8838 Align(8), /*isStore*/ true)
8839 .first;
8840
8841 Value *VrSrcPtr = IRB.CreateInBoundsPtrAdd(
8842 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy,
8843 IRB.getInt32(AArch64VrBegOffset)),
8844 VrRegSaveAreaShadowPtrOff);
8845 Value *VrCopySize = IRB.CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
8846
8847 IRB.CreateMemCpy(VrRegSaveAreaShadowPtr, Align(8), VrSrcPtr, Align(8),
8848 VrCopySize);
8849
8850 // And finally for remaining arguments.
8851 Value *StackSaveAreaShadowPtr =
8852 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.getInt8Ty(),
8853 Align(16), /*isStore*/ true)
8854 .first;
8855
8856 Value *StackSrcPtr = IRB.CreateInBoundsPtrAdd(
8857 VAArgTLSCopy, IRB.getInt32(AArch64VAEndOffset));
8858
8859 IRB.CreateMemCpy(StackSaveAreaShadowPtr, Align(16), StackSrcPtr,
8860 Align(16), VAArgOverflowSize);
8861 }
8862 }
8863};
8864
8865/// PowerPC64-specific implementation of VarArgHelper.
8866struct VarArgPowerPC64Helper : public VarArgHelperBase {
8867 AllocaInst *VAArgTLSCopy = nullptr;
8868 Value *VAArgSize = nullptr;
8869
8870 VarArgPowerPC64Helper(Function &F, MemorySanitizer &MS,
8871 MemorySanitizerVisitor &MSV)
8872 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/8) {}
8873
8874 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
8875 // For PowerPC, we need to deal with alignment of stack arguments -
8876 // they are mostly aligned to 8 bytes, but vectors and i128 arrays
8877 // are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
8878 // For that reason, we compute current offset from stack pointer (which is
8879 // always properly aligned), and offset for the first vararg, then subtract
8880 // them.
8881 unsigned VAArgBase;
8882 Triple TargetTriple(F.getParent()->getTargetTriple());
8883 // Parameter save area starts at 48 bytes from frame pointer for ABIv1,
8884 // and 32 bytes for ABIv2. This is usually determined by target
8885 // endianness, but in theory could be overridden by function attribute.
8886 if (TargetTriple.isPPC64ELFv2ABI())
8887 VAArgBase = 32;
8888 else
8889 VAArgBase = 48;
8890 unsigned VAArgOffset = VAArgBase;
8891 const DataLayout &DL = F.getDataLayout();
8892 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
8893 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
8894 bool IsByVal = CB.isByValArgument(ArgNo);
8895 if (IsByVal) {
8896 assert(A->getType()->isPointerTy());
8897 Type *RealTy = CB.getParamByValType(ArgNo);
8898 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
8899 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(8));
8900 if (ArgAlign < 8)
8901 ArgAlign = Align(8);
8902 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
8903 if (!IsFixed) {
8904 Value *Base =
8905 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8906 if (Base) {
8907 Value *AShadowPtr, *AOriginPtr;
8908 std::tie(AShadowPtr, AOriginPtr) =
8909 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
8910 kShadowTLSAlignment, /*isStore*/ false);
8911
8912 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
8913 kShadowTLSAlignment, ArgSize);
8914 }
8915 }
8916 VAArgOffset += alignTo(ArgSize, Align(8));
8917 } else {
8918 Value *Base;
8919 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
8920 Align ArgAlign = Align(8);
8921 if (A->getType()->isArrayTy()) {
8922 // Arrays are aligned to element size, except for long double
8923 // arrays, which are aligned to 8 bytes.
8924 Type *ElementTy = A->getType()->getArrayElementType();
8925 if (!ElementTy->isPPC_FP128Ty())
8926 ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
8927 } else if (A->getType()->isVectorTy()) {
8928 // Vectors are naturally aligned.
8929 ArgAlign = Align(ArgSize);
8930 }
8931 if (ArgAlign < 8)
8932 ArgAlign = Align(8);
8933 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
8934 if (DL.isBigEndian()) {
8935 // Adjusting the shadow for argument with size < 8 to match the
8936 // placement of bits in big endian system
8937 if (ArgSize < 8)
8938 VAArgOffset += (8 - ArgSize);
8939 }
8940 if (!IsFixed) {
8941 Base =
8942 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
8943 if (Base)
8944 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
8945 }
8946 VAArgOffset += ArgSize;
8947 VAArgOffset = alignTo(VAArgOffset, Align(8));
8948 }
8949 if (IsFixed)
8950 VAArgBase = VAArgOffset;
8951 }
8952
8953 Constant *TotalVAArgSize =
8954 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
8955 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
8956 // a new class member i.e. it is the total size of all VarArgs.
8957 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
8958 }
8959
8960 void finalizeInstrumentation() override {
8961 assert(!VAArgSize && !VAArgTLSCopy &&
8962 "finalizeInstrumentation called twice");
8963 IRBuilder<> IRB(MSV.FnPrologueEnd);
8964 VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
8965 Value *CopySize = VAArgSize;
8966
8967 if (!VAStartInstrumentationList.empty()) {
8968 // If there is a va_start in this function, make a backup copy of
8969 // va_arg_tls somewhere in the function entry block.
8970
8971 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
8972 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
8973 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
8974 CopySize, kShadowTLSAlignment, false);
8975
8976 Value *SrcSize = IRB.CreateBinaryIntrinsic(
8977 Intrinsic::umin, CopySize,
8978 ConstantInt::get(IRB.getInt64Ty(), kParamTLSSize));
8979 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
8980 kShadowTLSAlignment, SrcSize);
8981 }
8982
8983 // Instrument va_start.
8984 // Copy va_list shadow from the backup copy of the TLS contents.
8985 for (CallInst *OrigInst : VAStartInstrumentationList) {
8986 NextNodeIRBuilder IRB(OrigInst);
8987 Value *VAListTag = OrigInst->getArgOperand(0);
8988 Value *RegSaveAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
8989
8990 RegSaveAreaPtrPtr = IRB.CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
8991
8992 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
8993 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
8994 const DataLayout &DL = F.getDataLayout();
8995 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
8996 const Align Alignment = Align(IntptrSize);
8997 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
8998 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
8999 Alignment, /*isStore*/ true);
9000 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9001 CopySize);
9002 }
9003 }
9004};
9005
9006/// PowerPC32-specific implementation of VarArgHelper.
9007struct VarArgPowerPC32Helper : public VarArgHelperBase {
9008 AllocaInst *VAArgTLSCopy = nullptr;
9009 Value *VAArgSize = nullptr;
9010
9011 VarArgPowerPC32Helper(Function &F, MemorySanitizer &MS,
9012 MemorySanitizerVisitor &MSV)
9013 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/12) {}
9014
9015 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9016 unsigned VAArgBase;
9017 // Parameter save area is 8 bytes from frame pointer in PPC32
9018 VAArgBase = 8;
9019 unsigned VAArgOffset = VAArgBase;
9020 const DataLayout &DL = F.getDataLayout();
9021 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9022 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9023 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9024 bool IsByVal = CB.isByValArgument(ArgNo);
9025 if (IsByVal) {
9026 assert(A->getType()->isPointerTy());
9027 Type *RealTy = CB.getParamByValType(ArgNo);
9028 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
9029 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(IntptrSize));
9030 if (ArgAlign < IntptrSize)
9031 ArgAlign = Align(IntptrSize);
9032 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9033 if (!IsFixed) {
9034 Value *Base =
9035 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
9036 if (Base) {
9037 Value *AShadowPtr, *AOriginPtr;
9038 std::tie(AShadowPtr, AOriginPtr) =
9039 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
9040 kShadowTLSAlignment, /*isStore*/ false);
9041
9042 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
9043 kShadowTLSAlignment, ArgSize);
9044 }
9045 }
9046 VAArgOffset += alignTo(ArgSize, Align(IntptrSize));
9047 } else {
9048 Value *Base;
9049 Type *ArgTy = A->getType();
9050
9051 // On PPC 32 floating point variable arguments are stored in separate
9052 // area: fp_save_area = reg_save_area + 4*8. We do not copy shaodow for
9053 // them as they will be found when checking call arguments.
9054 if (!ArgTy->isFloatingPointTy()) {
9055 uint64_t ArgSize = DL.getTypeAllocSize(ArgTy);
9056 Align ArgAlign = Align(IntptrSize);
9057 if (ArgTy->isArrayTy()) {
9058 // Arrays are aligned to element size, except for long double
9059 // arrays, which are aligned to 8 bytes.
9060 Type *ElementTy = ArgTy->getArrayElementType();
9061 if (!ElementTy->isPPC_FP128Ty())
9062 ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
9063 } else if (ArgTy->isVectorTy()) {
9064 // Vectors are naturally aligned.
9065 ArgAlign = Align(ArgSize);
9066 }
9067 if (ArgAlign < IntptrSize)
9068 ArgAlign = Align(IntptrSize);
9069 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9070 if (DL.isBigEndian()) {
9071 // Adjusting the shadow for argument with size < IntptrSize to match
9072 // the placement of bits in big endian system
9073 if (ArgSize < IntptrSize)
9074 VAArgOffset += (IntptrSize - ArgSize);
9075 }
9076 if (!IsFixed) {
9077 Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
9078 ArgSize);
9079 if (Base)
9080 IRB.CreateAlignedStore(MSV.getShadow(A), Base,
9082 }
9083 VAArgOffset += ArgSize;
9084 VAArgOffset = alignTo(VAArgOffset, Align(IntptrSize));
9085 }
9086 }
9087 }
9088
9089 Constant *TotalVAArgSize =
9090 ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
9091 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9092 // a new class member i.e. it is the total size of all VarArgs.
9093 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9094 }
9095
9096 void finalizeInstrumentation() override {
9097 assert(!VAArgSize && !VAArgTLSCopy &&
9098 "finalizeInstrumentation called twice");
9099 IRBuilder<> IRB(MSV.FnPrologueEnd);
9100 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9101 Value *CopySize = VAArgSize;
9102
9103 if (!VAStartInstrumentationList.empty()) {
9104 // If there is a va_start in this function, make a backup copy of
9105 // va_arg_tls somewhere in the function entry block.
9106
9107 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9108 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9109 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9110 CopySize, kShadowTLSAlignment, false);
9111
9112 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9113 Intrinsic::umin, CopySize,
9114 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9115 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9116 kShadowTLSAlignment, SrcSize);
9117 }
9118
9119 // Instrument va_start.
9120 // Copy va_list shadow from the backup copy of the TLS contents.
9121 for (CallInst *OrigInst : VAStartInstrumentationList) {
9122 NextNodeIRBuilder IRB(OrigInst);
9123 Value *VAListTag = OrigInst->getArgOperand(0);
9124 Value *RegSaveAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
9125 Value *RegSaveAreaSize = CopySize;
9126
9127 // In PPC32 va_list_tag is a struct
9128 RegSaveAreaPtrPtr =
9129 IRB.CreateAdd(RegSaveAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 8));
9130
9131 // On PPC 32 reg_save_area can only hold 32 bytes of data
9132 RegSaveAreaSize = IRB.CreateBinaryIntrinsic(
9133 Intrinsic::umin, CopySize, ConstantInt::get(MS.IntptrTy, 32));
9134
9135 RegSaveAreaPtrPtr = IRB.CreateIntToPtr(RegSaveAreaPtrPtr, MS.PtrTy);
9136 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
9137
9138 const DataLayout &DL = F.getDataLayout();
9139 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9140 const Align Alignment = Align(IntptrSize);
9141
9142 { // Copy reg save area
9143 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9144 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9145 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9146 Alignment, /*isStore*/ true);
9147 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy,
9148 Alignment, RegSaveAreaSize);
9149
9150 RegSaveAreaShadowPtr =
9151 IRB.CreatePtrToInt(RegSaveAreaShadowPtr, MS.IntptrTy);
9152 Value *FPSaveArea = IRB.CreateAdd(RegSaveAreaShadowPtr,
9153 ConstantInt::get(MS.IntptrTy, 32));
9154 FPSaveArea = IRB.CreateIntToPtr(FPSaveArea, MS.PtrTy);
9155 // We fill fp shadow with zeroes as uninitialized fp args should have
9156 // been found during call base check
9157 IRB.CreateMemSet(FPSaveArea, ConstantInt::getNullValue(IRB.getInt8Ty()),
9158 ConstantInt::get(MS.IntptrTy, 32), Alignment);
9159 }
9160
9161 { // Copy overflow area
9162 // RegSaveAreaSize is min(CopySize, 32) -> no overflow can occur
9163 Value *OverflowAreaSize = IRB.CreateSub(CopySize, RegSaveAreaSize);
9164
9165 Value *OverflowAreaPtrPtr = IRB.CreatePtrToInt(VAListTag, MS.IntptrTy);
9166 OverflowAreaPtrPtr =
9167 IRB.CreateAdd(OverflowAreaPtrPtr, ConstantInt::get(MS.IntptrTy, 4));
9168 OverflowAreaPtrPtr = IRB.CreateIntToPtr(OverflowAreaPtrPtr, MS.PtrTy);
9169
9170 Value *OverflowAreaPtr = IRB.CreateLoad(MS.PtrTy, OverflowAreaPtrPtr);
9171
9172 Value *OverflowAreaShadowPtr, *OverflowAreaOriginPtr;
9173 std::tie(OverflowAreaShadowPtr, OverflowAreaOriginPtr) =
9174 MSV.getShadowOriginPtr(OverflowAreaPtr, IRB, IRB.getInt8Ty(),
9175 Alignment, /*isStore*/ true);
9176
9177 Value *OverflowVAArgTLSCopyPtr =
9178 IRB.CreatePtrToInt(VAArgTLSCopy, MS.IntptrTy);
9179 OverflowVAArgTLSCopyPtr =
9180 IRB.CreateAdd(OverflowVAArgTLSCopyPtr, RegSaveAreaSize);
9181
9182 OverflowVAArgTLSCopyPtr =
9183 IRB.CreateIntToPtr(OverflowVAArgTLSCopyPtr, MS.PtrTy);
9184 IRB.CreateMemCpy(OverflowAreaShadowPtr, Alignment,
9185 OverflowVAArgTLSCopyPtr, Alignment, OverflowAreaSize);
9186 }
9187 }
9188 }
9189};
9190
9191/// SystemZ-specific implementation of VarArgHelper.
9192struct VarArgSystemZHelper : public VarArgHelperBase {
9193 static const unsigned SystemZGpOffset = 16;
9194 static const unsigned SystemZGpEndOffset = 56;
9195 static const unsigned SystemZFpOffset = 128;
9196 static const unsigned SystemZFpEndOffset = 160;
9197 static const unsigned SystemZMaxVrArgs = 8;
9198 static const unsigned SystemZRegSaveAreaSize = 160;
9199 static const unsigned SystemZOverflowOffset = 160;
9200 static const unsigned SystemZVAListTagSize = 32;
9201 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
9202 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
9203
9204 bool IsSoftFloatABI;
9205 AllocaInst *VAArgTLSCopy = nullptr;
9206 AllocaInst *VAArgTLSOriginCopy = nullptr;
9207 Value *VAArgOverflowSize = nullptr;
9208
9209 enum class ArgKind {
9210 GeneralPurpose,
9211 FloatingPoint,
9212 Vector,
9213 Memory,
9214 Indirect,
9215 };
9216
9217 enum class ShadowExtension { None, Zero, Sign };
9218
9219 VarArgSystemZHelper(Function &F, MemorySanitizer &MS,
9220 MemorySanitizerVisitor &MSV)
9221 : VarArgHelperBase(F, MS, MSV, SystemZVAListTagSize),
9222 IsSoftFloatABI(F.getFnAttribute("use-soft-float").getValueAsBool()) {}
9223
9224 ArgKind classifyArgument(Type *T) {
9225 // T is a SystemZABIInfo::classifyArgumentType() output, and there are
9226 // only a few possibilities of what it can be. In particular, enums, single
9227 // element structs and large types have already been taken care of.
9228
9229 // Some i128 and fp128 arguments are converted to pointers only in the
9230 // back end.
9231 if (T->isIntegerTy(128) || T->isFP128Ty())
9232 return ArgKind::Indirect;
9233 if (T->isFloatingPointTy())
9234 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
9235 if (T->isIntegerTy() || T->isPointerTy())
9236 return ArgKind::GeneralPurpose;
9237 if (T->isVectorTy())
9238 return ArgKind::Vector;
9239 return ArgKind::Memory;
9240 }
9241
9242 ShadowExtension getShadowExtension(const CallBase &CB, unsigned ArgNo) {
9243 // ABI says: "One of the simple integer types no more than 64 bits wide.
9244 // ... If such an argument is shorter than 64 bits, replace it by a full
9245 // 64-bit integer representing the same number, using sign or zero
9246 // extension". Shadow for an integer argument has the same type as the
9247 // argument itself, so it can be sign or zero extended as well.
9248 bool ZExt = CB.paramHasAttr(ArgNo, Attribute::ZExt);
9249 bool SExt = CB.paramHasAttr(ArgNo, Attribute::SExt);
9250 if (ZExt) {
9251 assert(!SExt);
9252 return ShadowExtension::Zero;
9253 }
9254 if (SExt) {
9255 assert(!ZExt);
9256 return ShadowExtension::Sign;
9257 }
9258 return ShadowExtension::None;
9259 }
9260
9261 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9262 unsigned GpOffset = SystemZGpOffset;
9263 unsigned FpOffset = SystemZFpOffset;
9264 unsigned VrIndex = 0;
9265 unsigned OverflowOffset = SystemZOverflowOffset;
9266 const DataLayout &DL = F.getDataLayout();
9267 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9268 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9269 // SystemZABIInfo does not produce ByVal parameters.
9270 assert(!CB.isByValArgument(ArgNo));
9271 Type *T = A->getType();
9272 ArgKind AK = classifyArgument(T);
9273 if (AK == ArgKind::Indirect) {
9274 T = MS.PtrTy;
9275 AK = ArgKind::GeneralPurpose;
9276 }
9277 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
9278 AK = ArgKind::Memory;
9279 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
9280 AK = ArgKind::Memory;
9281 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
9282 AK = ArgKind::Memory;
9283 Value *ShadowBase = nullptr;
9284 Value *OriginBase = nullptr;
9285 ShadowExtension SE = ShadowExtension::None;
9286 switch (AK) {
9287 case ArgKind::GeneralPurpose: {
9288 // Always keep track of GpOffset, but store shadow only for varargs.
9289 uint64_t ArgSize = 8;
9290 if (GpOffset + ArgSize <= kParamTLSSize) {
9291 if (!IsFixed) {
9292 SE = getShadowExtension(CB, ArgNo);
9293 uint64_t GapSize = 0;
9294 if (SE == ShadowExtension::None) {
9295 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
9296 assert(ArgAllocSize <= ArgSize);
9297 GapSize = ArgSize - ArgAllocSize;
9298 }
9299 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
9300 if (MS.TrackOrigins)
9301 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
9302 }
9303 GpOffset += ArgSize;
9304 } else {
9305 GpOffset = kParamTLSSize;
9306 }
9307 break;
9308 }
9309 case ArgKind::FloatingPoint: {
9310 // Always keep track of FpOffset, but store shadow only for varargs.
9311 uint64_t ArgSize = 8;
9312 if (FpOffset + ArgSize <= kParamTLSSize) {
9313 if (!IsFixed) {
9314 // PoP says: "A short floating-point datum requires only the
9315 // left-most 32 bit positions of a floating-point register".
9316 // Therefore, in contrast to AK_GeneralPurpose and AK_Memory,
9317 // don't extend shadow and don't mind the gap.
9318 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
9319 if (MS.TrackOrigins)
9320 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
9321 }
9322 FpOffset += ArgSize;
9323 } else {
9324 FpOffset = kParamTLSSize;
9325 }
9326 break;
9327 }
9328 case ArgKind::Vector: {
9329 // Keep track of VrIndex. No need to store shadow, since vector varargs
9330 // go through AK_Memory.
9331 assert(IsFixed);
9332 VrIndex++;
9333 break;
9334 }
9335 case ArgKind::Memory: {
9336 // Keep track of OverflowOffset and store shadow only for varargs.
9337 // Ignore fixed args, since we need to copy only the vararg portion of
9338 // the overflow area shadow.
9339 if (!IsFixed) {
9340 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
9341 uint64_t ArgSize = alignTo(ArgAllocSize, 8);
9342 if (OverflowOffset + ArgSize <= kParamTLSSize) {
9343 SE = getShadowExtension(CB, ArgNo);
9344 uint64_t GapSize =
9345 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
9346 ShadowBase =
9347 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
9348 if (MS.TrackOrigins)
9349 OriginBase =
9350 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
9351 OverflowOffset += ArgSize;
9352 } else {
9353 OverflowOffset = kParamTLSSize;
9354 }
9355 }
9356 break;
9357 }
9358 case ArgKind::Indirect:
9359 llvm_unreachable("Indirect must be converted to GeneralPurpose");
9360 }
9361 if (ShadowBase == nullptr)
9362 continue;
9363 Value *Shadow = MSV.getShadow(A);
9364 if (SE != ShadowExtension::None)
9365 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.getInt64Ty(),
9366 /*Signed*/ SE == ShadowExtension::Sign);
9367 ShadowBase = IRB.CreateIntToPtr(ShadowBase, MS.PtrTy, "_msarg_va_s");
9368 IRB.CreateStore(Shadow, ShadowBase);
9369 if (MS.TrackOrigins) {
9370 Value *Origin = MSV.getOrigin(A);
9371 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
9372 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
9374 }
9375 }
9376 Constant *OverflowSize = ConstantInt::get(
9377 IRB.getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
9378 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
9379 }
9380
9381 void copyRegSaveArea(IRBuilder<> &IRB, Value *VAListTag) {
9382 Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
9383 IRB.CreateAdd(
9384 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9385 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
9386 MS.PtrTy);
9387 Value *RegSaveAreaPtr = IRB.CreateLoad(MS.PtrTy, RegSaveAreaPtrPtr);
9388 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9389 const Align Alignment = Align(8);
9390 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9391 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), Alignment,
9392 /*isStore*/ true);
9393 // TODO(iii): copy only fragments filled by visitCallBase()
9394 // TODO(iii): support packed-stack && !use-soft-float
9395 // For use-soft-float functions, it is enough to copy just the GPRs.
9396 unsigned RegSaveAreaSize =
9397 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
9398 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9399 RegSaveAreaSize);
9400 if (MS.TrackOrigins)
9401 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
9402 Alignment, RegSaveAreaSize);
9403 }
9404
9405 // FIXME: This implementation limits OverflowOffset to kParamTLSSize, so we
9406 // don't know real overflow size and can't clear shadow beyond kParamTLSSize.
9407 void copyOverflowArea(IRBuilder<> &IRB, Value *VAListTag) {
9408 Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
9409 IRB.CreateAdd(
9410 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9411 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
9412 MS.PtrTy);
9413 Value *OverflowArgAreaPtr = IRB.CreateLoad(MS.PtrTy, OverflowArgAreaPtrPtr);
9414 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
9415 const Align Alignment = Align(8);
9416 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
9417 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
9418 Alignment, /*isStore*/ true);
9419 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
9420 SystemZOverflowOffset);
9421 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
9422 VAArgOverflowSize);
9423 if (MS.TrackOrigins) {
9424 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
9425 SystemZOverflowOffset);
9426 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
9427 VAArgOverflowSize);
9428 }
9429 }
9430
9431 void finalizeInstrumentation() override {
9432 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
9433 "finalizeInstrumentation called twice");
9434 if (!VAStartInstrumentationList.empty()) {
9435 // If there is a va_start in this function, make a backup copy of
9436 // va_arg_tls somewhere in the function entry block.
9437 IRBuilder<> IRB(MSV.FnPrologueEnd);
9438 VAArgOverflowSize =
9439 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
9440 Value *CopySize =
9441 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
9442 VAArgOverflowSize);
9443 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9444 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9445 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9446 CopySize, kShadowTLSAlignment, false);
9447
9448 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9449 Intrinsic::umin, CopySize,
9450 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9451 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9452 kShadowTLSAlignment, SrcSize);
9453 if (MS.TrackOrigins) {
9454 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9455 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
9456 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
9457 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
9458 }
9459 }
9460
9461 // Instrument va_start.
9462 // Copy va_list shadow from the backup copy of the TLS contents.
9463 for (CallInst *OrigInst : VAStartInstrumentationList) {
9464 NextNodeIRBuilder IRB(OrigInst);
9465 Value *VAListTag = OrigInst->getArgOperand(0);
9466 copyRegSaveArea(IRB, VAListTag);
9467 copyOverflowArea(IRB, VAListTag);
9468 }
9469 }
9470};
9471
9472/// i386-specific implementation of VarArgHelper.
9473struct VarArgI386Helper : public VarArgHelperBase {
9474 AllocaInst *VAArgTLSCopy = nullptr;
9475 Value *VAArgSize = nullptr;
9476
9477 VarArgI386Helper(Function &F, MemorySanitizer &MS,
9478 MemorySanitizerVisitor &MSV)
9479 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/4) {}
9480
9481 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9482 const DataLayout &DL = F.getDataLayout();
9483 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9484 unsigned VAArgOffset = 0;
9485 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9486 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9487 bool IsByVal = CB.isByValArgument(ArgNo);
9488 if (IsByVal) {
9489 assert(A->getType()->isPointerTy());
9490 Type *RealTy = CB.getParamByValType(ArgNo);
9491 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
9492 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(IntptrSize));
9493 if (ArgAlign < IntptrSize)
9494 ArgAlign = Align(IntptrSize);
9495 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9496 if (!IsFixed) {
9497 Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9498 if (Base) {
9499 Value *AShadowPtr, *AOriginPtr;
9500 std::tie(AShadowPtr, AOriginPtr) =
9501 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
9502 kShadowTLSAlignment, /*isStore*/ false);
9503
9504 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
9505 kShadowTLSAlignment, ArgSize);
9506 }
9507 VAArgOffset += alignTo(ArgSize, Align(IntptrSize));
9508 }
9509 } else {
9510 Value *Base;
9511 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
9512 Align ArgAlign = Align(IntptrSize);
9513 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
9514 if (DL.isBigEndian()) {
9515 // Adjusting the shadow for argument with size < IntptrSize to match
9516 // the placement of bits in big endian system
9517 if (ArgSize < IntptrSize)
9518 VAArgOffset += (IntptrSize - ArgSize);
9519 }
9520 if (!IsFixed) {
9521 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9522 if (Base)
9523 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
9524 VAArgOffset += ArgSize;
9525 VAArgOffset = alignTo(VAArgOffset, Align(IntptrSize));
9526 }
9527 }
9528 }
9529
9530 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9531 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9532 // a new class member i.e. it is the total size of all VarArgs.
9533 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9534 }
9535
9536 void finalizeInstrumentation() override {
9537 assert(!VAArgSize && !VAArgTLSCopy &&
9538 "finalizeInstrumentation called twice");
9539 IRBuilder<> IRB(MSV.FnPrologueEnd);
9540 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9541 Value *CopySize = VAArgSize;
9542
9543 if (!VAStartInstrumentationList.empty()) {
9544 // If there is a va_start in this function, make a backup copy of
9545 // va_arg_tls somewhere in the function entry block.
9546 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9547 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9548 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9549 CopySize, kShadowTLSAlignment, false);
9550
9551 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9552 Intrinsic::umin, CopySize,
9553 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9554 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9555 kShadowTLSAlignment, SrcSize);
9556 }
9557
9558 // Instrument va_start.
9559 // Copy va_list shadow from the backup copy of the TLS contents.
9560 for (CallInst *OrigInst : VAStartInstrumentationList) {
9561 NextNodeIRBuilder IRB(OrigInst);
9562 Value *VAListTag = OrigInst->getArgOperand(0);
9563 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9564 Value *RegSaveAreaPtrPtr =
9565 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9566 PointerType::get(*MS.C, 0));
9567 Value *RegSaveAreaPtr =
9568 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9569 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9570 const DataLayout &DL = F.getDataLayout();
9571 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9572 const Align Alignment = Align(IntptrSize);
9573 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9574 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9575 Alignment, /*isStore*/ true);
9576 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9577 CopySize);
9578 }
9579 }
9580};
9581
9582/// Implementation of VarArgHelper that is used for ARM32, MIPS, RISCV,
9583/// LoongArch64.
9584struct VarArgGenericHelper : public VarArgHelperBase {
9585 AllocaInst *VAArgTLSCopy = nullptr;
9586 Value *VAArgSize = nullptr;
9587
9588 VarArgGenericHelper(Function &F, MemorySanitizer &MS,
9589 MemorySanitizerVisitor &MSV, const unsigned VAListTagSize)
9590 : VarArgHelperBase(F, MS, MSV, VAListTagSize) {}
9591
9592 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
9593 unsigned VAArgOffset = 0;
9594 const DataLayout &DL = F.getDataLayout();
9595 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9596 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
9597 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
9598 if (IsFixed)
9599 continue;
9600 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
9601 if (DL.isBigEndian()) {
9602 // Adjusting the shadow for argument with size < IntptrSize to match the
9603 // placement of bits in big endian system
9604 if (ArgSize < IntptrSize)
9605 VAArgOffset += (IntptrSize - ArgSize);
9606 }
9607 Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
9608 VAArgOffset += ArgSize;
9609 VAArgOffset = alignTo(VAArgOffset, IntptrSize);
9610 if (!Base)
9611 continue;
9612 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
9613 }
9614
9615 Constant *TotalVAArgSize = ConstantInt::get(MS.IntptrTy, VAArgOffset);
9616 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
9617 // a new class member i.e. it is the total size of all VarArgs.
9618 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
9619 }
9620
9621 void finalizeInstrumentation() override {
9622 assert(!VAArgSize && !VAArgTLSCopy &&
9623 "finalizeInstrumentation called twice");
9624 IRBuilder<> IRB(MSV.FnPrologueEnd);
9625 VAArgSize = IRB.CreateLoad(MS.IntptrTy, MS.VAArgOverflowSizeTLS);
9626 Value *CopySize = VAArgSize;
9627
9628 if (!VAStartInstrumentationList.empty()) {
9629 // If there is a va_start in this function, make a backup copy of
9630 // va_arg_tls somewhere in the function entry block.
9631 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
9632 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
9633 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
9634 CopySize, kShadowTLSAlignment, false);
9635
9636 Value *SrcSize = IRB.CreateBinaryIntrinsic(
9637 Intrinsic::umin, CopySize,
9638 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
9639 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
9640 kShadowTLSAlignment, SrcSize);
9641 }
9642
9643 // Instrument va_start.
9644 // Copy va_list shadow from the backup copy of the TLS contents.
9645 for (CallInst *OrigInst : VAStartInstrumentationList) {
9646 NextNodeIRBuilder IRB(OrigInst);
9647 Value *VAListTag = OrigInst->getArgOperand(0);
9648 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C);
9649 Value *RegSaveAreaPtrPtr =
9650 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
9651 PointerType::get(*MS.C, 0));
9652 Value *RegSaveAreaPtr =
9653 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
9654 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
9655 const DataLayout &DL = F.getDataLayout();
9656 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
9657 const Align Alignment = Align(IntptrSize);
9658 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
9659 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
9660 Alignment, /*isStore*/ true);
9661 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
9662 CopySize);
9663 }
9664 }
9665};
9666
9667// ARM32, Loongarch64, MIPS and RISCV share the same calling conventions
9668// regarding VAArgs.
9669using VarArgARM32Helper = VarArgGenericHelper;
9670using VarArgRISCVHelper = VarArgGenericHelper;
9671using VarArgMIPSHelper = VarArgGenericHelper;
9672using VarArgLoongArch64Helper = VarArgGenericHelper;
9673using VarArgHexagonHelper = VarArgGenericHelper;
9674
9675/// A no-op implementation of VarArgHelper.
9676struct VarArgNoOpHelper : public VarArgHelper {
9677 VarArgNoOpHelper(Function &F, MemorySanitizer &MS,
9678 MemorySanitizerVisitor &MSV) {}
9679
9680 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {}
9681
9682 void visitVAStartInst(VAStartInst &I) override {}
9683
9684 void visitVACopyInst(VACopyInst &I) override {}
9685
9686 void finalizeInstrumentation() override {}
9687};
9688
9689} // end anonymous namespace
9690
9691static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
9692 MemorySanitizerVisitor &Visitor) {
9693 // VarArg handling is only implemented on AMD64. False positives are possible
9694 // on other platforms.
9695 Triple TargetTriple(Func.getParent()->getTargetTriple());
9696
9697 if (TargetTriple.getArch() == Triple::x86)
9698 return new VarArgI386Helper(Func, Msan, Visitor);
9699
9700 if (TargetTriple.getArch() == Triple::x86_64)
9701 return new VarArgAMD64Helper(Func, Msan, Visitor);
9702
9703 if (TargetTriple.isARM())
9704 return new VarArgARM32Helper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9705
9706 if (TargetTriple.isAArch64())
9707 return new VarArgAArch64Helper(Func, Msan, Visitor);
9708
9709 if (TargetTriple.isSystemZ())
9710 return new VarArgSystemZHelper(Func, Msan, Visitor);
9711
9712 // On PowerPC32 VAListTag is a struct
9713 // {char, char, i16 padding, char *, char *}
9714 if (TargetTriple.isPPC32())
9715 return new VarArgPowerPC32Helper(Func, Msan, Visitor);
9716
9717 if (TargetTriple.isPPC64())
9718 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
9719
9720 if (TargetTriple.isRISCV32())
9721 return new VarArgRISCVHelper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9722
9723 if (TargetTriple.isRISCV64())
9724 return new VarArgRISCVHelper(Func, Msan, Visitor, /*VAListTagSize=*/8);
9725
9726 if (TargetTriple.isMIPS32())
9727 return new VarArgMIPSHelper(Func, Msan, Visitor, /*VAListTagSize=*/4);
9728
9729 if (TargetTriple.isMIPS64())
9730 return new VarArgMIPSHelper(Func, Msan, Visitor, /*VAListTagSize=*/8);
9731
9732 if (TargetTriple.isLoongArch64())
9733 return new VarArgLoongArch64Helper(Func, Msan, Visitor,
9734 /*VAListTagSize=*/8);
9735
9736 if (TargetTriple.getArch() == Triple::hexagon)
9737 return new VarArgHexagonHelper(Func, Msan, Visitor, /*VAListTagSize=*/12);
9738
9739 return new VarArgNoOpHelper(Func, Msan, Visitor);
9740}
9741
9742bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
9743 if (!CompileKernel && F.getName() == kMsanModuleCtorName)
9744 return false;
9745
9746 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
9747 return false;
9748
9749 MemorySanitizerVisitor Visitor(F, *this, TLI);
9750
9751 // Clear out memory attributes.
9753 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
9754 F.removeFnAttrs(B);
9755
9756 return Visitor.runOnFunction();
9757}
#define Success
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
uint64_t Imm
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
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:665
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 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.
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 const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static MemorySanitizerOptions resolveOptions(const InstrumentationOptions &Opts, MemorySanitizerOptions O)
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static const Align kShadowTLSAlignment
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static const PlatformMemoryMapParams Linux_Hexagon_MemoryMapParams_P
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
OddOrEvenLanes
@ kOddLanes
@ kEvenLanes
@ kBothLanes
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 VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static const MemoryMapParams Linux_Hexagon_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static const unsigned kRetvalTLSSize
static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
const char kMsanModuleCtorName[]
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
#define T
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
if(PassOpts->AAPipeline)
SmallVector< MachineOperand, 4 > 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:453
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:44
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition Constant.h:65
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:62
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:716
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:440
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:2669
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition IRBuilder.h:2024
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition IRBuilder.h:1880
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Definition IRBuilder.h:507
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:2723
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:2657
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition IRBuilder.h:535
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition IRBuilder.h:1934
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:651
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2297
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2716
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:2133
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2238
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1528
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:522
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Definition IRBuilder.h:455
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2092
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition IRBuilder.h:527
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1469
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2386
IntegerType * getInt16Ty()
Fetch the type representing a 16-bit integer.
Definition IRBuilder.h:517
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2011
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Definition IRBuilder.h:1826
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:465
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition IRBuilder.h:2547
Value * CreateNot(Value *V, const Twine &Name="")
Definition IRBuilder.h:1850
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2382
LLVM_ABI DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Definition IRBuilder.cpp:66
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1435
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2243
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended from a 64-bit value.
Definition IRBuilder.h:475
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:1907
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1507
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:596
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2121
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition IRBuilder.h:2691
LLVMContext & getContext() const
Definition IRBuilder.h:177
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1566
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:1925
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:1418
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2233
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Definition IRBuilder.h:2763
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2561
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2107
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:565
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:1727
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2414
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:2394
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2323
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
Definition IRBuilder.h:2758
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:196
Type * getVoidTy()
Fetch the type representing void.
Definition IRBuilder.h:560
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition IRBuilder.h:1953
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:2097
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1547
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1618
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2492
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1588
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition IRBuilder.h:512
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1452
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:2477
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
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:1133
@ loongarch64
Definition Triple.h:66
bool isRISCV32() const
Tests whether the target is 32-bit RISC-V.
Definition Triple.h:1171
bool isPPC32() const
Tests whether the target is 32-bit PowerPC (little and big endian).
Definition Triple.h:1147
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:515
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
Definition Triple.h:1176
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
Definition Triple.h:1122
bool isMIPS32() const
Tests whether the target is MIPS 32-bit (little and big endian).
Definition Triple.h:1128
bool isARM() const
Tests whether the target is ARM (little and big endian).
Definition Triple.h:1006
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
Definition Triple.h:1152
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
Definition Triple.h:1099
bool isSystemZ() const
Tests whether the target is SystemZ.
Definition Triple.h:1195
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:390
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
Type * getElementType() const
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:201
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
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....
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.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
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:139
@ 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:2911
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:149
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
constexpr bool valueOr(BoolOrDefault X, bool Default)
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 ...
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
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:3902
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:82
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)