[llvm] 50cc9a0 - [MemCpyOpt] Extract common function for unwinding check
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 17 06:38:25 PDT 2020
Author: Nikita Popov
Date: 2020-10-17T15:30:39+02:00
New Revision: 50cc9a0e6124f6177633b9e5edcee25860cfa094
URL: https://github.com/llvm/llvm-project/commit/50cc9a0e6124f6177633b9e5edcee25860cfa094
DIFF: https://github.com/llvm/llvm-project/commit/50cc9a0e6124f6177633b9e5edcee25860cfa094.diff
LOG: [MemCpyOpt] Extract common function for unwinding check
These two cases should be using the same logic. Not NFC, as this
resolves the TODO regarding use of the underlying object.
Added:
Modified:
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
llvm/test/Transforms/MemCpyOpt/callslot.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 9504abe7aa91..d8a2f55957b1 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -311,6 +311,22 @@ INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
INITIALIZE_PASS_END(MemCpyOptLegacyPass, "memcpyopt", "MemCpy Optimization",
false, false)
+// Check that V is either not accessible by the caller, or unwinding cannot
+// occur between Start and End.
+static bool mayBeVisibleThroughUnwinding(Value *V, Instruction *Start,
+ Instruction *End) {
+ assert(Start->getParent() == End->getParent() && "Must be in same block");
+ if (!Start->getFunction()->doesNotThrow() &&
+ !isa<AllocaInst>(getUnderlyingObject(V))) {
+ for (const Instruction &I :
+ make_range(Start->getIterator(), End->getIterator())) {
+ if (I.mayThrow())
+ return true;
+ }
+ }
+ return false;
+}
+
void MemCpyOptPass::eraseInstruction(Instruction *I) {
if (MSSAU)
MSSAU->removeMemoryAccess(I);
@@ -848,16 +864,8 @@ bool MemCpyOptPass::performCallSlotOptzn(Instruction *cpyLoad,
// guaranteed to be executed if C is. As it is a non-atomic access, it
// renders accesses from other threads undefined.
// TODO: This is currently not checked.
- // TODO: Check underlying object, so we can look through GEPs.
- if (!isa<AllocaInst>(cpyDest)) {
- assert(C->getParent() == cpyStore->getParent() &&
- "call and copy must be in the same block");
- for (const Instruction &I : make_range(C->getIterator(),
- cpyStore->getIterator())) {
- if (I.mayThrow())
- return false;
- }
- }
+ if (mayBeVisibleThroughUnwinding(cpyDest, C, cpyStore))
+ return false;
// Check that dest points to memory that is at least as aligned as src.
Align srcAlign = srcAlloca->getAlign();
@@ -1094,16 +1102,8 @@ bool MemCpyOptPass::processMemSetMemCpyDependence(MemCpyInst *MemCpy,
Value *DestSize = MemSet->getLength();
Value *SrcSize = MemCpy->getLength();
- // If the destination might be accessible by the caller, make sure we cannot
- // unwind between the memset and the memcpy.
- if (!MemCpy->getFunction()->doesNotThrow() &&
- !isa<AllocaInst>(getUnderlyingObject(Dest))) {
- for (const Instruction &I :
- make_range(MemSet->getIterator(), MemCpy->getIterator())) {
- if (I.mayThrow())
- return false;
- }
- }
+ if (mayBeVisibleThroughUnwinding(Dest, MemSet, MemCpy))
+ return false;
// By default, create an unaligned memset.
unsigned Align = 1;
diff --git a/llvm/test/Transforms/MemCpyOpt/callslot.ll b/llvm/test/Transforms/MemCpyOpt/callslot.ll
index 67bdad8fa535..37a3cdea88e5 100644
--- a/llvm/test/Transforms/MemCpyOpt/callslot.ll
+++ b/llvm/test/Transforms/MemCpyOpt/callslot.ll
@@ -131,8 +131,9 @@ define void @dest_is_gep_may_throw_call() {
; CHECK-NEXT: [[SRC:%.*]] = alloca [8 x i8], align 1
; CHECK-NEXT: [[SRC_I8:%.*]] = bitcast [8 x i8]* [[SRC]] to i8*
; CHECK-NEXT: [[DEST_I8:%.*]] = getelementptr [16 x i8], [16 x i8]* [[DEST]], i64 0, i64 8
-; CHECK-NEXT: call void @accept_ptr(i8* [[SRC_I8]])
-; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST_I8]], i8* [[SRC_I8]], i64 8, i1 false)
+; CHECK-NEXT: [[DEST_I81:%.*]] = bitcast i8* [[DEST_I8]] to [8 x i8]*
+; CHECK-NEXT: [[DEST_I812:%.*]] = bitcast [8 x i8]* [[DEST_I81]] to i8*
+; CHECK-NEXT: call void @accept_ptr(i8* [[DEST_I812]])
; CHECK-NEXT: ret void
;
%dest = alloca [16 x i8]
More information about the llvm-commits
mailing list