1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4 declare noalias ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc"
5 declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc"
6 declare noalias ptr @realloc(ptr nocapture, i64) allockind("realloc") allocsize(1) "alloc-family"="malloc"
7 declare noalias nonnull ptr @_Znam(i64) ; throwing version of 'new'
8 declare noalias nonnull ptr @_Znwm(i64) ; throwing version of 'new'
9 declare noalias ptr @strdup(ptr)
10 declare noalias ptr @aligned_alloc(i64 allocalign, i64) allockind("alloc,uninitialized,aligned") allocsize(1) "alloc-family"="malloc"
11 declare noalias align 16 ptr @memalign(i64 allocalign, i64) allocsize(1)
12 ; new[](unsigned int, align_val_t)
13 declare noalias ptr @_ZnamSt11align_val_t(i64 %size, i64 %align)
15 declare ptr @my_malloc(i64) allocsize(0)
16 declare ptr @my_calloc(i64, i64) allocsize(0, 1)
18 @.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
20 define noalias ptr @malloc_nonconstant_size(i64 %n) {
21 ; CHECK-LABEL: @malloc_nonconstant_size(
22 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 [[N:%.*]])
23 ; CHECK-NEXT: ret ptr [[CALL]]
25 %call = tail call noalias ptr @malloc(i64 %n)
29 define noalias ptr @malloc_constant_size() {
30 ; CHECK-LABEL: @malloc_constant_size(
31 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @malloc(i64 40)
32 ; CHECK-NEXT: ret ptr [[CALL]]
34 %call = tail call noalias ptr @malloc(i64 40)
38 define noalias ptr @aligned_alloc_constant_size() {
39 ; CHECK-LABEL: @aligned_alloc_constant_size(
40 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) ptr @aligned_alloc(i64 32, i64 512)
41 ; CHECK-NEXT: ret ptr [[CALL]]
43 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 512)
47 define noalias ptr @aligned_alloc_unknown_size_nonzero(i1 %c) {
48 ; CHECK-LABEL: @aligned_alloc_unknown_size_nonzero(
49 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 128
50 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE]])
51 ; CHECK-NEXT: ret ptr [[CALL]]
53 %size = select i1 %c, i64 64, i64 128
54 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)
58 define noalias ptr @aligned_alloc_unknown_size_possibly_zero(i1 %c) {
59 ; CHECK-LABEL: @aligned_alloc_unknown_size_possibly_zero(
60 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 0
61 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE]])
62 ; CHECK-NEXT: ret ptr [[CALL]]
64 %size = select i1 %c, i64 64, i64 0
65 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)
69 define noalias ptr @aligned_alloc_unknown_align(i64 %align) {
70 ; CHECK-LABEL: @aligned_alloc_unknown_align(
71 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @aligned_alloc(i64 [[ALIGN:%.*]], i64 128)
72 ; CHECK-NEXT: ret ptr [[CALL]]
74 %call = tail call noalias ptr @aligned_alloc(i64 %align, i64 128)
78 declare noalias ptr @foo(ptr, ptr, ptr)
80 define noalias ptr @aligned_alloc_dynamic_args(i64 %align, i64 %size) {
81 ; CHECK-LABEL: @aligned_alloc_dynamic_args(
82 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(1024) ptr @aligned_alloc(i64 [[ALIGN:%.*]], i64 1024)
83 ; CHECK-NEXT: [[CALL_1:%.*]] = tail call noalias dereferenceable_or_null(1024) ptr @aligned_alloc(i64 0, i64 1024)
84 ; CHECK-NEXT: [[CALL_2:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE:%.*]])
85 ; CHECK-NEXT: [[TMP1:%.*]] = call ptr @foo(ptr [[CALL]], ptr [[CALL_1]], ptr [[CALL_2]])
86 ; CHECK-NEXT: ret ptr [[CALL]]
88 %call = tail call noalias ptr @aligned_alloc(i64 %align, i64 1024)
89 %call_1 = tail call noalias ptr @aligned_alloc(i64 0, i64 1024)
90 %call_2 = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)
92 call ptr @foo(ptr %call, ptr %call_1, ptr %call_2)
96 define noalias ptr @memalign_constant_size() {
97 ; CHECK-LABEL: @memalign_constant_size(
98 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) ptr @memalign(i64 32, i64 512)
99 ; CHECK-NEXT: ret ptr [[CALL]]
101 %call = tail call noalias ptr @memalign(i64 32, i64 512)
105 define noalias ptr @memalign_unknown_size_nonzero(i1 %c) {
106 ; CHECK-LABEL: @memalign_unknown_size_nonzero(
107 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 128
108 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @memalign(i64 32, i64 [[SIZE]])
109 ; CHECK-NEXT: ret ptr [[CALL]]
111 %size = select i1 %c, i64 64, i64 128
112 %call = tail call noalias ptr @memalign(i64 32, i64 %size)
116 define noalias ptr @memalign_unknown_size_possibly_zero(i1 %c) {
117 ; CHECK-LABEL: @memalign_unknown_size_possibly_zero(
118 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 0
119 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @memalign(i64 32, i64 [[SIZE]])
120 ; CHECK-NEXT: ret ptr [[CALL]]
122 %size = select i1 %c, i64 64, i64 0
123 %call = tail call noalias ptr @memalign(i64 32, i64 %size)
127 define noalias ptr @memalign_unknown_align(i64 %align) {
128 ; CHECK-LABEL: @memalign_unknown_align(
129 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @memalign(i64 [[ALIGN:%.*]], i64 128)
130 ; CHECK-NEXT: ret ptr [[CALL]]
132 %call = tail call noalias ptr @memalign(i64 %align, i64 128)
136 define noalias ptr @malloc_constant_size2() {
137 ; CHECK-LABEL: @malloc_constant_size2(
138 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @malloc(i64 40)
139 ; CHECK-NEXT: ret ptr [[CALL]]
141 %call = tail call noalias dereferenceable_or_null(80) ptr @malloc(i64 40)
145 define noalias ptr @malloc_constant_size3() {
146 ; CHECK-LABEL: @malloc_constant_size3(
147 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable(80) dereferenceable_or_null(40) ptr @malloc(i64 40)
148 ; CHECK-NEXT: ret ptr [[CALL]]
150 %call = tail call noalias dereferenceable(80) ptr @malloc(i64 40)
154 define noalias ptr @malloc_constant_zero_size() {
155 ; CHECK-LABEL: @malloc_constant_zero_size(
156 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 0)
157 ; CHECK-NEXT: ret ptr [[CALL]]
159 %call = tail call noalias ptr @malloc(i64 0)
163 define noalias ptr @realloc_nonconstant_size(ptr %p, i64 %n) {
164 ; CHECK-LABEL: @realloc_nonconstant_size(
165 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @realloc(ptr [[P:%.*]], i64 [[N:%.*]])
166 ; CHECK-NEXT: ret ptr [[CALL]]
168 %call = tail call noalias ptr @realloc(ptr %p, i64 %n)
172 define noalias ptr @realloc_constant_zero_size(ptr %p) {
173 ; CHECK-LABEL: @realloc_constant_zero_size(
174 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @realloc(ptr [[P:%.*]], i64 0)
175 ; CHECK-NEXT: ret ptr [[CALL]]
177 %call = tail call noalias ptr @realloc(ptr %p, i64 0)
181 define noalias ptr @realloc_constant_size(ptr %p) {
182 ; CHECK-LABEL: @realloc_constant_size(
183 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @realloc(ptr [[P:%.*]], i64 40)
184 ; CHECK-NEXT: ret ptr [[CALL]]
186 %call = tail call noalias ptr @realloc(ptr %p, i64 40)
190 define noalias ptr @calloc_nonconstant_size(i64 %n) {
191 ; CHECK-LABEL: @calloc_nonconstant_size(
192 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 1, i64 [[N:%.*]])
193 ; CHECK-NEXT: ret ptr [[CALL]]
195 %call = tail call noalias ptr @calloc(i64 1, i64 %n)
199 define noalias ptr @calloc_nonconstant_size2(i64 %n) {
200 ; CHECK-LABEL: @calloc_nonconstant_size2(
201 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 0)
202 ; CHECK-NEXT: ret ptr [[CALL]]
204 %call = tail call noalias ptr @calloc(i64 %n, i64 0)
208 define noalias ptr @calloc_nonconstant_size3(i64 %n) {
209 ; CHECK-LABEL: @calloc_nonconstant_size3(
210 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 [[N]])
211 ; CHECK-NEXT: ret ptr [[CALL]]
213 %call = tail call noalias ptr @calloc(i64 %n, i64 %n)
217 define noalias ptr @calloc_constant_zero_size() {
218 ; CHECK-LABEL: @calloc_constant_zero_size(
219 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 0)
220 ; CHECK-NEXT: ret ptr [[CALL]]
222 %call = tail call noalias ptr @calloc(i64 0, i64 0)
226 define noalias ptr @calloc_constant_zero_size2(i64 %n) {
227 ; CHECK-LABEL: @calloc_constant_zero_size2(
228 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 0)
229 ; CHECK-NEXT: ret ptr [[CALL]]
231 %call = tail call noalias ptr @calloc(i64 %n, i64 0)
236 define noalias ptr @calloc_constant_zero_size3(i64 %n) {
237 ; CHECK-LABEL: @calloc_constant_zero_size3(
238 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 [[N:%.*]])
239 ; CHECK-NEXT: ret ptr [[CALL]]
241 %call = tail call noalias ptr @calloc(i64 0, i64 %n)
245 define noalias ptr @calloc_constant_zero_size4(i64 %n) {
246 ; CHECK-LABEL: @calloc_constant_zero_size4(
247 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 1)
248 ; CHECK-NEXT: ret ptr [[CALL]]
250 %call = tail call noalias ptr @calloc(i64 0, i64 1)
254 define noalias ptr @calloc_constant_zero_size5(i64 %n) {
255 ; CHECK-LABEL: @calloc_constant_zero_size5(
256 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 1, i64 0)
257 ; CHECK-NEXT: ret ptr [[CALL]]
259 %call = tail call noalias ptr @calloc(i64 1, i64 0)
263 define noalias ptr @calloc_constant_size() {
264 ; CHECK-LABEL: @calloc_constant_size(
265 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @calloc(i64 16, i64 8)
266 ; CHECK-NEXT: ret ptr [[CALL]]
268 %call = tail call noalias ptr @calloc(i64 16, i64 8)
272 define noalias ptr @calloc_constant_size_overflow() {
273 ; CHECK-LABEL: @calloc_constant_size_overflow(
274 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 2000000000000, i64 80000000000)
275 ; CHECK-NEXT: ret ptr [[CALL]]
277 %call = tail call noalias ptr @calloc(i64 2000000000000, i64 80000000000)
281 define noalias ptr @op_new_nonconstant_size(i64 %n) {
282 ; CHECK-LABEL: @op_new_nonconstant_size(
283 ; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @_Znam(i64 [[N:%.*]])
284 ; CHECK-NEXT: ret ptr [[CALL]]
286 %call = tail call ptr @_Znam(i64 %n)
290 define noalias ptr @op_new_constant_size() {
291 ; CHECK-LABEL: @op_new_constant_size(
292 ; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable(40) ptr @_Znam(i64 40)
293 ; CHECK-NEXT: ret ptr [[CALL]]
295 %call = tail call ptr @_Znam(i64 40)
299 define noalias ptr @op_new_constant_size2() {
300 ; CHECK-LABEL: @op_new_constant_size2(
301 ; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable(40) ptr @_Znwm(i64 40)
302 ; CHECK-NEXT: ret ptr [[CALL]]
304 %call = tail call ptr @_Znwm(i64 40)
308 define noalias ptr @op_new_constant_zero_size() {
309 ; CHECK-LABEL: @op_new_constant_zero_size(
310 ; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @_Znam(i64 0)
311 ; CHECK-NEXT: ret ptr [[CALL]]
313 %call = tail call ptr @_Znam(i64 0)
317 define noalias ptr @strdup_constant_str() {
318 ; CHECK-LABEL: @strdup_constant_str(
319 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(6) ptr @strdup(ptr nonnull @.str)
320 ; CHECK-NEXT: ret ptr [[CALL]]
322 %call = tail call noalias ptr @strdup(ptr @.str)
326 define noalias ptr @strdup_notconstant_str(ptr %str) {
327 ; CHECK-LABEL: @strdup_notconstant_str(
328 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @strdup(ptr [[STR:%.*]])
329 ; CHECK-NEXT: ret ptr [[CALL]]
331 %call = tail call noalias ptr @strdup(ptr %str)
336 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23214
337 define noalias ptr @ossfuzz_23214() {
338 ; CHECK-LABEL: @ossfuzz_23214(
340 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(512) ptr @aligned_alloc(i64 -9223372036854775808, i64 512)
341 ; CHECK-NEXT: ret ptr [[CALL]]
344 %and = and i64 -1, -9223372036854775808
345 %call = tail call noalias ptr @aligned_alloc(i64 %and, i64 512)
349 define noalias ptr @op_new_align() {
350 ; CHECK-LABEL: @op_new_align(
351 ; CHECK-NEXT: [[CALL:%.*]] = tail call align 32 dereferenceable_or_null(32) ptr @_ZnamSt11align_val_t(i64 32, i64 32)
352 ; CHECK-NEXT: ret ptr [[CALL]]
354 %call = tail call ptr @_ZnamSt11align_val_t(i64 32, i64 32)
358 define ptr @my_malloc_constant_size() {
359 ; CHECK-LABEL: @my_malloc_constant_size(
360 ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(32) ptr @my_malloc(i64 32)
361 ; CHECK-NEXT: ret ptr [[CALL]]
363 %call = call ptr @my_malloc(i64 32)
367 define ptr @my_calloc_constant_size() {
368 ; CHECK-LABEL: @my_calloc_constant_size(
369 ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(128) ptr @my_calloc(i64 32, i64 4)
370 ; CHECK-NEXT: ret ptr [[CALL]]
372 %call = call ptr @my_calloc(i64 32, i64 4)
376 define ptr @virtual_constant_size(ptr %alloc) {
377 ; CHECK-LABEL: @virtual_constant_size(
378 ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(16) ptr [[ALLOC:%.*]](i64 16) #[[ATTR5:[0-9]+]]
379 ; CHECK-NEXT: ret ptr [[CALL]]
381 %call = call ptr %alloc(i64 16) allocsize(0)