-
Notifications
You must be signed in to change notification settings - Fork 14.1k
[LICM] Only check for provenance captures #141731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
When performing scalar promotions, only consider provenance escapes, which may lead to non-thread-safe accesses. Address captures can be ignored.
@llvm/pr-subscribers-llvm-transforms Author: Nikita Popov (nikic) ChangesWhen performing scalar promotions, only consider provenance captures, which may lead to non-thread-safe accesses. Address captures can be ignored. Full diff: https://github.com/llvm/llvm-project/pull/141731.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 006a09b38bc71..7965ed76a81b7 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -1928,8 +1928,9 @@ bool isNotCapturedBeforeOrInLoop(const Value *V, const Loop *L,
// loop header, as the loop header is reachable from any instruction inside
// the loop.
// TODO: ReturnCaptures=true shouldn't be necessary here.
- return !PointerMayBeCapturedBefore(V, /* ReturnCaptures */ true,
- L->getHeader()->getTerminator(), DT);
+ return capturesNothing(PointerMayBeCapturedBefore(
+ V, /*ReturnCaptures=*/true, L->getHeader()->getTerminator(), DT,
+ /*IncludeI=*/false, CaptureComponents::Provenance));
}
/// Return true if we can prove that a caller cannot inspect the object if an
diff --git a/llvm/test/Transforms/LICM/promote-capture.ll b/llvm/test/Transforms/LICM/promote-capture.ll
index 5cbe158e47a3c..eac670e6f3edd 100644
--- a/llvm/test/Transforms/LICM/promote-capture.ll
+++ b/llvm/test/Transforms/LICM/promote-capture.ll
@@ -158,6 +158,58 @@ exit:
ret void
}
+define void @test_captured_before_loop_address_only(i32 %len) {
+; CHECK-LABEL: @test_captured_before_loop_address_only(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[COUNT:%.*]] = alloca i32, align 4
+; CHECK-NEXT: store i32 0, ptr [[COUNT]], align 4
+; CHECK-NEXT: call void @capture(ptr captures(address) [[COUNT]])
+; CHECK-NEXT: [[COUNT_PROMOTED:%.*]] = load i32, ptr [[COUNT]], align 4
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[C_INC2:%.*]] = phi i32 [ [[COUNT_PROMOTED]], [[ENTRY:%.*]] ], [ [[C_INC1:%.*]], [[LATCH:%.*]] ]
+; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[I_NEXT:%.*]], [[LATCH]] ]
+; CHECK-NEXT: [[COND:%.*]] = call i1 @cond(i32 [[I]])
+; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[LATCH]]
+; CHECK: if:
+; CHECK-NEXT: [[C_INC:%.*]] = add i32 [[C_INC2]], 1
+; CHECK-NEXT: br label [[LATCH]]
+; CHECK: latch:
+; CHECK-NEXT: [[C_INC1]] = phi i32 [ [[C_INC]], [[IF]] ], [ [[C_INC2]], [[LOOP]] ]
+; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[LEN:%.*]]
+; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
+; CHECK: exit:
+; CHECK-NEXT: [[C_INC1_LCSSA:%.*]] = phi i32 [ [[C_INC1]], [[LATCH]] ]
+; CHECK-NEXT: store i32 [[C_INC1_LCSSA]], ptr [[COUNT]], align 4
+; CHECK-NEXT: ret void
+;
+entry:
+ %count = alloca i32
+ store i32 0, ptr %count
+ call void @capture(ptr captures(address) %count)
+ br label %loop
+
+loop:
+ %i = phi i32 [ 0, %entry ], [ %i.next, %latch ]
+ %cond = call i1 @cond(i32 %i)
+ br i1 %cond, label %if, label %latch
+
+if:
+ %c = load i32, ptr %count
+ %c.inc = add i32 %c, 1
+ store i32 %c.inc, ptr %count
+ br label %latch
+
+latch:
+ %i.next = add nuw i32 %i, 1
+ %cmp = icmp eq i32 %i.next, %len
+ br i1 %cmp, label %exit, label %loop
+
+exit:
+ ret void
+}
+
; Should not get promoted, because the pointer is captured and may not
; be thread-local.
define void @test_captured_before_loop_byval(ptr byval(i32) align 4 %count, i32 %len) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
When performing scalar promotions, only consider provenance captures, which may lead to non-thread-safe accesses. Address captures can be ignored.
When performing scalar promotions, only consider provenance captures, which may lead to non-thread-safe accesses. Address captures can be ignored.