1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
3 ; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,GNU
6 declare noalias ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc"
7 declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc"
8 declare noalias ptr @realloc(ptr nocapture, i64) allockind("realloc") allocsize(1) "alloc-family"="malloc"
9 declare noalias nonnull ptr @_Znam(i64) ; throwing version of 'new'
10 declare noalias nonnull ptr @_Znwm(i64) ; throwing version of 'new'
11 declare noalias ptr @strdup(ptr)
12 declare noalias ptr @aligned_alloc(i64 allocalign, i64) allockind("alloc,uninitialized,aligned") allocsize(1) "alloc-family"="malloc"
13 declare noalias align 16 ptr @memalign(i64 allocalign, i64) allocsize(1)
14 ; new[](unsigned int, align_val_t)
15 declare noalias ptr @_ZnamSt11align_val_t(i64 %size, i64 %align)
17 declare ptr @my_malloc(i64) allocsize(0)
18 declare ptr @my_calloc(i64, i64) allocsize(0, 1)
20 @.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
22 define noalias ptr @malloc_nonconstant_size(i64 %n) {
23 ; CHECK-LABEL: @malloc_nonconstant_size(
24 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 [[N:%.*]])
25 ; CHECK-NEXT: ret ptr [[CALL]]
27 %call = tail call noalias ptr @malloc(i64 %n)
31 define noalias ptr @malloc_constant_size() {
32 ; CHECK-LABEL: @malloc_constant_size(
33 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @malloc(i64 40)
34 ; CHECK-NEXT: ret ptr [[CALL]]
36 %call = tail call noalias ptr @malloc(i64 40)
40 define noalias ptr @aligned_alloc_constant_size() {
41 ; CHECK-LABEL: @aligned_alloc_constant_size(
42 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) ptr @aligned_alloc(i64 32, i64 512)
43 ; CHECK-NEXT: ret ptr [[CALL]]
45 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 512)
49 define noalias ptr @aligned_alloc_unknown_size_nonzero(i1 %c) {
50 ; CHECK-LABEL: @aligned_alloc_unknown_size_nonzero(
51 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 128
52 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE]])
53 ; CHECK-NEXT: ret ptr [[CALL]]
55 %size = select i1 %c, i64 64, i64 128
56 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)
60 define noalias ptr @aligned_alloc_unknown_size_possibly_zero(i1 %c) {
61 ; CHECK-LABEL: @aligned_alloc_unknown_size_possibly_zero(
62 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 0
63 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE]])
64 ; CHECK-NEXT: ret ptr [[CALL]]
66 %size = select i1 %c, i64 64, i64 0
67 %call = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)
71 define noalias ptr @aligned_alloc_unknown_align(i64 %align) {
72 ; CHECK-LABEL: @aligned_alloc_unknown_align(
73 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @aligned_alloc(i64 [[ALIGN:%.*]], i64 128)
74 ; CHECK-NEXT: ret ptr [[CALL]]
76 %call = tail call noalias ptr @aligned_alloc(i64 %align, i64 128)
80 declare noalias ptr @foo(ptr, ptr, ptr)
82 define noalias ptr @aligned_alloc_dynamic_args(i64 %align, i64 %size) {
83 ; CHECK-LABEL: @aligned_alloc_dynamic_args(
84 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(1024) ptr @aligned_alloc(i64 [[ALIGN:%.*]], i64 1024)
85 ; CHECK-NEXT: [[CALL_1:%.*]] = tail call noalias dereferenceable_or_null(1024) ptr @aligned_alloc(i64 0, i64 1024)
86 ; CHECK-NEXT: [[CALL_2:%.*]] = tail call noalias align 32 ptr @aligned_alloc(i64 32, i64 [[SIZE:%.*]])
87 ; CHECK-NEXT: [[TMP1:%.*]] = call ptr @foo(ptr [[CALL]], ptr [[CALL_1]], ptr [[CALL_2]])
88 ; CHECK-NEXT: ret ptr [[CALL]]
90 %call = tail call noalias ptr @aligned_alloc(i64 %align, i64 1024)
91 %call_1 = tail call noalias ptr @aligned_alloc(i64 0, i64 1024)
92 %call_2 = tail call noalias ptr @aligned_alloc(i64 32, i64 %size)
94 call ptr @foo(ptr %call, ptr %call_1, ptr %call_2)
98 define noalias ptr @memalign_constant_size() {
99 ; GNU-LABEL: @memalign_constant_size(
100 ; GNU-NEXT: [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) ptr @memalign(i64 32, i64 512)
101 ; GNU-NEXT: ret ptr [[CALL]]
103 %call = tail call noalias ptr @memalign(i64 32, i64 512)
107 define noalias ptr @memalign_unknown_size_nonzero(i1 %c) {
108 ; GNU-LABEL: @memalign_unknown_size_nonzero(
109 ; GNU-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 128
110 ; GNU-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @memalign(i64 32, i64 [[SIZE]])
111 ; GNU-NEXT: ret ptr [[CALL]]
113 %size = select i1 %c, i64 64, i64 128
114 %call = tail call noalias ptr @memalign(i64 32, i64 %size)
118 define noalias ptr @memalign_unknown_size_possibly_zero(i1 %c) {
119 ; GNU-LABEL: @memalign_unknown_size_possibly_zero(
120 ; GNU-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 0
121 ; GNU-NEXT: [[CALL:%.*]] = tail call noalias align 32 ptr @memalign(i64 32, i64 [[SIZE]])
122 ; GNU-NEXT: ret ptr [[CALL]]
124 %size = select i1 %c, i64 64, i64 0
125 %call = tail call noalias ptr @memalign(i64 32, i64 %size)
129 define noalias ptr @memalign_unknown_align(i64 %align) {
130 ; GNU-LABEL: @memalign_unknown_align(
131 ; GNU-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @memalign(i64 [[ALIGN:%.*]], i64 128)
132 ; GNU-NEXT: ret ptr [[CALL]]
134 %call = tail call noalias ptr @memalign(i64 %align, i64 128)
138 define noalias ptr @malloc_constant_size2() {
139 ; CHECK-LABEL: @malloc_constant_size2(
140 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @malloc(i64 40)
141 ; CHECK-NEXT: ret ptr [[CALL]]
143 %call = tail call noalias dereferenceable_or_null(80) ptr @malloc(i64 40)
147 define noalias ptr @malloc_constant_size3() {
148 ; CHECK-LABEL: @malloc_constant_size3(
149 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable(80) dereferenceable_or_null(40) ptr @malloc(i64 40)
150 ; CHECK-NEXT: ret ptr [[CALL]]
152 %call = tail call noalias dereferenceable(80) ptr @malloc(i64 40)
156 define noalias ptr @malloc_constant_zero_size() {
157 ; CHECK-LABEL: @malloc_constant_zero_size(
158 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @malloc(i64 0)
159 ; CHECK-NEXT: ret ptr [[CALL]]
161 %call = tail call noalias ptr @malloc(i64 0)
165 define noalias ptr @realloc_nonconstant_size(ptr %p, i64 %n) {
166 ; CHECK-LABEL: @realloc_nonconstant_size(
167 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @realloc(ptr [[P:%.*]], i64 [[N:%.*]])
168 ; CHECK-NEXT: ret ptr [[CALL]]
170 %call = tail call noalias ptr @realloc(ptr %p, i64 %n)
174 define noalias ptr @realloc_constant_zero_size(ptr %p) {
175 ; CHECK-LABEL: @realloc_constant_zero_size(
176 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @realloc(ptr [[P:%.*]], i64 0)
177 ; CHECK-NEXT: ret ptr [[CALL]]
179 %call = tail call noalias ptr @realloc(ptr %p, i64 0)
183 define noalias ptr @realloc_constant_size(ptr %p) {
184 ; CHECK-LABEL: @realloc_constant_size(
185 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) ptr @realloc(ptr [[P:%.*]], i64 40)
186 ; CHECK-NEXT: ret ptr [[CALL]]
188 %call = tail call noalias ptr @realloc(ptr %p, i64 40)
192 define noalias ptr @calloc_nonconstant_size(i64 %n) {
193 ; CHECK-LABEL: @calloc_nonconstant_size(
194 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 1, i64 [[N:%.*]])
195 ; CHECK-NEXT: ret ptr [[CALL]]
197 %call = tail call noalias ptr @calloc(i64 1, i64 %n)
201 define noalias ptr @calloc_nonconstant_size2(i64 %n) {
202 ; CHECK-LABEL: @calloc_nonconstant_size2(
203 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 0)
204 ; CHECK-NEXT: ret ptr [[CALL]]
206 %call = tail call noalias ptr @calloc(i64 %n, i64 0)
210 define noalias ptr @calloc_nonconstant_size3(i64 %n) {
211 ; CHECK-LABEL: @calloc_nonconstant_size3(
212 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 [[N]])
213 ; CHECK-NEXT: ret ptr [[CALL]]
215 %call = tail call noalias ptr @calloc(i64 %n, i64 %n)
219 define noalias ptr @calloc_constant_zero_size() {
220 ; CHECK-LABEL: @calloc_constant_zero_size(
221 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 0)
222 ; CHECK-NEXT: ret ptr [[CALL]]
224 %call = tail call noalias ptr @calloc(i64 0, i64 0)
228 define noalias ptr @calloc_constant_zero_size2(i64 %n) {
229 ; CHECK-LABEL: @calloc_constant_zero_size2(
230 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 [[N:%.*]], i64 0)
231 ; CHECK-NEXT: ret ptr [[CALL]]
233 %call = tail call noalias ptr @calloc(i64 %n, i64 0)
238 define noalias ptr @calloc_constant_zero_size3(i64 %n) {
239 ; CHECK-LABEL: @calloc_constant_zero_size3(
240 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 [[N:%.*]])
241 ; CHECK-NEXT: ret ptr [[CALL]]
243 %call = tail call noalias ptr @calloc(i64 0, i64 %n)
247 define noalias ptr @calloc_constant_zero_size4(i64 %n) {
248 ; CHECK-LABEL: @calloc_constant_zero_size4(
249 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 0, i64 1)
250 ; CHECK-NEXT: ret ptr [[CALL]]
252 %call = tail call noalias ptr @calloc(i64 0, i64 1)
256 define noalias ptr @calloc_constant_zero_size5(i64 %n) {
257 ; CHECK-LABEL: @calloc_constant_zero_size5(
258 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 1, i64 0)
259 ; CHECK-NEXT: ret ptr [[CALL]]
261 %call = tail call noalias ptr @calloc(i64 1, i64 0)
265 define noalias ptr @calloc_constant_size() {
266 ; CHECK-LABEL: @calloc_constant_size(
267 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) ptr @calloc(i64 16, i64 8)
268 ; CHECK-NEXT: ret ptr [[CALL]]
270 %call = tail call noalias ptr @calloc(i64 16, i64 8)
274 define noalias ptr @calloc_constant_size_overflow() {
275 ; CHECK-LABEL: @calloc_constant_size_overflow(
276 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @calloc(i64 2000000000000, i64 80000000000)
277 ; CHECK-NEXT: ret ptr [[CALL]]
279 %call = tail call noalias ptr @calloc(i64 2000000000000, i64 80000000000)
283 define noalias ptr @op_new_nonconstant_size(i64 %n) {
284 ; CHECK-LABEL: @op_new_nonconstant_size(
285 ; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @_Znam(i64 [[N:%.*]])
286 ; CHECK-NEXT: ret ptr [[CALL]]
288 %call = tail call ptr @_Znam(i64 %n)
292 define noalias ptr @op_new_constant_size() {
293 ; CHECK-LABEL: @op_new_constant_size(
294 ; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable(40) ptr @_Znam(i64 40)
295 ; CHECK-NEXT: ret ptr [[CALL]]
297 %call = tail call ptr @_Znam(i64 40)
301 define noalias ptr @op_new_constant_size2() {
302 ; CHECK-LABEL: @op_new_constant_size2(
303 ; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable(40) ptr @_Znwm(i64 40)
304 ; CHECK-NEXT: ret ptr [[CALL]]
306 %call = tail call ptr @_Znwm(i64 40)
310 define noalias ptr @op_new_constant_zero_size() {
311 ; CHECK-LABEL: @op_new_constant_zero_size(
312 ; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @_Znam(i64 0)
313 ; CHECK-NEXT: ret ptr [[CALL]]
315 %call = tail call ptr @_Znam(i64 0)
319 define noalias ptr @strdup_constant_str() {
320 ; CHECK-LABEL: @strdup_constant_str(
321 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(6) ptr @strdup(ptr nonnull @.str)
322 ; CHECK-NEXT: ret ptr [[CALL]]
324 %call = tail call noalias ptr @strdup(ptr @.str)
328 define noalias ptr @strdup_notconstant_str(ptr %str) {
329 ; CHECK-LABEL: @strdup_notconstant_str(
330 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @strdup(ptr [[STR:%.*]])
331 ; CHECK-NEXT: ret ptr [[CALL]]
333 %call = tail call noalias ptr @strdup(ptr %str)
338 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23214
339 define noalias ptr @ossfuzz_23214() {
340 ; CHECK-LABEL: @ossfuzz_23214(
342 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(512) ptr @aligned_alloc(i64 -9223372036854775808, i64 512)
343 ; CHECK-NEXT: ret ptr [[CALL]]
346 %and = and i64 -1, -9223372036854775808
347 %call = tail call noalias ptr @aligned_alloc(i64 %and, i64 512)
351 define noalias ptr @op_new_align() {
352 ; CHECK-LABEL: @op_new_align(
353 ; CHECK-NEXT: [[CALL:%.*]] = tail call align 32 dereferenceable_or_null(32) ptr @_ZnamSt11align_val_t(i64 32, i64 32)
354 ; CHECK-NEXT: ret ptr [[CALL]]
356 %call = tail call ptr @_ZnamSt11align_val_t(i64 32, i64 32)
360 define ptr @my_malloc_constant_size() {
361 ; CHECK-LABEL: @my_malloc_constant_size(
362 ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(32) ptr @my_malloc(i64 32)
363 ; CHECK-NEXT: ret ptr [[CALL]]
365 %call = call ptr @my_malloc(i64 32)
369 define ptr @my_calloc_constant_size() {
370 ; CHECK-LABEL: @my_calloc_constant_size(
371 ; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(128) ptr @my_calloc(i64 32, i64 4)
372 ; CHECK-NEXT: ret ptr [[CALL]]
374 %call = call ptr @my_calloc(i64 32, i64 4)