Nikita Popov bc7fafbeea
[AA] Take read-only provenance captures into account (#143097)
Update the AA CaptureAnalysis providers to return CaptureComponents, so
we can distinguish between full provenance and read-only provenance
captures.

Use this to restrict "other" memory effects on call from ModRef to Ref.

Ideally we would also apply the same reasoning for escape sources, but
the current API cannot actually convey the necessary information (we can
only say NoAlias or MayAlias, not MayAlias but only via Ref).
2025-06-12 14:13:15 +02:00

81 lines
2.3 KiB
LLVM

; RUN: opt < %s -passes=aa-eval -print-all-alias-modref-info -disable-output 2>&1 | FileCheck %s
declare void @capture(ptr)
declare ptr @get_ptr()
; CHECK-LABEL: address_capture
; CHECK: NoAlias: i32* %a, i32* %p
; CHECK: NoModRef: Ptr: i32* %a <-> %p = call ptr @get_ptr()
define void @address_capture() {
%a = alloca i32
call void @capture(ptr captures(address) %a)
%p = call ptr @get_ptr()
store i32 0, ptr %p
load i32, ptr %a
ret void
}
; CHECK-LABEL: read_only_capture
; CHECK: MayAlias: i32* %a, i32* %p
; CHECK: Just Ref: Ptr: i32* %a <-> %p = call ptr @get_ptr()
define void @read_only_capture() {
%a = alloca i32
call void @capture(ptr captures(address, read_provenance) %a)
%p = call ptr @get_ptr()
store i32 0, ptr %p
load i32, ptr %a
ret void
}
; CHECK-LABEL: address_capture_and_full_capture
; CHECK: MayAlias: i32* %a, i32* %p
; CHECK: Both ModRef: Ptr: i32* %a <-> %p = call ptr @get_ptr()
define void @address_capture_and_full_capture() {
%a = alloca i32
call void @capture(ptr captures(address) %a)
call void @capture(ptr %a)
%p = call ptr @get_ptr()
store i32 0, ptr %p
load i32, ptr %a
ret void
}
; CHECK-LABEL: address_capture_and_full_capture_commuted
; CHECK: MayAlias: i32* %a, i32* %p
; CHECK: Both ModRef: Ptr: i32* %a <-> %p = call ptr @get_ptr()
define void @address_capture_and_full_capture_commuted() {
%a = alloca i32
call void @capture(ptr %a)
call void @capture(ptr captures(address) %a)
%p = call ptr @get_ptr()
store i32 0, ptr %p
load i32, ptr %a
ret void
}
; CHECK-LABEL: read_only_capture_and_full_capture
; CHECK: MayAlias: i32* %a, i32* %p
; CHECK: Both ModRef: Ptr: i32* %a <-> %p = call ptr @get_ptr()
define void @read_only_capture_and_full_capture() {
%a = alloca i32
call void @capture(ptr captures(address, read_provenance) %a)
call void @capture(ptr %a)
%p = call ptr @get_ptr()
store i32 0, ptr %p
load i32, ptr %a
ret void
}
; CHECK-LABEL: read_only_capture_and_full_capture_commuted
; CHECK: MayAlias: i32* %a, i32* %p
; CHECK: Both ModRef: Ptr: i32* %a <-> %p = call ptr @get_ptr()
define void @read_only_capture_and_full_capture_commuted() {
%a = alloca i32
call void @capture(ptr %a)
call void @capture(ptr captures(address, read_provenance) %a)
%p = call ptr @get_ptr()
store i32 0, ptr %p
load i32, ptr %a
ret void
}