Unlike Attributor, FunctionAttrs currently only supports inferring nofree on functions. This PR adds support for inferring it on arguments as well. I've chosen to integrate this with the inference for readnone/readonly/writeonly attributes, as the core logic for these is the same. There is a lot of test fallout. The only significant changes are in llvm/lib/Transforms/IPO/FunctionAttrs.cpp and llvm/test/Transforms/FunctionAttrs/nofree.ll.
84 lines
3.4 KiB
C
84 lines
3.4 KiB
C
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
|
|
// RUN: %clang_cc1 -O1 -triple=x86_64-unknown-linux %s -emit-llvm -o - | FileCheck %s
|
|
|
|
typedef unsigned char uint8_t;
|
|
typedef unsigned long long uint64_t;
|
|
|
|
struct a {
|
|
uint64_t b;
|
|
uint8_t block[16];
|
|
};
|
|
|
|
// CHECK-LABEL: define dso_local void @ptradd_0(
|
|
// CHECK-SAME: ptr nofree noundef writeonly captures(none) initializes((8, 9)) [[CTX:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[BLOCK:%.*]] = getelementptr inbounds nuw i8, ptr [[CTX]], i64 8
|
|
// CHECK-NEXT: store i8 0, ptr [[BLOCK]], align 8, !tbaa [[TBAA5:![0-9]+]]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void ptradd_0(struct a *ctx) {
|
|
*(ctx->block + 0) = 0;
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @ptradd_4(
|
|
// CHECK-SAME: ptr nofree noundef writeonly captures(none) initializes((12, 13)) [[CTX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[CTX]], i64 12
|
|
// CHECK-NEXT: store i8 0, ptr [[ADD_PTR]], align 4, !tbaa [[TBAA5]]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void ptradd_4(struct a *ctx) {
|
|
*(ctx->block + 4) = 0;
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @ptradd_8(
|
|
// CHECK-SAME: ptr nofree noundef writeonly captures(none) initializes((16, 17)) [[CTX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[CTX]], i64 16
|
|
// CHECK-NEXT: store i8 0, ptr [[ADD_PTR]], align 8, !tbaa [[TBAA5]]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void ptradd_8(struct a *ctx) {
|
|
*(ctx->block + 8) = 0;
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @ptradd_8_commuted(
|
|
// CHECK-SAME: ptr nofree noundef writeonly captures(none) initializes((16, 17)) [[CTX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[CTX]], i64 16
|
|
// CHECK-NEXT: store i8 0, ptr [[ADD_PTR]], align 8, !tbaa [[TBAA5]]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void ptradd_8_commuted(struct a *ctx) {
|
|
*(8 + ctx->block) = 0;
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @ptrsub_4(
|
|
// CHECK-SAME: ptr nofree noundef writeonly captures(none) initializes((8, 9)) [[CTX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[CTX]], i64 8
|
|
// CHECK-NEXT: store i8 0, ptr [[ADD_PTR]], align 4, !tbaa [[TBAA5]]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void ptrsub_4(struct a *ctx) {
|
|
*(&ctx->block[4] - 4) = 0;
|
|
}
|
|
|
|
// CHECK-LABEL: define dso_local void @neg_ptradd_var_index(
|
|
// CHECK-SAME: ptr nofree noundef writeonly captures(none) [[CTX:%.*]], i8 noundef zeroext [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] {
|
|
// CHECK-NEXT: [[ENTRY:.*:]]
|
|
// CHECK-NEXT: [[BLOCK:%.*]] = getelementptr inbounds nuw i8, ptr [[CTX]], i64 8
|
|
// CHECK-NEXT: [[IDX_EXT:%.*]] = zext i8 [[IDX]] to i64
|
|
// CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[BLOCK]], i64 [[IDX_EXT]]
|
|
// CHECK-NEXT: store i8 0, ptr [[ADD_PTR]], align 1, !tbaa [[TBAA5]]
|
|
// CHECK-NEXT: ret void
|
|
//
|
|
void neg_ptradd_var_index(struct a *ctx, uint8_t idx) {
|
|
*(ctx->block + idx) = 0;
|
|
}
|
|
//.
|
|
// CHECK: [[META3:![0-9]+]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
|
|
// CHECK: [[META4]] = !{!"Simple C/C++ TBAA"}
|
|
// CHECK: [[TBAA5]] = !{[[META3]], [[META3]], i64 0}
|
|
//.
|