1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -instcombine -S < %s | FileCheck %s
3 ; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -instcombine -S | FileCheck %s --check-prefixes=CHECK,GNU
6 declare noalias i8* @malloc(i64)
7 declare noalias i8* @calloc(i64, i64)
8 declare noalias i8* @realloc(i8* nocapture, i64)
9 declare noalias nonnull i8* @_Znam(i64) ; throwing version of 'new'
10 declare noalias nonnull i8* @_Znwm(i64) ; throwing version of 'new'
11 declare noalias i8* @strdup(i8*)
12 declare noalias i8* @aligned_alloc(i64, i64)
13 declare noalias align 16 i8* @memalign(i64, i64)
15 @.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
17 define noalias i8* @malloc_nonconstant_size(i64 %n) {
18 ; CHECK-LABEL: @malloc_nonconstant_size(
19 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @malloc(i64 [[N:%.*]])
20 ; CHECK-NEXT: ret i8* [[CALL]]
22 %call = tail call noalias i8* @malloc(i64 %n)
26 define noalias i8* @malloc_constant_size() {
27 ; CHECK-LABEL: @malloc_constant_size(
28 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) i8* @malloc(i64 40)
29 ; CHECK-NEXT: ret i8* [[CALL]]
31 %call = tail call noalias i8* @malloc(i64 40)
35 define noalias i8* @aligned_alloc_constant_size() {
36 ; CHECK-LABEL: @aligned_alloc_constant_size(
37 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) i8* @aligned_alloc(i64 32, i64 512)
38 ; CHECK-NEXT: ret i8* [[CALL]]
40 %call = tail call noalias i8* @aligned_alloc(i64 32, i64 512)
44 define noalias i8* @aligned_alloc_unknown_size_nonzero(i1 %c) {
45 ; CHECK-LABEL: @aligned_alloc_unknown_size_nonzero(
46 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 128
47 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias align 32 i8* @aligned_alloc(i64 32, i64 [[SIZE]])
48 ; CHECK-NEXT: ret i8* [[CALL]]
50 %size = select i1 %c, i64 64, i64 128
51 %call = tail call noalias i8* @aligned_alloc(i64 32, i64 %size)
55 define noalias i8* @aligned_alloc_unknown_size_possibly_zero(i1 %c) {
56 ; CHECK-LABEL: @aligned_alloc_unknown_size_possibly_zero(
57 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 0
58 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @aligned_alloc(i64 32, i64 [[SIZE]])
59 ; CHECK-NEXT: ret i8* [[CALL]]
61 %size = select i1 %c, i64 64, i64 0
62 %call = tail call noalias i8* @aligned_alloc(i64 32, i64 %size)
66 define noalias i8* @aligned_alloc_unknown_align(i64 %align) {
67 ; CHECK-LABEL: @aligned_alloc_unknown_align(
68 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) i8* @aligned_alloc(i64 [[ALIGN:%.*]], i64 128)
69 ; CHECK-NEXT: ret i8* [[CALL]]
71 %call = tail call noalias i8* @aligned_alloc(i64 %align, i64 128)
75 declare noalias i8* @foo(i8*, i8*, i8*)
77 define noalias i8* @aligned_alloc_dynamic_args(i64 %align, i64 %size) {
78 ; CHECK-LABEL: @aligned_alloc_dynamic_args(
79 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(1024) i8* @aligned_alloc(i64 [[ALIGN:%.*]], i64 1024)
80 ; CHECK-NEXT: [[CALL_1:%.*]] = tail call noalias i8* @aligned_alloc(i64 0, i64 1024)
81 ; CHECK-NEXT: [[CALL_2:%.*]] = tail call noalias i8* @aligned_alloc(i64 32, i64 [[SIZE:%.*]])
82 ; CHECK-NEXT: [[TMP1:%.*]] = call i8* @foo(i8* [[CALL]], i8* [[CALL_1]], i8* [[CALL_2]])
83 ; CHECK-NEXT: ret i8* [[CALL]]
85 %call = tail call noalias i8* @aligned_alloc(i64 %align, i64 1024)
86 %call_1 = tail call noalias i8* @aligned_alloc(i64 0, i64 1024)
87 %call_2 = tail call noalias i8* @aligned_alloc(i64 32, i64 %size)
89 call i8* @foo(i8* %call, i8* %call_1, i8* %call_2)
93 define noalias i8* @memalign_constant_size() {
94 ; GNU-LABEL: @memalign_constant_size(
95 ; GNU-NEXT: [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) i8* @memalign(i64 32, i64 512)
96 ; GNU-NEXT: ret i8* [[CALL]]
98 %call = tail call noalias i8* @memalign(i64 32, i64 512)
102 define noalias i8* @memalign_unknown_size_nonzero(i1 %c) {
103 ; GNU-LABEL: @memalign_unknown_size_nonzero(
104 ; GNU-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 128
105 ; GNU-NEXT: [[CALL:%.*]] = tail call noalias align 32 i8* @memalign(i64 32, i64 [[SIZE]])
106 ; GNU-NEXT: ret i8* [[CALL]]
108 %size = select i1 %c, i64 64, i64 128
109 %call = tail call noalias i8* @memalign(i64 32, i64 %size)
113 define noalias i8* @memalign_unknown_size_possibly_zero(i1 %c) {
114 ; CHECK-LABEL: @memalign_unknown_size_possibly_zero(
115 ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[C:%.*]], i64 64, i64 0
116 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @memalign(i64 32, i64 [[SIZE]])
117 ; CHECK-NEXT: ret i8* [[CALL]]
119 %size = select i1 %c, i64 64, i64 0
120 %call = tail call noalias i8* @memalign(i64 32, i64 %size)
124 define noalias i8* @memalign_unknown_align(i64 %align) {
125 ; GNU-LABEL: @memalign_unknown_align(
126 ; GNU-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) i8* @memalign(i64 [[ALIGN:%.*]], i64 128)
127 ; GNU-NEXT: ret i8* [[CALL]]
129 %call = tail call noalias i8* @memalign(i64 %align, i64 128)
133 define noalias i8* @malloc_constant_size2() {
134 ; CHECK-LABEL: @malloc_constant_size2(
135 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(80) i8* @malloc(i64 40)
136 ; CHECK-NEXT: ret i8* [[CALL]]
138 %call = tail call noalias dereferenceable_or_null(80) i8* @malloc(i64 40)
142 define noalias i8* @malloc_constant_size3() {
143 ; CHECK-LABEL: @malloc_constant_size3(
144 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable(80) dereferenceable_or_null(40) i8* @malloc(i64 40)
145 ; CHECK-NEXT: ret i8* [[CALL]]
147 %call = tail call noalias dereferenceable(80) i8* @malloc(i64 40)
151 define noalias i8* @malloc_constant_zero_size() {
152 ; CHECK-LABEL: @malloc_constant_zero_size(
153 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @malloc(i64 0)
154 ; CHECK-NEXT: ret i8* [[CALL]]
156 %call = tail call noalias i8* @malloc(i64 0)
160 define noalias i8* @realloc_nonconstant_size(i8* %p, i64 %n) {
161 ; CHECK-LABEL: @realloc_nonconstant_size(
162 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @realloc(i8* [[P:%.*]], i64 [[N:%.*]])
163 ; CHECK-NEXT: ret i8* [[CALL]]
165 %call = tail call noalias i8* @realloc(i8* %p, i64 %n)
169 define noalias i8* @realloc_constant_zero_size(i8* %p) {
170 ; CHECK-LABEL: @realloc_constant_zero_size(
171 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @realloc(i8* [[P:%.*]], i64 0)
172 ; CHECK-NEXT: ret i8* [[CALL]]
174 %call = tail call noalias i8* @realloc(i8* %p, i64 0)
178 define noalias i8* @realloc_constant_size(i8* %p) {
179 ; CHECK-LABEL: @realloc_constant_size(
180 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) i8* @realloc(i8* [[P:%.*]], i64 40)
181 ; CHECK-NEXT: ret i8* [[CALL]]
183 %call = tail call noalias i8* @realloc(i8* %p, i64 40)
187 define noalias i8* @calloc_nonconstant_size(i64 %n) {
188 ; CHECK-LABEL: @calloc_nonconstant_size(
189 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 1, i64 [[N:%.*]])
190 ; CHECK-NEXT: ret i8* [[CALL]]
192 %call = tail call noalias i8* @calloc(i64 1, i64 %n)
196 define noalias i8* @calloc_nonconstant_size2(i64 %n) {
197 ; CHECK-LABEL: @calloc_nonconstant_size2(
198 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 [[N:%.*]], i64 0)
199 ; CHECK-NEXT: ret i8* [[CALL]]
201 %call = tail call noalias i8* @calloc(i64 %n, i64 0)
205 define noalias i8* @calloc_nonconstant_size3(i64 %n) {
206 ; CHECK-LABEL: @calloc_nonconstant_size3(
207 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 [[N:%.*]], i64 [[N]])
208 ; CHECK-NEXT: ret i8* [[CALL]]
210 %call = tail call noalias i8* @calloc(i64 %n, i64 %n)
214 define noalias i8* @calloc_constant_zero_size() {
215 ; CHECK-LABEL: @calloc_constant_zero_size(
216 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 0, i64 0)
217 ; CHECK-NEXT: ret i8* [[CALL]]
219 %call = tail call noalias i8* @calloc(i64 0, i64 0)
223 define noalias i8* @calloc_constant_zero_size2(i64 %n) {
224 ; CHECK-LABEL: @calloc_constant_zero_size2(
225 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 [[N:%.*]], i64 0)
226 ; CHECK-NEXT: ret i8* [[CALL]]
228 %call = tail call noalias i8* @calloc(i64 %n, i64 0)
233 define noalias i8* @calloc_constant_zero_size3(i64 %n) {
234 ; CHECK-LABEL: @calloc_constant_zero_size3(
235 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 0, i64 [[N:%.*]])
236 ; CHECK-NEXT: ret i8* [[CALL]]
238 %call = tail call noalias i8* @calloc(i64 0, i64 %n)
242 define noalias i8* @calloc_constant_zero_size4(i64 %n) {
243 ; CHECK-LABEL: @calloc_constant_zero_size4(
244 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 0, i64 1)
245 ; CHECK-NEXT: ret i8* [[CALL]]
247 %call = tail call noalias i8* @calloc(i64 0, i64 1)
251 define noalias i8* @calloc_constant_zero_size5(i64 %n) {
252 ; CHECK-LABEL: @calloc_constant_zero_size5(
253 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 1, i64 0)
254 ; CHECK-NEXT: ret i8* [[CALL]]
256 %call = tail call noalias i8* @calloc(i64 1, i64 0)
260 define noalias i8* @calloc_constant_size() {
261 ; CHECK-LABEL: @calloc_constant_size(
262 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) i8* @calloc(i64 16, i64 8)
263 ; CHECK-NEXT: ret i8* [[CALL]]
265 %call = tail call noalias i8* @calloc(i64 16, i64 8)
269 define noalias i8* @calloc_constant_size_overflow() {
270 ; CHECK-LABEL: @calloc_constant_size_overflow(
271 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @calloc(i64 2000000000000, i64 80000000000)
272 ; CHECK-NEXT: ret i8* [[CALL]]
274 %call = tail call noalias i8* @calloc(i64 2000000000000, i64 80000000000)
278 define noalias i8* @op_new_nonconstant_size(i64 %n) {
279 ; CHECK-LABEL: @op_new_nonconstant_size(
280 ; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @_Znam(i64 [[N:%.*]])
281 ; CHECK-NEXT: ret i8* [[CALL]]
283 %call = tail call i8* @_Znam(i64 %n)
287 define noalias i8* @op_new_constant_size() {
288 ; CHECK-LABEL: @op_new_constant_size(
289 ; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable(40) i8* @_Znam(i64 40)
290 ; CHECK-NEXT: ret i8* [[CALL]]
292 %call = tail call i8* @_Znam(i64 40)
296 define noalias i8* @op_new_constant_size2() {
297 ; CHECK-LABEL: @op_new_constant_size2(
298 ; CHECK-NEXT: [[CALL:%.*]] = tail call dereferenceable(40) i8* @_Znwm(i64 40)
299 ; CHECK-NEXT: ret i8* [[CALL]]
301 %call = tail call i8* @_Znwm(i64 40)
305 define noalias i8* @op_new_constant_zero_size() {
306 ; CHECK-LABEL: @op_new_constant_zero_size(
307 ; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @_Znam(i64 0)
308 ; CHECK-NEXT: ret i8* [[CALL]]
310 %call = tail call i8* @_Znam(i64 0)
314 define noalias i8* @strdup_constant_str() {
315 ; CHECK-LABEL: @strdup_constant_str(
316 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(6) i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0))
317 ; CHECK-NEXT: ret i8* [[CALL]]
319 %call = tail call noalias i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0))
323 define noalias i8* @strdup_notconstant_str(i8 * %str) {
324 ; CHECK-LABEL: @strdup_notconstant_str(
325 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @strdup(i8* [[STR:%.*]])
326 ; CHECK-NEXT: ret i8* [[CALL]]
328 %call = tail call noalias i8* @strdup(i8* %str)
333 ; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23214
334 define noalias i8* @ossfuzz_23214() {
335 ; CHECK-LABEL: @ossfuzz_23214(
337 ; CHECK-NEXT: [[CALL:%.*]] = tail call noalias dereferenceable_or_null(512) i8* @aligned_alloc(i64 -9223372036854775808, i64 512)
338 ; CHECK-NEXT: ret i8* [[CALL]]
341 %and = and i64 -1, -9223372036854775808
342 %call = tail call noalias i8* @aligned_alloc(i64 %and, i64 512)