Let Clang emit `llvm.tbaa.errno` metadata in order to let LLVM carry out optimizations around errno-writing libcalls to, as long as it is proved the involved memory location does not alias `errno`. Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972.
120 lines
4.5 KiB
C
120 lines
4.5 KiB
C
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
|
|
// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -no-struct-path-tbaa -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
|
|
// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefixes=PATH
|
|
// RUN: %clang_cc1 -triple x86_64-apple-darwin -O0 -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA
|
|
// RUN: %clang_cc1 -triple x86_64-apple-darwin -O1 -relaxed-aliasing -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s -check-prefix=NO-TBAA
|
|
// Test TBAA metadata generated by front-end.
|
|
//
|
|
// NO-TBAA-NOT: !tbaa
|
|
|
|
typedef unsigned char uint8_t;
|
|
typedef unsigned short uint16_t;
|
|
typedef unsigned int uint32_t;
|
|
typedef unsigned long long uint64_t;
|
|
|
|
typedef enum {
|
|
RED_AUTO_32,
|
|
GREEN_AUTO_32,
|
|
BLUE_AUTO_32
|
|
} EnumAuto32;
|
|
|
|
typedef enum {
|
|
RED_AUTO_64,
|
|
GREEN_AUTO_64,
|
|
BLUE_AUTO_64 = 0x100000000ull
|
|
} EnumAuto64;
|
|
|
|
typedef enum : uint16_t {
|
|
RED_16,
|
|
GREEN_16,
|
|
BLUE_16
|
|
} Enum16;
|
|
|
|
typedef enum : uint8_t {
|
|
RED_8,
|
|
GREEN_8,
|
|
BLUE_8
|
|
} Enum8;
|
|
|
|
uint32_t g0(EnumAuto32 *E, uint32_t *val) {
|
|
// CHECK-LABEL: define{{.*}} i32 @g0(
|
|
// CHECK: store i32 5, ptr %{{.*}}, align 4, !tbaa [[TBAA2:![0-9]+]]
|
|
// CHECK: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TBAA2]]
|
|
// CHECK: load i32, ptr %{{.*}}, align 4, !tbaa [[TBAA2]]
|
|
// PATH-LABEL: define{{.*}} i32 @g0(
|
|
// PATH: store i32 5, ptr %{{.*}}, align 4, !tbaa [[TBAA2:![0-9]+]]
|
|
// PATH: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TBAA2]]
|
|
// PATH: load i32, ptr %{{.*}}, align 4, !tbaa [[TBAA2]]
|
|
*val = 5;
|
|
*E = RED_AUTO_32;
|
|
return *val;
|
|
}
|
|
|
|
uint64_t g1(EnumAuto64 *E, uint64_t *val) {
|
|
// CHECK-LABEL: define{{.*}} i64 @g1(
|
|
// CHECK: store i64 5, ptr %{{.*}}, align 8, !tbaa [[TBAA12:![0-9]+]]
|
|
// CHECK: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TBAA14:![0-9]+]]
|
|
// CHECK: load i64, ptr %{{.*}}, align 8, !tbaa [[TBAA12]]
|
|
// PATH-LABEL: define{{.*}} i64 @g1(
|
|
// PATH: store i64 5, ptr %{{.*}}, align 8, !tbaa [[TBAA12:![0-9]+]]
|
|
// PATH: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TBAA14:![0-9]+]]
|
|
// PATH: load i64, ptr %{{.*}}, align 8, !tbaa [[TBAA12]]
|
|
*val = 5;
|
|
*E = RED_AUTO_64;
|
|
return *val;
|
|
}
|
|
|
|
uint16_t g2(Enum16 *E, uint16_t *val) {
|
|
// CHECK-LABEL: define{{.*}} i16 @g2(
|
|
// CHECK: store i16 5, ptr %{{.*}}, align 2, !tbaa [[TBAA18:![0-9]+]]
|
|
// CHECK: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TBAA18]]
|
|
// CHECK: load i16, ptr %{{.*}}, align 2, !tbaa [[TBAA18]]
|
|
// PATH-LABEL: define{{.*}} i16 @g2(
|
|
// PATH: store i16 5, ptr %{{.*}}, align 2, !tbaa [[TBAA18:![0-9]+]]
|
|
// PATH: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TBAA18]]
|
|
// PATH: load i16, ptr %{{.*}}, align 2, !tbaa [[TBAA18]]
|
|
*val = 5;
|
|
*E = RED_16;
|
|
return *val;
|
|
}
|
|
|
|
uint8_t g3(Enum8 *E, uint8_t *val) {
|
|
// CHECK-LABEL: define{{.*}} i8 @g3(
|
|
// CHECK: store i8 5, ptr %{{.*}}, align 1, !tbaa [[TBAA22:![0-9]+]]
|
|
// CHECK: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TBAA22]]
|
|
// CHECK: load i8, ptr %{{.*}}, align 1, !tbaa [[TBAA22]]
|
|
// PATH-LABEL: define{{.*}} i8 @g3(
|
|
// PATH: store i8 5, ptr %{{.*}}, align 1, !tbaa [[TBAA22:![0-9]+]]
|
|
// PATH: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TBAA22]]
|
|
// PATH: load i8, ptr %{{.*}}, align 1, !tbaa [[TBAA22]]
|
|
*val = 5;
|
|
*E = RED_8;
|
|
return *val;
|
|
}
|
|
|
|
//.
|
|
// CHECK: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0}
|
|
// CHECK: [[META3]] = !{!"int", [[META4:![0-9]+]], i64 0}
|
|
// CHECK: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
|
|
// CHECK: [[META5]] = !{!"Simple C/C++ TBAA"}
|
|
// CHECK: [[TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
|
|
// CHECK: [[META13]] = !{!"long long", [[META4]], i64 0}
|
|
// CHECK: [[TBAA14]] = !{[[META15:![0-9]+]], [[META15]], i64 0}
|
|
// CHECK: [[META15]] = !{!"long", [[META4]], i64 0}
|
|
// CHECK: [[TBAA18]] = !{[[META19:![0-9]+]], [[META19]], i64 0}
|
|
// CHECK: [[META19]] = !{!"short", [[META4]], i64 0}
|
|
// CHECK: [[TBAA22]] = !{[[META4]], [[META4]], i64 0}
|
|
//.
|
|
// PATH: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0}
|
|
// PATH: [[META3]] = !{!"int", [[META4:![0-9]+]], i64 0}
|
|
// PATH: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
|
|
// PATH: [[META5]] = !{!"Simple C/C++ TBAA"}
|
|
// PATH: [[TBAA12]] = !{[[META13:![0-9]+]], [[META13]], i64 0}
|
|
// PATH: [[META13]] = !{!"long long", [[META4]], i64 0}
|
|
// PATH: [[TBAA14]] = !{[[META15:![0-9]+]], [[META15]], i64 0}
|
|
// PATH: [[META15]] = !{!"long", [[META4]], i64 0}
|
|
// PATH: [[TBAA18]] = !{[[META19:![0-9]+]], [[META19]], i64 0}
|
|
// PATH: [[META19]] = !{!"short", [[META4]], i64 0}
|
|
// PATH: [[TBAA22]] = !{[[META4]], [[META4]], i64 0}
|
|
//.
|