1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instcombine  -S < %s | FileCheck %s
3
4declare noalias i8* @malloc(i64)
5declare noalias i8* @calloc(i64, i64)
6declare noalias i8* @realloc(i8* nocapture, i64)
7declare noalias nonnull i8* @_Znam(i64) ; throwing version of 'new'
8declare noalias nonnull i8* @_Znwm(i64) ; throwing version of 'new'
9declare noalias i8* @strdup(i8*)
10declare noalias i8* @aligned_alloc(i64, i64)
11
12@.str = private unnamed_addr constant [6 x i8] c"hello\00", align 1
13
14define noalias i8* @malloc_nonconstant_size(i64 %n) {
15; CHECK-LABEL: @malloc_nonconstant_size(
16; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @malloc(i64 [[N:%.*]])
17; CHECK-NEXT:    ret i8* [[CALL]]
18;
19  %call = tail call noalias i8* @malloc(i64 %n)
20  ret i8* %call
21}
22
23define noalias i8* @malloc_constant_size() {
24; CHECK-LABEL: @malloc_constant_size(
25; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) i8* @malloc(i64 40)
26; CHECK-NEXT:    ret i8* [[CALL]]
27;
28  %call = tail call noalias i8* @malloc(i64 40)
29  ret i8* %call
30}
31
32define noalias i8* @aligned_alloc_constant_size() {
33; CHECK-LABEL: @aligned_alloc_constant_size(
34; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias align 32 dereferenceable_or_null(512) i8* @aligned_alloc(i64 32, i64 512)
35; CHECK-NEXT:    ret i8* [[CALL]]
36;
37  %call = tail call noalias i8* @aligned_alloc(i64 32, i64 512)
38  ret i8* %call
39}
40
41declare noalias i8* @foo(i8*, i8*, i8*)
42
43define noalias i8* @aligned_alloc_dynamic_args(i64 %align, i64 %size) {
44; CHECK-LABEL: @aligned_alloc_dynamic_args(
45; CHECK-NEXT:    tail call noalias dereferenceable_or_null(1024) i8* @aligned_alloc(i64 %{{.*}}, i64 1024)
46; CHECK-NEXT:    tail call noalias i8* @aligned_alloc(i64 0, i64 1024)
47; CHECK-NEXT:    tail call noalias i8* @aligned_alloc(i64 32, i64 %{{.*}})
48;
49  %call = tail call noalias i8* @aligned_alloc(i64 %align, i64 1024)
50  %call_1 = tail call noalias i8* @aligned_alloc(i64 0, i64 1024)
51  %call_2 = tail call noalias i8* @aligned_alloc(i64 32, i64 %size)
52
53  call i8* @foo(i8* %call, i8* %call_1, i8* %call_2)
54  ret i8* %call
55}
56
57define noalias i8* @malloc_constant_size2() {
58; CHECK-LABEL: @malloc_constant_size2(
59; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias dereferenceable_or_null(80) i8* @malloc(i64 40)
60; CHECK-NEXT:    ret i8* [[CALL]]
61;
62  %call = tail call noalias dereferenceable_or_null(80) i8* @malloc(i64 40)
63  ret i8* %call
64}
65
66define noalias i8* @malloc_constant_size3() {
67; CHECK-LABEL: @malloc_constant_size3(
68; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias dereferenceable(80) dereferenceable_or_null(40) i8* @malloc(i64 40)
69; CHECK-NEXT:    ret i8* [[CALL]]
70;
71  %call = tail call noalias dereferenceable(80) i8* @malloc(i64 40)
72  ret i8* %call
73}
74
75define noalias i8* @malloc_constant_zero_size() {
76; CHECK-LABEL: @malloc_constant_zero_size(
77; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @malloc(i64 0)
78; CHECK-NEXT:    ret i8* [[CALL]]
79;
80  %call = tail call noalias i8* @malloc(i64 0)
81  ret i8* %call
82}
83
84define noalias i8* @realloc_nonconstant_size(i8* %p, i64 %n) {
85; CHECK-LABEL: @realloc_nonconstant_size(
86; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @realloc(i8* [[P:%.*]], i64 [[N:%.*]])
87; CHECK-NEXT:    ret i8* [[CALL]]
88;
89  %call = tail call noalias i8* @realloc(i8* %p, i64 %n)
90  ret i8* %call
91}
92
93define noalias i8* @realloc_constant_zero_size(i8* %p) {
94; CHECK-LABEL: @realloc_constant_zero_size(
95; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @realloc(i8* [[P:%.*]], i64 0)
96; CHECK-NEXT:    ret i8* [[CALL]]
97;
98  %call = tail call noalias i8* @realloc(i8* %p, i64 0)
99  ret i8* %call
100}
101
102define noalias i8* @realloc_constant_size(i8* %p) {
103; CHECK-LABEL: @realloc_constant_size(
104; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias dereferenceable_or_null(40) i8* @realloc(i8* [[P:%.*]], i64 40)
105; CHECK-NEXT:    ret i8* [[CALL]]
106;
107  %call = tail call noalias i8* @realloc(i8* %p, i64 40)
108  ret i8* %call
109}
110
111define noalias i8* @calloc_nonconstant_size(i64 %n) {
112; CHECK-LABEL: @calloc_nonconstant_size(
113; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 1, i64 [[N:%.*]])
114; CHECK-NEXT:    ret i8* [[CALL]]
115;
116  %call = tail call noalias i8* @calloc(i64 1, i64 %n)
117  ret i8* %call
118}
119
120define noalias i8* @calloc_nonconstant_size2(i64 %n) {
121; CHECK-LABEL: @calloc_nonconstant_size2(
122; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 [[N:%.*]], i64 0)
123; CHECK-NEXT:    ret i8* [[CALL]]
124;
125  %call = tail call noalias i8* @calloc(i64 %n, i64 0)
126  ret i8* %call
127}
128
129define noalias i8* @calloc_nonconstant_size3(i64 %n) {
130; CHECK-LABEL: @calloc_nonconstant_size3(
131; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 [[N:%.*]], i64 [[N]])
132; CHECK-NEXT:    ret i8* [[CALL]]
133;
134  %call = tail call noalias i8* @calloc(i64 %n, i64 %n)
135  ret i8* %call
136}
137
138define noalias i8* @calloc_constant_zero_size() {
139; CHECK-LABEL: @calloc_constant_zero_size(
140; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 0, i64 0)
141; CHECK-NEXT:    ret i8* [[CALL]]
142;
143  %call = tail call noalias i8* @calloc(i64 0, i64 0)
144  ret i8* %call
145}
146
147define noalias i8* @calloc_constant_zero_size2(i64 %n) {
148; CHECK-LABEL: @calloc_constant_zero_size2(
149; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 [[N:%.*]], i64 0)
150; CHECK-NEXT:    ret i8* [[CALL]]
151;
152  %call = tail call noalias i8* @calloc(i64 %n, i64 0)
153  ret i8* %call
154}
155
156
157define noalias i8* @calloc_constant_zero_size3(i64 %n) {
158; CHECK-LABEL: @calloc_constant_zero_size3(
159; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 0, i64 [[N:%.*]])
160; CHECK-NEXT:    ret i8* [[CALL]]
161;
162  %call = tail call noalias i8* @calloc(i64 0, i64 %n)
163  ret i8* %call
164}
165
166define noalias i8* @calloc_constant_zero_size4(i64 %n) {
167; CHECK-LABEL: @calloc_constant_zero_size4(
168; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 0, i64 1)
169; CHECK-NEXT:    ret i8* [[CALL]]
170;
171  %call = tail call noalias i8* @calloc(i64 0, i64 1)
172  ret i8* %call
173}
174
175define noalias i8* @calloc_constant_zero_size5(i64 %n) {
176; CHECK-LABEL: @calloc_constant_zero_size5(
177; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 1, i64 0)
178; CHECK-NEXT:    ret i8* [[CALL]]
179;
180  %call = tail call noalias i8* @calloc(i64 1, i64 0)
181  ret i8* %call
182}
183
184define noalias i8* @calloc_constant_size() {
185; CHECK-LABEL: @calloc_constant_size(
186; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias dereferenceable_or_null(128) i8* @calloc(i64 16, i64 8)
187; CHECK-NEXT:    ret i8* [[CALL]]
188;
189  %call = tail call noalias i8* @calloc(i64 16, i64 8)
190  ret i8* %call
191}
192
193define noalias i8* @calloc_constant_size_overflow() {
194; CHECK-LABEL: @calloc_constant_size_overflow(
195; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @calloc(i64 2000000000000, i64 80000000000)
196; CHECK-NEXT:    ret i8* [[CALL]]
197;
198  %call = tail call noalias i8* @calloc(i64 2000000000000, i64 80000000000)
199  ret i8* %call
200}
201
202define noalias i8* @op_new_nonconstant_size(i64 %n) {
203; CHECK-LABEL: @op_new_nonconstant_size(
204; CHECK-NEXT:    [[CALL:%.*]] = tail call i8* @_Znam(i64 [[N:%.*]])
205; CHECK-NEXT:    ret i8* [[CALL]]
206;
207  %call = tail call i8* @_Znam(i64 %n)
208  ret i8* %call
209}
210
211define noalias i8* @op_new_constant_size() {
212; CHECK-LABEL: @op_new_constant_size(
213; CHECK-NEXT:    [[CALL:%.*]] = tail call dereferenceable(40) i8* @_Znam(i64 40)
214; CHECK-NEXT:    ret i8* [[CALL]]
215;
216  %call = tail call i8* @_Znam(i64 40)
217  ret i8* %call
218}
219
220define noalias i8* @op_new_constant_size2() {
221; CHECK-LABEL: @op_new_constant_size2(
222; CHECK-NEXT:    [[CALL:%.*]] = tail call dereferenceable(40) i8* @_Znwm(i64 40)
223; CHECK-NEXT:    ret i8* [[CALL]]
224;
225  %call = tail call i8* @_Znwm(i64 40)
226  ret i8* %call
227}
228
229define noalias i8* @op_new_constant_zero_size() {
230; CHECK-LABEL: @op_new_constant_zero_size(
231; CHECK-NEXT:    [[CALL:%.*]] = tail call i8* @_Znam(i64 0)
232; CHECK-NEXT:    ret i8* [[CALL]]
233;
234  %call = tail call i8* @_Znam(i64 0)
235  ret i8* %call
236}
237
238define noalias i8* @strdup_constant_str() {
239; CHECK-LABEL: @strdup_constant_str(
240; 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))
241; CHECK-NEXT:    ret i8* [[CALL]]
242;
243  %call = tail call noalias i8* @strdup(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i64 0, i64 0))
244  ret i8* %call
245}
246
247define noalias i8* @strdup_notconstant_str(i8 * %str) {
248; CHECK-LABEL: @strdup_notconstant_str(
249; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias i8* @strdup(i8* [[STR:%.*]])
250; CHECK-NEXT:    ret i8* [[CALL]]
251;
252  %call = tail call noalias i8* @strdup(i8* %str)
253  ret i8* %call
254}
255
256; OSS-Fuzz #23214
257; https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=23214
258define noalias i8* @ossfuzz_23214() {
259; CHECK-LABEL: @ossfuzz_23214(
260; CHECK-NEXT:  bb:
261; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias dereferenceable_or_null(512) i8* @aligned_alloc(i64 -9223372036854775808, i64 512)
262; CHECK-NEXT:    ret i8* [[CALL]]
263;
264bb:
265  %and = and i64 -1, -9223372036854775808
266  %call = tail call noalias i8* @aligned_alloc(i64 %and, i64 512)
267  ret i8* %call
268}
269
270