Skip to content

Commit 3371375

Browse files
authored
[InstCombine] Read-only call without return can capture (#157878)
The copied from constant memory analysis had a special case where nocapture was not required for read-only calls without (or unused) return. This is not correct, as the address can still be captured though means other than memory and the return value, for example using divergence. This code should not be trying to do its own nocapture inference.
1 parent 02d3e6a commit 3371375

File tree

2 files changed

+23
-8
lines changed

2 files changed

+23
-8
lines changed

llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ isOnlyCopiedFromConstantMemory(AAResults *AA, AllocaInst *V,
107107
// a load (but one that potentially returns the value itself), so we can
108108
// ignore it if we know that the value isn't captured.
109109
bool NoCapture = Call->doesNotCapture(DataOpNo);
110-
if ((Call->onlyReadsMemory() && (Call->use_empty() || NoCapture)) ||
111-
(Call->onlyReadsMemory(DataOpNo) && NoCapture))
110+
if (NoCapture &&
111+
(Call->onlyReadsMemory() || Call->onlyReadsMemory(DataOpNo)))
112112
continue;
113113
}
114114

llvm/test/Transforms/InstCombine/memcpy-from-global.ll

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,14 @@ define void @test2_addrspacecast() {
139139
ret void
140140
}
141141

142-
declare void @bar(ptr)
143-
declare void @bar_as1(ptr addrspace(1))
142+
declare void @bar(ptr nocapture)
143+
declare void @bar_may_capture(ptr)
144+
declare void @bar_as1(ptr addrspace(1) nocapture)
144145

145146

146147
;; Should be able to eliminate the alloca.
147-
define void @test3() {
148-
; CHECK-LABEL: @test3(
148+
define void @test3_nocapture() {
149+
; CHECK-LABEL: @test3_nocapture(
149150
; CHECK-NEXT: call void @bar(ptr nonnull @G) #[[ATTR3:[0-9]+]]
150151
; CHECK-NEXT: ret void
151152
;
@@ -155,6 +156,20 @@ define void @test3() {
155156
ret void
156157
}
157158

159+
; Can not eliminate the alloca, as the function may capture its address.
160+
define void @test3_may_capture() {
161+
; CHECK-LABEL: @test3_may_capture(
162+
; CHECK-NEXT: [[A:%.*]] = alloca [[T:%.*]], align 8
163+
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(124) [[A]], ptr noundef nonnull align 16 dereferenceable(124) @G, i64 124, i1 false)
164+
; CHECK-NEXT: call void @bar_may_capture(ptr nonnull [[A]]) #[[ATTR3]]
165+
; CHECK-NEXT: ret void
166+
;
167+
%A = alloca %T
168+
call void @llvm.memcpy.p0.p0.i64(ptr align 4 %A, ptr align 4 @G, i64 124, i1 false)
169+
call void @bar_may_capture(ptr %A) readonly
170+
ret void
171+
}
172+
158173
define void @test3_addrspacecast() {
159174
; CHECK-LABEL: @test3_addrspacecast(
160175
; CHECK-NEXT: call void @bar(ptr nonnull @G) #[[ATTR3]]
@@ -395,12 +410,12 @@ define void @memcpy_to_capturing_readonly() {
395410
; CHECK-LABEL: @memcpy_to_capturing_readonly(
396411
; CHECK-NEXT: [[A:%.*]] = alloca [[U:%.*]], align 16
397412
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 16 dereferenceable(20) [[A]], ptr noundef nonnull align 16 dereferenceable(20) @H, i64 20, i1 false)
398-
; CHECK-NEXT: call void @bar(ptr nonnull readonly [[A]])
413+
; CHECK-NEXT: call void @bar_may_capture(ptr nonnull readonly [[A]])
399414
; CHECK-NEXT: ret void
400415
;
401416
%A = alloca %U, align 16
402417
call void @llvm.memcpy.p0.p0.i64(ptr align 4 %A, ptr align 4 @H, i64 20, i1 false)
403-
call void @bar(ptr readonly %A)
418+
call void @bar_may_capture(ptr readonly %A)
404419
ret void
405420
}
406421

0 commit comments

Comments
 (0)