1aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov//===-- MemorySanitizer.cpp - detector of uninitialized reads -------------===//
2aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov//
3aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov//                     The LLVM Compiler Infrastructure
4aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov//
5aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov// This file is distributed under the University of Illinois Open Source
6aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov// License. See LICENSE.TXT for details.
7aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov//
8aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov//===----------------------------------------------------------------------===//
9aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// \file
10aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// This file is a part of MemorySanitizer, a detector of uninitialized
11aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// reads.
12aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov///
13aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// The algorithm of the tool is similar to Memcheck
14aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// (http://goo.gl/QKbem). We associate a few shadow bits with every
15aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// byte of the application memory, poison the shadow of the malloc-ed
16aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// or alloca-ed memory, load the shadow bits on every memory read,
17aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// propagate the shadow bits through some of the arithmetic
18aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// instruction (including MOV), store the shadow bits on every memory
19aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// write, report a bug on some other instructions (e.g. JMP) if the
20aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// associated shadow is poisoned.
21aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov///
22aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// But there are differences too. The first and the major one:
23aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// compiler instrumentation instead of binary instrumentation. This
24aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// gives us much better register allocation, possible compiler
25aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// optimizations and a fast start-up. But this brings the major issue
26aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// as well: msan needs to see all program events, including system
27aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// calls and reads/writes in system libraries, so we either need to
28aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// compile *everything* with msan or use a binary translation
29aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// component (e.g. DynamoRIO) to instrument pre-built libraries.
30aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// Another difference from Memcheck is that we use 8 shadow bits per
31aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// byte of application memory and use a direct shadow mapping. This
32aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// greatly simplifies the instrumentation code and avoids races on
33aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// shadow updates (Memcheck is single-threaded so races are not a
34aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// concern there. Memcheck uses 2 shadow bits per byte with a slow
35aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// path storage that uses 8 bits per byte).
36aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov///
37aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// The default value of shadow is 0, which means "clean" (not poisoned).
38aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov///
39aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// Every module initializer should call __msan_init to ensure that the
40aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// shadow memory is ready. On error, __msan_warning is called. Since
41aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// parameters and return values may be passed via registers, we have a
42aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// specialized thread-local shadow for return values
43aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// (__msan_retval_tls) and parameters (__msan_param_tls).
44ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov///
45ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov///                           Origin tracking.
46ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov///
47ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// MemorySanitizer can track origins (allocation points) of all uninitialized
48ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// values. This behavior is controlled with a flag (msan-track-origins) and is
49ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// disabled by default.
50ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov///
51ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// Origins are 4-byte values created and interpreted by the runtime library.
52ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// They are stored in a second shadow mapping, one 4-byte value for 4 bytes
53ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// of application memory. Propagation of origins is basically a bunch of
54ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// "select" instructions that pick the origin of a dirty argument, if an
55ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// instruction has one.
56ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov///
57ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// Every 4 aligned, consecutive bytes of application memory have one origin
58ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// value associated with them. If these bytes contain uninitialized data
59ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// coming from 2 different allocations, the last store wins. Because of this,
60ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// MemorySanitizer reports can show unrelated origins, but this is unlikely in
61f045df1b8b7f80e17e34c2b5639082a1d0e289aeAlexey Samsonov/// practice.
62ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov///
63ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// Origins are meaningless for fully initialized values, so MemorySanitizer
64ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// avoids storing origin to memory when a fully initialized value is stored.
65ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// This way it avoids needless overwritting origin of the 4-byte region on
66ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// a short (i.e. 1 byte) clean store, and it is also good for performance.
67ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov///
68ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov///                            Atomic handling.
69ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov///
70ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// Ideally, every atomic store of application value should update the
71ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// corresponding shadow location in an atomic way. Unfortunately, atomic store
72ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// of two disjoint locations can not be done without severe slowdown.
73ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov///
74ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// Therefore, we implement an approximation that may err on the safe side.
75ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// In this implementation, every atomically accessed location in the program
76ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// may only change from (partially) uninitialized to fully initialized, but
77ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// not the other way around. We load the shadow _after_ the application load,
78ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// and we store the shadow _before_ the app store. Also, we always store clean
79ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// shadow (if the application store is atomic). This way, if the store-load
80ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// pair constitutes a happens-before arc, shadow store and load are correctly
81ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// ordered such that the load will get either the value that was stored, or
82ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// some later value (which is always clean).
83ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov///
84ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// This does not work very well with Compare-And-Swap (CAS) and
85ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// Read-Modify-Write (RMW) operations. To follow the above logic, CAS and RMW
86ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// must store the new shadow before the app operation, and load the shadow
87ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// after the app operation. Computers don't work this way. Current
88ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// implementation ignores the load aspect of CAS/RMW, always returning a clean
89ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// value. It implements the store part as a simple atomic store by storing a
90ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov/// clean shadow.
91ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
92aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov//===----------------------------------------------------------------------===//
93aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
94d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Transforms/Instrumentation.h"
95d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/DepthFirstIterator.h"
96d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallString.h"
97d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallVector.h"
98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/ADT/StringExtras.h"
99bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov#include "llvm/ADT/Triple.h"
1000b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
1010b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
1020b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h"
1030b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h"
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstVisitor.h"
1050b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h"
1060b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
1070b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/MDBuilder.h"
1080b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
1090b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Type.h"
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/ValueMap.h"
111aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov#include "llvm/Support/CommandLine.h"
112aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov#include "llvm/Support/Compiler.h"
113aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov#include "llvm/Support/Debug.h"
114aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov#include "llvm/Support/raw_ostream.h"
115aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov#include "llvm/Transforms/Utils/BasicBlockUtils.h"
1163333e668221f52f8c708df0037ee9c4bf2417929Evgeniy Stepanov#include "llvm/Transforms/Utils/Local.h"
117aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov#include "llvm/Transforms/Utils/ModuleUtils.h"
118aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
119aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovusing namespace llvm;
120aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "msan"
122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
123aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic const uint64_t kShadowMask32 = 1ULL << 31;
124aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic const uint64_t kShadowMask64 = 1ULL << 46;
125aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic const uint64_t kOriginOffset32 = 1ULL << 30;
126aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic const uint64_t kOriginOffset64 = 1ULL << 45;
127b53be53c72ff7b3846f0ba990a889de444601e0bEvgeniy Stepanovstatic const unsigned kMinOriginAlignment = 4;
128b53be53c72ff7b3846f0ba990a889de444601e0bEvgeniy Stepanovstatic const unsigned kShadowTLSAlignment = 8;
129aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Accesses sizes are powers of two: 1, 2, 4, 8.
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic const size_t kNumberOfAccessSizes = 4;
132dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
133ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// \brief Track origins of uninitialized values.
134f045df1b8b7f80e17e34c2b5639082a1d0e289aeAlexey Samsonov///
135ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// Adds a section to MemorySanitizer report that points to the allocation
136ab29644a33c3cbd237a9844a1e1b69b07c6fb8c3Evgeniy Stepanov/// (stack or heap) the uninitialized bits came from originally.
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic cl::opt<int> ClTrackOrigins("msan-track-origins",
138aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::desc("Track origins (allocation sites) of poisoned memory"),
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       cl::Hidden, cl::init(0));
140aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic cl::opt<bool> ClKeepGoing("msan-keep-going",
141aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::desc("keep going after reporting a UMR"),
142aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::Hidden, cl::init(false));
143aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic cl::opt<bool> ClPoisonStack("msan-poison-stack",
144aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::desc("poison uninitialized stack variables"),
145aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::Hidden, cl::init(true));
146aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic cl::opt<bool> ClPoisonStackWithCall("msan-poison-stack-with-call",
147aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::desc("poison uninitialized stack variables with a call"),
148aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::Hidden, cl::init(false));
149aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic cl::opt<int> ClPoisonStackPattern("msan-poison-stack-pattern",
150aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::desc("poison uninitialized stack variables with the given patter"),
151aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::Hidden, cl::init(0xff));
152930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanovstatic cl::opt<bool> ClPoisonUndef("msan-poison-undef",
153930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov       cl::desc("poison undef temps"),
154930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov       cl::Hidden, cl::init(true));
155aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
156aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic cl::opt<bool> ClHandleICmp("msan-handle-icmp",
157aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
158aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::Hidden, cl::init(true));
159aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
160351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanovstatic cl::opt<bool> ClHandleICmpExact("msan-handle-icmp-exact",
161351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov       cl::desc("exact handling of relational integer ICmp"),
162647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov       cl::Hidden, cl::init(false));
163351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov
164aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov// This flag controls whether we check the shadow of the address
165aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov// operand of load or store. Such bugs are very rare, since load from
166aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov// a garbage address typically results in SEGV, but still happen
167aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov// (e.g. only lower bits of address are garbage, or the access happens
168aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov// early at program startup where malloc-ed memory is more likely to
169aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov// be zeroed. As of 2012-08-28 this flag adds 20% slowdown.
170aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic cl::opt<bool> ClCheckAccessAddress("msan-check-access-address",
171aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::desc("report accesses through a pointer which has poisoned shadow"),
172aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::Hidden, cl::init(true));
173aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
174aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic cl::opt<bool> ClDumpStrictInstructions("msan-dump-strict-instructions",
175aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::desc("print out instructions with default strict semantics"),
176aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov       cl::Hidden, cl::init(false));
177aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic cl::opt<int> ClInstrumentationWithCallThreshold(
179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    "msan-instrumentation-with-call-threshold",
180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    cl::desc(
181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        "If the function being instrumented requires more than "
182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        "this number of checks and origin stores, use callbacks instead of "
183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        "inline checks (-1 means never use callbacks)."),
184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    cl::Hidden, cl::init(3500));
185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1866591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov// Experimental. Wraps all indirect calls in the instrumented code with
1876591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov// a call to the given function. This is needed to assist the dynamic
1886591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov// helper tool (MSanDR) to regain control on transition between instrumented and
1896591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov// non-instrumented code.
1906591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanovstatic cl::opt<std::string> ClWrapIndirectCalls("msan-wrap-indirect-calls",
1916591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov       cl::desc("Wrap indirect calls with a given function"),
1926591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov       cl::Hidden);
1936591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov
19434432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanovstatic cl::opt<bool> ClWrapIndirectCallsFast("msan-wrap-indirect-calls-fast",
19534432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov       cl::desc("Do not wrap indirect calls with target in the same module"),
19634432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov       cl::Hidden, cl::init(true));
19734432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
198aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovnamespace {
199aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
200aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// \brief An instrumentation pass implementing detection of uninitialized
201aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// reads.
202aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov///
203aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// MemorySanitizer: instrument the code in module to find
204aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// uninitialized reads.
205aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovclass MemorySanitizer : public FunctionPass {
20679c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov public:
207cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MemorySanitizer(int TrackOrigins = 0)
2086591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov      : FunctionPass(ID),
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        TrackOrigins(std::max(TrackOrigins, (int)ClTrackOrigins)),
210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        DL(nullptr),
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        WarningFn(nullptr),
2126591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov        WrapIndirectCalls(!ClWrapIndirectCalls.empty()) {}
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const char *getPassName() const override { return "MemorySanitizer"; }
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool runOnFunction(Function &F) override;
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool doInitialization(Module &M) override;
216aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  static char ID;  // Pass identification, replacement for typeid.
217aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
21879c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov private:
2191b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  void initializeCallbacks(Module &M);
2201b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov
22133660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov  /// \brief Track origins (allocation points) of uninitialized values.
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int TrackOrigins;
22333660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const DataLayout *DL;
225aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  LLVMContext *C;
226aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Type *IntptrTy;
227aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Type *OriginTy;
228aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Thread-local shadow storage for function parameters.
229aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  GlobalVariable *ParamTLS;
230aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Thread-local origin storage for function parameters.
231aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  GlobalVariable *ParamOriginTLS;
232aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Thread-local shadow storage for function return value.
233aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  GlobalVariable *RetvalTLS;
234aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Thread-local origin storage for function return value.
235aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  GlobalVariable *RetvalOriginTLS;
236aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Thread-local shadow storage for in-register va_arg function
237aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// parameters (x86_64-specific).
238aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  GlobalVariable *VAArgTLS;
239aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Thread-local shadow storage for va_arg overflow area
240aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// (x86_64-specific).
241aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  GlobalVariable *VAArgOverflowSizeTLS;
242aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Thread-local space used to pass origin value to the UMR reporting
243aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// function.
244aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  GlobalVariable *OriginTLS;
245aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
24634432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov  GlobalVariable *MsandrModuleStart;
24734432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov  GlobalVariable *MsandrModuleEnd;
24834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
249aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief The run-time callback to print a warning.
250aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *WarningFn;
251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // These arrays are indexed by log2(AccessSize).
252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Value *MaybeWarningFn[kNumberOfAccessSizes];
253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Value *MaybeStoreOriginFn[kNumberOfAccessSizes];
254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
255aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Run-time helper that generates a new origin value for a stack
256aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// allocation.
257993a0c56ec166ed1e6cc5b9275f81bc3ca4ed880Evgeniy Stepanov  Value *MsanSetAllocaOrigin4Fn;
258aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Run-time helper that poisons stack on function entry.
259aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *MsanPoisonStackFn;
26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Run-time helper that records a store (or any event) of an
26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// uninitialized value and returns an updated origin id encoding this info.
26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *MsanChainOriginFn;
2632e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  /// \brief MSan runtime replacements for memmove, memcpy and memset.
2642e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  Value *MemmoveFn, *MemcpyFn, *MemsetFn;
265aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
266aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Address mask used in application-to-shadow address calculation.
267aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// ShadowAddr is computed as ApplicationAddr & ~ShadowMask.
268aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  uint64_t ShadowMask;
269aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Offset of the origin shadow from the "normal" shadow.
270aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// OriginAddr is computed as (ShadowAddr + OriginOffset) & ~3ULL
271aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  uint64_t OriginOffset;
272aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Branch weights for error reporting.
273aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  MDNode *ColdCallWeights;
2744031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov  /// \brief Branch weights for origin store.
2754031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov  MDNode *OriginStoreWeights;
276f62b4e3ee3cc667020d5de91dfec69ce58c1d1eaEvgeniy Stepanov  /// \brief An empty volatile inline asm that prevents callback merge.
277f62b4e3ee3cc667020d5de91dfec69ce58c1d1eaEvgeniy Stepanov  InlineAsm *EmptyAsm;
278aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2796591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov  bool WrapIndirectCalls;
2806591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov  /// \brief Run-time wrapper for indirect calls.
2816591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov  Value *IndirectCallWrapperFn;
2826591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov  // Argument and return type of IndirectCallWrapperFn: void (*f)(void).
2836591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov  Type *AnyFunctionPtrTy;
2846591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov
2852ea25f2f1cd29b617c768af504210127827fa2e3Evgeniy Stepanov  friend struct MemorySanitizerVisitor;
2862ea25f2f1cd29b617c768af504210127827fa2e3Evgeniy Stepanov  friend struct VarArgAMD64Helper;
287aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov};
288aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov}  // namespace
289aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
290aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovchar MemorySanitizer::ID = 0;
291aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy StepanovINITIALIZE_PASS(MemorySanitizer, "msan",
292aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                "MemorySanitizer: detects uninitialized reads.",
293aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                false, false)
294aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesFunctionPass *llvm::createMemorySanitizerPass(int TrackOrigins) {
296cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return new MemorySanitizer(TrackOrigins);
297aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov}
298aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
299aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// \brief Create a non-const global initialized with the given string.
300aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov///
301aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// Creates a writable global for Str so that we can pass it to the
302aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// run-time lib. Runtime uses first 4 bytes of the string to store the
303aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// frame ID, so the string needs to be mutable.
304aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstatic GlobalVariable *createPrivateNonConstGlobalForString(Module &M,
305aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                                            StringRef Str) {
306aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
307aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  return new GlobalVariable(M, StrConst->getType(), /*isConstant=*/false,
308aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                            GlobalValue::PrivateLinkage, StrConst, "");
309aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov}
310aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
311aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
3121b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov/// \brief Insert extern declaration of runtime-provided functions and globals.
3131b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanovvoid MemorySanitizer::initializeCallbacks(Module &M) {
3141b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  // Only do this once.
3151b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  if (WarningFn)
3161b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov    return;
317aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
3181b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  IRBuilder<> IRB(*C);
319aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // Create the callback.
320aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // FIXME: this function should have "Cold" calling conv,
321aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // which is not yet implemented.
322aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  StringRef WarningFnName = ClKeepGoing ? "__msan_warning"
323aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                        : "__msan_warning_noreturn";
324aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy(), NULL);
325aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines       AccessSizeIndex++) {
328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned AccessSize = 1 << AccessSizeIndex;
329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    std::string FunctionName = "__msan_maybe_warning_" + itostr(AccessSize);
330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction(
331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        FunctionName, IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8),
332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IRB.getInt32Ty(), NULL);
333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    FunctionName = "__msan_maybe_store_origin_" + itostr(AccessSize);
335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaybeStoreOriginFn[AccessSizeIndex] = M.getOrInsertFunction(
336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        FunctionName, IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8),
337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IRB.getInt8PtrTy(), IRB.getInt32Ty(), NULL);
338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
340993a0c56ec166ed1e6cc5b9275f81bc3ca4ed880Evgeniy Stepanov  MsanSetAllocaOrigin4Fn = M.getOrInsertFunction(
341993a0c56ec166ed1e6cc5b9275f81bc3ca4ed880Evgeniy Stepanov    "__msan_set_alloca_origin4", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy,
342993a0c56ec166ed1e6cc5b9275f81bc3ca4ed880Evgeniy Stepanov    IRB.getInt8PtrTy(), IntptrTy, NULL);
343aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  MsanPoisonStackFn = M.getOrInsertFunction(
344aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    "__msan_poison_stack", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy, NULL);
34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MsanChainOriginFn = M.getOrInsertFunction(
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    "__msan_chain_origin", IRB.getInt32Ty(), IRB.getInt32Ty(), NULL);
347aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  MemmoveFn = M.getOrInsertFunction(
34879c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov    "__msan_memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
34979c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov    IRB.getInt8PtrTy(), IntptrTy, NULL);
3502e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  MemcpyFn = M.getOrInsertFunction(
3512e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    "__msan_memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
3522e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    IntptrTy, NULL);
3532e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  MemsetFn = M.getOrInsertFunction(
3542e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    "__msan_memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(),
355aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IntptrTy, NULL);
356aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
357aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // Create globals.
358aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  RetvalTLS = new GlobalVariable(
359aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    M, ArrayType::get(IRB.getInt64Ty(), 8), false,
360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    GlobalVariable::ExternalLinkage, nullptr, "__msan_retval_tls", nullptr,
3618f79b2f762a1f6ca933892aed35bfb2471c39201Evgeniy Stepanov    GlobalVariable::InitialExecTLSModel);
362aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  RetvalOriginTLS = new GlobalVariable(
363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    M, OriginTy, false, GlobalVariable::ExternalLinkage, nullptr,
364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    "__msan_retval_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel);
365aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
366aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ParamTLS = new GlobalVariable(
367aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    M, ArrayType::get(IRB.getInt64Ty(), 1000), false,
368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    GlobalVariable::ExternalLinkage, nullptr, "__msan_param_tls", nullptr,
3698f79b2f762a1f6ca933892aed35bfb2471c39201Evgeniy Stepanov    GlobalVariable::InitialExecTLSModel);
370aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ParamOriginTLS = new GlobalVariable(
371aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    M, ArrayType::get(OriginTy, 1000), false, GlobalVariable::ExternalLinkage,
372dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    nullptr, "__msan_param_origin_tls", nullptr,
373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    GlobalVariable::InitialExecTLSModel);
374aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
375aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  VAArgTLS = new GlobalVariable(
376aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    M, ArrayType::get(IRB.getInt64Ty(), 1000), false,
377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    GlobalVariable::ExternalLinkage, nullptr, "__msan_va_arg_tls", nullptr,
3788f79b2f762a1f6ca933892aed35bfb2471c39201Evgeniy Stepanov    GlobalVariable::InitialExecTLSModel);
379aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  VAArgOverflowSizeTLS = new GlobalVariable(
380dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    M, IRB.getInt64Ty(), false, GlobalVariable::ExternalLinkage, nullptr,
381dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    "__msan_va_arg_overflow_size_tls", nullptr,
3828f79b2f762a1f6ca933892aed35bfb2471c39201Evgeniy Stepanov    GlobalVariable::InitialExecTLSModel);
383aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  OriginTLS = new GlobalVariable(
384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    M, IRB.getInt32Ty(), false, GlobalVariable::ExternalLinkage, nullptr,
385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    "__msan_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel);
386f62b4e3ee3cc667020d5de91dfec69ce58c1d1eaEvgeniy Stepanov
387f62b4e3ee3cc667020d5de91dfec69ce58c1d1eaEvgeniy Stepanov  // We insert an empty inline asm after __msan_report* to avoid callback merge.
388f62b4e3ee3cc667020d5de91dfec69ce58c1d1eaEvgeniy Stepanov  EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false),
389f62b4e3ee3cc667020d5de91dfec69ce58c1d1eaEvgeniy Stepanov                            StringRef(""), StringRef(""),
390f62b4e3ee3cc667020d5de91dfec69ce58c1d1eaEvgeniy Stepanov                            /*hasSideEffects=*/true);
3916591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov
3926591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov  if (WrapIndirectCalls) {
3936591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov    AnyFunctionPtrTy =
3946591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov        PointerType::getUnqual(FunctionType::get(IRB.getVoidTy(), false));
3956591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov    IndirectCallWrapperFn = M.getOrInsertFunction(
3966591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov        ClWrapIndirectCalls, AnyFunctionPtrTy, AnyFunctionPtrTy, NULL);
3976591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov  }
39834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (WrapIndirectCalls && ClWrapIndirectCallsFast) {
40034432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov    MsandrModuleStart = new GlobalVariable(
40134432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        M, IRB.getInt32Ty(), false, GlobalValue::ExternalLinkage,
402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        nullptr, "__executable_start");
40334432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov    MsandrModuleStart->setVisibility(GlobalVariable::HiddenVisibility);
40434432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov    MsandrModuleEnd = new GlobalVariable(
40534432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        M, IRB.getInt32Ty(), false, GlobalValue::ExternalLinkage,
406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        nullptr, "_end");
40734432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov    MsandrModuleEnd->setVisibility(GlobalVariable::HiddenVisibility);
40834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov  }
4091b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov}
4101b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov
4111b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov/// \brief Module-level initialization.
4121b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov///
4131b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov/// inserts a call to __msan_init to the module's constructor list.
4141b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanovbool MemorySanitizer::doInitialization(Module &M) {
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!DLP)
417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    report_fatal_error("data layout missing");
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DL = &DLP->getDataLayout();
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4201b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  C = &(M.getContext());
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned PtrSize = DL->getPointerSizeInBits(/* AddressSpace */0);
4221b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  switch (PtrSize) {
4231b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov    case 64:
4241b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov      ShadowMask = kShadowMask64;
4251b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov      OriginOffset = kOriginOffset64;
4261b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov      break;
4271b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov    case 32:
4281b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov      ShadowMask = kShadowMask32;
4291b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov      OriginOffset = kOriginOffset32;
4301b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov      break;
4311b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov    default:
4321b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov      report_fatal_error("unsupported pointer size");
4331b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov      break;
4341b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  }
4351b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov
4361b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  IRBuilder<> IRB(*C);
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  IntptrTy = IRB.getIntPtrTy(DL);
4381b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  OriginTy = IRB.getInt32Ty();
4391b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov
4401b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  ColdCallWeights = MDBuilder(*C).createBranchWeights(1, 1000);
4414031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov  OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000);
4421b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov
4431b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  // Insert a call to __msan_init/__msan_track_origins into the module's CTORs.
4441b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov  appendToGlobalCtors(M, cast<Function>(M.getOrInsertFunction(
4451b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov                      "__msan_init", IRB.getVoidTy(), NULL)), 0);
4461b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov
4477ae921dbec5db9823c89fa736b2a4c3afe163e4fEvgeniy Stepanov  if (TrackOrigins)
4487ae921dbec5db9823c89fa736b2a4c3afe163e4fEvgeniy Stepanov    new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
4497ae921dbec5db9823c89fa736b2a4c3afe163e4fEvgeniy Stepanov                       IRB.getInt32(TrackOrigins), "__msan_track_origins");
4501b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov
4517ae921dbec5db9823c89fa736b2a4c3afe163e4fEvgeniy Stepanov  if (ClKeepGoing)
4527ae921dbec5db9823c89fa736b2a4c3afe163e4fEvgeniy Stepanov    new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
4537ae921dbec5db9823c89fa736b2a4c3afe163e4fEvgeniy Stepanov                       IRB.getInt32(ClKeepGoing), "__msan_keep_going");
454be0008a4df72bf9da3246707cdec2766ace75d32Evgeniy Stepanov
455aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  return true;
456aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov}
457aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
458aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovnamespace {
459aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
460aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// \brief A helper class that handles instrumentation of VarArg
461aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// functions on a particular platform.
462aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov///
463aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// Implementations are expected to insert the instrumentation
464aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// necessary to propagate argument shadow through VarArg function
465aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// calls. Visit* methods are called during an InstVisitor pass over
466aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// the function, and should avoid creating new basic blocks. A new
467aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// instance of this class is created for each instrumented function.
468aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstruct VarArgHelper {
469aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Visit a CallSite.
470aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  virtual void visitCallSite(CallSite &CS, IRBuilder<> &IRB) = 0;
471aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
472aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Visit a va_start call.
473aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  virtual void visitVAStartInst(VAStartInst &I) = 0;
474aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
475aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Visit a va_copy call.
476aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  virtual void visitVACopyInst(VACopyInst &I) = 0;
477aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
478aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Finalize function instrumentation.
479aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
480aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// This method is called after visiting all interesting (see above)
481aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// instructions in a function.
482aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  virtual void finalizeInstrumentation() = 0;
4832ea25f2f1cd29b617c768af504210127827fa2e3Evgeniy Stepanov
4842ea25f2f1cd29b617c768af504210127827fa2e3Evgeniy Stepanov  virtual ~VarArgHelper() {}
485aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov};
486aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
487aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstruct MemorySanitizerVisitor;
488aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
489aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy StepanovVarArgHelper*
490aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy StepanovCreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
491aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                   MemorySanitizerVisitor &Visitor);
492aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
493dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesunsigned TypeSizeToSizeIndex(unsigned TypeSize) {
494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (TypeSize <= 8) return 0;
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Log2_32_Ceil(TypeSize / 8);
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
498aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// This class does all the work for a given function. Store and Load
499aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// instructions store and load corresponding shadow and origin
500aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// values. Most instructions propagate shadow from arguments to their
501aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// return values. Certain instructions (most importantly, BranchInst)
502aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// test their argument shadow and print reports (with a runtime call) if it's
503aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// non-zero.
504aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstruct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
505aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Function &F;
506aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  MemorySanitizer &MS;
507aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  SmallVector<PHINode *, 16> ShadowPHINodes, OriginPHINodes;
508aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ValueMap<Value*, Value*> ShadowMap, OriginMap;
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<VarArgHelper> VAHelper;
51095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov
51195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // The following flags disable parts of MSan instrumentation based on
51295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // blacklist contents and command-line options.
513aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  bool InsertChecks;
514cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool PropagateShadow;
515d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov  bool PoisonStack;
516d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov  bool PoisonUndef;
517e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov  bool CheckReturnValue;
518aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
519aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  struct ShadowOriginAndInsertPoint {
52095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    Value *Shadow;
52195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    Value *Origin;
522aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Instruction *OrigIns;
52395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I)
524aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      : Shadow(S), Origin(O), OrigIns(I) { }
525aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  };
526aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  SmallVector<ShadowOriginAndInsertPoint, 16> InstrumentationList;
5274031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov  SmallVector<Instruction*, 16> StoreList;
52834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov  SmallVector<CallSite, 16> IndirectCallList;
529aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
530aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  MemorySanitizerVisitor(Function &F, MemorySanitizer &MS)
5315e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)) {
532cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    bool SanitizeFunction = F.getAttributes().hasAttribute(
533cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        AttributeSet::FunctionIndex, Attribute::SanitizeMemory);
534d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov    InsertChecks = SanitizeFunction;
535cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    PropagateShadow = SanitizeFunction;
536d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov    PoisonStack = SanitizeFunction && ClPoisonStack;
537d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov    PoisonUndef = SanitizeFunction && ClPoisonUndef;
538e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov    // FIXME: Consider using SpecialCaseList to specify a list of functions that
539e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov    // must always return fully initialized values. For now, we hardcode "main".
540e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov    CheckReturnValue = SanitizeFunction && (F.getName() == "main");
5415e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov
542aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(if (!InsertChecks)
5435e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov          dbgs() << "MemorySanitizer is not inserting checks into '"
5445e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov                 << F.getName() << "'\n");
545aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
546aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *updateOrigin(Value *V, IRBuilder<> &IRB) {
54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (MS.TrackOrigins <= 1) return V;
54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return IRB.CreateCall(MS.MsanChainOriginFn, V);
55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
552dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void storeOrigin(IRBuilder<> &IRB, Value *Addr, Value *Shadow, Value *Origin,
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                   unsigned Alignment, bool AsCall) {
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isa<StructType>(Shadow->getType())) {
555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      IRB.CreateAlignedStore(updateOrigin(Origin, IRB), getOriginPtr(Addr, IRB),
556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                             Alignment);
557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value *ConvertedShadow = convertToShadowTyNoVec(Shadow, IRB);
559dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // TODO(eugenis): handle non-zero constant shadow by inserting an
560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // unconditional check (can not simply fail compilation as this could
561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // be in the dead code).
562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (isa<Constant>(ConvertedShadow)) return;
563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned TypeSizeInBits =
564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          MS.DL->getTypeSizeInBits(ConvertedShadow->getType());
565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (AsCall && SizeIndex < kNumberOfAccessSizes) {
567dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Value *Fn = MS.MaybeStoreOriginFn[SizeIndex];
568dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Value *ConvertedShadow2 = IRB.CreateZExt(
569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IRB.CreateCall3(Fn, ConvertedShadow2,
571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                        IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()),
572cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                        Origin);
573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      } else {
574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Value *Cmp = IRB.CreateICmpNE(
575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            ConvertedShadow, getCleanShadow(ConvertedShadow), "_mscmp");
576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        Instruction *CheckTerm = SplitBlockAndInsertIfThen(
577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            Cmp, IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IRBuilder<> IRBNew(CheckTerm);
579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IRBNew.CreateAlignedStore(updateOrigin(Origin, IRBNew),
580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                  getOriginPtr(Addr, IRBNew), Alignment);
581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      }
582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void materializeStores(bool InstrumentWithCalls) {
586cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    for (auto Inst : StoreList) {
587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      StoreInst &SI = *dyn_cast<StoreInst>(Inst);
5884031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov
589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      IRBuilder<> IRB(&SI);
590cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Value *Val = SI.getValueOperand();
591cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Value *Addr = SI.getPointerOperand();
592cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Value *Shadow = SI.isAtomic() ? getCleanShadow(Val) : getShadow(Val);
5934031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov      Value *ShadowPtr = getShadowPtr(Addr, Shadow->getType(), IRB);
5944031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov
59579c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov      StoreInst *NewSI =
596cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          IRB.CreateAlignedStore(Shadow, ShadowPtr, SI.getAlignment());
5974031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov      DEBUG(dbgs() << "  STORE: " << *NewSI << "\n");
59867b9928a937f57831c7270ba9911515d64c2cfb9NAKAMURA Takumi      (void)NewSI;
5994247b13252a99b284e1ed396be9755878d42df2aEvgeniy Stepanov
600cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (ClCheckAccessAddress) insertShadowCheck(Addr, &SI);
6014031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov
602cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (SI.isAtomic()) SI.setOrdering(addReleaseOrdering(SI.getOrdering()));
603ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
60433660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov      if (MS.TrackOrigins) {
605cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        unsigned Alignment = std::max(kMinOriginAlignment, SI.getAlignment());
606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        storeOrigin(IRB, Addr, Shadow, getOrigin(Val), Alignment,
607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    InstrumentWithCalls);
6084031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov      }
6094031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov    }
6104031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov  }
6114031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov
612dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void materializeOneCheck(Instruction *OrigIns, Value *Shadow, Value *Origin,
613dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                           bool AsCall) {
614dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    IRBuilder<> IRB(OrigIns);
615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DEBUG(dbgs() << "  SHAD0 : " << *Shadow << "\n");
616dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value *ConvertedShadow = convertToShadowTyNoVec(Shadow, IRB);
617dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    DEBUG(dbgs() << "  SHAD1 : " << *ConvertedShadow << "\n");
618dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // See the comment in materializeStores().
619dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (isa<Constant>(ConvertedShadow)) return;
620dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned TypeSizeInBits =
621dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        MS.DL->getTypeSizeInBits(ConvertedShadow->getType());
622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
623dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (AsCall && SizeIndex < kNumberOfAccessSizes) {
624dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value *Fn = MS.MaybeWarningFn[SizeIndex];
625dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value *ConvertedShadow2 =
626dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
627dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      IRB.CreateCall2(Fn, ConvertedShadow2, MS.TrackOrigins && Origin
628dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                ? Origin
629dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                : (Value *)IRB.getInt32(0));
630dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
631aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *Cmp = IRB.CreateICmpNE(ConvertedShadow,
632aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                    getCleanShadow(ConvertedShadow), "_mscmp");
63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Instruction *CheckTerm = SplitBlockAndInsertIfThen(
63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Cmp, OrigIns,
63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          /* Unreachable */ !ClKeepGoing, MS.ColdCallWeights);
636aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
637aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.SetInsertPoint(CheckTerm);
63833660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov      if (MS.TrackOrigins) {
639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        IRB.CreateStore(Origin ? (Value *)Origin : (Value *)IRB.getInt32(0),
640aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                        MS.OriginTLS);
641aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
64236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      IRB.CreateCall(MS.WarningFn);
643f62b4e3ee3cc667020d5de91dfec69ce58c1d1eaEvgeniy Stepanov      IRB.CreateCall(MS.EmptyAsm);
644aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      DEBUG(dbgs() << "  CHECK: " << *Cmp << "\n");
645aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void materializeChecks(bool InstrumentWithCalls) {
649cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    for (const auto &ShadowData : InstrumentationList) {
650cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Instruction *OrigIns = ShadowData.OrigIns;
651cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Value *Shadow = ShadowData.Shadow;
652cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Value *Origin = ShadowData.Origin;
653dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      materializeOneCheck(OrigIns, Shadow, Origin, InstrumentWithCalls);
654dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
655aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "DONE:\n" << F);
656aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
657aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
65834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov  void materializeIndirectCalls() {
659cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    for (auto &CS : IndirectCallList) {
66034432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      Instruction *I = CS.getInstruction();
66134432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      BasicBlock *B = I->getParent();
66234432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      IRBuilder<> IRB(I);
66334432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      Value *Fn0 = CS.getCalledValue();
66434432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      Value *Fn = IRB.CreateBitCast(Fn0, MS.AnyFunctionPtrTy);
66534432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
66634432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      if (ClWrapIndirectCallsFast) {
66734432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        // Check that call target is inside this module limits.
66834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        Value *Start =
66934432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov            IRB.CreateBitCast(MS.MsandrModuleStart, MS.AnyFunctionPtrTy);
67034432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        Value *End = IRB.CreateBitCast(MS.MsandrModuleEnd, MS.AnyFunctionPtrTy);
67134432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
67234432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        Value *NotInThisModule = IRB.CreateOr(IRB.CreateICmpULT(Fn, Start),
67334432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov                                              IRB.CreateICmpUGE(Fn, End));
67434432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
67534432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        PHINode *NewFnPhi =
67634432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov            IRB.CreatePHI(Fn0->getType(), 2, "msandr.indirect_target");
67734432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
67834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        Instruction *CheckTerm = SplitBlockAndInsertIfThen(
67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            NotInThisModule, NewFnPhi,
68034432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov            /* Unreachable */ false, MS.ColdCallWeights);
68134432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
68234432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        IRB.SetInsertPoint(CheckTerm);
68334432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        // Slow path: call wrapper function to possibly transform the call
68434432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        // target.
68534432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        Value *NewFn = IRB.CreateBitCast(
68634432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov            IRB.CreateCall(MS.IndirectCallWrapperFn, Fn), Fn0->getType());
68734432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
68834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        NewFnPhi->addIncoming(Fn0, B);
68934432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        NewFnPhi->addIncoming(NewFn, dyn_cast<Instruction>(NewFn)->getParent());
69034432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        CS.setCalledFunction(NewFnPhi);
69134432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      } else {
69234432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        Value *NewFn = IRB.CreateBitCast(
69334432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov            IRB.CreateCall(MS.IndirectCallWrapperFn, Fn), Fn0->getType());
69434432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov        CS.setCalledFunction(NewFn);
69534432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      }
69634432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov    }
69734432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov  }
69834432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
699aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Add MemorySanitizer instrumentation to a function.
700aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  bool runOnFunction() {
7011b3fcf94a49fbbf0b1d0fb6086c3349c2092bd75Evgeniy Stepanov    MS.initializeCallbacks(*F.getParent());
70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!MS.DL) return false;
7033333e668221f52f8c708df0037ee9c4bf2417929Evgeniy Stepanov
7043333e668221f52f8c708df0037ee9c4bf2417929Evgeniy Stepanov    // In the presence of unreachable blocks, we may see Phi nodes with
7053333e668221f52f8c708df0037ee9c4bf2417929Evgeniy Stepanov    // incoming nodes from such blocks. Since InstVisitor skips unreachable
7063333e668221f52f8c708df0037ee9c4bf2417929Evgeniy Stepanov    // blocks, such nodes will not have any shadow value associated with them.
7073333e668221f52f8c708df0037ee9c4bf2417929Evgeniy Stepanov    // It's easier to remove unreachable blocks than deal with missing shadow.
7083333e668221f52f8c708df0037ee9c4bf2417929Evgeniy Stepanov    removeUnreachableBlocks(F);
7093333e668221f52f8c708df0037ee9c4bf2417929Evgeniy Stepanov
710aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Iterate all BBs in depth-first order and create shadow instructions
711aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // for all instructions (where applicable).
712aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // For PHI nodes we create dummy shadow PHIs which will be finalized later.
713dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (BasicBlock *BB : depth_first(&F.getEntryBlock()))
714aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      visit(*BB);
715dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
716aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
717aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Finalize PHI nodes.
718cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    for (PHINode *PN : ShadowPHINodes) {
719aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      PHINode *PNS = cast<PHINode>(getShadow(PN));
720dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
721aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      size_t NumValues = PN->getNumIncomingValues();
722aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      for (size_t v = 0; v < NumValues; v++) {
723aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
724cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        if (PNO) PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
725aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
726aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
727aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
728aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    VAHelper->finalizeInstrumentation();
729aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
730dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool InstrumentWithCalls = ClInstrumentationWithCallThreshold >= 0 &&
731dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               InstrumentationList.size() + StoreList.size() >
732dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                   (unsigned)ClInstrumentationWithCallThreshold;
733dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
7344031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov    // Delayed instrumentation of StoreInst.
7357baaee37cc4391b472fcce572d1ae68a8c547a71Evgeniy Stepanov    // This may add new checks to be inserted later.
736dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    materializeStores(InstrumentWithCalls);
7374031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov
7384031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov    // Insert shadow value checks.
739dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    materializeChecks(InstrumentWithCalls);
740aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
74134432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov    // Wrap indirect calls.
74234432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov    materializeIndirectCalls();
74334432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov
744aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return true;
745aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
746aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
747aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the shadow type that corresponds to a given Value.
748aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Type *getShadowTy(Value *V) {
749aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return getShadowTy(V->getType());
750aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
751aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
752aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the shadow type that corresponds to a given Type.
753aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Type *getShadowTy(Type *OrigTy) {
754aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (!OrigTy->isSized()) {
755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
756aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
757aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // For integer type, shadow is the same as the original type.
758aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // This may return weird-sized types like i1.
759aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (IntegerType *IT = dyn_cast<IntegerType>(OrigTy))
760aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return IT;
76159a65f7b24350cf483d777acfb403e9b8a31a771Evgeniy Stepanov    if (VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint32_t EltSize = MS.DL->getTypeSizeInBits(VT->getElementType());
76359a65f7b24350cf483d777acfb403e9b8a31a771Evgeniy Stepanov      return VectorType::get(IntegerType::get(*MS.C, EltSize),
76459a65f7b24350cf483d777acfb403e9b8a31a771Evgeniy Stepanov                             VT->getNumElements());
76559a65f7b24350cf483d777acfb403e9b8a31a771Evgeniy Stepanov    }
766aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
767aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      SmallVector<Type*, 4> Elements;
768aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
769aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        Elements.push_back(getShadowTy(ST->getElementType(i)));
770aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      StructType *Res = StructType::get(*MS.C, Elements, ST->isPacked());
771aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      DEBUG(dbgs() << "getShadowTy: " << *ST << " ===> " << *Res << "\n");
772aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return Res;
773aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t TypeSize = MS.DL->getTypeSizeInBits(OrigTy);
775aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return IntegerType::get(*MS.C, TypeSize);
776aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
777aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
778aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Flatten a vector type.
779aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Type *getShadowTyNoVec(Type *ty) {
780aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (VectorType *vt = dyn_cast<VectorType>(ty))
781aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return IntegerType::get(*MS.C, vt->getBitWidth());
782aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return ty;
783aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
784aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
785aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Convert a shadow value to it's flattened variant.
786aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *convertToShadowTyNoVec(Value *V, IRBuilder<> &IRB) {
787aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Type *Ty = V->getType();
788aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Type *NoVecTy = getShadowTyNoVec(Ty);
789aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (Ty == NoVecTy) return V;
790aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return IRB.CreateBitCast(V, NoVecTy);
791aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
792aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
793aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the shadow address that corresponds to a given application
794aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// address.
795aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
796aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// Shadow = Addr & ~ShadowMask.
797aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getShadowPtr(Value *Addr, Type *ShadowTy,
798aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                      IRBuilder<> &IRB) {
799aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *ShadowLong =
800aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateAnd(IRB.CreatePointerCast(Addr, MS.IntptrTy),
801aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                    ConstantInt::get(MS.IntptrTy, ~MS.ShadowMask));
802aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return IRB.CreateIntToPtr(ShadowLong, PointerType::get(ShadowTy, 0));
803aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
804aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
805aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the origin address that corresponds to a given application
806aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// address.
807aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
808aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// OriginAddr = (ShadowAddr + OriginOffset) & ~3ULL
809aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getOriginPtr(Value *Addr, IRBuilder<> &IRB) {
810aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *ShadowLong =
811aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateAnd(IRB.CreatePointerCast(Addr, MS.IntptrTy),
812af4451b37e381c643144dc00614e63eef8db6082Evgeniy Stepanov                    ConstantInt::get(MS.IntptrTy, ~MS.ShadowMask));
813aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Add =
814aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateAdd(ShadowLong,
815aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                    ConstantInt::get(MS.IntptrTy, MS.OriginOffset));
816af4451b37e381c643144dc00614e63eef8db6082Evgeniy Stepanov    Value *SecondAnd =
817af4451b37e381c643144dc00614e63eef8db6082Evgeniy Stepanov      IRB.CreateAnd(Add, ConstantInt::get(MS.IntptrTy, ~3ULL));
818af4451b37e381c643144dc00614e63eef8db6082Evgeniy Stepanov    return IRB.CreateIntToPtr(SecondAnd, PointerType::get(IRB.getInt32Ty(), 0));
819aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
820aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
821aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the shadow address for a given function argument.
822aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
823aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// Shadow = ParamTLS+ArgOffset.
824aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getShadowPtrForArgument(Value *A, IRBuilder<> &IRB,
825aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                 int ArgOffset) {
826aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Base = IRB.CreatePointerCast(MS.ParamTLS, MS.IntptrTy);
827aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
828aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return IRB.CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0),
829aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                              "_msarg");
830aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
831aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
832aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the origin address for a given function argument.
833aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getOriginPtrForArgument(Value *A, IRBuilder<> &IRB,
834aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                 int ArgOffset) {
835dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MS.TrackOrigins) return nullptr;
836aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Base = IRB.CreatePointerCast(MS.ParamOriginTLS, MS.IntptrTy);
837aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
838aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0),
839aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                              "_msarg_o");
840aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
841aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
842aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the shadow address for a retval.
843aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getShadowPtrForRetval(Value *A, IRBuilder<> &IRB) {
844aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Base = IRB.CreatePointerCast(MS.RetvalTLS, MS.IntptrTy);
845aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return IRB.CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0),
846aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                              "_msret");
847aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
848aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
849aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the origin address for a retval.
850aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getOriginPtrForRetval(IRBuilder<> &IRB) {
851aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // We keep a single origin for the entire retval. Might be too optimistic.
852aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return MS.RetvalOriginTLS;
853aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
854aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
855aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Set SV to be the shadow value for V.
856aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void setShadow(Value *V, Value *SV) {
857aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    assert(!ShadowMap.count(V) && "Values may only have one shadow");
858cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
859aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
860aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
861aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Set Origin to be the origin value for V.
862aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void setOrigin(Value *V, Value *Origin) {
86333660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov    if (!MS.TrackOrigins) return;
864aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    assert(!OriginMap.count(V) && "Values may only have one origin");
865aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "ORIGIN: " << *V << "  ==> " << *Origin << "\n");
866aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    OriginMap[V] = Origin;
867aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
868aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
869aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Create a clean shadow value for a given value.
870aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
871aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// Clean shadow (all zeroes) means all bits of the value are defined
872aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// (initialized).
873930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov  Constant *getCleanShadow(Value *V) {
874aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Type *ShadowTy = getShadowTy(V);
875aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (!ShadowTy)
876dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
877aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return Constant::getNullValue(ShadowTy);
878aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
879aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
880aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Create a dirty shadow of a given shadow type.
881aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Constant *getPoisonedShadow(Type *ShadowTy) {
882aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    assert(ShadowTy);
883aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
884aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return Constant::getAllOnesValue(ShadowTy);
885aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    StructType *ST = cast<StructType>(ShadowTy);
886aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    SmallVector<Constant *, 4> Vals;
887aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
888aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Vals.push_back(getPoisonedShadow(ST->getElementType(i)));
889aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return ConstantStruct::get(ST, Vals);
890aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
891aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
892930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov  /// \brief Create a dirty shadow for a given value.
893930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov  Constant *getPoisonedShadow(Value *V) {
894930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov    Type *ShadowTy = getShadowTy(V);
895930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov    if (!ShadowTy)
896dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
897930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov    return getPoisonedShadow(ShadowTy);
898930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov  }
899930a4fa8e5ef7d9937635d9058d6ab315fa4a314Evgeniy Stepanov
900aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Create a clean (zero) origin.
901aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getCleanOrigin() {
902aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return Constant::getNullValue(MS.OriginTy);
903aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
904aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
905aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Get the shadow value for a given Value.
906aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
907aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// This function either returns the value set earlier with setShadow,
908aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// or extracts if from ParamTLS (for function arguments).
909aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getShadow(Value *V) {
910cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!PropagateShadow) return getCleanShadow(V);
911aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (Instruction *I = dyn_cast<Instruction>(V)) {
912aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // For instructions the shadow is already stored in the map.
913aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *Shadow = ShadowMap[V];
914aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      if (!Shadow) {
915aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent()));
916cb5d04a9045b59d6aaf8707c63e9a90ad7a40c08Matt Beaumont-Gay        (void)I;
917aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        assert(Shadow && "No shadow for a value");
918aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
919aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return Shadow;
920aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
921aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (UndefValue *U = dyn_cast<UndefValue>(V)) {
922d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov      Value *AllOnes = PoisonUndef ? getPoisonedShadow(V) : getCleanShadow(V);
923aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n");
924cb5d04a9045b59d6aaf8707c63e9a90ad7a40c08Matt Beaumont-Gay      (void)U;
925aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return AllOnes;
926aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
927aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (Argument *A = dyn_cast<Argument>(V)) {
928aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // For arguments we compute the shadow on demand and store it in the map.
929aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value **ShadowPtr = &ShadowMap[V];
930aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      if (*ShadowPtr)
931aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        return *ShadowPtr;
932aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Function *F = A->getParent();
933aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRBuilder<> EntryIRB(F->getEntryBlock().getFirstNonPHI());
934aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      unsigned ArgOffset = 0;
935cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      for (auto &FArg : F->args()) {
936cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        if (!FArg.getType()->isSized()) {
937aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          DEBUG(dbgs() << "Arg is not sized\n");
938aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          continue;
939aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        }
940cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        unsigned Size = FArg.hasByValAttr()
941cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          ? MS.DL->getTypeAllocSize(FArg.getType()->getPointerElementType())
942cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          : MS.DL->getTypeAllocSize(FArg.getType());
943cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        if (A == &FArg) {
944cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          Value *Base = getShadowPtrForArgument(&FArg, EntryIRB, ArgOffset);
945cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          if (FArg.hasByValAttr()) {
946aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov            // ByVal pointer itself has clean shadow. We copy the actual
947aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov            // argument shadow to the underlying memory.
9489903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov            // Figure out maximal valid memcpy alignment.
949cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            unsigned ArgAlign = FArg.getParamAlignment();
9509903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov            if (ArgAlign == 0) {
9519903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov              Type *EltType = A->getType()->getPointerElementType();
95236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines              ArgAlign = MS.DL->getABITypeAlignment(EltType);
9539903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov            }
9549903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov            unsigned CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
955aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov            Value *Cpy = EntryIRB.CreateMemCpy(
9569903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov                getShadowPtr(V, EntryIRB.getInt8Ty(), EntryIRB), Base, Size,
9579903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov                CopyAlign);
958aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov            DEBUG(dbgs() << "  ByValCpy: " << *Cpy << "\n");
959cb5d04a9045b59d6aaf8707c63e9a90ad7a40c08Matt Beaumont-Gay            (void)Cpy;
960aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov            *ShadowPtr = getCleanShadow(V);
961aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          } else {
9629903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov            *ShadowPtr = EntryIRB.CreateAlignedLoad(Base, kShadowTLSAlignment);
963aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          }
964cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          DEBUG(dbgs() << "  ARG:    "  << FArg << " ==> " <<
965aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                **ShadowPtr << "\n");
96633660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov          if (MS.TrackOrigins) {
967cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            Value *OriginPtr =
968cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                getOriginPtrForArgument(&FArg, EntryIRB, ArgOffset);
969aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov            setOrigin(A, EntryIRB.CreateLoad(OriginPtr));
970aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          }
971aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        }
9729903f75bf6ec4136bd752595c689db845eedad3dEvgeniy Stepanov        ArgOffset += DataLayout::RoundUpAlignment(Size, kShadowTLSAlignment);
973aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
974aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      assert(*ShadowPtr && "Could not find shadow for an argument");
975aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return *ShadowPtr;
976aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
977aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // For everything else the shadow is zero.
978aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return getCleanShadow(V);
979aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
980aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
981aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Get the shadow for i-th argument of the instruction I.
982aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getShadow(Instruction *I, int i) {
983aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return getShadow(I->getOperand(i));
984aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
985aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
986aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Get the origin for a value.
987aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getOrigin(Value *V) {
988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!MS.TrackOrigins) return nullptr;
989aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (isa<Instruction>(V) || isa<Argument>(V)) {
990aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *Origin = OriginMap[V];
991aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      if (!Origin) {
992aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        DEBUG(dbgs() << "NO ORIGIN: " << *V << "\n");
993aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        Origin = getCleanOrigin();
994aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
995aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return Origin;
996aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
997aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return getCleanOrigin();
998aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
999aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1000aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Get the origin for i-th argument of the instruction I.
1001aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *getOrigin(Instruction *I, int i) {
1002aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return getOrigin(I->getOperand(i));
1003aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1004aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1005aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Remember the place where a shadow check should be inserted.
1006aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
1007aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// This location will be later instrumented with a check that will print a
100895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  /// UMR warning in runtime if the shadow value is not 0.
100995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  void insertShadowCheck(Value *Shadow, Value *Origin, Instruction *OrigIns) {
101095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    assert(Shadow);
1011aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (!InsertChecks) return;
1012cb5d04a9045b59d6aaf8707c63e9a90ad7a40c08Matt Beaumont-Gay#ifndef NDEBUG
1013aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Type *ShadowTy = Shadow->getType();
1014aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy)) &&
1015aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov           "Can only insert checks for integer and vector shadow types");
1016cb5d04a9045b59d6aaf8707c63e9a90ad7a40c08Matt Beaumont-Gay#endif
1017aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    InstrumentationList.push_back(
101895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov        ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
101995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  }
102095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov
102195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  /// \brief Remember the place where a shadow check should be inserted.
102295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  ///
102395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  /// This location will be later instrumented with a check that will print a
102495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  /// UMR warning in runtime if the value is not fully defined.
102595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  void insertShadowCheck(Value *Val, Instruction *OrigIns) {
102695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    assert(Val);
102795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    Instruction *Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
102895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    if (!Shadow) return;
102995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    Instruction *Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
103095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    insertShadowCheck(Shadow, Origin, OrigIns);
1031aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1032aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1033ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  AtomicOrdering addReleaseOrdering(AtomicOrdering a) {
1034ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    switch (a) {
1035ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case NotAtomic:
1036ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov        return NotAtomic;
1037ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case Unordered:
1038ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case Monotonic:
1039ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case Release:
1040ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov        return Release;
1041ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case Acquire:
1042ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case AcquireRelease:
1043ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov        return AcquireRelease;
1044ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case SequentiallyConsistent:
1045ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov        return SequentiallyConsistent;
1046ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    }
104763799f6febc91ebec0d308737bfd1c659e4c24b7Evgeniy Stepanov    llvm_unreachable("Unknown ordering");
1048ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  }
1049ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1050ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  AtomicOrdering addAcquireOrdering(AtomicOrdering a) {
1051ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    switch (a) {
1052ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case NotAtomic:
1053ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov        return NotAtomic;
1054ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case Unordered:
1055ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case Monotonic:
1056ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case Acquire:
1057ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov        return Acquire;
1058ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case Release:
1059ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case AcquireRelease:
1060ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov        return AcquireRelease;
1061ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      case SequentiallyConsistent:
1062ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov        return SequentiallyConsistent;
1063ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    }
106463799f6febc91ebec0d308737bfd1c659e4c24b7Evgeniy Stepanov    llvm_unreachable("Unknown ordering");
1065ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  }
1066ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
106779c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov  // ------------------- Visitors.
1068aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1069aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Instrument LoadInst
1070aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
1071aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// Loads the corresponding shadow and (optionally) origin.
1072aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// Optionally, checks that the load address is fully defined.
1073aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitLoadInst(LoadInst &I) {
1074cb5d04a9045b59d6aaf8707c63e9a90ad7a40c08Matt Beaumont-Gay    assert(I.getType()->isSized() && "Load type must have size");
1075ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    IRBuilder<> IRB(I.getNextNode());
1076aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Type *ShadowTy = getShadowTy(&I);
1077aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Addr = I.getPointerOperand();
1078cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (PropagateShadow) {
10795e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
10805e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      setShadow(&I,
10815e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov                IRB.CreateAlignedLoad(ShadowPtr, I.getAlignment(), "_msld"));
10825e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov    } else {
10835e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      setShadow(&I, getCleanShadow(&I));
10845e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov    }
1085aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1086aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (ClCheckAccessAddress)
108795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      insertShadowCheck(I.getPointerOperand(), &I);
1088aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1089ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    if (I.isAtomic())
1090ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov      I.setOrdering(addAcquireOrdering(I.getOrdering()));
1091ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1092b53be53c72ff7b3846f0ba990a889de444601e0bEvgeniy Stepanov    if (MS.TrackOrigins) {
1093cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (PropagateShadow) {
10945e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov        unsigned Alignment = std::max(kMinOriginAlignment, I.getAlignment());
10955e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov        setOrigin(&I,
10965e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov                  IRB.CreateAlignedLoad(getOriginPtr(Addr, IRB), Alignment));
10975e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      } else {
10985e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov        setOrigin(&I, getCleanOrigin());
10995e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      }
1100b53be53c72ff7b3846f0ba990a889de444601e0bEvgeniy Stepanov    }
1101aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1102aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1103aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Instrument StoreInst
1104aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
1105aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// Stores the corresponding shadow and (optionally) origin.
1106aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// Optionally, checks that the store address is fully defined.
1107aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitStoreInst(StoreInst &I) {
11084031b194acd50f35b75658f66ee3bb1b4afcfd25Evgeniy Stepanov    StoreList.push_back(&I);
1109aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1110aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1111ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  void handleCASOrRMW(Instruction &I) {
1112ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    assert(isa<AtomicRMWInst>(I) || isa<AtomicCmpXchgInst>(I));
1113ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1114ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    IRBuilder<> IRB(&I);
1115ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    Value *Addr = I.getOperand(0);
1116ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    Value *ShadowPtr = getShadowPtr(Addr, I.getType(), IRB);
1117ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1118ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    if (ClCheckAccessAddress)
111995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      insertShadowCheck(Addr, &I);
1120ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1121ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    // Only test the conditional argument of cmpxchg instruction.
1122ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    // The other argument can potentially be uninitialized, but we can not
1123ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    // detect this situation reliably without possible false positives.
1124ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    if (isa<AtomicCmpXchgInst>(I))
112595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      insertShadowCheck(I.getOperand(1), &I);
1126ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1127ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    IRB.CreateStore(getCleanShadow(&I), ShadowPtr);
1128ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1129ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    setShadow(&I, getCleanShadow(&I));
1130ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  }
1131ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1132ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  void visitAtomicRMWInst(AtomicRMWInst &I) {
1133ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    handleCASOrRMW(I);
1134ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    I.setOrdering(addReleaseOrdering(I.getOrdering()));
1135ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  }
1136ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
1137ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
1138ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov    handleCASOrRMW(I);
113936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
1140ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov  }
1141ecf0fcd2b17ccc71b2a7b5849c1416aeb48a9390Evgeniy Stepanov
11422aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov  // Vector manipulation.
11432aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov  void visitExtractElementInst(ExtractElementInst &I) {
114495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    insertShadowCheck(I.getOperand(1), &I);
11452aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    IRBuilder<> IRB(&I);
11462aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    setShadow(&I, IRB.CreateExtractElement(getShadow(&I, 0), I.getOperand(1),
11472aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov              "_msprop"));
11482aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    setOrigin(&I, getOrigin(&I, 0));
11492aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov  }
11502aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov
11512aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov  void visitInsertElementInst(InsertElementInst &I) {
115295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    insertShadowCheck(I.getOperand(2), &I);
11532aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    IRBuilder<> IRB(&I);
11542aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    setShadow(&I, IRB.CreateInsertElement(getShadow(&I, 0), getShadow(&I, 1),
11552aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov              I.getOperand(2), "_msprop"));
11562aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    setOriginForNaryOp(I);
11572aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov  }
11582aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov
11592aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov  void visitShuffleVectorInst(ShuffleVectorInst &I) {
116095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    insertShadowCheck(I.getOperand(2), &I);
11612aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    IRBuilder<> IRB(&I);
11622aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    setShadow(&I, IRB.CreateShuffleVector(getShadow(&I, 0), getShadow(&I, 1),
11632aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov              I.getOperand(2), "_msprop"));
11642aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov    setOriginForNaryOp(I);
11652aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov  }
11662aac38541708f37f9ddc5b2d3047b68835484a23Evgeniy Stepanov
1167aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // Casts.
1168aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitSExtInst(SExtInst &I) {
1169aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1170aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateSExt(getShadow(&I, 0), I.getType(), "_msprop"));
1171aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getOrigin(&I, 0));
1172aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1173aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1174aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitZExtInst(ZExtInst &I) {
1175aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1176aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateZExt(getShadow(&I, 0), I.getType(), "_msprop"));
1177aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getOrigin(&I, 0));
1178aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1179aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1180aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitTruncInst(TruncInst &I) {
1181aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1182aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateTrunc(getShadow(&I, 0), I.getType(), "_msprop"));
1183aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getOrigin(&I, 0));
1184aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1185aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1186aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitBitCastInst(BitCastInst &I) {
1187aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1188aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateBitCast(getShadow(&I, 0), getShadowTy(&I)));
1189aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getOrigin(&I, 0));
1190aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1191aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1192aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitPtrToIntInst(PtrToIntInst &I) {
1193aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1194aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
1195aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov             "_msprop_ptrtoint"));
1196aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getOrigin(&I, 0));
1197aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1198aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1199aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitIntToPtrInst(IntToPtrInst &I) {
1200aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1201aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
1202aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov             "_msprop_inttoptr"));
1203aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getOrigin(&I, 0));
1204aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1205aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1206aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitFPToSIInst(CastInst& I) { handleShadowOr(I); }
1207aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitFPToUIInst(CastInst& I) { handleShadowOr(I); }
1208aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitSIToFPInst(CastInst& I) { handleShadowOr(I); }
1209aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitUIToFPInst(CastInst& I) { handleShadowOr(I); }
1210aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitFPExtInst(CastInst& I) { handleShadowOr(I); }
1211aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitFPTruncInst(CastInst& I) { handleShadowOr(I); }
1212aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1213aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Propagate shadow for bitwise AND.
1214aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
1215aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// This code is exact, i.e. if, for example, a bit in the left argument
1216aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// is defined and 0, then neither the value not definedness of the
1217aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// corresponding bit in B don't affect the resulting shadow.
1218aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitAnd(BinaryOperator &I) {
1219aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1220aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  "And" of 0 and a poisoned value results in unpoisoned value.
1221aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  1&1 => 1;     0&1 => 0;     p&1 => p;
1222aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  1&0 => 0;     0&0 => 0;     p&0 => 0;
1223aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  1&p => p;     0&p => 0;     p&p => p;
1224aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  S = (S1 & S2) | (V1 & S2) | (S1 & V2)
1225aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S1 = getShadow(&I, 0);
1226aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S2 = getShadow(&I, 1);
1227aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *V1 = I.getOperand(0);
1228aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *V2 = I.getOperand(1);
1229aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (V1->getType() != S1->getType()) {
1230aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      V1 = IRB.CreateIntCast(V1, S1->getType(), false);
1231aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      V2 = IRB.CreateIntCast(V2, S2->getType(), false);
1232aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
1233aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S1S2 = IRB.CreateAnd(S1, S2);
1234aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *V1S2 = IRB.CreateAnd(V1, S2);
1235aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S1V2 = IRB.CreateAnd(S1, V2);
1236aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateOr(S1S2, IRB.CreateOr(V1S2, S1V2)));
1237aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOriginForNaryOp(I);
1238aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1239aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1240aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitOr(BinaryOperator &I) {
1241aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1242aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  "Or" of 1 and a poisoned value results in unpoisoned value.
1243aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  1|1 => 1;     0|1 => 1;     p|1 => 1;
1244aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  1|0 => 1;     0|0 => 0;     p|0 => p;
1245aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  1|p => 1;     0|p => p;     p|p => p;
1246aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    //  S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2)
1247aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S1 = getShadow(&I, 0);
1248aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S2 = getShadow(&I, 1);
1249aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *V1 = IRB.CreateNot(I.getOperand(0));
1250aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *V2 = IRB.CreateNot(I.getOperand(1));
1251aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (V1->getType() != S1->getType()) {
1252aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      V1 = IRB.CreateIntCast(V1, S1->getType(), false);
1253aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      V2 = IRB.CreateIntCast(V2, S2->getType(), false);
1254aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
1255aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S1S2 = IRB.CreateAnd(S1, S2);
1256aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *V1S2 = IRB.CreateAnd(V1, S2);
1257aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S1V2 = IRB.CreateAnd(S1, V2);
1258aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateOr(S1S2, IRB.CreateOr(V1S2, S1V2)));
1259aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOriginForNaryOp(I);
1260aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1261aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1262e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// \brief Default propagation of shadow and/or origin.
1263aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
1264e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// This class implements the general case of shadow propagation, used in all
1265e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// cases where we don't know and/or don't care about what the operation
1266e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// actually does. It converts all input shadow values to a common type
1267e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// (extending or truncating as necessary), and bitwise OR's them.
1268e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  ///
1269e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// This is much cheaper than inserting checks (i.e. requiring inputs to be
1270e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// fully initialized), and less prone to false positives.
1271e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  ///
1272e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// This class also implements the general case of origin propagation. For a
1273e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// Nary operation, result origin is set to the origin of an argument that is
1274e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// not entirely initialized. If there is more than one such arguments, the
1275e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// rightmost of them is picked. It does not matter which one is picked if all
1276e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// arguments are initialized.
1277e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  template <bool CombineShadow>
1278e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  class Combiner {
1279e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    Value *Shadow;
1280e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    Value *Origin;
1281e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    IRBuilder<> &IRB;
1282e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    MemorySanitizerVisitor *MSV;
128379c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov
1284e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  public:
1285e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    Combiner(MemorySanitizerVisitor *MSV, IRBuilder<> &IRB) :
1286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Shadow(nullptr), Origin(nullptr), IRB(IRB), MSV(MSV) {}
1287e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov
1288e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    /// \brief Add a pair of shadow and origin values to the mix.
1289e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    Combiner &Add(Value *OpShadow, Value *OpOrigin) {
1290e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      if (CombineShadow) {
1291e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        assert(OpShadow);
1292e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        if (!Shadow)
1293e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov          Shadow = OpShadow;
1294e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        else {
1295e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov          OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
1296e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov          Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop");
1297e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        }
1298e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      }
1299e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov
130033660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov      if (MSV->MS.TrackOrigins) {
1301e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        assert(OpOrigin);
1302e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        if (!Origin) {
1303e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov          Origin = OpOrigin;
1304e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        } else {
1305cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
1306cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          // No point in adding something that might result in 0 origin value.
1307cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          if (!ConstOrigin || !ConstOrigin->isNullValue()) {
1308cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            Value *FlatShadow = MSV->convertToShadowTyNoVec(OpShadow, IRB);
1309cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            Value *Cond =
1310cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                IRB.CreateICmpNE(FlatShadow, MSV->getCleanShadow(FlatShadow));
1311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
1312cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          }
1313e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        }
1314e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      }
1315e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      return *this;
1316e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    }
1317e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov
1318e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    /// \brief Add an application value to the mix.
1319e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    Combiner &Add(Value *V) {
1320e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      Value *OpShadow = MSV->getShadow(V);
1321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : nullptr;
1322e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      return Add(OpShadow, OpOrigin);
1323e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    }
1324e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov
1325e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    /// \brief Set the current combined values as the given instruction's shadow
1326e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    /// and origin.
1327e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    void Done(Instruction *I) {
1328e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      if (CombineShadow) {
1329e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        assert(Shadow);
1330e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
1331e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        MSV->setShadow(I, Shadow);
1332e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      }
133333660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov      if (MSV->MS.TrackOrigins) {
1334e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        assert(Origin);
1335e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        MSV->setOrigin(I, Origin);
1336e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      }
1337e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    }
1338e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  };
1339e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov
1340e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  typedef Combiner<true> ShadowAndOriginCombiner;
1341e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  typedef Combiner<false> OriginCombiner;
1342e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov
1343e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// \brief Propagate origin for arbitrary operation.
1344aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void setOriginForNaryOp(Instruction &I) {
134533660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov    if (!MS.TrackOrigins) return;
1346aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1347e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    OriginCombiner OC(this, IRB);
1348e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    for (Instruction::op_iterator OI = I.op_begin(); OI != I.op_end(); ++OI)
1349e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      OC.Add(OI->get());
1350e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    OC.Done(&I);
1351aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1352aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1353e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  size_t VectorOrPrimitiveTypeSizeInBits(Type *Ty) {
135459a65f7b24350cf483d777acfb403e9b8a31a771Evgeniy Stepanov    assert(!(Ty->isVectorTy() && Ty->getScalarType()->isPointerTy()) &&
135559a65f7b24350cf483d777acfb403e9b8a31a771Evgeniy Stepanov           "Vector of pointers is not a valid shadow type");
1356e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    return Ty->isVectorTy() ?
1357e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      Ty->getVectorNumElements() * Ty->getScalarSizeInBits() :
1358e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      Ty->getPrimitiveSizeInBits();
1359e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  }
1360e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov
1361e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// \brief Cast between two shadow types, extending or truncating as
1362e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  /// necessary.
1363f5e3811607dd54fded0bb6b6ab97345446e086b9Evgeniy Stepanov  Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
1364f5e3811607dd54fded0bb6b6ab97345446e086b9Evgeniy Stepanov                          bool Signed = false) {
1365e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    Type *srcTy = V->getType();
1366e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
1367f5e3811607dd54fded0bb6b6ab97345446e086b9Evgeniy Stepanov      return IRB.CreateIntCast(V, dstTy, Signed);
1368e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
1369e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov        dstTy->getVectorNumElements() == srcTy->getVectorNumElements())
1370f5e3811607dd54fded0bb6b6ab97345446e086b9Evgeniy Stepanov      return IRB.CreateIntCast(V, dstTy, Signed);
1371e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
1372e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
1373e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
1374e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    Value *V2 =
1375f5e3811607dd54fded0bb6b6ab97345446e086b9Evgeniy Stepanov      IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
1376e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    return IRB.CreateBitCast(V2, dstTy);
1377e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    // TODO: handle struct types.
1378aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1379aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
138036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// \brief Cast an application value to the type of its own shadow.
138136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *CreateAppToShadowCast(IRBuilder<> &IRB, Value *V) {
138236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Type *ShadowTy = getShadowTy(V);
138336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (V->getType() == ShadowTy)
138436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return V;
138536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (V->getType()->isPtrOrPtrVectorTy())
138636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return IRB.CreatePtrToInt(V, ShadowTy);
138736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
138836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return IRB.CreateBitCast(V, ShadowTy);
138936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
139036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1391aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Propagate shadow for arbitrary operation.
1392aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void handleShadowOr(Instruction &I) {
1393aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1394e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    ShadowAndOriginCombiner SC(this, IRB);
1395e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    for (Instruction::op_iterator OI = I.op_begin(); OI != I.op_end(); ++OI)
1396e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov      SC.Add(OI->get());
1397e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov    SC.Done(&I);
1398aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1399aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // \brief Handle multiplication by constant.
1401cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //
1402cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Handle a special case of multiplication by constant that may have one or
1403cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // more zeros in the lower bits. This makes corresponding number of lower bits
1404cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // of the result zero as well. We model it by shifting the other operand
1405cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // shadow left by the required number of bits. Effectively, we transform
1406cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B).
1407cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // We use multiplication by 2**N instead of shift to cover the case of
1408cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // multiplication by 0, which may occur in some elements of a vector operand.
1409cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void handleMulByConstant(BinaryOperator &I, Constant *ConstArg,
1410cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                           Value *OtherArg) {
1411cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Constant *ShadowMul;
1412cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Type *Ty = ConstArg->getType();
1413cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Ty->isVectorTy()) {
1414cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      unsigned NumElements = Ty->getVectorNumElements();
1415cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Type *EltTy = Ty->getSequentialElementType();
1416cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      SmallVector<Constant *, 16> Elements;
1417cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
1418cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        ConstantInt *Elt =
1419cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            dyn_cast<ConstantInt>(ConstArg->getAggregateElement(Idx));
1420cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        APInt V = Elt->getValue();
1421cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        APInt V2 = APInt(V.getBitWidth(), 1) << V.countTrailingZeros();
1422cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        Elements.push_back(ConstantInt::get(EltTy, V2));
1423cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      }
1424cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ShadowMul = ConstantVector::get(Elements);
1425cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    } else {
1426cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg);
1427cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      APInt V = Elt->getValue();
1428cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      APInt V2 = APInt(V.getBitWidth(), 1) << V.countTrailingZeros();
1429cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ShadowMul = ConstantInt::get(Elt->getType(), V2);
1430cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1431cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1432cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    IRBuilder<> IRB(&I);
1433cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setShadow(&I,
1434cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines              IRB.CreateMul(getShadow(OtherArg), ShadowMul, "msprop_mul_cst"));
1435cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOrigin(&I, getOrigin(OtherArg));
1436cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1437cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1438cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void visitMul(BinaryOperator &I) {
1439cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
1440cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
1441cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (constOp0 && !constOp1)
1442cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleMulByConstant(I, constOp0, I.getOperand(1));
1443cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    else if (constOp1 && !constOp0)
1444cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleMulByConstant(I, constOp1, I.getOperand(0));
1445cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    else
1446cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleShadowOr(I);
1447cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1448cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1449e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  void visitFAdd(BinaryOperator &I) { handleShadowOr(I); }
1450e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  void visitFSub(BinaryOperator &I) { handleShadowOr(I); }
1451e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  void visitFMul(BinaryOperator &I) { handleShadowOr(I); }
1452e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  void visitAdd(BinaryOperator &I) { handleShadowOr(I); }
1453e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  void visitSub(BinaryOperator &I) { handleShadowOr(I); }
1454e08878efa34b506e6baff04df6c29e65bef24daaEvgeniy Stepanov  void visitXor(BinaryOperator &I) { handleShadowOr(I); }
1455aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1456aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void handleDiv(Instruction &I) {
1457aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1458aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Strict on the second argument.
145995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    insertShadowCheck(I.getOperand(1), &I);
1460aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, getShadow(&I, 0));
1461aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getOrigin(&I, 0));
1462aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1463aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1464aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitUDiv(BinaryOperator &I) { handleDiv(I); }
1465aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitSDiv(BinaryOperator &I) { handleDiv(I); }
1466aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitFDiv(BinaryOperator &I) { handleDiv(I); }
1467aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitURem(BinaryOperator &I) { handleDiv(I); }
1468aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitSRem(BinaryOperator &I) { handleDiv(I); }
1469aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitFRem(BinaryOperator &I) { handleDiv(I); }
1470aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1471aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Instrument == and != comparisons.
1472aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
1473aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// Sometimes the comparison result is known even if some of the bits of the
1474aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// arguments are not.
1475aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void handleEqualityComparison(ICmpInst &I) {
1476aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1477aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *A = I.getOperand(0);
1478aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *B = I.getOperand(1);
1479aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Sa = getShadow(A);
1480aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Sb = getShadow(B);
1481967a946cb463c8b137c6e040f62100efebad93b1Evgeniy Stepanov
1482967a946cb463c8b137c6e040f62100efebad93b1Evgeniy Stepanov    // Get rid of pointers and vectors of pointers.
1483967a946cb463c8b137c6e040f62100efebad93b1Evgeniy Stepanov    // For ints (and vectors of ints), types of A and Sa match,
1484967a946cb463c8b137c6e040f62100efebad93b1Evgeniy Stepanov    // and this is a no-op.
1485967a946cb463c8b137c6e040f62100efebad93b1Evgeniy Stepanov    A = IRB.CreatePointerCast(A, Sa->getType());
1486967a946cb463c8b137c6e040f62100efebad93b1Evgeniy Stepanov    B = IRB.CreatePointerCast(B, Sb->getType());
1487967a946cb463c8b137c6e040f62100efebad93b1Evgeniy Stepanov
1488aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // A == B  <==>  (C = A^B) == 0
1489aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // A != B  <==>  (C = A^B) != 0
1490aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Sc = Sa | Sb
1491aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *C = IRB.CreateXor(A, B);
1492aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Sc = IRB.CreateOr(Sa, Sb);
1493aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
1494aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Result is defined if one of the following is true
1495aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // * there is a defined 1 bit in C
1496aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // * C is fully defined
1497aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Si = !(C & ~Sc) && Sc
1498aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Zero = Constant::getNullValue(Sc->getType());
1499aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *MinusOne = Constant::getAllOnesValue(Sc->getType());
1500aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Si =
1501aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateAnd(IRB.CreateICmpNE(Sc, Zero),
1502aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                    IRB.CreateICmpEQ(
1503aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                      IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero));
1504aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Si->setName("_msprop_icmp");
1505aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, Si);
1506aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOriginForNaryOp(I);
1507aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1508aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1509351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  /// \brief Build the lowest possible value of V, taking into account V's
1510351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  ///        uninitialized bits.
1511351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  Value *getLowestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
1512351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov                                bool isSigned) {
1513351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    if (isSigned) {
1514351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      // Split shadow into sign bit and other bits.
1515351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
1516351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
1517351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      // Maximise the undefined shadow bit, minimize other undefined bits.
1518351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      return
1519351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov        IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaOtherBits)), SaSignBit);
1520351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    } else {
1521351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      // Minimize undefined bits.
1522351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      return IRB.CreateAnd(A, IRB.CreateNot(Sa));
1523351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    }
1524351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  }
1525351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov
1526351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  /// \brief Build the highest possible value of V, taking into account V's
1527351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  ///        uninitialized bits.
1528351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  Value *getHighestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
1529351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov                                bool isSigned) {
1530351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    if (isSigned) {
1531351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      // Split shadow into sign bit and other bits.
1532351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
1533351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
1534351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      // Minimise the undefined shadow bit, maximise other undefined bits.
1535351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      return
1536351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov        IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaSignBit)), SaOtherBits);
1537351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    } else {
1538351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      // Maximize undefined bits.
1539351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      return IRB.CreateOr(A, Sa);
1540351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    }
1541351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  }
1542351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov
1543351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  /// \brief Instrument relational comparisons.
1544351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  ///
1545351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  /// This function does exact shadow propagation for all relational
1546351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  /// comparisons of integers, pointers and vectors of those.
1547351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  /// FIXME: output seems suboptimal when one of the operands is a constant
1548351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  void handleRelationalComparisonExact(ICmpInst &I) {
1549351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    IRBuilder<> IRB(&I);
1550351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    Value *A = I.getOperand(0);
1551351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    Value *B = I.getOperand(1);
1552351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    Value *Sa = getShadow(A);
1553351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    Value *Sb = getShadow(B);
1554351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov
1555351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    // Get rid of pointers and vectors of pointers.
1556351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    // For ints (and vectors of ints), types of A and Sa match,
1557351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    // and this is a no-op.
1558351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    A = IRB.CreatePointerCast(A, Sa->getType());
1559351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    B = IRB.CreatePointerCast(B, Sb->getType());
1560351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov
156194d1f5b10cbc65d12fc8eb46fd36a2f407cf4a35Evgeniy Stepanov    // Let [a0, a1] be the interval of possible values of A, taking into account
156294d1f5b10cbc65d12fc8eb46fd36a2f407cf4a35Evgeniy Stepanov    // its undefined bits. Let [b0, b1] be the interval of possible values of B.
156394d1f5b10cbc65d12fc8eb46fd36a2f407cf4a35Evgeniy Stepanov    // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
1564351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    bool IsSigned = I.isSigned();
1565351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    Value *S1 = IRB.CreateICmp(I.getPredicate(),
1566351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov                               getLowestPossibleValue(IRB, A, Sa, IsSigned),
1567351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov                               getHighestPossibleValue(IRB, B, Sb, IsSigned));
1568351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    Value *S2 = IRB.CreateICmp(I.getPredicate(),
1569351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov                               getHighestPossibleValue(IRB, A, Sa, IsSigned),
1570351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov                               getLowestPossibleValue(IRB, B, Sb, IsSigned));
1571351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    Value *Si = IRB.CreateXor(S1, S2);
1572351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    setShadow(&I, Si);
1573351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov    setOriginForNaryOp(I);
1574351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov  }
1575351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov
157684af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov  /// \brief Instrument signed relational comparisons.
157784af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov  ///
157884af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov  /// Handle (x<0) and (x>=0) comparisons (essentially, sign bit tests) by
157984af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov  /// propagating the highest bit of the shadow. Everything else is delegated
158084af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov  /// to handleShadowOr().
158184af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov  void handleSignedRelationalComparison(ICmpInst &I) {
158284af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
158384af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
1584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value* op = nullptr;
158584af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    CmpInst::Predicate pre = I.getPredicate();
158684af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    if (constOp0 && constOp0->isNullValue() &&
158784af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov        (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE)) {
158884af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov      op = I.getOperand(1);
158984af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    } else if (constOp1 && constOp1->isNullValue() &&
159084af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov               (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) {
159184af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov      op = I.getOperand(0);
159284af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    }
159384af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    if (op) {
159484af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov      IRBuilder<> IRB(&I);
159584af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov      Value* Shadow =
159684af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov        IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op), "_msprop_icmpslt");
159784af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov      setShadow(&I, Shadow);
159884af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov      setOrigin(&I, getOrigin(op));
159984af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    } else {
160084af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov      handleShadowOr(I);
160184af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov    }
160284af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov  }
160384af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov
1604aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitICmpInst(ICmpInst &I) {
1605647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    if (!ClHandleICmp) {
1606647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov      handleShadowOr(I);
1607647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov      return;
1608647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    }
1609647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    if (I.isEquality()) {
1610aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      handleEqualityComparison(I);
1611647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov      return;
1612647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    }
1613647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov
1614647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    assert(I.isRelational());
1615647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    if (ClHandleICmpExact) {
1616351f65d9723c075af86466c07a0a3dc28be272cdEvgeniy Stepanov      handleRelationalComparisonExact(I);
1617647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov      return;
1618647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    }
1619647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    if (I.isSigned()) {
162084af05e1ba3a97d98b76929df858edc7b8b0d252Evgeniy Stepanov      handleSignedRelationalComparison(I);
1621647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov      return;
1622647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    }
1623647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov
1624647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    assert(I.isUnsigned());
1625647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
1626647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov      handleRelationalComparisonExact(I);
1627647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov      return;
1628647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    }
1629647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov
1630647c66e24dc913db8e3e038d2fe6351bd98941a2Evgeniy Stepanov    handleShadowOr(I);
1631aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1632aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1633aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitFCmpInst(FCmpInst &I) {
1634aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    handleShadowOr(I);
1635aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1636aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1637aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void handleShift(BinaryOperator &I) {
1638aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1639aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // If any of the S2 bits are poisoned, the whole thing is poisoned.
1640aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Otherwise perform the same shift on S1.
1641aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S1 = getShadow(&I, 0);
1642aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S2 = getShadow(&I, 1);
1643aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *S2Conv = IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)),
1644aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                   S2->getType());
1645aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *V2 = I.getOperand(1);
1646aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Shift = IRB.CreateBinOp(I.getOpcode(), S1, V2);
1647aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreateOr(Shift, S2Conv));
1648aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOriginForNaryOp(I);
1649aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1650aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1651aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitShl(BinaryOperator &I) { handleShift(I); }
1652aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitAShr(BinaryOperator &I) { handleShift(I); }
1653aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitLShr(BinaryOperator &I) { handleShift(I); }
1654aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1655aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Instrument llvm.memmove
1656aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
1657aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// At this point we don't know if llvm.memmove will be inlined or not.
1658aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// If we don't instrument it and it gets inlined,
1659aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// our interceptor will not kick in and we will lose the memmove.
1660aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// If we instrument the call here, but it does not get inlined,
1661aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// we will memove the shadow twice: which is bad in case
1662aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// of overlapping regions. So, we simply lower the intrinsic to a call.
1663aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ///
16642e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  /// Similar situation exists for memcpy and memset.
1665aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitMemMoveInst(MemMoveInst &I) {
1666aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
1667aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRB.CreateCall3(
1668aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      MS.MemmoveFn,
1669aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()),
1670aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreatePointerCast(I.getArgOperand(1), IRB.getInt8PtrTy()),
1671aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false));
1672aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    I.eraseFromParent();
1673aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1674aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
16752e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  // Similar to memmove: avoid copying shadow twice.
16762e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  // This is somewhat unfortunate as it may slowdown small constant memcpys.
16772e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  // FIXME: consider doing manual inline for small constant sizes and proper
16782e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  // alignment.
16792e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  void visitMemCpyInst(MemCpyInst &I) {
16802e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    IRBuilder<> IRB(&I);
16812e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    IRB.CreateCall3(
16822e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov      MS.MemcpyFn,
16832e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov      IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()),
16842e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov      IRB.CreatePointerCast(I.getArgOperand(1), IRB.getInt8PtrTy()),
16852e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov      IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false));
16862e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    I.eraseFromParent();
16872e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  }
16882e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov
16892e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  // Same as memcpy.
16902e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  void visitMemSetInst(MemSetInst &I) {
16912e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    IRBuilder<> IRB(&I);
16922e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    IRB.CreateCall3(
16932e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov      MS.MemsetFn,
16942e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov      IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()),
16952e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov      IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
16962e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov      IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false));
16972e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov    I.eraseFromParent();
16982e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov  }
16992e815e7cf4f31c53ad64059192e70828d476680eEvgeniy Stepanov
1700aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitVAStartInst(VAStartInst &I) {
1701aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    VAHelper->visitVAStartInst(I);
1702aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1703aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1704aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitVACopyInst(VACopyInst &I) {
1705aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    VAHelper->visitVACopyInst(I);
1706aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
1707aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
1708b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  enum IntrinsicKind {
1709b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    IK_DoesNotAccessMemory,
1710b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    IK_OnlyReadsMemory,
1711b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    IK_WritesMemory
1712b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  };
1713b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1714b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  static IntrinsicKind getIntrinsicKind(Intrinsic::ID iid) {
1715b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    const int DoesNotAccessMemory = IK_DoesNotAccessMemory;
1716b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    const int OnlyReadsArgumentPointees = IK_OnlyReadsMemory;
1717b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    const int OnlyReadsMemory = IK_OnlyReadsMemory;
1718b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    const int OnlyAccessesArgumentPointees = IK_WritesMemory;
1719b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    const int UnknownModRefBehavior = IK_WritesMemory;
1720b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov#define GET_INTRINSIC_MODREF_BEHAVIOR
1721b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov#define ModRefBehavior IntrinsicKind
1722351ba145a7db32b457f118ecc4d873765ac2a16bChandler Carruth#include "llvm/IR/Intrinsics.gen"
1723b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov#undef ModRefBehavior
1724b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov#undef GET_INTRINSIC_MODREF_BEHAVIOR
1725b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  }
1726b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1727b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// \brief Handle vector store-like intrinsics.
1728b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  ///
1729b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// Instrument intrinsics that look like a simple SIMD store: writes memory,
1730b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// has 1 pointer argument and 1 vector argument, returns void.
1731b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  bool handleVectorStoreIntrinsic(IntrinsicInst &I) {
1732b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    IRBuilder<> IRB(&I);
1733b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    Value* Addr = I.getArgOperand(0);
1734b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    Value *Shadow = getShadow(&I, 1);
1735b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    Value *ShadowPtr = getShadowPtr(Addr, Shadow->getType(), IRB);
1736b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1737b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    // We don't know the pointer alignment (could be unaligned SSE store!).
1738b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    // Have to assume to worst case.
1739b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    IRB.CreateAlignedStore(Shadow, ShadowPtr, 1);
1740b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1741b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    if (ClCheckAccessAddress)
174295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      insertShadowCheck(Addr, &I);
1743b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1744b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    // FIXME: use ClStoreCleanOrigin
1745b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    // FIXME: factor out common code from materializeStores
174633660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov    if (MS.TrackOrigins)
1747b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      IRB.CreateStore(getOrigin(&I, 1), getOriginPtr(Addr, IRB));
1748b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    return true;
1749b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  }
1750b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1751b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// \brief Handle vector load-like intrinsics.
1752b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  ///
1753b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// Instrument intrinsics that look like a simple SIMD load: reads memory,
1754b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// has 1 pointer argument, returns a vector.
1755b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  bool handleVectorLoadIntrinsic(IntrinsicInst &I) {
1756b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    IRBuilder<> IRB(&I);
1757b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    Value *Addr = I.getArgOperand(0);
1758b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1759b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    Type *ShadowTy = getShadowTy(&I);
1760cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (PropagateShadow) {
17615e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
17625e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      // We don't know the pointer alignment (could be unaligned SSE load!).
17635e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      // Have to assume to worst case.
17645e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      setShadow(&I, IRB.CreateAlignedLoad(ShadowPtr, 1, "_msld"));
17655e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov    } else {
17665e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      setShadow(&I, getCleanShadow(&I));
17675e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov    }
17685e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov
1769b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    if (ClCheckAccessAddress)
177095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      insertShadowCheck(Addr, &I);
1771b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
17725e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov    if (MS.TrackOrigins) {
1773cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (PropagateShadow)
17745e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov        setOrigin(&I, IRB.CreateLoad(getOriginPtr(Addr, IRB)));
17755e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov      else
17765e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov        setOrigin(&I, getCleanOrigin());
17775e812139690ce077d568ef6559992b2cf74eb536Evgeniy Stepanov    }
1778b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    return true;
1779b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  }
1780b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1781b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// \brief Handle (SIMD arithmetic)-like intrinsics.
1782b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  ///
1783b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// Instrument intrinsics with any number of arguments of the same type,
1784b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// equal to the return type. The type should be simple (no aggregates or
1785b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// pointers; vectors are fine).
1786b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// Caller guarantees that this intrinsic does not access memory.
1787b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  bool maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I) {
1788b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    Type *RetTy = I.getType();
1789b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    if (!(RetTy->isIntOrIntVectorTy() ||
1790b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov          RetTy->isFPOrFPVectorTy() ||
1791b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov          RetTy->isX86_MMXTy()))
1792b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      return false;
1793b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1794b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    unsigned NumArgOperands = I.getNumArgOperands();
1795b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1796b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    for (unsigned i = 0; i < NumArgOperands; ++i) {
1797b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      Type *Ty = I.getArgOperand(i)->getType();
1798b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      if (Ty != RetTy)
1799b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        return false;
1800b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    }
1801b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1802b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    IRBuilder<> IRB(&I);
1803b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    ShadowAndOriginCombiner SC(this, IRB);
1804b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    for (unsigned i = 0; i < NumArgOperands; ++i)
1805b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      SC.Add(I.getArgOperand(i));
1806b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    SC.Done(&I);
1807b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1808b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    return true;
1809b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  }
1810b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1811b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// \brief Heuristically instrument unknown intrinsics.
1812b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  ///
1813b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// The main purpose of this code is to do something reasonable with all
1814b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// random intrinsics we might encounter, most importantly - SIMD intrinsics.
1815b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// We recognize several classes of intrinsics by their argument types and
1816b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// ModRefBehaviour and apply special intrumentation when we are reasonably
1817b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// sure that we know what the intrinsic does.
1818b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  ///
1819b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// We special-case intrinsics where this approach fails. See llvm.bswap
1820b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  /// handling as an example of that.
1821b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  bool handleUnknownIntrinsic(IntrinsicInst &I) {
1822b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    unsigned NumArgOperands = I.getNumArgOperands();
1823b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    if (NumArgOperands == 0)
1824b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      return false;
1825b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1826b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    Intrinsic::ID iid = I.getIntrinsicID();
1827b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    IntrinsicKind IK = getIntrinsicKind(iid);
1828b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    bool OnlyReadsMemory = IK == IK_OnlyReadsMemory;
1829b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    bool WritesMemory = IK == IK_WritesMemory;
1830b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    assert(!(OnlyReadsMemory && WritesMemory));
1831b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1832b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    if (NumArgOperands == 2 &&
1833b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        I.getArgOperand(0)->getType()->isPointerTy() &&
1834b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        I.getArgOperand(1)->getType()->isVectorTy() &&
1835b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        I.getType()->isVoidTy() &&
1836b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        WritesMemory) {
1837b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      // This looks like a vector store.
1838b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      return handleVectorStoreIntrinsic(I);
1839b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    }
1840b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1841b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    if (NumArgOperands == 1 &&
1842b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        I.getArgOperand(0)->getType()->isPointerTy() &&
1843b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        I.getType()->isVectorTy() &&
1844b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        OnlyReadsMemory) {
1845b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      // This looks like a vector load.
1846b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      return handleVectorLoadIntrinsic(I);
1847b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    }
1848b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1849b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    if (!OnlyReadsMemory && !WritesMemory)
1850b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      if (maybeHandleSimpleNomemIntrinsic(I))
1851b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        return true;
1852b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
1853b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    // FIXME: detect and handle SSE maskstore/maskload
1854b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov    return false;
1855b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov  }
1856b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov
18571e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov  void handleBswap(IntrinsicInst &I) {
18581e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    IRBuilder<> IRB(&I);
18591e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    Value *Op = I.getArgOperand(0);
18601e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    Type *OpType = Op->getType();
18611e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    Function *BswapFunc = Intrinsic::getDeclaration(
18621e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov      F.getParent(), Intrinsic::bswap, ArrayRef<Type*>(&OpType, 1));
18631e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    setShadow(&I, IRB.CreateCall(BswapFunc, getShadow(Op)));
18641e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    setOrigin(&I, getOrigin(Op));
18651e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov  }
18661e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov
186795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // \brief Instrument vector convert instrinsic.
186895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  //
186995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // This function instruments intrinsics like cvtsi2ss:
187095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // %Out = int_xxx_cvtyyy(%ConvertOp)
187195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // or
187295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp)
187395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same
187495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // number \p Out elements, and (if has 2 arguments) copies the rest of the
187595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // elements from \p CopyOp.
187695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // In most cases conversion involves floating-point value which may trigger a
187795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // hardware exception when not fully initialized. For this reason we require
187895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise.
187995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // We copy the shadow of \p CopyOp[NumUsedElements:] to \p
188095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
188195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  // return a fully initialized value.
188295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  void handleVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements) {
188395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    IRBuilder<> IRB(&I);
188495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    Value *CopyOp, *ConvertOp;
188595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov
188695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    switch (I.getNumArgOperands()) {
188795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case 2:
188895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      CopyOp = I.getArgOperand(0);
188995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      ConvertOp = I.getArgOperand(1);
189095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      break;
189195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case 1:
189295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      ConvertOp = I.getArgOperand(0);
1893dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      CopyOp = nullptr;
189495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      break;
189595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    default:
189695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      llvm_unreachable("Cvt intrinsic with unsupported number of arguments.");
189795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    }
189895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov
189995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // The first *NumUsedElements* elements of ConvertOp are converted to the
190095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // same number of output elements. The rest of the output is copied from
190195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // CopyOp, or (if not available) filled with zeroes.
190295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // Combine shadow for elements of ConvertOp that are used in this operation,
190395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // and insert a check.
190495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // FIXME: consider propagating shadow of ConvertOp, at least in the case of
190595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // int->any conversion.
190695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    Value *ConvertShadow = getShadow(ConvertOp);
1907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Value *AggShadow = nullptr;
190895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    if (ConvertOp->getType()->isVectorTy()) {
190995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      AggShadow = IRB.CreateExtractElement(
191095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov          ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
191195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      for (int i = 1; i < NumUsedElements; ++i) {
191295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov        Value *MoreShadow = IRB.CreateExtractElement(
191395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov            ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), i));
191495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov        AggShadow = IRB.CreateOr(AggShadow, MoreShadow);
191595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      }
191695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    } else {
191795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      AggShadow = ConvertShadow;
191895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    }
191995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    assert(AggShadow->getType()->isIntegerTy());
192095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    insertShadowCheck(AggShadow, getOrigin(ConvertOp), &I);
192195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov
192295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // Build result shadow by zero-filling parts of CopyOp shadow that come from
192395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    // ConvertOp.
192495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    if (CopyOp) {
192595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      assert(CopyOp->getType() == I.getType());
192695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      assert(CopyOp->getType()->isVectorTy());
192795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      Value *ResultShadow = getShadow(CopyOp);
192895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      Type *EltTy = ResultShadow->getType()->getVectorElementType();
192995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      for (int i = 0; i < NumUsedElements; ++i) {
193095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov        ResultShadow = IRB.CreateInsertElement(
193195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov            ResultShadow, ConstantInt::getNullValue(EltTy),
193295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov            ConstantInt::get(IRB.getInt32Ty(), i));
193395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      }
193495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      setShadow(&I, ResultShadow);
193595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      setOrigin(&I, getOrigin(CopyOp));
193695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    } else {
193795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      setShadow(&I, getCleanShadow(&I));
193895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    }
193995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov  }
194095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov
194136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Given a scalar or vector, extract lower 64 bits (or less), and return all
194236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // zeroes if it is zero, and all ones otherwise.
194336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *Lower64ShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
194436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (S->getType()->isVectorTy())
194536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      S = CreateShadowCast(IRB, S, IRB.getInt64Ty(), /* Signed */ true);
194636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(S->getType()->getPrimitiveSizeInBits() <= 64);
194736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
194836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateShadowCast(IRB, S2, T, /* Signed */ true);
194936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
195036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
195136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) {
195236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Type *T = S->getType();
195336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(T->isVectorTy());
195436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
195536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return IRB.CreateSExt(S2, T);
195636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
195736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
195836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // \brief Instrument vector shift instrinsic.
195936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  //
196036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // This function instruments intrinsics like int_x86_avx2_psll_w.
196136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Intrinsic shifts %In by %ShiftSize bits.
196236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // %ShiftSize may be a vector. In that case the lower 64 bits determine shift
196336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // size, and the rest is ignored. Behavior is defined even if shift size is
196436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // greater than register (or field) width.
196536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void handleVectorShiftIntrinsic(IntrinsicInst &I, bool Variable) {
196636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(I.getNumArgOperands() == 2);
196736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    IRBuilder<> IRB(&I);
196836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // If any of the S2 bits are poisoned, the whole thing is poisoned.
196936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Otherwise perform the same shift on S1.
197036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *S1 = getShadow(&I, 0);
197136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *S2 = getShadow(&I, 1);
197236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
197336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                             : Lower64ShadowExtend(IRB, S2, getShadowTy(&I));
197436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *V1 = I.getOperand(0);
197536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *V2 = I.getOperand(1);
197636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *Shift = IRB.CreateCall2(I.getCalledValue(),
197736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                   IRB.CreateBitCast(S1, V1->getType()), V2);
197836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Shift = IRB.CreateBitCast(Shift, getShadowTy(&I));
197936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setShadow(&I, IRB.CreateOr(Shift, S2Conv));
198036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setOriginForNaryOp(I);
198136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
198236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1983cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // \brief Get an X86_MMX-sized vector type.
1984cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Type *getMMXVectorTy(unsigned EltSizeInBits) {
1985cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const unsigned X86_MMXSizeInBits = 64;
1986cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return VectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
1987cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                           X86_MMXSizeInBits / EltSizeInBits);
1988cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1989cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1990cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // \brief Returns a signed counterpart for an (un)signed-saturate-and-pack
1991cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // intrinsic.
1992cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
1993cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    switch (id) {
1994cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_sse2_packsswb_128:
1995cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_sse2_packuswb_128:
1996cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return llvm::Intrinsic::x86_sse2_packsswb_128;
1997cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1998cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_sse2_packssdw_128:
1999cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_sse41_packusdw:
2000cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return llvm::Intrinsic::x86_sse2_packssdw_128;
2001cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2002cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_avx2_packsswb:
2003cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_avx2_packuswb:
2004cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return llvm::Intrinsic::x86_avx2_packsswb;
2005cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2006cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_avx2_packssdw:
2007cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_avx2_packusdw:
2008cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return llvm::Intrinsic::x86_avx2_packssdw;
2009cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2010cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_mmx_packsswb:
2011cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_mmx_packuswb:
2012cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return llvm::Intrinsic::x86_mmx_packsswb;
2013cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2014cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      case llvm::Intrinsic::x86_mmx_packssdw:
2015cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return llvm::Intrinsic::x86_mmx_packssdw;
2016cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      default:
2017cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        llvm_unreachable("unexpected intrinsic id");
2018cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2019cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2020cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2021cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // \brief Instrument vector pack instrinsic.
2022cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //
2023cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // This function instruments intrinsics like x86_mmx_packsswb, that
2024cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // packs elements of 2 input vectors into half as many bits with saturation.
2025cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Shadow is propagated with the signed variant of the same intrinsic applied
2026cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
2027cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // EltSizeInBits is used only for x86mmx arguments.
2028cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void handleVectorPackIntrinsic(IntrinsicInst &I, unsigned EltSizeInBits = 0) {
2029cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    assert(I.getNumArgOperands() == 2);
2030cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
2031cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    IRBuilder<> IRB(&I);
2032cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value *S1 = getShadow(&I, 0);
2033cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value *S2 = getShadow(&I, 1);
2034cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    assert(isX86_MMX || S1->getType()->isVectorTy());
2035cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2036cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // SExt and ICmpNE below must apply to individual elements of input vectors.
2037cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // In case of x86mmx arguments, cast them to appropriate vector types and
2038cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // back.
2039cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Type *T = isX86_MMX ? getMMXVectorTy(EltSizeInBits) : S1->getType();
2040cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (isX86_MMX) {
2041cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      S1 = IRB.CreateBitCast(S1, T);
2042cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      S2 = IRB.CreateBitCast(S2, T);
2043cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2044cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value *S1_ext = IRB.CreateSExt(
2045cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        IRB.CreateICmpNE(S1, llvm::Constant::getNullValue(T)), T);
2046cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value *S2_ext = IRB.CreateSExt(
2047cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        IRB.CreateICmpNE(S2, llvm::Constant::getNullValue(T)), T);
2048cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (isX86_MMX) {
2049cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Type *X86_MMXTy = Type::getX86_MMXTy(*MS.C);
2050cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      S1_ext = IRB.CreateBitCast(S1_ext, X86_MMXTy);
2051cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      S2_ext = IRB.CreateBitCast(S2_ext, X86_MMXTy);
2052cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2053cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2054cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Function *ShadowFn = Intrinsic::getDeclaration(
2055cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        F.getParent(), getSignedPackIntrinsic(I.getIntrinsicID()));
2056cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2057cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value *S = IRB.CreateCall2(ShadowFn, S1_ext, S2_ext, "_msprop_vector_pack");
2058cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (isX86_MMX) S = IRB.CreateBitCast(S, getShadowTy(&I));
2059cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setShadow(&I, S);
2060cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOriginForNaryOp(I);
2061cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2062cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2063cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // \brief Instrument sum-of-absolute-differencies intrinsic.
2064cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void handleVectorSadIntrinsic(IntrinsicInst &I) {
2065cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    const unsigned SignificantBitsPerResultElement = 16;
2066cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
2067cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Type *ResTy = isX86_MMX ? IntegerType::get(*MS.C, 64) : I.getType();
2068cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    unsigned ZeroBitsPerResultElement =
2069cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        ResTy->getScalarSizeInBits() - SignificantBitsPerResultElement;
2070cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2071cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    IRBuilder<> IRB(&I);
2072cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value *S = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1));
2073cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    S = IRB.CreateBitCast(S, ResTy);
2074cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
2075cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                       ResTy);
2076cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    S = IRB.CreateLShr(S, ZeroBitsPerResultElement);
2077cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    S = IRB.CreateBitCast(S, getShadowTy(&I));
2078cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setShadow(&I, S);
2079cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOriginForNaryOp(I);
2080cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2081cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2082cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // \brief Instrument multiply-add intrinsic.
2083cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  void handleVectorPmaddIntrinsic(IntrinsicInst &I,
2084cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                  unsigned EltSizeInBits = 0) {
2085cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
2086cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Type *ResTy = isX86_MMX ? getMMXVectorTy(EltSizeInBits * 2) : I.getType();
2087cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    IRBuilder<> IRB(&I);
2088cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Value *S = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1));
2089cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    S = IRB.CreateBitCast(S, ResTy);
2090cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
2091cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                       ResTy);
2092cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    S = IRB.CreateBitCast(S, getShadowTy(&I));
2093cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setShadow(&I, S);
2094cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    setOriginForNaryOp(I);
2095cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2096cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
20971e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov  void visitIntrinsicInst(IntrinsicInst &I) {
20981e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    switch (I.getIntrinsicID()) {
20991e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    case llvm::Intrinsic::bswap:
210079c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov      handleBswap(I);
210179c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov      break;
210295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvtsd2usi64:
210395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvtsd2usi:
210495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvtss2usi64:
210595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvtss2usi:
210695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvttss2usi64:
210795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvttss2usi:
210895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvttsd2usi64:
210995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvttsd2usi:
211095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvtusi2sd:
211195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvtusi2ss:
211295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvtusi642sd:
211395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_avx512_cvtusi642ss:
211495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvtsd2si64:
211595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvtsd2si:
211695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvtsd2ss:
211795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvtsi2sd:
211895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvtsi642sd:
211995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvtss2sd:
212095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvttsd2si64:
212195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvttsd2si:
212295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse_cvtsi2ss:
212395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse_cvtsi642ss:
212495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse_cvtss2si64:
212595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse_cvtss2si:
212695864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse_cvttss2si64:
212795864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse_cvttss2si:
212895864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      handleVectorConvertIntrinsic(I, 1);
212995864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      break;
213095864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvtdq2pd:
213195864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse2_cvtps2pd:
213295864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse_cvtps2pi:
213395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov    case llvm::Intrinsic::x86_sse_cvttps2pi:
213495864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      handleVectorConvertIntrinsic(I, 2);
213595864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      break;
213636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx512_psll_dq:
213736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx512_psrl_dq:
213836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psll_w:
213936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psll_d:
214036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psll_q:
214136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_pslli_w:
214236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_pslli_d:
214336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_pslli_q:
214436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psll_dq:
214536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrl_w:
214636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrl_d:
214736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrl_q:
214836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psra_w:
214936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psra_d:
215036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrli_w:
215136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrli_d:
215236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrli_q:
215336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrai_w:
215436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrai_d:
215536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrl_dq:
215636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psll_w:
215736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psll_d:
215836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psll_q:
215936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_pslli_w:
216036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_pslli_d:
216136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_pslli_q:
216236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psll_dq:
216336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrl_w:
216436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrl_d:
216536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrl_q:
216636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psra_w:
216736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psra_d:
216836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrli_w:
216936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrli_d:
217036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrli_q:
217136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrai_w:
217236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrai_d:
217336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_sse2_psrl_dq:
217436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psll_w:
217536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psll_d:
217636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psll_q:
217736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_pslli_w:
217836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_pslli_d:
217936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_pslli_q:
218036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psrl_w:
218136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psrl_d:
218236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psrl_q:
218336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psra_w:
218436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psra_d:
218536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psrli_w:
218636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psrli_d:
218736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psrli_q:
218836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psrai_w:
218936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_mmx_psrai_d:
219036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      handleVectorShiftIntrinsic(I, /* Variable */ false);
219136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
219236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psllv_d:
219336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psllv_d_256:
219436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psllv_q:
219536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psllv_q_256:
219636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrlv_d:
219736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrlv_d_256:
219836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrlv_q:
219936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrlv_q_256:
220036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrav_d:
220136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case llvm::Intrinsic::x86_avx2_psrav_d_256:
220236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      handleVectorShiftIntrinsic(I, /* Variable */ true);
220336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
220436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
220536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Byte shifts are not implemented.
220636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // case llvm::Intrinsic::x86_avx512_psll_dq_bs:
220736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // case llvm::Intrinsic::x86_avx512_psrl_dq_bs:
220836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // case llvm::Intrinsic::x86_avx2_psll_dq_bs:
220936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // case llvm::Intrinsic::x86_avx2_psrl_dq_bs:
221036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // case llvm::Intrinsic::x86_sse2_psll_dq_bs:
221136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // case llvm::Intrinsic::x86_sse2_psrl_dq_bs:
221236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2213cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_sse2_packsswb_128:
2214cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_sse2_packssdw_128:
2215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_sse2_packuswb_128:
2216cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_sse41_packusdw:
2217cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_avx2_packsswb:
2218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_avx2_packssdw:
2219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_avx2_packuswb:
2220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_avx2_packusdw:
2221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleVectorPackIntrinsic(I);
2222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
2223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_mmx_packsswb:
2225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_mmx_packuswb:
2226cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleVectorPackIntrinsic(I, 16);
2227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
2228cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2229cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_mmx_packssdw:
2230cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleVectorPackIntrinsic(I, 32);
2231cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
2232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_mmx_psad_bw:
2234cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_sse2_psad_bw:
2235cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_avx2_psad_bw:
2236cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleVectorSadIntrinsic(I);
2237cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
2238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_sse2_pmadd_wd:
2240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_avx2_pmadd_wd:
2241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_ssse3_pmadd_ub_sw_128:
2242cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_avx2_pmadd_ub_sw:
2243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleVectorPmaddIntrinsic(I);
2244cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
2245cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2246cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_ssse3_pmadd_ub_sw:
2247cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleVectorPmaddIntrinsic(I, 8);
2248cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
2249cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    case llvm::Intrinsic::x86_mmx_pmadd_wd:
2251cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      handleVectorPmaddIntrinsic(I, 16);
2252cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      break;
2253cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
22541e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    default:
2255b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov      if (!handleUnknownIntrinsic(I))
2256b8837ab8fc22bc9c1d23577e4cdfb732f710478fEvgeniy Stepanov        visitInstruction(I);
22572dfa3eb56679fcb0ac36d2956924e59acf4fc19eEvgeniy Stepanov      break;
22581e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov    }
22591e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov  }
22601e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov
2261aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitCallSite(CallSite CS) {
2262aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Instruction &I = *CS.getInstruction();
2263aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    assert((CS.isCall() || CS.isInvoke()) && "Unknown type of CallSite");
2264aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (CS.isCall()) {
22656d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov      CallInst *Call = cast<CallInst>(&I);
22666d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov
22676d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov      // For inline asm, do the usual thing: check argument shadow and mark all
22686d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov      // outputs as clean. Note that any side effects of the inline asm that are
22696d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov      // not immediately visible in its constraints are not handled.
22706d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov      if (Call->isInlineAsm()) {
22716d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov        visitInstruction(I);
22726d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov        return;
22736d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov      }
22746d988b423acf37ed4d0b50b2678a18f65ab1a207Evgeniy Stepanov
22751e3b656be52e94c523d5fdb5a586a62ec59c3c51Evgeniy Stepanov      assert(!isa<IntrinsicInst>(&I) && "intrinsics are handled elsewhere");
2276ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov
2277ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov      // We are going to insert code that relies on the fact that the callee
2278ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov      // will become a non-readonly function after it is instrumented by us. To
2279ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov      // prevent this code from being optimized out, mark that function
2280ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov      // non-readonly in advance.
2281ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov      if (Function *Func = Call->getCalledFunction()) {
2282ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov        // Clear out readonly/readnone attributes.
2283ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov        AttrBuilder B;
2284034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling        B.addAttribute(Attribute::ReadOnly)
2285034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling          .addAttribute(Attribute::ReadNone);
22868246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling        Func->removeAttributes(AttributeSet::FunctionIndex,
22878246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling                               AttributeSet::get(Func->getContext(),
22888246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling                                                 AttributeSet::FunctionIndex,
22898246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling                                                 B));
2290ece6db5f16a83ff4cab3544643d226eeb8a15784Evgeniy Stepanov      }
2291aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2292aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
22936591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov
22946591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov    if (MS.WrapIndirectCalls && !CS.getCalledFunction())
229534432aeb6d42fbe3e327d1d339ea4156c99aa133Evgeniy Stepanov      IndirectCallList.push_back(CS);
22966591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov
2297aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    unsigned ArgOffset = 0;
2298aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "  CallSite: " << I << "\n");
2299aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    for (CallSite::arg_iterator ArgIt = CS.arg_begin(), End = CS.arg_end();
2300aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov         ArgIt != End; ++ArgIt) {
2301aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *A = *ArgIt;
2302aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      unsigned i = ArgIt - CS.arg_begin();
2303aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      if (!A->getType()->isSized()) {
2304aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        DEBUG(dbgs() << "Arg " << i << " is not sized: " << I << "\n");
2305aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        continue;
2306aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
2307aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      unsigned Size = 0;
2308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Value *Store = nullptr;
2309aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // Compute the Shadow for arg even if it is ByVal, because
2310aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // in that case getShadow() will copy the actual arg shadow to
2311aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // __msan_param_tls.
2312aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *ArgShadow = getShadow(A);
2313aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *ArgShadowBase = getShadowPtrForArgument(A, IRB, ArgOffset);
2314aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      DEBUG(dbgs() << "  Arg#" << i << ": " << *A <<
2315aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov            " Shadow: " << *ArgShadow << "\n");
2316034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling      if (CS.paramHasAttr(i + 1, Attribute::ByVal)) {
2317aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        assert(A->getType()->isPointerTy() &&
2318aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov               "ByVal argument is not a pointer!");
231936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Size = MS.DL->getTypeAllocSize(A->getType()->getPointerElementType());
2320aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        unsigned Alignment = CS.getParamAlignment(i + 1);
2321aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        Store = IRB.CreateMemCpy(ArgShadowBase,
2322aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                 getShadowPtr(A, Type::getInt8Ty(*MS.C), IRB),
2323aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                 Size, Alignment);
2324aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      } else {
232536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Size = MS.DL->getTypeAllocSize(A->getType());
23267fa22404855e996efb1963b9152505c9e1f27fd5Evgeniy Stepanov        Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
23277fa22404855e996efb1963b9152505c9e1f27fd5Evgeniy Stepanov                                       kShadowTLSAlignment);
2328aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
232933660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov      if (MS.TrackOrigins)
233063cca4e2fd4dd70e54055c4d34d858f810e0bd44Evgeniy Stepanov        IRB.CreateStore(getOrigin(A),
233163cca4e2fd4dd70e54055c4d34d858f810e0bd44Evgeniy Stepanov                        getOriginPtrForArgument(A, IRB, ArgOffset));
2332f1af1feeee0f0ec797410762c006211f9c1e2a0fEdwin Vane      (void)Store;
2333dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      assert(Size != 0 && Store != nullptr);
2334aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      DEBUG(dbgs() << "  Param:" << *Store << "\n");
2335aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      ArgOffset += DataLayout::RoundUpAlignment(Size, 8);
2336aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2337aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "  done with call args\n");
2338aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2339aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    FunctionType *FT =
23406591308b7e041bb8e5e211f84bcc4a97d3764cc5Evgeniy Stepanov      cast<FunctionType>(CS.getCalledValue()->getType()->getContainedType(0));
2341aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (FT->isVarArg()) {
2342aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      VAHelper->visitCallSite(CS, IRB);
2343aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2344aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2345aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Now, get the shadow for the RetVal.
2346aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (!I.getType()->isSized()) return;
2347aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRBBefore(&I);
234836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Until we have full dynamic coverage, make sure the retval shadow is 0.
2349aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Base = getShadowPtrForRetval(&I, IRBBefore);
23507fa22404855e996efb1963b9152505c9e1f27fd5Evgeniy Stepanov    IRBBefore.CreateAlignedStore(getCleanShadow(&I), Base, kShadowTLSAlignment);
2351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Instruction *NextInsn = nullptr;
2352aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (CS.isCall()) {
2353aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      NextInsn = I.getNextNode();
2354aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    } else {
2355aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      BasicBlock *NormalDest = cast<InvokeInst>(&I)->getNormalDest();
2356aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      if (!NormalDest->getSinglePredecessor()) {
2357aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        // FIXME: this case is tricky, so we are just conservative here.
2358aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        // Perhaps we need to split the edge between this BB and NormalDest,
2359aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        // but a naive attempt to use SplitEdge leads to a crash.
2360aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        setShadow(&I, getCleanShadow(&I));
2361aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        setOrigin(&I, getCleanOrigin());
2362aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        return;
2363aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
2364aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      NextInsn = NormalDest->getFirstInsertionPt();
2365aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      assert(NextInsn &&
2366aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov             "Could not find insertion point for retval shadow load");
2367aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2368aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRBAfter(NextInsn);
23697fa22404855e996efb1963b9152505c9e1f27fd5Evgeniy Stepanov    Value *RetvalShadow =
23707fa22404855e996efb1963b9152505c9e1f27fd5Evgeniy Stepanov      IRBAfter.CreateAlignedLoad(getShadowPtrForRetval(&I, IRBAfter),
23717fa22404855e996efb1963b9152505c9e1f27fd5Evgeniy Stepanov                                 kShadowTLSAlignment, "_msret");
23727fa22404855e996efb1963b9152505c9e1f27fd5Evgeniy Stepanov    setShadow(&I, RetvalShadow);
237333660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov    if (MS.TrackOrigins)
2374aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      setOrigin(&I, IRBAfter.CreateLoad(getOriginPtrForRetval(IRBAfter)));
2375aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2376aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2377aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitReturnInst(ReturnInst &I) {
2378aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
2379e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov    Value *RetVal = I.getReturnValue();
2380e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov    if (!RetVal) return;
2381e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov    Value *ShadowPtr = getShadowPtrForRetval(RetVal, IRB);
2382e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov    if (CheckReturnValue) {
238395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      insertShadowCheck(RetVal, &I);
2384e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov      Value *Shadow = getCleanShadow(RetVal);
2385e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov      IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
2386e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov    } else {
2387aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *Shadow = getShadow(RetVal);
23887fa22404855e996efb1963b9152505c9e1f27fd5Evgeniy Stepanov      IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
2389e5c8c5a1bcecff7e2aa60672be6af2062ad63e6aEvgeniy Stepanov      // FIXME: make it conditional if ClStoreCleanOrigin==0
239033660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov      if (MS.TrackOrigins)
2391aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval(IRB));
2392aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2393aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2394aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2395aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitPHINode(PHINode &I) {
2396aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
2397cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!PropagateShadow) {
2398cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      setShadow(&I, getCleanShadow(&I));
2399cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return;
2400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2401cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2402aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    ShadowPHINodes.push_back(&I);
2403aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
2404aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                "_msphi_s"));
240533660cdfbd521f39982e86844db6784848b8f5d5Evgeniy Stepanov    if (MS.TrackOrigins)
2406aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      setOrigin(&I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(),
2407aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                  "_msphi_o"));
2408aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2409aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2410aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitAllocaInst(AllocaInst &I) {
2411aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, getCleanShadow(&I));
2412aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(I.getNextNode());
241336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint64_t Size = MS.DL->getTypeAllocSize(I.getAllocatedType());
2414d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov    if (PoisonStack && ClPoisonStackWithCall) {
2415aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateCall2(MS.MsanPoisonStackFn,
2416aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                      IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()),
2417aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                      ConstantInt::get(MS.IntptrTy, Size));
2418aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    } else {
2419aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *ShadowBase = getShadowPtr(&I, Type::getInt8PtrTy(*MS.C), IRB);
2420d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov      Value *PoisonValue = IRB.getInt8(PoisonStack ? ClPoisonStackPattern : 0);
2421d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov      IRB.CreateMemSet(ShadowBase, PoisonValue, Size, I.getAlignment());
2422aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2423aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2424d55ef5ce5f92fc02063e65ef328b89a7d66a3636Evgeniy Stepanov    if (PoisonStack && MS.TrackOrigins) {
2425aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      setOrigin(&I, getCleanOrigin());
2426aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      SmallString<2048> StackDescriptionStorage;
2427aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      raw_svector_ostream StackDescription(StackDescriptionStorage);
2428aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // We create a string with a description of the stack allocation and
2429aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // pass it into __msan_set_alloca_origin.
2430aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // It will be printed by the run-time if stack-originated UMR is found.
2431aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // The first 4 bytes of the string are set to '----' and will be replaced
2432aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // by __msan_va_arg_overflow_size_tls at the first call.
2433aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      StackDescription << "----" << I.getName() << "@" << F.getName();
2434aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *Descr =
2435aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          createPrivateNonConstGlobalForString(*F.getParent(),
2436aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                               StackDescription.str());
2437993a0c56ec166ed1e6cc5b9275f81bc3ca4ed880Evgeniy Stepanov
2438993a0c56ec166ed1e6cc5b9275f81bc3ca4ed880Evgeniy Stepanov      IRB.CreateCall4(MS.MsanSetAllocaOrigin4Fn,
2439aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                      IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()),
2440aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                      ConstantInt::get(MS.IntptrTy, Size),
2441993a0c56ec166ed1e6cc5b9275f81bc3ca4ed880Evgeniy Stepanov                      IRB.CreatePointerCast(Descr, IRB.getInt8PtrTy()),
2442993a0c56ec166ed1e6cc5b9275f81bc3ca4ed880Evgeniy Stepanov                      IRB.CreatePointerCast(&F, MS.IntptrTy));
2443aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2444aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2445aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2446aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitSelectInst(SelectInst& I) {
2447aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
24486a9b29ec9b42e792732659e510a655449a41b661Evgeniy Stepanov    // a = select b, c, d
244936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *B = I.getCondition();
245036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *C = I.getTrueValue();
245136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *D = I.getFalseValue();
245236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *Sb = getShadow(B);
245336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *Sc = getShadow(C);
245436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *Sd = getShadow(D);
245536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
245636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Result shadow if condition shadow is 0.
245736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *Sa0 = IRB.CreateSelect(B, Sc, Sd);
245836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *Sa1;
245969086b2962b16a9e78aea0605202c5ea126049aeEvgeniy Stepanov    if (I.getType()->isAggregateType()) {
246069086b2962b16a9e78aea0605202c5ea126049aeEvgeniy Stepanov      // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do
246169086b2962b16a9e78aea0605202c5ea126049aeEvgeniy Stepanov      // an extra "select". This results in much more compact IR.
246269086b2962b16a9e78aea0605202c5ea126049aeEvgeniy Stepanov      // Sa = select Sb, poisoned, (select b, Sc, Sd)
246336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Sa1 = getPoisonedShadow(getShadowTy(I.getType()));
246469086b2962b16a9e78aea0605202c5ea126049aeEvgeniy Stepanov    } else {
246536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ]
246636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // If Sb (condition is poisoned), look for bits in c and d that are equal
246736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // and both unpoisoned.
246836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd.
246936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
247036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Cast arguments to shadow-compatible type.
247136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      C = CreateAppToShadowCast(IRB, C);
247236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      D = CreateAppToShadowCast(IRB, D);
247336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
247436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Result shadow if condition shadow is 1.
247536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Sa1 = IRB.CreateOr(IRB.CreateXor(C, D), IRB.CreateOr(Sc, Sd));
247669086b2962b16a9e78aea0605202c5ea126049aeEvgeniy Stepanov    }
247736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
247836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    setShadow(&I, Sa);
24796607716368ba04454ff9ad62ac25936357d67c51Evgeniy Stepanov    if (MS.TrackOrigins) {
24806607716368ba04454ff9ad62ac25936357d67c51Evgeniy Stepanov      // Origins are always i32, so any vector conditions must be flattened.
24816607716368ba04454ff9ad62ac25936357d67c51Evgeniy Stepanov      // FIXME: consider tracking vector origins for app vectors?
248236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (B->getType()->isVectorTy()) {
248336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Type *FlatTy = getShadowTyNoVec(B->getType());
248436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        B = IRB.CreateICmpNE(IRB.CreateBitCast(B, FlatTy),
248536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                ConstantInt::getNullValue(FlatTy));
248636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Sb = IRB.CreateICmpNE(IRB.CreateBitCast(Sb, FlatTy),
248736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                      ConstantInt::getNullValue(FlatTy));
24886607716368ba04454ff9ad62ac25936357d67c51Evgeniy Stepanov      }
248936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // a = select b, c, d
249036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Oa = Sb ? Ob : (b ? Oc : Od)
249136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      setOrigin(&I, IRB.CreateSelect(
249236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        Sb, getOrigin(I.getCondition()),
249336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                        IRB.CreateSelect(B, getOrigin(C), getOrigin(D))));
24946607716368ba04454ff9ad62ac25936357d67c51Evgeniy Stepanov    }
2495aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2496aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2497aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitLandingPadInst(LandingPadInst &I) {
2498aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Do nothing.
2499aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // See http://code.google.com/p/memory-sanitizer/issues/detail?id=1
2500aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, getCleanShadow(&I));
2501aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getCleanOrigin());
2502aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2503aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2504aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitGetElementPtrInst(GetElementPtrInst &I) {
2505aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    handleShadowOr(I);
2506aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2507aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2508aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitExtractValueInst(ExtractValueInst &I) {
2509aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
2510aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Agg = I.getAggregateOperand();
2511aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "ExtractValue:  " << I << "\n");
2512aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *AggShadow = getShadow(Agg);
2513aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "   AggShadow:  " << *AggShadow << "\n");
2514aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
2515aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "   ResShadow:  " << *ResShadow << "\n");
2516aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, ResShadow);
25174590b8c090dade63d6cb1ba39109331607036f4dEvgeniy Stepanov    setOriginForNaryOp(I);
2518aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2519aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2520aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitInsertValueInst(InsertValueInst &I) {
2521aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
2522aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "InsertValue:  " << I << "\n");
2523aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *AggShadow = getShadow(I.getAggregateOperand());
2524aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *InsShadow = getShadow(I.getInsertedValueOperand());
2525aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "   AggShadow:  " << *AggShadow << "\n");
2526aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "   InsShadow:  " << *InsShadow << "\n");
2527aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
2528aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "   Res:        " << *Res << "\n");
2529aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, Res);
25304590b8c090dade63d6cb1ba39109331607036f4dEvgeniy Stepanov    setOriginForNaryOp(I);
2531aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2532aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2533aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void dumpInst(Instruction &I) {
2534aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (CallInst *CI = dyn_cast<CallInst>(&I)) {
2535aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      errs() << "ZZZ call " << CI->getCalledFunction()->getName() << "\n";
2536aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    } else {
2537aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      errs() << "ZZZ " << I.getOpcodeName() << "\n";
2538aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2539aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    errs() << "QQQ " << I << "\n";
2540aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2541aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2542aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitResumeInst(ResumeInst &I) {
2543aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "Resume: " << I << "\n");
2544aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Nothing to do here.
2545aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2546aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2547aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  void visitInstruction(Instruction &I) {
2548aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Everything else: stop propagating and check for poisoned shadow.
2549aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (ClDumpStrictInstructions)
2550aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      dumpInst(I);
2551aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    DEBUG(dbgs() << "DEFAULT: " << I << "\n");
2552aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    for (size_t i = 0, n = I.getNumOperands(); i < n; i++)
255395864303f5054c68043febc861764070e8f13913Evgeniy Stepanov      insertShadowCheck(I.getOperand(i), &I);
2554aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setShadow(&I, getCleanShadow(&I));
2555aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    setOrigin(&I, getCleanOrigin());
2556aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2557aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov};
2558aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2559aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov/// \brief AMD64-specific implementation of VarArgHelper.
2560aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovstruct VarArgAMD64Helper : public VarArgHelper {
2561aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // An unfortunate workaround for asymmetric lowering of va_arg stuff.
2562aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // See a comment in visitCallSite for more details.
256379c3742620efccf7c36ea1738bb121ad70d644d0Evgeniy Stepanov  static const unsigned AMD64GpEndOffset = 48;  // AMD64 ABI Draft 0.99.6 p3.5.7
2564aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  static const unsigned AMD64FpEndOffset = 176;
2565aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2566aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Function &F;
2567aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  MemorySanitizer &MS;
2568aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  MemorySanitizerVisitor &MSV;
2569aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *VAArgTLSCopy;
2570aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  Value *VAArgOverflowSize;
2571aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2572aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  SmallVector<CallInst*, 16> VAStartInstrumentationList;
2573aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2574aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  VarArgAMD64Helper(Function &F, MemorySanitizer &MS,
2575aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                    MemorySanitizerVisitor &MSV)
2576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : F(F), MS(MS), MSV(MSV), VAArgTLSCopy(nullptr),
2577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      VAArgOverflowSize(nullptr) {}
2578aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2579aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
2580aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2581aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  ArgKind classifyArgument(Value* arg) {
2582aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // A very rough approximation of X86_64 argument classification rules.
2583aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Type *T = arg->getType();
2584aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (T->isFPOrFPVectorTy() || T->isX86_MMXTy())
2585aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return AK_FloatingPoint;
2586aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64)
2587aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return AK_GeneralPurpose;
2588aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (T->isPointerTy())
2589aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      return AK_GeneralPurpose;
2590aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    return AK_Memory;
2591aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2592aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2593aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // For VarArg functions, store the argument shadow in an ABI-specific format
2594aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // that corresponds to va_list layout.
2595aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // We do this because Clang lowers va_arg in the frontend, and this pass
2596aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // only sees the low level code that deals with va_list internals.
2597aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // A much easier alternative (provided that Clang emits va_arg instructions)
2598aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // would have been to associate each live instance of va_list with a copy of
2599aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // MSanParamTLS, and extract shadow on va_arg() call in the argument list
2600aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // order.
260136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void visitCallSite(CallSite &CS, IRBuilder<> &IRB) override {
2602aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    unsigned GpOffset = 0;
2603aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    unsigned FpOffset = AMD64GpEndOffset;
2604aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    unsigned OverflowOffset = AMD64FpEndOffset;
2605aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    for (CallSite::arg_iterator ArgIt = CS.arg_begin(), End = CS.arg_end();
2606aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov         ArgIt != End; ++ArgIt) {
2607aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *A = *ArgIt;
260836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned ArgNo = CS.getArgumentNo(ArgIt);
260936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      bool IsByVal = CS.paramHasAttr(ArgNo + 1, Attribute::ByVal);
261036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (IsByVal) {
261136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        // ByVal arguments always go to the overflow area.
261236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        assert(A->getType()->isPointerTy());
261336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Type *RealTy = A->getType()->getPointerElementType();
261436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        uint64_t ArgSize = MS.DL->getTypeAllocSize(RealTy);
261536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Value *Base = getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset);
2616aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        OverflowOffset += DataLayout::RoundUpAlignment(ArgSize, 8);
261736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        IRB.CreateMemCpy(Base, MSV.getShadowPtr(A, IRB.getInt8Ty(), IRB),
261836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         ArgSize, kShadowTLSAlignment);
261936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      } else {
262036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ArgKind AK = classifyArgument(A);
262136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
262236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          AK = AK_Memory;
262336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
262436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          AK = AK_Memory;
262536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Value *Base;
262636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        switch (AK) {
262736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          case AK_GeneralPurpose:
262836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            Base = getShadowPtrForVAArgument(A->getType(), IRB, GpOffset);
262936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            GpOffset += 8;
263036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            break;
263136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          case AK_FloatingPoint:
263236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            Base = getShadowPtrForVAArgument(A->getType(), IRB, FpOffset);
263336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            FpOffset += 16;
263436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            break;
263536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          case AK_Memory:
263636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            uint64_t ArgSize = MS.DL->getTypeAllocSize(A->getType());
263736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            Base = getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset);
263836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            OverflowOffset += DataLayout::RoundUpAlignment(ArgSize, 8);
263936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        }
264036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
2641aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      }
2642aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2643aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Constant *OverflowSize =
2644aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
2645aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
2646aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2647aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2648aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  /// \brief Compute the shadow address for a given va_arg.
264936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
2650aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                   int ArgOffset) {
2651aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
2652aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
265336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
2654aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                              "_msarg");
2655aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2656aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
265736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void visitVAStartInst(VAStartInst &I) override {
2658aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
2659aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    VAStartInstrumentationList.push_back(&I);
2660aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *VAListTag = I.getArgOperand(0);
2661aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *ShadowPtr = MSV.getShadowPtr(VAListTag, IRB.getInt8Ty(), IRB);
2662aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2663aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Unpoison the whole __va_list_tag.
2664aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // FIXME: magic ABI constants.
2665aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
266603de2a621c2f063294eb3f65ea1136f3acac4e98Peter Collingbourne                     /* size */24, /* alignment */8, false);
2667aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2668aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
266936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void visitVACopyInst(VACopyInst &I) override {
2670aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRBuilder<> IRB(&I);
2671aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *VAListTag = I.getArgOperand(0);
2672aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    Value *ShadowPtr = MSV.getShadowPtr(VAListTag, IRB.getInt8Ty(), IRB);
2673aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2674aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Unpoison the whole __va_list_tag.
2675aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // FIXME: magic ABI constants.
2676aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
267703de2a621c2f063294eb3f65ea1136f3acac4e98Peter Collingbourne                     /* size */24, /* alignment */8, false);
2678aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2679aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
268036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void finalizeInstrumentation() override {
2681aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    assert(!VAArgOverflowSize && !VAArgTLSCopy &&
2682aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov           "finalizeInstrumentation called twice");
2683aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    if (!VAStartInstrumentationList.empty()) {
2684aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // If there is a va_start in this function, make a backup copy of
2685aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      // va_arg_tls somewhere in the function entry block.
2686aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI());
2687aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      VAArgOverflowSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS);
2688aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *CopySize =
2689aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset),
2690aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                      VAArgOverflowSize);
2691aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
2692aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8);
2693aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2694aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2695aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Instrument va_start.
2696aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    // Copy va_list shadow from the backup copy of the TLS contents.
2697aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
2698aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      CallInst *OrigInst = VAStartInstrumentationList[i];
2699aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRBuilder<> IRB(OrigInst->getNextNode());
2700aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *VAListTag = OrigInst->getArgOperand(0);
2701aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2702aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *RegSaveAreaPtrPtr =
2703aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        IRB.CreateIntToPtr(
2704aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
2705aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                        ConstantInt::get(MS.IntptrTy, 16)),
2706aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          Type::getInt64PtrTy(*MS.C));
2707aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *RegSaveAreaPtr = IRB.CreateLoad(RegSaveAreaPtrPtr);
2708aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *RegSaveAreaShadowPtr =
2709aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        MSV.getShadowPtr(RegSaveAreaPtr, IRB.getInt8Ty(), IRB);
2710aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy,
2711aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                       AMD64FpEndOffset, 16);
2712aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2713aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *OverflowArgAreaPtrPtr =
2714aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        IRB.CreateIntToPtr(
2715aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
2716aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                        ConstantInt::get(MS.IntptrTy, 8)),
2717aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov          Type::getInt64PtrTy(*MS.C));
2718aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *OverflowArgAreaPtr = IRB.CreateLoad(OverflowArgAreaPtrPtr);
2719aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      Value *OverflowArgAreaShadowPtr =
2720aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov        MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB);
27217c7b8e57f8f3d20610cdbf1888e2f0101752f986Evgeniy Stepanov      Value *SrcPtr = IRB.CreateConstGEP1_32(VAArgTLSCopy, AMD64FpEndOffset);
2722aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov      IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16);
2723aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov    }
2724aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  }
2725aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov};
2726aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2727bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov/// \brief A no-op implementation of VarArgHelper.
2728bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanovstruct VarArgNoOpHelper : public VarArgHelper {
2729bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov  VarArgNoOpHelper(Function &F, MemorySanitizer &MS,
2730bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov                   MemorySanitizerVisitor &MSV) {}
2731bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov
273236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void visitCallSite(CallSite &CS, IRBuilder<> &IRB) override {}
2733bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov
273436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void visitVAStartInst(VAStartInst &I) override {}
2735bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov
273636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void visitVACopyInst(VACopyInst &I) override {}
2737bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov
273836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void finalizeInstrumentation() override {}
2739bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov};
2740bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov
2741bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy StepanovVarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
2742aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov                                 MemorySanitizerVisitor &Visitor) {
2743bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov  // VarArg handling is only implemented on AMD64. False positives are possible
2744bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov  // on other platforms.
2745bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov  llvm::Triple TargetTriple(Func.getParent()->getTargetTriple());
2746bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov  if (TargetTriple.getArch() == llvm::Triple::x86_64)
2747bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov    return new VarArgAMD64Helper(Func, Msan, Visitor);
2748bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov  else
2749bf4150656f9d82b26864c1115e8444dd3eae4ceeEvgeniy Stepanov    return new VarArgNoOpHelper(Func, Msan, Visitor);
2750aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov}
2751aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2752aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov}  // namespace
2753aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2754aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanovbool MemorySanitizer::runOnFunction(Function &F) {
2755aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  MemorySanitizerVisitor Visitor(F, *this);
2756aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2757aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  // Clear out readonly/readnone attributes.
2758aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  AttrBuilder B;
2759034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  B.addAttribute(Attribute::ReadOnly)
2760034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    .addAttribute(Attribute::ReadNone);
27618246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling  F.removeAttributes(AttributeSet::FunctionIndex,
27628246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling                     AttributeSet::get(F.getContext(),
27638246df61f6de716acf1f8c64fac3c19970a2c174Bill Wendling                                       AttributeSet::FunctionIndex, B));
2764aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov
2765aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov  return Visitor.runOnFunction();
2766aa4f97d6ed9c2b6db6a902d796d86d566c804008Evgeniy Stepanov}
2767