Skip to content

Commit 55b480e

Browse files
authored
[SROA] Allow load-only promotion with read-only captures (llvm#130735)
It's okay if the address or read-provenance of the pointer is captured. We only have to make sure that there are no unanalyzable writes to the pointer.
1 parent 59fd287 commit 55b480e

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

llvm/lib/Transforms/Scalar/SROA.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,10 +1397,10 @@ class AllocaSlices::SliceBuilder : public PtrUseVisitor<SliceBuilder> {
13971397
void visitInstruction(Instruction &I) { PI.setAborted(&I); }
13981398

13991399
void visitCallBase(CallBase &CB) {
1400-
// If the call operand is NoCapture ReadOnly, then we mark it as
1401-
// EscapedReadOnly.
1400+
// If the call operand is read-only and only does a read-only or address
1401+
// capture, then we mark it as EscapedReadOnly.
14021402
if (CB.isDataOperand(U) &&
1403-
CB.doesNotCapture(U->getOperandNo()) &&
1403+
!capturesFullProvenance(CB.getCaptureInfo(U->getOperandNo())) &&
14041404
CB.onlyReadsMemory(U->getOperandNo())) {
14051405
PI.setEscapedReadOnly(&CB);
14061406
return;

llvm/test/Transforms/SROA/readonlynocapture.ll

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,54 @@ define i32 @simple_byval() {
406406
ret i32 %l1
407407
}
408408

409+
declare void @callee_address_only_capture(ptr readonly captures(address) %p)
410+
411+
define i32 @address_only_capture() {
412+
; CHECK-LABEL: @address_only_capture(
413+
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
414+
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
415+
; CHECK-NEXT: call void @callee_address_only_capture(ptr [[A]])
416+
; CHECK-NEXT: ret i32 0
417+
;
418+
%a = alloca i32
419+
store i32 0, ptr %a
420+
call void @callee_address_only_capture(ptr %a)
421+
%l1 = load i32, ptr %a
422+
ret i32 %l1
423+
}
424+
425+
declare void @callee_read_only_capture(ptr readonly captures(address, read_provenance) %p)
426+
427+
define i32 @read_only_capture() {
428+
; CHECK-LABEL: @read_only_capture(
429+
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
430+
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
431+
; CHECK-NEXT: call void @callee_read_only_capture(ptr [[A]])
432+
; CHECK-NEXT: ret i32 0
433+
;
434+
%a = alloca i32
435+
store i32 0, ptr %a
436+
call void @callee_read_only_capture(ptr %a)
437+
%l1 = load i32, ptr %a
438+
ret i32 %l1
439+
}
440+
441+
declare void @callee_provenance_only_capture(ptr readonly captures(provenance) %p)
442+
443+
; Should not be transformed, as write-provenance is captured.
444+
define i32 @provenance_only_capture() {
445+
; CHECK-LABEL: @provenance_only_capture(
446+
; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
447+
; CHECK-NEXT: store i32 0, ptr [[A]], align 4
448+
; CHECK-NEXT: call void @callee_provenance_only_capture(ptr [[A]])
449+
; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[A]], align 4
450+
; CHECK-NEXT: ret i32 [[L1]]
451+
;
452+
%a = alloca i32
453+
store i32 0, ptr %a
454+
call void @callee_provenance_only_capture(ptr %a)
455+
%l1 = load i32, ptr %a
456+
ret i32 %l1
457+
}
458+
409459
declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)

0 commit comments

Comments
 (0)