Skip to content

Commit abd97d9

Browse files
committed
[CaptureTracking] Take non-willreturn calls into account
We can leak one bit of information about the address by either diverging or not. Part of #129090.
1 parent 0ba4767 commit abd97d9

File tree

5 files changed

+121
-74
lines changed

5 files changed

+121
-74
lines changed

llvm/lib/Analysis/CaptureTracking.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,9 @@ UseCaptureInfo llvm::DetermineUseCaptureKind(
279279
case Instruction::Invoke: {
280280
auto *Call = cast<CallBase>(I);
281281
// Not captured if the callee is readonly, doesn't return a copy through
282-
// its return value and doesn't unwind (a readonly function can leak bits
283-
// by throwing an exception or not depending on the input value).
284-
if (Call->onlyReadsMemory() && Call->doesNotThrow() &&
282+
// its return value and doesn't unwind or diverge (a readonly function can
283+
// leak bits by throwing an exception or not depending on the input value).
284+
if (Call->onlyReadsMemory() && Call->doesNotThrow() && Call->willReturn() &&
285285
Call->getType()->isVoidTy())
286286
return CaptureComponents::None;
287287

llvm/test/Transforms/Attributor/nocapture-1.ll

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,9 @@ define void @nc4(ptr %p) {
337337
ret void
338338
}
339339

340-
define void @nc5(ptr %f, ptr %p) {
341-
; CHECK-LABEL: define {{[^@]+}}@nc5
342-
; CHECK-SAME: (ptr nofree noundef nonnull captures(none) [[F:%.*]], ptr captures(none) [[P:%.*]]) {
340+
define void @callsite_readonly_nounwind_not_willreturn(ptr %f, ptr %p) {
341+
; CHECK-LABEL: define {{[^@]+}}@callsite_readonly_nounwind_not_willreturn
342+
; CHECK-SAME: (ptr nofree noundef nonnull captures(none) [[F:%.*]], ptr [[P:%.*]]) {
343343
; CHECK-NEXT: call void [[F]](ptr captures(none) [[P]])
344344
; CHECK-NEXT: ret void
345345
;
@@ -348,6 +348,17 @@ define void @nc5(ptr %f, ptr %p) {
348348
ret void
349349
}
350350

351+
define void @callsite_readonly_nounwind_willreturn(ptr %f, ptr %p) {
352+
; CHECK-LABEL: define {{[^@]+}}@callsite_readonly_nounwind_willreturn
353+
; CHECK-SAME: (ptr nofree noundef nonnull captures(none) [[F:%.*]], ptr captures(none) [[P:%.*]]) {
354+
; CHECK-NEXT: call void [[F]](ptr captures(none) [[P]])
355+
; CHECK-NEXT: ret void
356+
;
357+
call void %f(ptr %p) readonly nounwind willreturn
358+
call void %f(ptr nocapture %p)
359+
ret void
360+
}
361+
351362
; It would be acceptable to add readnone to %y1_1 and %y1_2.
352363
define void @test1_1(ptr %x1_1, ptr %y1_1, i1 %c) {
353364
; TUNIT: Function Attrs: nofree nosync nounwind memory(write)

0 commit comments

Comments
 (0)