Revert "[llvm] Improve llvm.objectsize computation by computing GEP, alloca and mallo...
[llvm-project.git] / clang / test / CodeGen / builtin-align.c
blob932b93972a85e6651b36c9f22a9b5358ffb5c225
1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 /// Check the code generation for the alignment builtins
3 /// To make the test case easier to read, run SROA after generating IR to remove the alloca instructions.
4 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -DTEST_VOID_PTR \
5 // RUN: -o - -emit-llvm %s -disable-O0-optnone | opt -S -passes=sroa | \
6 // RUN: FileCheck %s -check-prefixes CHECK,CHECK-VOID_PTR \
7 // RUN: -enable-var-scope '-D$PTRTYPE=i8'
8 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -DTEST_FLOAT_PTR \
9 // RUN: -o - -emit-llvm %s -disable-O0-optnone | opt -S -passes=sroa | \
10 // RUN: FileCheck %s -check-prefixes CHECK,CHECK-FLOAT_PTR \
11 // RUN: -enable-var-scope '-D$PTRTYPE=f32'
12 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -DTEST_LONG \
13 // RUN: -o - -emit-llvm %s -disable-O0-optnone | opt -S -passes=sroa | \
14 // RUN: FileCheck %s -check-prefixes CHECK,CHECK-LONG -enable-var-scope
15 /// Check that we can handle the case where the alignment parameter is wider
16 /// than the source type (generate a trunc on alignment instead of zext)
17 // RUN: %clang_cc1 -triple=x86_64-unknown-unknown -DTEST_USHORT \
18 // RUN: -o - -emit-llvm %s -disable-O0-optnone | opt -S -passes=sroa | \
19 // RUN: FileCheck %s -check-prefixes CHECK,CHECK-USHORT -enable-var-scope
22 #ifdef TEST_VOID_PTR
23 #define TYPE void *
24 #elif defined(TEST_FLOAT_PTR)
25 #define TYPE float *
26 #elif defined(TEST_LONG)
27 #define TYPE long
28 #elif defined(TEST_USHORT)
29 #define TYPE unsigned short
30 #else
31 #error MISSING TYPE
32 #endif
34 /// Check that constant initializers work and are correct
35 _Bool aligned_true = __builtin_is_aligned(1024, 512);
36 // CHECK: @aligned_true ={{.*}} global i8 1, align 1
37 _Bool aligned_false = __builtin_is_aligned(123, 512);
38 // CHECK: @aligned_false ={{.*}} global i8 0, align 1
40 int down_1 = __builtin_align_down(1023, 32);
41 // CHECK: @down_1 ={{.*}} global i32 992, align 4
42 int down_2 = __builtin_align_down(256, 32);
43 // CHECK: @down_2 ={{.*}} global i32 256, align 4
45 int up_1 = __builtin_align_up(1023, 32);
46 // CHECK: @up_1 ={{.*}} global i32 1024, align 4
47 int up_2 = __builtin_align_up(256, 32);
48 // CHECK: @up_2 ={{.*}} global i32 256, align 4
50 /// Capture the IR type here to use in the remaining FileCheck captures:
51 // CHECK-VOID_PTR-LABEL: define {{[^@]+}}@get_type() #0
52 // CHECK-VOID_PTR-NEXT: entry:
53 // CHECK-VOID_PTR-NEXT: ret ptr null
55 // CHECK-FLOAT_PTR-LABEL: define {{[^@]+}}@get_type() #0
56 // CHECK-FLOAT_PTR-NEXT: entry:
57 // CHECK-FLOAT_PTR-NEXT: ret ptr null
59 // CHECK-LONG-LABEL: define {{[^@]+}}@get_type() #0
60 // CHECK-LONG-NEXT: entry:
61 // CHECK-LONG-NEXT: ret i64 0
63 // CHECK-USHORT-LABEL: define {{[^@]+}}@get_type() #0
64 // CHECK-USHORT-NEXT: entry:
65 // CHECK-USHORT-NEXT: ret i16 0
67 TYPE get_type(void) {
68 return (TYPE)0;
71 // CHECK-VOID_PTR-LABEL: define {{[^@]+}}@is_aligned
72 // CHECK-VOID_PTR-SAME: (ptr noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
73 // CHECK-VOID_PTR-NEXT: entry:
74 // CHECK-VOID_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
75 // CHECK-VOID_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
76 // CHECK-VOID_PTR-NEXT: [[SRC_ADDR:%.*]] = ptrtoint ptr [[PTR:%.*]] to i64
77 // CHECK-VOID_PTR-NEXT: [[SET_BITS:%.*]] = and i64 [[SRC_ADDR]], [[MASK]]
78 // CHECK-VOID_PTR-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i64 [[SET_BITS]], 0
79 // CHECK-VOID_PTR-NEXT: ret i1 [[IS_ALIGNED]]
81 // CHECK-FLOAT_PTR-LABEL: define {{[^@]+}}@is_aligned
82 // CHECK-FLOAT_PTR-SAME: (ptr noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
83 // CHECK-FLOAT_PTR-NEXT: entry:
84 // CHECK-FLOAT_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
85 // CHECK-FLOAT_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
86 // CHECK-FLOAT_PTR-NEXT: [[SRC_ADDR:%.*]] = ptrtoint ptr [[PTR:%.*]] to i64
87 // CHECK-FLOAT_PTR-NEXT: [[SET_BITS:%.*]] = and i64 [[SRC_ADDR]], [[MASK]]
88 // CHECK-FLOAT_PTR-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i64 [[SET_BITS]], 0
89 // CHECK-FLOAT_PTR-NEXT: ret i1 [[IS_ALIGNED]]
91 // CHECK-LONG-LABEL: define {{[^@]+}}@is_aligned
92 // CHECK-LONG-SAME: (i64 noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
93 // CHECK-LONG-NEXT: entry:
94 // CHECK-LONG-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
95 // CHECK-LONG-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
96 // CHECK-LONG-NEXT: [[SET_BITS:%.*]] = and i64 [[PTR:%.*]], [[MASK]]
97 // CHECK-LONG-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i64 [[SET_BITS]], 0
98 // CHECK-LONG-NEXT: ret i1 [[IS_ALIGNED]]
100 // CHECK-USHORT-LABEL: define {{[^@]+}}@is_aligned
101 // CHECK-USHORT-SAME: (i16 noundef zeroext [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
102 // CHECK-USHORT-NEXT: entry:
103 // CHECK-USHORT-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN:%.*]] to i16
104 // CHECK-USHORT-NEXT: [[MASK:%.*]] = sub i16 [[ALIGNMENT]], 1
105 // CHECK-USHORT-NEXT: [[SET_BITS:%.*]] = and i16 [[PTR:%.*]], [[MASK]]
106 // CHECK-USHORT-NEXT: [[IS_ALIGNED:%.*]] = icmp eq i16 [[SET_BITS]], 0
107 // CHECK-USHORT-NEXT: ret i1 [[IS_ALIGNED]]
109 _Bool is_aligned(TYPE ptr, unsigned align) {
110 return __builtin_is_aligned(ptr, align);
113 // NOTYET-POINTER-NEXT: [[ALIGNED_RESULT:%.*]] = call [[$TYPE]] @llvm.ptrmask.p0[[$PTRTYPE]].p0i8.i64(ptr [[OVER_BOUNDARY]], [[ALIGN_TYPE]] [[INVERTED_MASK]])
114 // CHECK-VOID_PTR-LABEL: define {{[^@]+}}@align_up
115 // CHECK-VOID_PTR-SAME: (ptr noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
116 // CHECK-VOID_PTR-NEXT: entry:
117 // CHECK-VOID_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
118 // CHECK-VOID_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
119 // CHECK-VOID_PTR-NEXT: [[OVER_BOUNDARY:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[MASK]]
120 // CHECK-VOID_PTR-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1
121 // CHECK-VOID_PTR-NEXT: [[ALIGNED_RESULT:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[OVER_BOUNDARY]], i64 [[INVERTED_MASK]])
122 // CHECK-VOID_PTR-NEXT: ret ptr [[ALIGNED_RESULT]]
124 // CHECK-FLOAT_PTR-LABEL: define {{[^@]+}}@align_up
125 // CHECK-FLOAT_PTR-SAME: (ptr noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
126 // CHECK-FLOAT_PTR-NEXT: entry:
127 // CHECK-FLOAT_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
128 // CHECK-FLOAT_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
129 // CHECK-FLOAT_PTR-NEXT: [[OVER_BOUNDARY:%.*]] = getelementptr inbounds i8, ptr [[PTR:%.*]], i64 [[MASK]]
130 // CHECK-FLOAT_PTR-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1
131 // CHECK-FLOAT_PTR-NEXT: [[ALIGNED_RESULT:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[OVER_BOUNDARY]], i64 [[INVERTED_MASK]])
132 // CHECK-FLOAT_PTR-NEXT: ret ptr [[ALIGNED_RESULT]]
134 // CHECK-LONG-LABEL: define {{[^@]+}}@align_up
135 // CHECK-LONG-SAME: (i64 noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
136 // CHECK-LONG-NEXT: entry:
137 // CHECK-LONG-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
138 // CHECK-LONG-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
139 // CHECK-LONG-NEXT: [[OVER_BOUNDARY:%.*]] = add i64 [[PTR:%.*]], [[MASK]]
140 // CHECK-LONG-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1
141 // CHECK-LONG-NEXT: [[ALIGNED_RESULT:%.*]] = and i64 [[OVER_BOUNDARY]], [[INVERTED_MASK]]
142 // CHECK-LONG-NEXT: ret i64 [[ALIGNED_RESULT]]
144 // CHECK-USHORT-LABEL: define {{[^@]+}}@align_up
145 // CHECK-USHORT-SAME: (i16 noundef zeroext [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
146 // CHECK-USHORT-NEXT: entry:
147 // CHECK-USHORT-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN:%.*]] to i16
148 // CHECK-USHORT-NEXT: [[MASK:%.*]] = sub i16 [[ALIGNMENT]], 1
149 // CHECK-USHORT-NEXT: [[OVER_BOUNDARY:%.*]] = add i16 [[PTR:%.*]], [[MASK]]
150 // CHECK-USHORT-NEXT: [[INVERTED_MASK:%.*]] = xor i16 [[MASK]], -1
151 // CHECK-USHORT-NEXT: [[ALIGNED_RESULT:%.*]] = and i16 [[OVER_BOUNDARY]], [[INVERTED_MASK]]
152 // CHECK-USHORT-NEXT: ret i16 [[ALIGNED_RESULT]]
154 TYPE align_up(TYPE ptr, unsigned align) {
155 return __builtin_align_up(ptr, align);
158 // NOTYET-POINTER-NEXT: [[ALIGNED_RESULT:%.*]] = call [[$TYPE]] @llvm.ptrmask.p0[[$PTRTYPE]].p0[[$PTRTYPE]].i64([[$TYPE]] [[PTR]], [[ALIGN_TYPE]] [[INVERTED_MASK]])
159 // CHECK-VOID_PTR-LABEL: define {{[^@]+}}@align_down
160 // CHECK-VOID_PTR-SAME: (ptr noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
161 // CHECK-VOID_PTR-NEXT: entry:
162 // CHECK-VOID_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
163 // CHECK-VOID_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
164 // CHECK-VOID_PTR-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1
165 // CHECK-VOID_PTR-NEXT: [[ALIGNED_RESULT:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 [[INVERTED_MASK]])
166 // CHECK-VOID_PTR-NEXT: ret ptr [[ALIGNED_RESULT]]
168 // CHECK-FLOAT_PTR-LABEL: define {{[^@]+}}@align_down
169 // CHECK-FLOAT_PTR-SAME: (ptr noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
170 // CHECK-FLOAT_PTR-NEXT: entry:
171 // CHECK-FLOAT_PTR-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
172 // CHECK-FLOAT_PTR-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
173 // CHECK-FLOAT_PTR-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1
174 // CHECK-FLOAT_PTR-NEXT: [[ALIGNED_RESULT:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PTR:%.*]], i64 [[INVERTED_MASK]])
175 // CHECK-FLOAT_PTR-NEXT: ret ptr [[ALIGNED_RESULT]]
177 // CHECK-LONG-LABEL: define {{[^@]+}}@align_down
178 // CHECK-LONG-SAME: (i64 noundef [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
179 // CHECK-LONG-NEXT: entry:
180 // CHECK-LONG-NEXT: [[ALIGNMENT:%.*]] = zext i32 [[ALIGN:%.*]] to i64
181 // CHECK-LONG-NEXT: [[MASK:%.*]] = sub i64 [[ALIGNMENT]], 1
182 // CHECK-LONG-NEXT: [[INVERTED_MASK:%.*]] = xor i64 [[MASK]], -1
183 // CHECK-LONG-NEXT: [[ALIGNED_RESULT:%.*]] = and i64 [[PTR:%.*]], [[INVERTED_MASK]]
184 // CHECK-LONG-NEXT: ret i64 [[ALIGNED_RESULT]]
186 // CHECK-USHORT-LABEL: define {{[^@]+}}@align_down
187 // CHECK-USHORT-SAME: (i16 noundef zeroext [[PTR:%.*]], i32 noundef [[ALIGN:%.*]]) #0
188 // CHECK-USHORT-NEXT: entry:
189 // CHECK-USHORT-NEXT: [[ALIGNMENT:%.*]] = trunc i32 [[ALIGN:%.*]] to i16
190 // CHECK-USHORT-NEXT: [[MASK:%.*]] = sub i16 [[ALIGNMENT]], 1
191 // CHECK-USHORT-NEXT: [[INVERTED_MASK:%.*]] = xor i16 [[MASK]], -1
192 // CHECK-USHORT-NEXT: [[ALIGNED_RESULT:%.*]] = and i16 [[PTR:%.*]], [[INVERTED_MASK]]
193 // CHECK-USHORT-NEXT: ret i16 [[ALIGNED_RESULT]]
195 TYPE align_down(TYPE ptr, unsigned align) {
196 return __builtin_align_down(ptr, align);