LLVM 22.0.0git
MemoryLocation.cpp
Go to the documentation of this file.
1//===- MemoryLocation.cpp - Memory location descriptions -------------------==//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/IR/DataLayout.h"
14#include "llvm/IR/IntrinsicsARM.h"
15#include "llvm/IR/Type.h"
16#include <optional>
17using namespace llvm;
18
20 OS << "LocationSize::";
21 if (*this == beforeOrAfterPointer())
22 OS << "beforeOrAfterPointer";
23 else if (*this == afterPointer())
24 OS << "afterPointer";
25 else if (*this == mapEmpty())
26 OS << "mapEmpty";
27 else if (*this == mapTombstone())
28 OS << "mapTombstone";
29 else if (isPrecise())
30 OS << "precise(" << getValue() << ')';
31 else
32 OS << "upperBound(" << getValue() << ')';
33}
34
36 const auto &DL = LI->getDataLayout();
37
38 return MemoryLocation(
40 LocationSize::precise(DL.getTypeStoreSize(LI->getType())),
41 LI->getAAMetadata());
42}
43
45 const auto &DL = SI->getDataLayout();
46
47 return MemoryLocation(SI->getPointerOperand(),
48 LocationSize::precise(DL.getTypeStoreSize(
49 SI->getValueOperand()->getType())),
50 SI->getAAMetadata());
51}
52
54 return MemoryLocation(VI->getPointerOperand(),
55 LocationSize::afterPointer(), VI->getAAMetadata());
56}
57
59 const auto &DL = CXI->getDataLayout();
60
62 LocationSize::precise(DL.getTypeStoreSize(
63 CXI->getCompareOperand()->getType())),
64 CXI->getAAMetadata());
65}
66
68 const auto &DL = RMWI->getDataLayout();
69
70 return MemoryLocation(RMWI->getPointerOperand(),
71 LocationSize::precise(DL.getTypeStoreSize(
72 RMWI->getValOperand()->getType())),
73 RMWI->getAAMetadata());
74}
75
76std::optional<MemoryLocation>
78 switch (Inst->getOpcode()) {
79 case Instruction::Load:
80 return get(cast<LoadInst>(Inst));
81 case Instruction::Store:
82 return get(cast<StoreInst>(Inst));
83 case Instruction::VAArg:
84 return get(cast<VAArgInst>(Inst));
85 case Instruction::AtomicCmpXchg:
86 return get(cast<AtomicCmpXchgInst>(Inst));
87 case Instruction::AtomicRMW:
88 return get(cast<AtomicRMWInst>(Inst));
89 default:
90 return std::nullopt;
91 }
92}
93
95 return getForSource(cast<AnyMemTransferInst>(MTI));
96}
97
99 assert(MTI->getRawSource() == MTI->getArgOperand(1));
100 return getForArgument(MTI, 1, nullptr);
101}
102
104 return getForDest(cast<AnyMemIntrinsic>(MI));
105}
106
108 assert(MI->getRawDest() == MI->getArgOperand(0));
109 return getForArgument(MI, 0, nullptr);
110}
111
112std::optional<MemoryLocation>
114 // Check that the only possible writes are to arguments.
116 if (!WriteME.onlyAccessesArgPointees())
117 return std::nullopt;
118
119 if (CB->hasOperandBundles())
120 // TODO: remove implementation restriction
121 return std::nullopt;
122
123 Value *UsedV = nullptr;
124 std::optional<unsigned> UsedIdx;
125 for (unsigned i = 0; i < CB->arg_size(); i++) {
126 if (!CB->getArgOperand(i)->getType()->isPointerTy())
127 continue;
128 if (CB->onlyReadsMemory(i))
129 continue;
130 if (!UsedV) {
131 // First potentially writing parameter
132 UsedV = CB->getArgOperand(i);
133 UsedIdx = i;
134 continue;
135 }
136 UsedIdx = std::nullopt;
137 if (UsedV != CB->getArgOperand(i))
138 // Can't describe writing to two distinct locations.
139 // TODO: This results in an inprecision when two values derived from the
140 // same object are passed as arguments to the same function.
141 return std::nullopt;
142 }
143 if (!UsedV)
144 // We don't currently have a way to represent a "does not write" result
145 // and thus have to be conservative and return unknown.
146 return std::nullopt;
147
148 if (UsedIdx)
149 return getForArgument(CB, *UsedIdx, &TLI);
151}
152
154 unsigned ArgIdx,
155 const TargetLibraryInfo *TLI) {
156 AAMDNodes AATags = Call->getAAMetadata();
157 const Value *Arg = Call->getArgOperand(ArgIdx);
158
159 // We may be able to produce an exact size for known intrinsics.
160 if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Call)) {
161 const DataLayout &DL = II->getDataLayout();
162
163 switch (II->getIntrinsicID()) {
164 default:
165 break;
166 case Intrinsic::memset:
167 case Intrinsic::memcpy:
168 case Intrinsic::memcpy_inline:
169 case Intrinsic::memmove:
170 case Intrinsic::memcpy_element_unordered_atomic:
171 case Intrinsic::memmove_element_unordered_atomic:
172 case Intrinsic::memset_element_unordered_atomic:
173 assert((ArgIdx == 0 || ArgIdx == 1) &&
174 "Invalid argument index for memory intrinsic");
175 if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
176 return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
177 AATags);
178 return MemoryLocation::getAfter(Arg, AATags);
179
180 case Intrinsic::experimental_memset_pattern:
181 assert((ArgIdx == 0 || ArgIdx == 1) &&
182 "Invalid argument index for memory intrinsic");
183 if (ConstantInt *LenCI = dyn_cast<ConstantInt>(II->getArgOperand(2)))
184 return MemoryLocation(
185 Arg,
187 LenCI->getZExtValue() *
188 DL.getTypeAllocSize(II->getArgOperand(1)->getType())),
189 AATags);
190 return MemoryLocation::getAfter(Arg, AATags);
191
192 case Intrinsic::lifetime_start:
193 case Intrinsic::lifetime_end: {
194 assert(ArgIdx == 0 && "Invalid argument index");
195 auto *AI = dyn_cast<AllocaInst>(Arg);
196 if (!AI)
197 // lifetime of poison value.
199
200 std::optional<TypeSize> AllocSize =
201 AI->getAllocationSize(II->getDataLayout());
202 return MemoryLocation(Arg,
203 AllocSize ? LocationSize::precise(*AllocSize)
205 AATags);
206 }
207
208 case Intrinsic::invariant_start:
209 assert(ArgIdx == 1 && "Invalid argument index");
210 return MemoryLocation(
211 Arg,
213 cast<ConstantInt>(II->getArgOperand(0))->getZExtValue()),
214 AATags);
215
216 case Intrinsic::masked_load:
217 assert(ArgIdx == 0 && "Invalid argument index");
218 return MemoryLocation(
219 Arg,
220 LocationSize::upperBound(DL.getTypeStoreSize(II->getType())),
221 AATags);
222
223 case Intrinsic::masked_store:
224 assert(ArgIdx == 1 && "Invalid argument index");
225 return MemoryLocation(
226 Arg,
228 DL.getTypeStoreSize(II->getArgOperand(0)->getType())),
229 AATags);
230
231 case Intrinsic::invariant_end:
232 // The first argument to an invariant.end is a "descriptor" type (e.g. a
233 // pointer to a empty struct) which is never actually dereferenced.
234 if (ArgIdx == 0)
236 assert(ArgIdx == 2 && "Invalid argument index");
237 return MemoryLocation(
238 Arg,
240 cast<ConstantInt>(II->getArgOperand(1))->getZExtValue()),
241 AATags);
242
243 case Intrinsic::arm_neon_vld1:
244 assert(ArgIdx == 0 && "Invalid argument index");
245 // LLVM's vld1 and vst1 intrinsics currently only support a single
246 // vector register.
247 return MemoryLocation(
248 Arg, LocationSize::precise(DL.getTypeStoreSize(II->getType())),
249 AATags);
250
251 case Intrinsic::arm_neon_vst1:
252 assert(ArgIdx == 0 && "Invalid argument index");
253 return MemoryLocation(Arg,
254 LocationSize::precise(DL.getTypeStoreSize(
255 II->getArgOperand(1)->getType())),
256 AATags);
257 }
258
259 assert(
260 !isa<AnyMemTransferInst>(II) &&
261 "all memory transfer intrinsics should be handled by the switch above");
262 }
263
264 // We can bound the aliasing properties of memset_pattern16 just as we can
265 // for memcpy/memset. This is particularly important because the
266 // LoopIdiomRecognizer likes to turn loops into calls to memset_pattern16
267 // whenever possible.
268 LibFunc F;
269 if (TLI && TLI->getLibFunc(*Call, F) && TLI->has(F)) {
270 switch (F) {
271 case LibFunc_strcpy:
272 case LibFunc_strcat:
273 case LibFunc_strncat:
274 assert((ArgIdx == 0 || ArgIdx == 1) && "Invalid argument index for str function");
275 return MemoryLocation::getAfter(Arg, AATags);
276
277 case LibFunc_memset_chk:
278 assert(ArgIdx == 0 && "Invalid argument index for memset_chk");
279 [[fallthrough]];
280 case LibFunc_memcpy_chk: {
281 assert((ArgIdx == 0 || ArgIdx == 1) &&
282 "Invalid argument index for memcpy_chk");
284 if (const auto *Len = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
285 // memset_chk writes at most Len bytes, memcpy_chk reads/writes at most
286 // Len bytes. They may read/write less, if Len exceeds the specified max
287 // size and aborts.
288 Size = LocationSize::upperBound(Len->getZExtValue());
289 }
290 return MemoryLocation(Arg, Size, AATags);
291 }
292 case LibFunc_strncpy: {
293 assert((ArgIdx == 0 || ArgIdx == 1) &&
294 "Invalid argument index for strncpy");
296 if (const auto *Len = dyn_cast<ConstantInt>(Call->getArgOperand(2))) {
297 // strncpy is guaranteed to write Len bytes, but only reads up to Len
298 // bytes.
299 Size = ArgIdx == 0 ? LocationSize::precise(Len->getZExtValue())
300 : LocationSize::upperBound(Len->getZExtValue());
301 }
302 return MemoryLocation(Arg, Size, AATags);
303 }
304 case LibFunc_memset_pattern16:
305 case LibFunc_memset_pattern4:
306 case LibFunc_memset_pattern8:
307 assert((ArgIdx == 0 || ArgIdx == 1) &&
308 "Invalid argument index for memset_pattern16");
309 if (ArgIdx == 1) {
310 unsigned Size = 16;
311 if (F == LibFunc_memset_pattern4)
312 Size = 4;
313 else if (F == LibFunc_memset_pattern8)
314 Size = 8;
316 }
317 if (const ConstantInt *LenCI =
318 dyn_cast<ConstantInt>(Call->getArgOperand(2)))
319 return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
320 AATags);
321 return MemoryLocation::getAfter(Arg, AATags);
322 case LibFunc_bcmp:
323 case LibFunc_memcmp:
324 assert((ArgIdx == 0 || ArgIdx == 1) &&
325 "Invalid argument index for memcmp/bcmp");
326 if (const ConstantInt *LenCI =
327 dyn_cast<ConstantInt>(Call->getArgOperand(2)))
328 return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
329 AATags);
330 return MemoryLocation::getAfter(Arg, AATags);
331 case LibFunc_memchr:
332 assert((ArgIdx == 0) && "Invalid argument index for memchr");
333 if (const ConstantInt *LenCI =
334 dyn_cast<ConstantInt>(Call->getArgOperand(2)))
335 return MemoryLocation(Arg, LocationSize::precise(LenCI->getZExtValue()),
336 AATags);
337 return MemoryLocation::getAfter(Arg, AATags);
338 case LibFunc_memccpy:
339 assert((ArgIdx == 0 || ArgIdx == 1) &&
340 "Invalid argument index for memccpy");
341 // We only know an upper bound on the number of bytes read/written.
342 if (const ConstantInt *LenCI =
343 dyn_cast<ConstantInt>(Call->getArgOperand(3)))
344 return MemoryLocation(
345 Arg, LocationSize::upperBound(LenCI->getZExtValue()), AATags);
346 return MemoryLocation::getAfter(Arg, AATags);
347 default:
348 break;
349 };
350 }
351
352 return MemoryLocation::getBeforeOrAfter(Call->getArgOperand(ArgIdx), AATags);
353}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition: MD5.cpp:55
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
raw_pwrite_stream & OS
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:506
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:709
Value * getPointerOperand()
Definition: Instructions.h:886
Value * getValOperand()
Definition: Instructions.h:890
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
LLVM_ABI MemoryEffects getMemoryEffects() const
bool onlyReadsMemory(unsigned OpNo) const
Definition: InstrTypes.h:1751
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1292
unsigned arg_size() const
Definition: InstrTypes.h:1290
bool hasOperandBundles() const
Return true if this User has any operand bundles.
Definition: InstrTypes.h:2001
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
LLVM_ABI AAMDNodes getAAMetadata() const
Returns the AA metadata for this instruction.
Definition: Metadata.cpp:1789
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:312
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
Definition: Instruction.cpp:86
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:49
An instruction for reading from memory.
Definition: Instructions.h:180
Value * getPointerOperand()
Definition: Instructions.h:259
static LocationSize precise(uint64_t Value)
static constexpr LocationSize mapEmpty()
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
TypeSize getValue() const
LLVM_ABI void print(raw_ostream &OS) const
bool isPrecise() const
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
static LocationSize upperBound(uint64_t Value)
static constexpr LocationSize mapTombstone()
This is the common base class for memset/memcpy/memmove.
Value * getRawSource() const
Return the arguments to the instruction.
This class wraps the llvm.memcpy/memmove intrinsics.
bool onlyAccessesArgPointees() const
Whether this function only (at most) accesses argument memory.
Definition: ModRef.h:224
static MemoryEffectsBase writeOnly()
Create MemoryEffectsBase that can write any memory.
Definition: ModRef.h:130
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static LLVM_ABI MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
static MemoryLocation getAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location after Ptr, while remaining within the underlying objec...
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
static LLVM_ABI MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
static LLVM_ABI MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
An instruction for storing to memory.
Definition: Instructions.h:296
Provides information about what library functions are available for the current target.
bool has(LibFunc F) const
Tests whether a library function is available.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:267
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition: Metadata.h:760