This avoid creating empty bins in AAPointerInfo which can lead to segfaults. Also ensure we do not try to translate from callee to caller except if we really take the argument state and move it to the call site argument state. Fixes: https://github.com/llvm/llvm-project/issues/55726
68 lines
4.5 KiB
LLVM
68 lines
4.5 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
|
|
; RUN: opt -attributor -enable-new-pm=0 -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
|
|
; 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,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
|
|
; RUN: opt -attributor-cgscc -enable-new-pm=0 -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
|
|
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
|
|
|
|
%struct.test.b = type { i32, i32 }
|
|
%struct.test.a = type { %struct.test.b, i32, i8*}
|
|
|
|
define void @foo(i8* %ptr) {
|
|
; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
|
|
; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
|
|
; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; IS__TUNIT____-NEXT: entry:
|
|
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = alloca [[STRUCT_TEST_A:%.*]], align 8
|
|
; IS__TUNIT____-NEXT: br label [[CALL_BR:%.*]]
|
|
; IS__TUNIT____: call.br:
|
|
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_A]], %struct.test.a* [[TMP0]], i64 0, i32 2
|
|
; IS__TUNIT____-NEXT: tail call void @bar(%struct.test.a* noalias nocapture nofree noundef nonnull readonly byval([[STRUCT_TEST_A]]) align 8 dereferenceable(24) [[TMP0]]) #[[ATTR2:[0-9]+]]
|
|
; IS__TUNIT____-NEXT: ret void
|
|
;
|
|
; IS__CGSCC____: Function Attrs: nofree nosync nounwind readnone willreturn
|
|
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
|
|
; IS__CGSCC____-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
|
|
; IS__CGSCC____-NEXT: entry:
|
|
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = alloca [[STRUCT_TEST_A:%.*]], align 8
|
|
; IS__CGSCC____-NEXT: br label [[CALL_BR:%.*]]
|
|
; IS__CGSCC____: call.br:
|
|
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_A]], %struct.test.a* [[TMP0]], i64 0, i32 2
|
|
; IS__CGSCC____-NEXT: store i8* [[PTR]], i8** [[TMP1]], align 8
|
|
; IS__CGSCC____-NEXT: tail call void @bar(%struct.test.a* noalias nocapture nofree noundef nonnull readnone byval([[STRUCT_TEST_A]]) align 8 dereferenceable(24) [[TMP0]]) #[[ATTR2:[0-9]+]]
|
|
; IS__CGSCC____-NEXT: ret void
|
|
;
|
|
entry:
|
|
%0 = alloca %struct.test.a, align 8
|
|
br label %call.br
|
|
|
|
call.br:
|
|
%1 = getelementptr inbounds %struct.test.a, %struct.test.a* %0, i64 0, i32 2
|
|
store i8* %ptr, i8** %1
|
|
tail call void @bar(%struct.test.a* noundef byval(%struct.test.a) align 8 %0)
|
|
ret void
|
|
}
|
|
|
|
define void @bar(%struct.test.a* noundef byval(%struct.test.a) align 8 %dev) {
|
|
; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
|
|
; CHECK-LABEL: define {{[^@]+}}@bar
|
|
; CHECK-SAME: (%struct.test.a* noalias nocapture nofree noundef nonnull writeonly byval([[STRUCT_TEST_A:%.*]]) align 8 dereferenceable(24) [[DEV:%.*]]) #[[ATTR1:[0-9]+]] {
|
|
; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds [[STRUCT_TEST_A]], %struct.test.a* [[DEV]], i64 0, i32 0
|
|
; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds [[STRUCT_TEST_B:%.*]], %struct.test.b* [[TMP1]], i64 0, i32 1
|
|
; CHECK-NEXT: store i32 1, i32* [[TMP2]], align 4
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%1 = getelementptr inbounds %struct.test.a, %struct.test.a* %dev, i64 0, i32 0
|
|
%2 = getelementptr inbounds %struct.test.b, %struct.test.b* %1, i64 0, i32 1
|
|
store i32 1, i32* %2
|
|
ret void
|
|
}
|
|
;.
|
|
; IS__TUNIT____: attributes #[[ATTR0]] = { nofree norecurse nosync nounwind readnone willreturn }
|
|
; IS__TUNIT____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
|
|
; IS__TUNIT____: attributes #[[ATTR2]] = { nofree nosync nounwind willreturn writeonly }
|
|
;.
|
|
; IS__CGSCC____: attributes #[[ATTR0]] = { nofree nosync nounwind readnone willreturn }
|
|
; IS__CGSCC____: attributes #[[ATTR1]] = { argmemonly nofree norecurse nosync nounwind willreturn writeonly }
|
|
; IS__CGSCC____: attributes #[[ATTR2]] = { nounwind willreturn writeonly }
|
|
;.
|