xref: /llvm-project/clang/test/CodeGen/builtin-counted-by-ref.c (revision 7475156d49406785a974b1205d11fe3de9c1553e)
1*7475156dSBill Wendling // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
2*7475156dSBill Wendling // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=X86_64
3*7475156dSBill Wendling // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=I386
4*7475156dSBill Wendling 
5*7475156dSBill Wendling struct a {
6*7475156dSBill Wendling   char x;
7*7475156dSBill Wendling   short count;
8*7475156dSBill Wendling   int array[] __attribute__((counted_by(count)));
9*7475156dSBill Wendling };
10*7475156dSBill Wendling 
11*7475156dSBill Wendling // X86_64-LABEL: define dso_local ptr @test1(
12*7475156dSBill Wendling // X86_64-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0:[0-9]+]] {
13*7475156dSBill Wendling // X86_64-NEXT:  [[ENTRY:.*:]]
14*7475156dSBill Wendling // X86_64-NEXT:    [[SIZE_ADDR:%.*]] = alloca i32, align 4
15*7475156dSBill Wendling // X86_64-NEXT:    [[P:%.*]] = alloca ptr, align 8
16*7475156dSBill Wendling // X86_64-NEXT:    store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4
17*7475156dSBill Wendling // X86_64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
18*7475156dSBill Wendling // X86_64-NEXT:    [[CONV:%.*]] = sext i32 [[TMP0]] to i64
19*7475156dSBill Wendling // X86_64-NEXT:    [[MUL:%.*]] = mul i64 4, [[CONV]]
20*7475156dSBill Wendling // X86_64-NEXT:    [[ADD:%.*]] = add i64 4, [[MUL]]
21*7475156dSBill Wendling // X86_64-NEXT:    [[CALL:%.*]] = call ptr @malloc(i64 noundef [[ADD]]) #[[ATTR2:[0-9]+]]
22*7475156dSBill Wendling // X86_64-NEXT:    store ptr [[CALL]], ptr [[P]], align 8
23*7475156dSBill Wendling // X86_64-NEXT:    [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
24*7475156dSBill Wendling // X86_64-NEXT:    [[CONV1:%.*]] = trunc i32 [[TMP1]] to i16
25*7475156dSBill Wendling // X86_64-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[P]], align 8
26*7475156dSBill Wendling // X86_64-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[TMP2]], i32 0, i32 1
27*7475156dSBill Wendling // X86_64-NEXT:    store i16 [[CONV1]], ptr [[DOT_COUNTED_BY_GEP]], align 2
28*7475156dSBill Wendling // X86_64-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[P]], align 8
29*7475156dSBill Wendling // X86_64-NEXT:    ret ptr [[TMP3]]
30*7475156dSBill Wendling //
31*7475156dSBill Wendling // I386-LABEL: define dso_local ptr @test1(
32*7475156dSBill Wendling // I386-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0:[0-9]+]] {
33*7475156dSBill Wendling // I386-NEXT:  [[ENTRY:.*:]]
34*7475156dSBill Wendling // I386-NEXT:    [[SIZE_ADDR:%.*]] = alloca i32, align 4
35*7475156dSBill Wendling // I386-NEXT:    [[P:%.*]] = alloca ptr, align 4
36*7475156dSBill Wendling // I386-NEXT:    store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4
37*7475156dSBill Wendling // I386-NEXT:    [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
38*7475156dSBill Wendling // I386-NEXT:    [[MUL:%.*]] = mul i32 4, [[TMP0]]
39*7475156dSBill Wendling // I386-NEXT:    [[ADD:%.*]] = add i32 4, [[MUL]]
40*7475156dSBill Wendling // I386-NEXT:    [[CALL:%.*]] = call ptr @malloc(i32 noundef [[ADD]]) #[[ATTR2:[0-9]+]]
41*7475156dSBill Wendling // I386-NEXT:    store ptr [[CALL]], ptr [[P]], align 4
42*7475156dSBill Wendling // I386-NEXT:    [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
43*7475156dSBill Wendling // I386-NEXT:    [[CONV:%.*]] = trunc i32 [[TMP1]] to i16
44*7475156dSBill Wendling // I386-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[P]], align 4
45*7475156dSBill Wendling // I386-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[TMP2]], i32 0, i32 1
46*7475156dSBill Wendling // I386-NEXT:    store i16 [[CONV]], ptr [[DOT_COUNTED_BY_GEP]], align 2
47*7475156dSBill Wendling // I386-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[P]], align 4
48*7475156dSBill Wendling // I386-NEXT:    ret ptr [[TMP3]]
49*7475156dSBill Wendling //
50*7475156dSBill Wendling struct a *test1(int size) {
51*7475156dSBill Wendling   struct a *p = __builtin_malloc(sizeof(struct a) + sizeof(int) * size);
52*7475156dSBill Wendling 
53*7475156dSBill Wendling   *__builtin_counted_by_ref(p->array) = size;
54*7475156dSBill Wendling   return p;
55*7475156dSBill Wendling }
56*7475156dSBill Wendling 
57*7475156dSBill Wendling struct b {
58*7475156dSBill Wendling   int _filler;
59*7475156dSBill Wendling   struct {
60*7475156dSBill Wendling     int __filler;
61*7475156dSBill Wendling     struct {
62*7475156dSBill Wendling       int ___filler;
63*7475156dSBill Wendling       struct {
64*7475156dSBill Wendling         char count;
65*7475156dSBill Wendling       };
66*7475156dSBill Wendling     };
67*7475156dSBill Wendling   };
68*7475156dSBill Wendling   struct {
69*7475156dSBill Wendling     int filler_;
70*7475156dSBill Wendling     struct {
71*7475156dSBill Wendling       int filler__;
72*7475156dSBill Wendling       struct {
73*7475156dSBill Wendling         long array[] __attribute__((counted_by(count)));
74*7475156dSBill Wendling       };
75*7475156dSBill Wendling     };
76*7475156dSBill Wendling   };
77*7475156dSBill Wendling };
78*7475156dSBill Wendling 
79*7475156dSBill Wendling // X86_64-LABEL: define dso_local ptr @test2(
80*7475156dSBill Wendling // X86_64-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0]] {
81*7475156dSBill Wendling // X86_64-NEXT:  [[ENTRY:.*:]]
82*7475156dSBill Wendling // X86_64-NEXT:    [[SIZE_ADDR:%.*]] = alloca i32, align 4
83*7475156dSBill Wendling // X86_64-NEXT:    [[P:%.*]] = alloca ptr, align 8
84*7475156dSBill Wendling // X86_64-NEXT:    store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4
85*7475156dSBill Wendling // X86_64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
86*7475156dSBill Wendling // X86_64-NEXT:    [[CONV:%.*]] = sext i32 [[TMP0]] to i64
87*7475156dSBill Wendling // X86_64-NEXT:    [[MUL:%.*]] = mul i64 4, [[CONV]]
88*7475156dSBill Wendling // X86_64-NEXT:    [[ADD:%.*]] = add i64 4, [[MUL]]
89*7475156dSBill Wendling // X86_64-NEXT:    [[CALL:%.*]] = call ptr @malloc(i64 noundef [[ADD]]) #[[ATTR2]]
90*7475156dSBill Wendling // X86_64-NEXT:    store ptr [[CALL]], ptr [[P]], align 8
91*7475156dSBill Wendling // X86_64-NEXT:    [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
92*7475156dSBill Wendling // X86_64-NEXT:    [[CONV1:%.*]] = trunc i32 [[TMP1]] to i8
93*7475156dSBill Wendling // X86_64-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[P]], align 8
94*7475156dSBill Wendling // X86_64-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_B:%.*]], ptr [[TMP2]], i32 0, i32 1, i32 1, i32 1, i32 0
95*7475156dSBill Wendling // X86_64-NEXT:    store i8 [[CONV1]], ptr [[DOT_COUNTED_BY_GEP]], align 1
96*7475156dSBill Wendling // X86_64-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[P]], align 8
97*7475156dSBill Wendling // X86_64-NEXT:    ret ptr [[TMP3]]
98*7475156dSBill Wendling //
99*7475156dSBill Wendling // I386-LABEL: define dso_local ptr @test2(
100*7475156dSBill Wendling // I386-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0]] {
101*7475156dSBill Wendling // I386-NEXT:  [[ENTRY:.*:]]
102*7475156dSBill Wendling // I386-NEXT:    [[SIZE_ADDR:%.*]] = alloca i32, align 4
103*7475156dSBill Wendling // I386-NEXT:    [[P:%.*]] = alloca ptr, align 4
104*7475156dSBill Wendling // I386-NEXT:    store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4
105*7475156dSBill Wendling // I386-NEXT:    [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
106*7475156dSBill Wendling // I386-NEXT:    [[MUL:%.*]] = mul i32 4, [[TMP0]]
107*7475156dSBill Wendling // I386-NEXT:    [[ADD:%.*]] = add i32 4, [[MUL]]
108*7475156dSBill Wendling // I386-NEXT:    [[CALL:%.*]] = call ptr @malloc(i32 noundef [[ADD]]) #[[ATTR2]]
109*7475156dSBill Wendling // I386-NEXT:    store ptr [[CALL]], ptr [[P]], align 4
110*7475156dSBill Wendling // I386-NEXT:    [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
111*7475156dSBill Wendling // I386-NEXT:    [[CONV:%.*]] = trunc i32 [[TMP1]] to i8
112*7475156dSBill Wendling // I386-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[P]], align 4
113*7475156dSBill Wendling // I386-NEXT:    [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds [[STRUCT_B:%.*]], ptr [[TMP2]], i32 0, i32 1, i32 1, i32 1, i32 0
114*7475156dSBill Wendling // I386-NEXT:    store i8 [[CONV]], ptr [[DOT_COUNTED_BY_GEP]], align 1
115*7475156dSBill Wendling // I386-NEXT:    [[TMP3:%.*]] = load ptr, ptr [[P]], align 4
116*7475156dSBill Wendling // I386-NEXT:    ret ptr [[TMP3]]
117*7475156dSBill Wendling //
118*7475156dSBill Wendling struct b *test2(int size) {
119*7475156dSBill Wendling   struct b *p = __builtin_malloc(sizeof(struct a) + sizeof(int) * size);
120*7475156dSBill Wendling 
121*7475156dSBill Wendling   *__builtin_counted_by_ref(p->array) = size;
122*7475156dSBill Wendling   return p;
123*7475156dSBill Wendling }
124*7475156dSBill Wendling 
125*7475156dSBill Wendling struct c {
126*7475156dSBill Wendling   char x;
127*7475156dSBill Wendling   short count;
128*7475156dSBill Wendling   int array[];
129*7475156dSBill Wendling };
130*7475156dSBill Wendling 
131*7475156dSBill Wendling // X86_64-LABEL: define dso_local ptr @test3(
132*7475156dSBill Wendling // X86_64-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0]] {
133*7475156dSBill Wendling // X86_64-NEXT:  [[ENTRY:.*:]]
134*7475156dSBill Wendling // X86_64-NEXT:    [[SIZE_ADDR:%.*]] = alloca i32, align 4
135*7475156dSBill Wendling // X86_64-NEXT:    [[P:%.*]] = alloca ptr, align 8
136*7475156dSBill Wendling // X86_64-NEXT:    [[__IGNORED:%.*]] = alloca i64, align 8
137*7475156dSBill Wendling // X86_64-NEXT:    store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4
138*7475156dSBill Wendling // X86_64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
139*7475156dSBill Wendling // X86_64-NEXT:    [[CONV:%.*]] = sext i32 [[TMP0]] to i64
140*7475156dSBill Wendling // X86_64-NEXT:    [[MUL:%.*]] = mul i64 4, [[CONV]]
141*7475156dSBill Wendling // X86_64-NEXT:    [[ADD:%.*]] = add i64 4, [[MUL]]
142*7475156dSBill Wendling // X86_64-NEXT:    [[CALL:%.*]] = call ptr @malloc(i64 noundef [[ADD]]) #[[ATTR2]]
143*7475156dSBill Wendling // X86_64-NEXT:    store ptr [[CALL]], ptr [[P]], align 8
144*7475156dSBill Wendling // X86_64-NEXT:    [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
145*7475156dSBill Wendling // X86_64-NEXT:    [[CONV1:%.*]] = sext i32 [[TMP1]] to i64
146*7475156dSBill Wendling // X86_64-NEXT:    store i64 [[CONV1]], ptr [[__IGNORED]], align 8
147*7475156dSBill Wendling // X86_64-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[P]], align 8
148*7475156dSBill Wendling // X86_64-NEXT:    ret ptr [[TMP2]]
149*7475156dSBill Wendling //
150*7475156dSBill Wendling // I386-LABEL: define dso_local ptr @test3(
151*7475156dSBill Wendling // I386-SAME: i32 noundef [[SIZE:%.*]]) #[[ATTR0]] {
152*7475156dSBill Wendling // I386-NEXT:  [[ENTRY:.*:]]
153*7475156dSBill Wendling // I386-NEXT:    [[SIZE_ADDR:%.*]] = alloca i32, align 4
154*7475156dSBill Wendling // I386-NEXT:    [[P:%.*]] = alloca ptr, align 4
155*7475156dSBill Wendling // I386-NEXT:    [[__IGNORED:%.*]] = alloca i32, align 4
156*7475156dSBill Wendling // I386-NEXT:    store i32 [[SIZE]], ptr [[SIZE_ADDR]], align 4
157*7475156dSBill Wendling // I386-NEXT:    [[TMP0:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
158*7475156dSBill Wendling // I386-NEXT:    [[MUL:%.*]] = mul i32 4, [[TMP0]]
159*7475156dSBill Wendling // I386-NEXT:    [[ADD:%.*]] = add i32 4, [[MUL]]
160*7475156dSBill Wendling // I386-NEXT:    [[CALL:%.*]] = call ptr @malloc(i32 noundef [[ADD]]) #[[ATTR2]]
161*7475156dSBill Wendling // I386-NEXT:    store ptr [[CALL]], ptr [[P]], align 4
162*7475156dSBill Wendling // I386-NEXT:    [[TMP1:%.*]] = load i32, ptr [[SIZE_ADDR]], align 4
163*7475156dSBill Wendling // I386-NEXT:    store i32 [[TMP1]], ptr [[__IGNORED]], align 4
164*7475156dSBill Wendling // I386-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[P]], align 4
165*7475156dSBill Wendling // I386-NEXT:    ret ptr [[TMP2]]
166*7475156dSBill Wendling //
167*7475156dSBill Wendling struct c *test3(int size) {
168*7475156dSBill Wendling   struct c *p = __builtin_malloc(sizeof(struct c) + sizeof(int) * size);
169*7475156dSBill Wendling   unsigned long int __ignored;
170*7475156dSBill Wendling 
171*7475156dSBill Wendling   *_Generic(
172*7475156dSBill Wendling     __builtin_counted_by_ref(p->array),
173*7475156dSBill Wendling       void *: &__ignored,
174*7475156dSBill Wendling       default: __builtin_counted_by_ref(p->array)) = size;
175*7475156dSBill Wendling 
176*7475156dSBill Wendling   return p;
177*7475156dSBill Wendling }
178