AANonNull is now the first AA that is always queried via the new APIs and not created manually. Others will follow shortly to avoid trivial AAs whenever possible. This commit introduced some helper logic that will make it simpler to port the next one. It also untangles AADereferenceable and AANonNull such that the former does not keep a handle on the latter. Finally, we stop deducing `nonnull` for `undef`, which was incorrect.
123 lines
3.4 KiB
LLVM
123 lines
3.4 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=attributor -S < %s | FileCheck %s --check-prefixes=CHECK
|
|
; RUN: opt -passes=attributor -attributor-print-call-graph -S -disable-output < %s | FileCheck %s --check-prefixes=DOT
|
|
|
|
define dso_local void @func1() {
|
|
; CHECK-LABEL: @func1(
|
|
; CHECK-NEXT: br label [[TMP2:%.*]]
|
|
; CHECK: 1:
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 2:
|
|
; CHECK-NEXT: call void @func3()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%1 = icmp ne i32 0, 0
|
|
br i1 %1, label %2, label %3
|
|
|
|
2: ; preds = %0
|
|
call void @func2()
|
|
br label %3
|
|
|
|
3: ; preds = %2, %0
|
|
call void () @func3()
|
|
ret void
|
|
}
|
|
|
|
declare void @func3()
|
|
declare void @func4()
|
|
|
|
define dso_local void @func2() {
|
|
; CHECK-LABEL: @func2(
|
|
; CHECK-NEXT: call void @func4()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @func4()
|
|
ret void
|
|
}
|
|
|
|
|
|
define void @func5(i32 %0) {
|
|
; CHECK-LABEL: @func5(
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 0
|
|
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], ptr @func4, ptr @func3
|
|
; CHECK-NEXT: call void [[TMP3]]()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%2 = icmp ne i32 %0, 0
|
|
%3 = select i1 %2, ptr @func4, ptr @func3
|
|
call void () %3()
|
|
ret void
|
|
}
|
|
|
|
define void @broker(ptr %unknown) !callback !0 {
|
|
; CHECK-LABEL: @broker(
|
|
; CHECK-NEXT: call void [[UNKNOWN:%.*]]()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void %unknown()
|
|
ret void
|
|
}
|
|
|
|
define void @func6() {
|
|
; CHECK-LABEL: @func6(
|
|
; CHECK-NEXT: call void @broker(ptr nocapture nofree noundef nonnull @func3)
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void @broker(ptr @func3)
|
|
ret void
|
|
}
|
|
|
|
define void @func7(ptr %unknown) {
|
|
; CHECK-LABEL: @func7(
|
|
; CHECK-NEXT: call void [[UNKNOWN:%.*]](), !callees !2
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
call void %unknown(), !callees !2
|
|
ret void
|
|
}
|
|
|
|
; Check there's no crash if something that isn't a function appears in !callees
|
|
define void @undef_in_callees() {
|
|
; CHECK-LABEL: @undef_in_callees(
|
|
; CHECK-NEXT: cond.end.i:
|
|
; CHECK-NEXT: call void undef(ptr undef, i32 undef, ptr undef), !callees !3
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
cond.end.i:
|
|
call void undef(ptr undef, i32 undef, ptr undef), !callees !3
|
|
ret void
|
|
}
|
|
|
|
!0 = !{!1}
|
|
!1 = !{i64 0, i1 false}
|
|
!2 = !{ptr @func3, ptr @func4}
|
|
!3 = distinct !{ptr undef, ptr null}
|
|
|
|
; UTC_ARGS: --disable
|
|
|
|
; DOT-DAG: Node[[FUNC1:0x[a-z0-9]+]] [shape=record,label="{func1}"];
|
|
; DOT-DAG: Node[[FUNC2:0x[a-z0-9]+]] [shape=record,label="{func2}"];
|
|
; DOT-DAG: Node[[FUNC3:0x[a-z0-9]+]] [shape=record,label="{func3}"];
|
|
; DOT-DAG: Node[[FUNC4:0x[a-z0-9]+]] [shape=record,label="{func4}"];
|
|
; DOT-DAG: Node[[FUNC5:0x[a-z0-9]+]] [shape=record,label="{func5}"];
|
|
; DOT-DAG: Node[[FUNC6:0x[a-z0-9]+]] [shape=record,label="{func6}"];
|
|
; DOT-DAG: Node[[FUNC7:0x[a-z0-9]+]] [shape=record,label="{func7}"];
|
|
|
|
; DOT-DAG: Node[[BROKER:0x[a-z0-9]+]] [shape=record,label="{broker}"];
|
|
|
|
; DOT-DAG: Node[[FUNC1]] -> Node[[FUNC3]];
|
|
; DOT-DAG: Node[[FUNC2]] -> Node[[FUNC4]];
|
|
; DOT-DAG: Node[[FUNC5]] -> Node[[FUNC3]];
|
|
; DOT-DAG: Node[[FUNC5]] -> Node[[FUNC4]];
|
|
|
|
; DOT-DAG: Node[[FUNC6]] -> Node[[BROKER]];
|
|
|
|
; This one gets added because of the callback metadata.
|
|
; DOT-DAG: Node[[FUNC6]] -> Node[[FUNC3]];
|
|
|
|
; These ones are added because of the callees metadata.
|
|
; DOT-DAG: Node[[FUNC7]] -> Node[[FUNC3]];
|
|
; DOT-DAG: Node[[FUNC7]] -> Node[[FUNC4]];
|
|
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
|
; DOT: {{.*}}
|