Skip to content

Commit b74362c

Browse files
author
git apple-llvm automerger
committed
Merge commit '760018df76e7' from apple/main into swift/next
2 parents 19f729e + 760018d commit b74362c

File tree

2 files changed

+23
-22
lines changed

2 files changed

+23
-22
lines changed

llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,22 @@ INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
311311
INITIALIZE_PASS_END(MemCpyOptLegacyPass, "memcpyopt", "MemCpy Optimization",
312312
false, false)
313313

314+
// Check that V is either not accessible by the caller, or unwinding cannot
315+
// occur between Start and End.
316+
static bool mayBeVisibleThroughUnwinding(Value *V, Instruction *Start,
317+
Instruction *End) {
318+
assert(Start->getParent() == End->getParent() && "Must be in same block");
319+
if (!Start->getFunction()->doesNotThrow() &&
320+
!isa<AllocaInst>(getUnderlyingObject(V))) {
321+
for (const Instruction &I :
322+
make_range(Start->getIterator(), End->getIterator())) {
323+
if (I.mayThrow())
324+
return true;
325+
}
326+
}
327+
return false;
328+
}
329+
314330
void MemCpyOptPass::eraseInstruction(Instruction *I) {
315331
if (MSSAU)
316332
MSSAU->removeMemoryAccess(I);
@@ -848,16 +864,8 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
848864
// guaranteed to be executed if C is. As it is a non-atomic access, it
849865
// renders accesses from other threads undefined.
850866
// TODO: This is currently not checked.
851-
// TODO: Check underlying object, so we can look through GEPs.
852-
if (!isa<AllocaInst>(cpyDest)) {
853-
assert(C->getParent() == cpyStore->getParent() &&
854-
"call and copy must be in the same block");
855-
for (const Instruction &I : make_range(C->getIterator(),
856-
cpyStore->getIterator())) {
857-
if (I.mayThrow())
858-
return false;
859-
}
860-
}
867+
if (mayBeVisibleThroughUnwinding(cpyDest, C, cpyStore))
868+
return false;
861869

862870
// Check that dest points to memory that is at least as aligned as src.
863871
Align srcAlign = srcAlloca->getAlign();
@@ -1094,16 +1102,8 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
10941102
Value *DestSize = MemSet->getLength();
10951103
Value *SrcSize = MemCpy->getLength();
10961104

1097-
// If the destination might be accessible by the caller, make sure we cannot
1098-
// unwind between the memset and the memcpy.
1099-
if (!MemCpy->getFunction()->doesNotThrow() &&
1100-
!isa<AllocaInst>(getUnderlyingObject(Dest))) {
1101-
for (const Instruction &I :
1102-
make_range(MemSet->getIterator(), MemCpy->getIterator())) {
1103-
if (I.mayThrow())
1104-
return false;
1105-
}
1106-
}
1105+
if (mayBeVisibleThroughUnwinding(Dest, MemSet, MemCpy))
1106+
return false;
11071107

11081108
// By default, create an unaligned memset.
11091109
unsigned Align = 1;

llvm/test/Transforms/MemCpyOpt/callslot.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,9 @@ define void @dest_is_gep_may_throw_call() {
131131
; CHECK-NEXT: [[SRC:%.*]] = alloca [8 x i8], align 1
132132
; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [8 x i8]* [[SRC]] to i8*
133133
; CHECK-NEXT: [[DEST_I8:%.*]] = getelementptr [16 x i8], [16 x i8]* [[DEST]], i64 0, i64 8
134-
; CHECK-NEXT: call void @accept_ptr(i8* [[SRC_I8]])
135-
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST_I8]], i8* [[SRC_I8]], i64 8, i1 false)
134+
; CHECK-NEXT: [[DEST_I81:%.*]] = bitcast i8* [[DEST_I8]] to [8 x i8]*
135+
; CHECK-NEXT: [[DEST_I812:%.*]] = bitcast [8 x i8]* [[DEST_I81]] to i8*
136+
; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I812]])
136137
; CHECK-NEXT: ret void
137138
;
138139
%dest = alloca [16 x i8]

0 commit comments

Comments
 (0)