|
| 1 | +// This is inspired from clang/test/CodeGen/tbaa.c, with both CIR and LLVM checks. |
| 2 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir -O1 |
| 3 | +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s |
| 4 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -O1 -disable-llvm-passes |
| 5 | +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s |
| 6 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -O1 -disable-llvm-passes -relaxed-aliasing |
| 7 | +// RUN: FileCheck --check-prefix=NO-TBAA --input-file=%t.ll %s |
| 8 | +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll -O0 -disable-llvm-passes |
| 9 | +// RUN: FileCheck --check-prefix=NO-TBAA --input-file=%t.ll %s |
| 10 | + |
| 11 | +// NO-TBAA-NOT: !tbaa |
| 12 | + |
| 13 | +// CIR: #tbaa[[NYI:.*]] = #cir.tbaa |
| 14 | +// CIR: #tbaa[[CHAR:.*]] = #cir.tbaa_omnipotent_char |
| 15 | +// CIR: #tbaa[[INT:.*]] = #cir.tbaa_scalar<id = "int", type = !s32i> |
| 16 | +// CIR: #tbaa[[EnumAuto32:.*]] = #cir.tbaa_scalar<id = "_ZTS10EnumAuto32", type = !u32i> |
| 17 | +// CIR: #tbaa[[LONG_LONG:.*]] = #cir.tbaa_scalar<id = "long long", type = !s64i> |
| 18 | +// CIR: #tbaa[[EnumAuto64:.*]] = #cir.tbaa_scalar<id = "_ZTS10EnumAuto64", type = !u64i> |
| 19 | +// CIR: #tbaa[[SHORT:.*]] = #cir.tbaa_scalar<id = "short", type = !s16i> |
| 20 | +// CIR: #tbaa[[Enum16:.*]] = #cir.tbaa_scalar<id = "_ZTS6Enum16", type = !u16i> |
| 21 | +// CIR: #tbaa[[Enum8:.*]] = #cir.tbaa_scalar<id = "_ZTS5Enum8", type = !u8i> |
| 22 | + |
| 23 | + |
| 24 | +typedef unsigned char uint8_t; |
| 25 | +typedef unsigned short uint16_t; |
| 26 | +typedef unsigned int uint32_t; |
| 27 | +typedef unsigned long long uint64_t; |
| 28 | + |
| 29 | +typedef enum { |
| 30 | + RED_AUTO_32, |
| 31 | + GREEN_AUTO_32, |
| 32 | + BLUE_AUTO_32 |
| 33 | +} EnumAuto32; |
| 34 | + |
| 35 | +typedef enum { |
| 36 | + RED_AUTO_64, |
| 37 | + GREEN_AUTO_64, |
| 38 | + BLUE_AUTO_64 = 0x100000000ull |
| 39 | +} EnumAuto64; |
| 40 | + |
| 41 | +typedef enum : uint16_t { |
| 42 | + RED_16, |
| 43 | + GREEN_16, |
| 44 | + BLUE_16 |
| 45 | +} Enum16; |
| 46 | + |
| 47 | +typedef enum : uint8_t { |
| 48 | + RED_8, |
| 49 | + GREEN_8, |
| 50 | + BLUE_8 |
| 51 | +} Enum8; |
| 52 | + |
| 53 | +uint32_t g0(EnumAuto32 *E, uint32_t *val) { |
| 54 | + // CIR-LABEL: cir.func @_Z2g0 |
| 55 | + // CIR: %[[C5:.*]] = cir.const #cir.int<5> : !s32i |
| 56 | + // CIR: %[[U_C5:.*]] = cir.cast(integral, %[[C5]] : !s32i), !u32i |
| 57 | + // CIR: %[[VAL_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i> |
| 58 | + // CIR: cir.store %[[U_C5]], %[[VAL_PTR]] : !u32i, !cir.ptr<!u32i> tbaa(#tbaa[[INT]]) |
| 59 | + // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !u32i |
| 60 | + // CIR: %[[E_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i> |
| 61 | + // CIR: cir.store %[[C0]], %[[E_PTR]] : !u32i, !cir.ptr<!u32i> tbaa(#tbaa[[EnumAuto32]]) |
| 62 | + // CIR: %[[RET_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u32i>>, !cir.ptr<!u32i> |
| 63 | + // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u32i>, !u32i tbaa(#tbaa[[INT]]) |
| 64 | + // CIR: cir.store %[[RET]], %{{.*}} : !u32i, !cir.ptr<!u32i> |
| 65 | + |
| 66 | + // LLVM-LABEL: define{{.*}} i32 @_Z2g0 |
| 67 | + // LLVM: store i32 5, ptr %{{.*}}, align 4, !tbaa [[TAG_i32:!.*]] |
| 68 | + // LLVM: store i32 0, ptr %{{.*}}, align 4, !tbaa [[TAG_EnumAuto32:!.*]] |
| 69 | + // LLVM: load i32, ptr %{{.*}}, align 4, !tbaa [[TAG_i32]] |
| 70 | + *val = 5; |
| 71 | + *E = RED_AUTO_32; |
| 72 | + return *val; |
| 73 | +} |
| 74 | + |
| 75 | +uint64_t g1(EnumAuto64 *E, uint64_t *val) { |
| 76 | + // CIR-LABEL: cir.func @_Z2g1 |
| 77 | + // CIR: %[[C5:.*]] = cir.const #cir.int<5> : !s32i |
| 78 | + // CIR: %[[U_C5:.*]] = cir.cast(integral, %[[C5]] : !s32i), !u64i |
| 79 | + // CIR: %[[VAL_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i> |
| 80 | + // CIR: cir.store %[[U_C5]], %[[VAL_PTR]] : !u64i, !cir.ptr<!u64i> tbaa(#tbaa[[LONG_LONG]]) |
| 81 | + // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !u64i |
| 82 | + // CIR: %[[E_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i> |
| 83 | + // CIR: cir.store %[[C0]], %[[E_PTR]] : !u64i, !cir.ptr<!u64i> tbaa(#tbaa[[EnumAuto64]]) |
| 84 | + // CIR: %[[RET_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i> |
| 85 | + // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u64i>, !u64i tbaa(#tbaa[[LONG_LONG]]) |
| 86 | + // CIR: cir.store %[[RET]], %{{.*}} : !u64i, !cir.ptr<!u64i> |
| 87 | + |
| 88 | + // LLVM-LABEL: define{{.*}} i64 @_Z2g1 |
| 89 | + // LLVM: store i64 5, ptr %{{.*}}, align 8, !tbaa [[TAG_i64:!.*]] |
| 90 | + // LLVM: store i64 0, ptr %{{.*}}, align 8, !tbaa [[TAG_EnumAuto64:!.*]] |
| 91 | + // LLVM: load i64, ptr %{{.*}}, align 8, !tbaa [[TAG_i64]] |
| 92 | + *val = 5; |
| 93 | + *E = RED_AUTO_64; |
| 94 | + return *val; |
| 95 | +} |
| 96 | + |
| 97 | +uint16_t g2(Enum16 *E, uint16_t *val) { |
| 98 | + // CIR-LABEL: cir.func @_Z2g2 |
| 99 | + // CIR: %[[C5:.*]] = cir.const #cir.int<5> : !s32i |
| 100 | + // CIR: %[[U_C5:.*]] = cir.cast(integral, %[[C5]] : !s32i), !u16i |
| 101 | + // CIR: %[[VAL_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u16i>>, !cir.ptr<!u16i> |
| 102 | + // CIR: cir.store %[[U_C5]], %[[VAL_PTR]] : !u16i, !cir.ptr<!u16i> tbaa(#tbaa[[SHORT]]) |
| 103 | + // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !u16i |
| 104 | + // CIR: %[[E_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u16i>>, !cir.ptr<!u16i> |
| 105 | + // CIR: cir.store %[[C0]], %[[E_PTR]] : !u16i, !cir.ptr<!u16i> tbaa(#tbaa[[Enum16]]) |
| 106 | + // CIR: %[[RET_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u16i>>, !cir.ptr<!u16i> |
| 107 | + // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u16i>, !u16i tbaa(#tbaa[[SHORT]]) |
| 108 | + // CIR: cir.store %[[RET]], %{{.*}} : !u16i, !cir.ptr<!u16i> |
| 109 | + |
| 110 | + // LLVM-LABEL: define{{.*}} i16 @_Z2g2 |
| 111 | + // LLVM: store i16 5, ptr %{{.*}}, align 2, !tbaa [[TAG_i16:!.*]] |
| 112 | + // LLVM: store i16 0, ptr %{{.*}}, align 2, !tbaa [[TAG_Enum16:!.*]] |
| 113 | + // LLVM: load i16, ptr %{{.*}}, align 2, !tbaa [[TAG_i16]] |
| 114 | + *val = 5; |
| 115 | + *E = RED_16; |
| 116 | + return *val; |
| 117 | +} |
| 118 | + |
| 119 | +uint8_t g3(Enum8 *E, uint8_t *val) { |
| 120 | + // CIR-LABEL: cir.func @_Z2g3 |
| 121 | + // CIR: %[[C5:.*]] = cir.const #cir.int<5> : !s32i |
| 122 | + // CIR: %[[U_C5:.*]] = cir.cast(integral, %[[C5]] : !s32i), !u8i |
| 123 | + // CIR: %[[VAL_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u8i>>, !cir.ptr<!u8i> |
| 124 | + // CIR: cir.store %[[U_C5]], %[[VAL_PTR]] : !u8i, !cir.ptr<!u8i> tbaa(#tbaa[[CHAR]]) |
| 125 | + // CIR: %[[C0:.*]] = cir.const #cir.int<0> : !u8i |
| 126 | + // CIR: %[[E_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u8i>>, !cir.ptr<!u8i> |
| 127 | + // CIR: cir.store %[[C0]], %[[E_PTR]] : !u8i, !cir.ptr<!u8i> tbaa(#tbaa[[Enum8]]) |
| 128 | + // CIR: %[[RET_PTR:.*]] = cir.load deref %{{.*}} : !cir.ptr<!cir.ptr<!u8i>>, !cir.ptr<!u8i> |
| 129 | + // CIR: %[[RET:.*]] = cir.load %[[RET_PTR]] : !cir.ptr<!u8i>, !u8i tbaa(#tbaa[[CHAR]]) |
| 130 | + // CIR: cir.store %[[RET]], %{{.*}} : !u8i, !cir.ptr<!u8i> |
| 131 | + |
| 132 | + |
| 133 | + // LLVM-LABEL: define{{.*}} i8 @_Z2g3 |
| 134 | + // LLVM: store i8 5, ptr %{{.*}}, align 1, !tbaa [[TAG_i8:!.*]] |
| 135 | + // LLVM: store i8 0, ptr %{{.*}}, align 1, !tbaa [[TAG_Enum8:!.*]] |
| 136 | + // LLVM: load i8, ptr %{{.*}}, align 1, !tbaa [[TAG_i8]] |
| 137 | + *val = 5; |
| 138 | + *E = RED_8; |
| 139 | + return *val; |
| 140 | +} |
| 141 | + |
| 142 | +// LLVM: [[TAG_i32]] = !{[[TYPE_i32:!.*]], [[TYPE_i32]], i64 0} |
| 143 | +// LLVM: [[TYPE_i32]] = !{!"int", [[TYPE_char:!.*]], |
| 144 | +// LLVM: [[TYPE_char]] = !{!"omnipotent char", [[TAG_c_tbaa:!.*]], |
| 145 | +// LLVM: [[TAG_c_tbaa]] = !{!"Simple C/C++ TBAA"} |
| 146 | +// LLVM: [[TAG_EnumAuto32]] = !{[[TYPE_EnumAuto32:!.*]], [[TYPE_EnumAuto32]], i64 0} |
| 147 | +// LLVM: [[TYPE_EnumAuto32]] = !{!"_ZTS10EnumAuto32", [[TYPE_char]], |
| 148 | +// LLVM: [[TAG_i64]] = !{[[TYPE_i64:!.*]], [[TYPE_i64]], i64 0} |
| 149 | +// LLVM: [[TYPE_i64]] = !{!"long long", [[TYPE_char]], |
| 150 | +// LLVM: [[TAG_EnumAuto64]] = !{[[TYPE_EnumAuto64:!.*]], [[TYPE_EnumAuto64]], i64 0} |
| 151 | +// LLVM: [[TYPE_EnumAuto64]] = !{!"_ZTS10EnumAuto64", [[TYPE_char]], |
| 152 | +// LLVM: [[TAG_i16]] = !{[[TYPE_i16:!.*]], [[TYPE_i16]], i64 0} |
| 153 | +// LLVM: [[TYPE_i16]] = !{!"short", [[TYPE_char]], |
| 154 | +// LLVM: [[TAG_Enum16]] = !{[[TYPE_Enum16:!.*]], [[TYPE_Enum16]], i64 0} |
| 155 | +// LLVM: [[TYPE_Enum16]] = !{!"_ZTS6Enum16", [[TYPE_char]], |
| 156 | +// LLVM: [[TAG_Enum8]] = !{[[TYPE_Enum8:!.*]], [[TYPE_Enum8]], i64 0} |
| 157 | +// LLVM: [[TYPE_Enum8]] = !{!"_ZTS5Enum8", [[TYPE_char]], |
0 commit comments