| // 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 [[TAG_i32:!.*]] | 
 | // CHECK: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] | 
 | // CHECK: load i32, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] | 
 | // PATH-LABEL: define{{.*}} i32 @g0( | 
 | // PATH: store i32 5, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]] | 
 | // PATH: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] | 
 | // PATH: load i32, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] | 
 |   *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 [[TAG_i64:!.*]] | 
 | // CHECK: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TAG_long:!.*]] | 
 | // CHECK: load i64, ptr %{{.*}}, align 8, !tbaa [[TAG_i64]] | 
 | // PATH-LABEL: define{{.*}} i64 @g1( | 
 | // PATH: store i64 5, ptr %{{.*}}, align 8, !tbaa [[TAG_i64:!.*]] | 
 | // PATH: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TAG_long:!.*]] | 
 | // PATH: load i64, ptr %{{.*}}, align 8, !tbaa [[TAG_i64]] | 
 |   *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 [[TAG_i16:!.*]] | 
 | // CHECK: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] | 
 | // CHECK: load i16, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] | 
 | // PATH-LABEL: define{{.*}} i16 @g2( | 
 | // PATH: store i16 5, ptr %{{.*}}, align 2, !tbaa [[TAG_i16:!.*]] | 
 | // PATH: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] | 
 | // PATH: load i16, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] | 
 |   *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 [[TAG_i8:!.*]] | 
 | // CHECK: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] | 
 | // CHECK: load i8, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] | 
 | // PATH-LABEL: define{{.*}} i8 @g3( | 
 | // PATH: store i8 5, ptr %{{.*}}, align 1, !tbaa [[TAG_i8:!.*]] | 
 | // PATH: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] | 
 | // PATH: load i8, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] | 
 |   *val = 5; | 
 |   *E = RED_8; | 
 |   return *val; | 
 | } | 
 |  | 
 | // CHECK: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_c_tbaa:!.*]], | 
 | // CHECK: [[TAG_c_tbaa]] = !{!"Simple C/C++ TBAA"} | 
 | // CHECK: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0} | 
 | // CHECK: [[TYPE_i32]] = !{!"int", [[TYPE_char]], | 
 | // CHECK: [[TAG_i64]] = !{[[TYPE_i64:!.*]], [[TYPE_i64]], i64 0} | 
 | // CHECK: [[TYPE_i64]] = !{!"long long", [[TYPE_char]], | 
 | // CHECK: [[TAG_long]] = !{[[TYPE_long:!.*]], [[TYPE_long]], i64 0} | 
 | // CHECK: [[TYPE_long]] = !{!"long", [[TYPE_char]], | 
 | // CHECK: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0} | 
 | // CHECK: [[TYPE_i16]] = !{!"short", [[TYPE_char]], | 
 | // CHECK: [[TAG_i8]] = !{[[TYPE_i8:!.*]], [[TYPE_char]], i64 0} | 
 |  | 
 | // PATH: [[TYPE_char:!.*]] = !{!"omnipotent char", [[TAG_c_tbaa:!.*]], | 
 | // PATH: [[TAG_c_tbaa]] = !{!"Simple C/C++ TBAA"} | 
 | // PATH: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0} | 
 | // PATH: [[TYPE_i32]] = !{!"int", [[TYPE_char]], | 
 | // PATH: [[TAG_i64]] = !{[[TYPE_i64:!.*]], [[TYPE_i64]], i64 0} | 
 | // PATH: [[TYPE_i64]] = !{!"long long", [[TYPE_char]], | 
 | // PATH: [[TAG_long]] = !{[[TYPE_long:!.*]], [[TYPE_long]], i64 0} | 
 | // PATH: [[TYPE_long]] = !{!"long", [[TYPE_char]], | 
 | // PATH: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0} | 
 | // PATH: [[TYPE_i16]] = !{!"short", [[TYPE_char]], | 
 | // PATH: [[TAG_i8]] = !{[[TYPE_i8:!.*]], [[TYPE_char]], i64 0} |