[llvm] 6b69985 - [MemCpyOpt] Use helper for unwind check
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 26 03:43:37 PST 2022
Author: Nikita Popov
Date: 2022-01-26T12:43:31+01:00
New Revision: 6b69985da42c6bdbe83127de9653ee795024c8d0
URL: https://github.com/llvm/llvm-project/commit/6b69985da42c6bdbe83127de9653ee795024c8d0
DIFF: https://github.com/llvm/llvm-project/commit/6b69985da42c6bdbe83127de9653ee795024c8d0.diff
LOG: [MemCpyOpt] Use helper for unwind check
This extends support to byval arguments. It would be further
extended to handle the case of non-captured noalias returns.
Added:
Modified:
llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
llvm/test/Transforms/MemCpyOpt/callslot_throw.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
index 4959125e1055e..6698db26626b7 100644
--- a/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
+++ b/llvm/lib/Transforms/Scalar/MemCpyOptimizer.cpp
@@ -313,15 +313,21 @@ INITIALIZE_PASS_END(MemCpyOptLegacyPass, "memcpyopt", "MemCpy Optimization",
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;
+ // Function can't unwind, so it also can't be visible through unwinding.
+ if (Start->getFunction()->doesNotThrow())
+ return false;
+
+ // Object is not visible on unwind.
+ // TODO: Support RequiresNoCaptureBeforeUnwind case.
+ bool RequiresNoCaptureBeforeUnwind;
+ if (isNotVisibleOnUnwind(getUnderlyingObject(V),
+ RequiresNoCaptureBeforeUnwind) &&
+ !RequiresNoCaptureBeforeUnwind)
+ return false;
+
+ // Check whether there are any unwinding instructions in the range.
+ return any_of(make_range(Start->getIterator(), End->getIterator()),
+ [](const Instruction &I) { return I.mayThrow(); });
}
void MemCpyOptPass::eraseInstruction(Instruction *I) {
diff --git a/llvm/test/Transforms/MemCpyOpt/callslot_throw.ll b/llvm/test/Transforms/MemCpyOpt/callslot_throw.ll
index ce0d575ab21b9..62b6fcfe4d5a3 100644
--- a/llvm/test/Transforms/MemCpyOpt/callslot_throw.ll
+++ b/llvm/test/Transforms/MemCpyOpt/callslot_throw.ll
@@ -40,14 +40,12 @@ entry:
ret void
}
-; TODO: byval argument is not visible on unwind.
+; byval argument is not visible on unwind.
define void @test_byval(i32* nocapture noalias dereferenceable(4) byval(i32) %x) {
; CHECK-LABEL: @test_byval(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[T:%.*]] = alloca i32, align 4
-; CHECK-NEXT: call void @may_throw(i32* nonnull [[T]])
-; CHECK-NEXT: [[LOAD:%.*]] = load i32, i32* [[T]], align 4
-; CHECK-NEXT: store i32 [[LOAD]], i32* [[X:%.*]], align 4
+; CHECK-NEXT: call void @may_throw(i32* nonnull [[X:%.*]])
; CHECK-NEXT: ret void
;
entry:
More information about the llvm-commits
mailing list