We had two AAs for reachability but it was very cumbersome to extend them. We also had some fallback to use LLVM-core mechanisms and cache the result. The new design shares the query code and interface nicely between AAIntraFnReachability and AAInterFnReachability. As part of the rewrite we also added the ExclusionSet to the queries.
118 lines
5.4 KiB
LLVM
118 lines
5.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
|
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
|
|
;
|
|
; Mostly check we do not crash on these uses
|
|
|
|
define internal void @internal(void (i8*)* %fp) {
|
|
;
|
|
;
|
|
; TUNIT-LABEL: define {{[^@]+}}@internal
|
|
; TUNIT-SAME: (void (i8*)* nonnull [[FP:%.*]]) {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; TUNIT-NEXT: call void @foo(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR1:[0-9]+]]
|
|
; TUNIT-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
|
|
; TUNIT-NEXT: call void @callback1(void (i32*)* noundef nonnull @foo)
|
|
; TUNIT-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*))
|
|
; TUNIT-NEXT: call void @callback2(void (i8*)* nonnull [[FP]])
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
|
|
; TUNIT-NEXT: call void [[FP]](i8* [[TMP1]])
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@internal
|
|
; CGSCC-SAME: (void (i8*)* noundef nonnull [[FP:%.*]]) {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; CGSCC-NEXT: call void @foo(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR1:[0-9]+]]
|
|
; CGSCC-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
|
|
; CGSCC-NEXT: call void @callback1(void (i32*)* noundef nonnull @foo)
|
|
; CGSCC-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*))
|
|
; CGSCC-NEXT: call void @callback2(void (i8*)* noundef nonnull [[FP]])
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
|
|
; CGSCC-NEXT: call void [[FP]](i8* [[TMP1]])
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 4
|
|
%tmp = bitcast i32* %a to i8*
|
|
call void @foo(i32* nonnull %a)
|
|
call void %fp(i8* bitcast (void (i32*)* @foo to i8*))
|
|
call void @callback1(void (i32*)* nonnull @foo)
|
|
call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
|
|
call void @callback2(void (i8*)* %fp)
|
|
%tmp1 = bitcast i32* %a to i8*
|
|
call void %fp(i8* %tmp1)
|
|
ret void
|
|
}
|
|
|
|
define void @external(void (i8*)* %fp) {
|
|
;
|
|
;
|
|
; TUNIT-LABEL: define {{[^@]+}}@external
|
|
; TUNIT-SAME: (void (i8*)* [[FP:%.*]]) {
|
|
; TUNIT-NEXT: entry:
|
|
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; TUNIT-NEXT: call void @foo(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR1]]
|
|
; TUNIT-NEXT: call void @callback1(void (i32*)* noundef nonnull @foo)
|
|
; TUNIT-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*))
|
|
; TUNIT-NEXT: call void @callback2(void (i8*)* [[FP]])
|
|
; TUNIT-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
|
|
; TUNIT-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
|
|
; TUNIT-NEXT: call void [[FP]](i8* [[TMP1]])
|
|
; TUNIT-NEXT: call void @internal(void (i8*)* nonnull [[FP]])
|
|
; TUNIT-NEXT: ret void
|
|
;
|
|
; CGSCC-LABEL: define {{[^@]+}}@external
|
|
; CGSCC-SAME: (void (i8*)* [[FP:%.*]]) {
|
|
; CGSCC-NEXT: entry:
|
|
; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
|
|
; CGSCC-NEXT: call void @foo(i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]]
|
|
; CGSCC-NEXT: call void @callback1(void (i32*)* noundef nonnull @foo)
|
|
; CGSCC-NEXT: call void @callback2(void (i8*)* noundef bitcast (void (i32*)* @foo to void (i8*)*))
|
|
; CGSCC-NEXT: call void @callback2(void (i8*)* [[FP]])
|
|
; CGSCC-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
|
|
; CGSCC-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
|
|
; CGSCC-NEXT: call void [[FP]](i8* [[TMP1]])
|
|
; CGSCC-NEXT: call void @internal(void (i8*)* noundef nonnull [[FP]])
|
|
; CGSCC-NEXT: ret void
|
|
;
|
|
entry:
|
|
%a = alloca i32, align 4
|
|
%tmp = bitcast i32* %a to i8*
|
|
call void @foo(i32* nonnull %a)
|
|
call void @callback1(void (i32*)* nonnull @foo)
|
|
call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
|
|
call void @callback2(void (i8*)* %fp)
|
|
call void %fp(i8* bitcast (void (i32*)* @foo to i8*))
|
|
%tmp1 = bitcast i32* %a to i8*
|
|
call void %fp(i8* %tmp1)
|
|
call void @internal(void (i8*)* %fp)
|
|
ret void
|
|
}
|
|
|
|
define internal void @foo(i32* %a) {
|
|
;
|
|
; CHECK: Function Attrs: nofree norecurse nosync nounwind willreturn memory(argmem: write)
|
|
; CHECK-LABEL: define {{[^@]+}}@foo
|
|
; CHECK-SAME: (i32* nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: store i32 0, i32* [[A]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
entry:
|
|
store i32 0, i32* %a
|
|
ret void
|
|
}
|
|
|
|
declare void @callback1(void (i32*)*)
|
|
declare void @callback2(void (i8*)*)
|
|
;.
|
|
; TUNIT: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) }
|
|
; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn }
|
|
;.
|
|
; CGSCC: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind willreturn memory(argmem: write) }
|
|
; CGSCC: attributes #[[ATTR1]] = { nounwind willreturn memory(write) }
|
|
; CGSCC: attributes #[[ATTR2]] = { nounwind willreturn }
|
|
;.
|