Skip to content

Commit eea6969

Browse files
authored
[LICM] Only check for provenance captures (#141731)
When performing scalar promotions, only consider provenance captures, which may lead to non-thread-safe accesses. Address captures can be ignored.
1 parent 9262e37 commit eea6969

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

llvm/lib/Transforms/Scalar/LICM.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,8 +1928,9 @@ bool isNotCapturedBeforeOrInLoop(const Value *V, const Loop *L,
19281928
// loop header, as the loop header is reachable from any instruction inside
19291929
// the loop.
19301930
// TODO: ReturnCaptures=true shouldn't be necessary here.
1931-
return !PointerMayBeCapturedBefore(V, /* ReturnCaptures */ true,
1932-
L->getHeader()->getTerminator(), DT);
1931+
return capturesNothing(PointerMayBeCapturedBefore(
1932+
V, /*ReturnCaptures=*/true, L->getHeader()->getTerminator(), DT,
1933+
/*IncludeI=*/false, CaptureComponents::Provenance));
19331934
}
19341935

19351936
/// Return true if we can prove that a caller cannot inspect the object if an

llvm/test/Transforms/LICM/promote-capture.ll

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,58 @@ exit:
158158
ret void
159159
}
160160

161+
define void @test_captured_before_loop_address_only(i32 %len) {
162+
; CHECK-LABEL: @test_captured_before_loop_address_only(
163+
; CHECK-NEXT: entry:
164+
; CHECK-NEXT: [[COUNT:%.*]] = alloca i32, align 4
165+
; CHECK-NEXT: store i32 0, ptr [[COUNT]], align 4
166+
; CHECK-NEXT: call void @capture(ptr captures(address) [[COUNT]])
167+
; CHECK-NEXT: [[COUNT_PROMOTED:%.*]] = load i32, ptr [[COUNT]], align 4
168+
; CHECK-NEXT: br label [[LOOP:%.*]]
169+
; CHECK: loop:
170+
; CHECK-NEXT: [[C_INC2:%.*]] = phi i32 [ [[COUNT_PROMOTED]], [[ENTRY:%.*]] ], [ [[C_INC1:%.*]], [[LATCH:%.*]] ]
171+
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[I_NEXT:%.*]], [[LATCH]] ]
172+
; CHECK-NEXT: [[COND:%.*]] = call i1 @cond(i32 [[I]])
173+
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[LATCH]]
174+
; CHECK: if:
175+
; CHECK-NEXT: [[C_INC:%.*]] = add i32 [[C_INC2]], 1
176+
; CHECK-NEXT: br label [[LATCH]]
177+
; CHECK: latch:
178+
; CHECK-NEXT: [[C_INC1]] = phi i32 [ [[C_INC]], [[IF]] ], [ [[C_INC2]], [[LOOP]] ]
179+
; CHECK-NEXT: [[I_NEXT]] = add nuw i32 [[I]], 1
180+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I_NEXT]], [[LEN:%.*]]
181+
; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[LOOP]]
182+
; CHECK: exit:
183+
; CHECK-NEXT: [[C_INC1_LCSSA:%.*]] = phi i32 [ [[C_INC1]], [[LATCH]] ]
184+
; CHECK-NEXT: store i32 [[C_INC1_LCSSA]], ptr [[COUNT]], align 4
185+
; CHECK-NEXT: ret void
186+
;
187+
entry:
188+
%count = alloca i32
189+
store i32 0, ptr %count
190+
call void @capture(ptr captures(address) %count)
191+
br label %loop
192+
193+
loop:
194+
%i = phi i32 [ 0, %entry ], [ %i.next, %latch ]
195+
%cond = call i1 @cond(i32 %i)
196+
br i1 %cond, label %if, label %latch
197+
198+
if:
199+
%c = load i32, ptr %count
200+
%c.inc = add i32 %c, 1
201+
store i32 %c.inc, ptr %count
202+
br label %latch
203+
204+
latch:
205+
%i.next = add nuw i32 %i, 1
206+
%cmp = icmp eq i32 %i.next, %len
207+
br i1 %cmp, label %exit, label %loop
208+
209+
exit:
210+
ret void
211+
}
212+
161213
; Should not get promoted, because the pointer is captured and may not
162214
; be thread-local.
163215
define void @test_captured_before_loop_byval(ptr byval(i32) align 4 %count, i32 %len) {

0 commit comments

Comments
 (0)