@@ -174,6 +174,7 @@ class MemoryBehaviorVisitor
174174
175175 MemBehavior visitLoadInst (LoadInst *LI);
176176 MemBehavior visitStoreInst (StoreInst *SI);
177+ MemBehavior visitCopyAddrInst (CopyAddrInst *CAI);
177178 MemBehavior visitApplyInst (ApplyInst *AI);
178179 MemBehavior visitTryApplyInst (TryApplyInst *AI);
179180 MemBehavior visitBuiltinInst (BuiltinInst *BI);
@@ -245,6 +246,10 @@ MemBehavior MemoryBehaviorVisitor::visitLoadInst(LoadInst *LI) {
245246 if (!mayAlias (LI->getOperand ()))
246247 return MemBehavior::None;
247248
249+ // A take is modelled as a write. See MemoryBehavior::MayWrite.
250+ if (LI->getOwnershipQualifier () == LoadOwnershipQualifier::Take)
251+ return MemBehavior::MayReadWrite;
252+
248253 LLVM_DEBUG (llvm::dbgs () << " Could not prove that load inst does not alias "
249254 " pointer. Returning may read.\n " );
250255 return MemBehavior::MayRead;
@@ -268,6 +273,34 @@ MemBehavior MemoryBehaviorVisitor::visitStoreInst(StoreInst *SI) {
268273 return MemBehavior::MayWrite;
269274}
270275
276+ MemBehavior MemoryBehaviorVisitor::visitCopyAddrInst (CopyAddrInst *CAI) {
277+ // If it's an assign to the destination, a destructor might be called on the
278+ // old value. This can have any side effects.
279+ // We could also check if it's a trivial type (which cannot have any side
280+ // effect on destruction), but such copy_addr instructions are optimized to
281+ // load/stores anyway, so it's probably not worth it.
282+ if (!CAI->isInitializationOfDest ())
283+ return MemBehavior::MayHaveSideEffects;
284+
285+ bool mayWrite = mayAlias (CAI->getDest ());
286+ bool mayRead = mayAlias (CAI->getSrc ());
287+
288+ if (mayRead) {
289+ if (mayWrite)
290+ return MemBehavior::MayReadWrite;
291+
292+ // A take is modelled as a write. See MemoryBehavior::MayWrite.
293+ if (CAI->isTakeOfSrc ())
294+ return MemBehavior::MayReadWrite;
295+
296+ return MemBehavior::MayRead;
297+ }
298+ if (mayWrite)
299+ return MemBehavior::MayWrite;
300+
301+ return MemBehavior::None;
302+ }
303+
271304MemBehavior MemoryBehaviorVisitor::visitBuiltinInst (BuiltinInst *BI) {
272305 // If our callee is not a builtin, be conservative and return may have side
273306 // effects.
0 commit comments