blob: 09f164d505fedf1ad9a39ce2519d6d82ffbcb770 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -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
; Check that nocapture introduction respects null_pointer_is_valid
@g = global ptr null
define void @capture(ptr %p) {
; CHECK-LABEL: define void @capture(
; CHECK-SAME: ptr nofree writeonly [[P:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: store ptr [[P]], ptr @g, align 8
; CHECK-NEXT: ret void
;
store ptr %p, ptr @g
ret void
}
define i8 @nocapture(ptr %p) {
; CHECK-LABEL: define i8 @nocapture(
; CHECK-SAME: ptr nofree noundef nonnull readonly captures(none) dereferenceable(1) [[P:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1
; CHECK-NEXT: ret i8 [[V]]
;
%v = load i8, ptr %p
ret i8 %v
}
define i8 @null_arg_null_pointer_is_valid() null_pointer_is_valid {
; TUNIT-LABEL: define i8 @null_arg_null_pointer_is_valid(
; TUNIT-SAME: ) #[[ATTR2:[0-9]+]] {
; TUNIT-NEXT: call void @capture(ptr noalias nofree noundef writeonly null) #[[ATTR6:[0-9]+]]
; TUNIT-NEXT: [[V:%.*]] = call i8 @nocapture(ptr noalias nofree noundef readonly captures(none) null) #[[ATTR7:[0-9]+]]
; TUNIT-NEXT: ret i8 [[V]]
;
; CGSCC-LABEL: define i8 @null_arg_null_pointer_is_valid(
; CGSCC-SAME: ) #[[ATTR2:[0-9]+]] {
; CGSCC-NEXT: call void @capture(ptr noalias nofree noundef writeonly null) #[[ATTR6:[0-9]+]]
; CGSCC-NEXT: unreachable
;
call void @capture(ptr null)
%v = call i8 @nocapture(ptr null)
ret i8 %v
}
define void @capture_null_pointer_is_valid(ptr %p) null_pointer_is_valid {
; CHECK-LABEL: define void @capture_null_pointer_is_valid(
; CHECK-SAME: ptr nofree writeonly [[P:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: store ptr [[P]], ptr @g, align 8
; CHECK-NEXT: ret void
;
store ptr %p, ptr @g
ret void
}
define i8 @nocapture_null_pointer_is_valid(ptr %p) null_pointer_is_valid {
; CHECK-LABEL: define i8 @nocapture_null_pointer_is_valid(
; CHECK-SAME: ptr nofree noundef readonly captures(none) dereferenceable_or_null(1) [[P:%.*]]) #[[ATTR4:[0-9]+]] {
; CHECK-NEXT: [[V:%.*]] = load i8, ptr [[P]], align 1
; CHECK-NEXT: ret i8 [[V]]
;
%v = load i8, ptr %p
ret i8 %v
}
define i8 @null_arg_callee_null_pointer_is_valid() {
; TUNIT-LABEL: define i8 @null_arg_callee_null_pointer_is_valid(
; TUNIT-SAME: ) #[[ATTR5:[0-9]+]] {
; TUNIT-NEXT: call void @capture_null_pointer_is_valid(ptr nofree noundef writeonly null) #[[ATTR6]]
; TUNIT-NEXT: [[V:%.*]] = call i8 @nocapture_null_pointer_is_valid(ptr nofree noundef readonly null) #[[ATTR7]]
; TUNIT-NEXT: ret i8 [[V]]
;
; CGSCC-LABEL: define i8 @null_arg_callee_null_pointer_is_valid(
; CGSCC-SAME: ) #[[ATTR5:[0-9]+]] {
; CGSCC-NEXT: call void @capture_null_pointer_is_valid(ptr nofree noundef writeonly null) #[[ATTR6]]
; CGSCC-NEXT: [[V:%.*]] = call i8 @nocapture_null_pointer_is_valid(ptr nofree noundef readonly dereferenceable_or_null(1) null) #[[ATTR7:[0-9]+]]
; CGSCC-NEXT: ret i8 [[V]]
;
call void @capture_null_pointer_is_valid(ptr null)
%v = call i8 @nocapture_null_pointer_is_valid(ptr null)
ret i8 %v
}
define i8 @null_arg_null_pointer_is_valid_callee_null_pointer_is_valid() null_pointer_is_valid {
; TUNIT-LABEL: define i8 @null_arg_null_pointer_is_valid_callee_null_pointer_is_valid(
; TUNIT-SAME: ) #[[ATTR2]] {
; TUNIT-NEXT: call void @capture_null_pointer_is_valid(ptr noalias nofree noundef writeonly null) #[[ATTR6]]
; TUNIT-NEXT: [[V:%.*]] = call i8 @nocapture_null_pointer_is_valid(ptr noalias nofree noundef readonly captures(none) null) #[[ATTR7]]
; TUNIT-NEXT: ret i8 [[V]]
;
; CGSCC-LABEL: define i8 @null_arg_null_pointer_is_valid_callee_null_pointer_is_valid(
; CGSCC-SAME: ) #[[ATTR2]] {
; CGSCC-NEXT: call void @capture_null_pointer_is_valid(ptr noalias nofree noundef writeonly null) #[[ATTR6]]
; CGSCC-NEXT: [[V:%.*]] = call i8 @nocapture_null_pointer_is_valid(ptr noalias nofree noundef readonly captures(none) dereferenceable_or_null(1) null) #[[ATTR7]]
; CGSCC-NEXT: ret i8 [[V]]
;
call void @capture_null_pointer_is_valid(ptr null)
%v = call i8 @nocapture_null_pointer_is_valid(ptr null)
ret i8 %v
}