blob: 642cc1e46f3d26c25231137e96fcf9a58eeacd49 [file] [edit]
// 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.
//
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;
// CHECK-LABEL: define i32 @g0(
// CHECK-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA5:![0-9]+]]
// CHECK-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA7:![0-9]+]]
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA7]]
// CHECK-NEXT: store i32 5, ptr [[TMP0]], align 4, !tbaa [[TBAA1:![0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA5]]
// CHECK-NEXT: store i32 0, ptr [[TMP1]], align 4, !tbaa [[TBAA1]]
// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA7]]
// CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4, !tbaa [[TBAA1]]
// CHECK-NEXT: ret i32 [[TMP3]]
//
// PATH-LABEL: define i32 @g0(
// PATH-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
// PATH-NEXT: [[ENTRY:.*:]]
// PATH-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// PATH-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// PATH-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA6:![0-9]+]]
// PATH-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA8:![0-9]+]]
// PATH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA8]]
// PATH-NEXT: store i32 5, ptr [[TMP0]], align 4, !tbaa [[TBAA10:![0-9]+]]
// PATH-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA6]]
// PATH-NEXT: store i32 0, ptr [[TMP1]], align 4, !tbaa [[TBAA10]]
// PATH-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA8]]
// PATH-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4, !tbaa [[TBAA10]]
// PATH-NEXT: ret i32 [[TMP3]]
//
// NO-TBAA-LABEL: define i32 @g0(
// NO-TBAA-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] {
// NO-TBAA-NEXT: [[ENTRY:.*:]]
// NO-TBAA-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// NO-TBAA-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// NO-TBAA-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8
// NO-TBAA-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: store i32 5, ptr [[TMP0]], align 4
// NO-TBAA-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8
// NO-TBAA-NEXT: store i32 0, ptr [[TMP1]], align 4
// NO-TBAA-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP2]], align 4
// NO-TBAA-NEXT: ret i32 [[TMP3]]
//
uint32_t g0(EnumAuto32 *E, uint32_t *val) {
*val = 5;
*E = RED_AUTO_32;
return *val;
}
// CHECK-LABEL: define i64 @g1(
// CHECK-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA5]]
// CHECK-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA9:![0-9]+]]
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA9]]
// CHECK-NEXT: store i64 5, ptr [[TMP0]], align 8, !tbaa [[TBAA11:![0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA5]]
// CHECK-NEXT: store i64 0, ptr [[TMP1]], align 8, !tbaa [[TBAA13:![0-9]+]]
// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA9]]
// CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8, !tbaa [[TBAA11]]
// CHECK-NEXT: ret i64 [[TMP3]]
//
// PATH-LABEL: define i64 @g1(
// PATH-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// PATH-NEXT: [[ENTRY:.*:]]
// PATH-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// PATH-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// PATH-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA6]]
// PATH-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA11:![0-9]+]]
// PATH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA11]]
// PATH-NEXT: store i64 5, ptr [[TMP0]], align 8, !tbaa [[TBAA13:![0-9]+]]
// PATH-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA6]]
// PATH-NEXT: store i64 0, ptr [[TMP1]], align 8, !tbaa [[TBAA15:![0-9]+]]
// PATH-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA11]]
// PATH-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8, !tbaa [[TBAA13]]
// PATH-NEXT: ret i64 [[TMP3]]
//
// NO-TBAA-LABEL: define i64 @g1(
// NO-TBAA-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// NO-TBAA-NEXT: [[ENTRY:.*:]]
// NO-TBAA-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// NO-TBAA-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// NO-TBAA-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8
// NO-TBAA-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: store i64 5, ptr [[TMP0]], align 8
// NO-TBAA-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8
// NO-TBAA-NEXT: store i64 0, ptr [[TMP1]], align 8
// NO-TBAA-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: [[TMP3:%.*]] = load i64, ptr [[TMP2]], align 8
// NO-TBAA-NEXT: ret i64 [[TMP3]]
//
uint64_t g1(EnumAuto64 *E, uint64_t *val) {
*val = 5;
*E = RED_AUTO_64;
return *val;
}
// CHECK-LABEL: define zeroext i16 @g2(
// CHECK-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA5]]
// CHECK-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA15:![0-9]+]]
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA15]]
// CHECK-NEXT: store i16 5, ptr [[TMP0]], align 2, !tbaa [[TBAA17:![0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA5]]
// CHECK-NEXT: store i16 0, ptr [[TMP1]], align 2, !tbaa [[TBAA17]]
// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA15]]
// CHECK-NEXT: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 2, !tbaa [[TBAA17]]
// CHECK-NEXT: ret i16 [[TMP3]]
//
// PATH-LABEL: define zeroext i16 @g2(
// PATH-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// PATH-NEXT: [[ENTRY:.*:]]
// PATH-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// PATH-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// PATH-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA6]]
// PATH-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA17:![0-9]+]]
// PATH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA17]]
// PATH-NEXT: store i16 5, ptr [[TMP0]], align 2, !tbaa [[TBAA19:![0-9]+]]
// PATH-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA6]]
// PATH-NEXT: store i16 0, ptr [[TMP1]], align 2, !tbaa [[TBAA19]]
// PATH-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA17]]
// PATH-NEXT: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 2, !tbaa [[TBAA19]]
// PATH-NEXT: ret i16 [[TMP3]]
//
// NO-TBAA-LABEL: define zeroext i16 @g2(
// NO-TBAA-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// NO-TBAA-NEXT: [[ENTRY:.*:]]
// NO-TBAA-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// NO-TBAA-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// NO-TBAA-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8
// NO-TBAA-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: store i16 5, ptr [[TMP0]], align 2
// NO-TBAA-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8
// NO-TBAA-NEXT: store i16 0, ptr [[TMP1]], align 2
// NO-TBAA-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 2
// NO-TBAA-NEXT: ret i16 [[TMP3]]
//
uint16_t g2(Enum16 *E, uint16_t *val) {
*val = 5;
*E = RED_16;
return *val;
}
// CHECK-LABEL: define zeroext i8 @g3(
// CHECK-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// CHECK-NEXT: [[ENTRY:.*:]]
// CHECK-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// CHECK-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA5]]
// CHECK-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA19:![0-9]+]]
// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA19]]
// CHECK-NEXT: store i8 5, ptr [[TMP0]], align 1, !tbaa [[TBAA21:![0-9]+]]
// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA5]]
// CHECK-NEXT: store i8 0, ptr [[TMP1]], align 1, !tbaa [[TBAA21]]
// CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA19]]
// CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr [[TMP2]], align 1, !tbaa [[TBAA21]]
// CHECK-NEXT: ret i8 [[TMP3]]
//
// PATH-LABEL: define zeroext i8 @g3(
// PATH-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// PATH-NEXT: [[ENTRY:.*:]]
// PATH-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// PATH-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// PATH-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8, !tbaa [[TBAA6]]
// PATH-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA21:![0-9]+]]
// PATH-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA21]]
// PATH-NEXT: store i8 5, ptr [[TMP0]], align 1, !tbaa [[TBAA23:![0-9]+]]
// PATH-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8, !tbaa [[TBAA6]]
// PATH-NEXT: store i8 0, ptr [[TMP1]], align 1, !tbaa [[TBAA23]]
// PATH-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8, !tbaa [[TBAA21]]
// PATH-NEXT: [[TMP3:%.*]] = load i8, ptr [[TMP2]], align 1, !tbaa [[TBAA23]]
// PATH-NEXT: ret i8 [[TMP3]]
//
// NO-TBAA-LABEL: define zeroext i8 @g3(
// NO-TBAA-SAME: ptr noundef [[E:%.*]], ptr noundef [[VAL:%.*]]) #[[ATTR0]] {
// NO-TBAA-NEXT: [[ENTRY:.*:]]
// NO-TBAA-NEXT: [[E_ADDR:%.*]] = alloca ptr, align 8
// NO-TBAA-NEXT: [[VAL_ADDR:%.*]] = alloca ptr, align 8
// NO-TBAA-NEXT: store ptr [[E]], ptr [[E_ADDR]], align 8
// NO-TBAA-NEXT: store ptr [[VAL]], ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: store i8 5, ptr [[TMP0]], align 1
// NO-TBAA-NEXT: [[TMP1:%.*]] = load ptr, ptr [[E_ADDR]], align 8
// NO-TBAA-NEXT: store i8 0, ptr [[TMP1]], align 1
// NO-TBAA-NEXT: [[TMP2:%.*]] = load ptr, ptr [[VAL_ADDR]], align 8
// NO-TBAA-NEXT: [[TMP3:%.*]] = load i8, ptr [[TMP2]], align 1
// NO-TBAA-NEXT: ret i8 [[TMP3]]
//
uint8_t g3(Enum8 *E, uint8_t *val) {
*val = 5;
*E = RED_8;
return *val;
}
//.
// CHECK: [[TBAA1]] = !{[[META2:![0-9]+]], [[META2]], i64 0}
// CHECK: [[META2]] = !{!"int", [[META3:![0-9]+]], i64 0}
// CHECK: [[META3]] = !{!"omnipotent char", [[META4:![0-9]+]], i64 0}
// CHECK: [[META4]] = !{!"Simple C/C++ TBAA"}
// CHECK: [[TBAA5]] = !{[[META6:![0-9]+]], [[META6]], i64 0}
// CHECK: [[META6]] = !{!"any pointer", [[META3]], i64 0}
// CHECK: [[TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0}
// CHECK: [[META8]] = !{!"p1 int", [[META6]], i64 0}
// CHECK: [[TBAA9]] = !{[[META10:![0-9]+]], [[META10]], i64 0}
// CHECK: [[META10]] = !{!"p1 long long", [[META6]], i64 0}
// CHECK: [[TBAA11]] = !{[[META12:![0-9]+]], [[META12]], i64 0}
// CHECK: [[META12]] = !{!"long long", [[META3]], i64 0}
// CHECK: [[TBAA13]] = !{[[META14:![0-9]+]], [[META14]], i64 0}
// CHECK: [[META14]] = !{!"long", [[META3]], i64 0}
// CHECK: [[TBAA15]] = !{[[META16:![0-9]+]], [[META16]], i64 0}
// CHECK: [[META16]] = !{!"p1 short", [[META6]], i64 0}
// CHECK: [[TBAA17]] = !{[[META18:![0-9]+]], [[META18]], i64 0}
// CHECK: [[META18]] = !{!"short", [[META3]], i64 0}
// CHECK: [[TBAA19]] = !{[[META20:![0-9]+]], [[META20]], i64 0}
// CHECK: [[META20]] = !{!"p1 omnipotent char", [[META6]], i64 0}
// CHECK: [[TBAA21]] = !{[[META3]], [[META3]], i64 0}
//.
// PATH: [[META3:![0-9]+]] = !{!"int", [[META4:![0-9]+]], i64 0}
// PATH: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0}
// PATH: [[META5]] = !{!"Simple C/C++ TBAA"}
// PATH: [[TBAA6]] = !{[[META7:![0-9]+]], [[META7]], i64 0}
// PATH: [[META7]] = !{!"any pointer", [[META4]], i64 0}
// PATH: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0}
// PATH: [[META9]] = !{!"p1 int", [[META7]], i64 0}
// PATH: [[TBAA10]] = !{[[META3]], [[META3]], i64 0}
// PATH: [[TBAA11]] = !{[[META12:![0-9]+]], [[META12]], i64 0}
// PATH: [[META12]] = !{!"p1 long long", [[META7]], i64 0}
// PATH: [[TBAA13]] = !{[[META14:![0-9]+]], [[META14]], i64 0}
// PATH: [[META14]] = !{!"long long", [[META4]], i64 0}
// PATH: [[TBAA15]] = !{[[META16:![0-9]+]], [[META16]], i64 0}
// PATH: [[META16]] = !{!"long", [[META4]], i64 0}
// PATH: [[TBAA17]] = !{[[META18:![0-9]+]], [[META18]], i64 0}
// PATH: [[META18]] = !{!"p1 short", [[META7]], i64 0}
// PATH: [[TBAA19]] = !{[[META20:![0-9]+]], [[META20]], i64 0}
// PATH: [[META20]] = !{!"short", [[META4]], i64 0}
// PATH: [[TBAA21]] = !{[[META22:![0-9]+]], [[META22]], i64 0}
// PATH: [[META22]] = !{!"p1 omnipotent char", [[META7]], i64 0}
// PATH: [[TBAA23]] = !{[[META4]], [[META4]], i64 0}
//.