@@ -184,3 +184,171 @@ return:
184
184
%retval = phi ptr [ %ptr , %if.then ], [ %obj , %entry ]
185
185
ret ptr %retval
186
186
}
187
+
188
+ define ptr @memset_tailc (ptr %ret_val , i64 %sz ) nounwind {
189
+ ; CHECK-LABEL: memset_tailc:
190
+ ; CHECK: ## %bb.0: ## %entry
191
+ ; CHECK-NEXT: pushq %rbx
192
+ ; CHECK-NEXT: movq %rdi, %rbx
193
+ ; CHECK-NEXT: testq %rdi, %rdi
194
+ ; CHECK-NEXT: je LBB4_2
195
+ ; CHECK-NEXT: ## %bb.1: ## %if.then
196
+ ; CHECK-NEXT: movq %rsi, %rdx
197
+ ; CHECK-NEXT: movq %rbx, %rdi
198
+ ; CHECK-NEXT: xorl %esi, %esi
199
+ ; CHECK-NEXT: callq _memset
200
+ ; CHECK-NEXT: LBB4_2: ## %return
201
+ ; CHECK-NEXT: movq %rbx, %rax
202
+ ; CHECK-NEXT: popq %rbx
203
+ ; CHECK-NEXT: retq
204
+ entry:
205
+ %cmp = icmp eq ptr %ret_val , null
206
+ br i1 %cmp , label %return , label %if.then
207
+
208
+ if.then:
209
+ tail call void @llvm.memset.p0.i64 (ptr nonnull align 1 %ret_val , i8 0 , i64 %sz , i1 false )
210
+ br label %return
211
+
212
+ return:
213
+ ret ptr %ret_val
214
+ }
215
+
216
+ define ptr @baz_not_to_tailc (ptr %ret_val , ptr %arg ) nounwind {
217
+ ; CHECK-LABEL: baz_not_to_tailc:
218
+ ; CHECK: ## %bb.0: ## %entry
219
+ ; CHECK-NEXT: pushq %rbx
220
+ ; CHECK-NEXT: movq %rdi, %rbx
221
+ ; CHECK-NEXT: testq %rdi, %rdi
222
+ ; CHECK-NEXT: je LBB5_2
223
+ ; CHECK-NEXT: ## %bb.1: ## %if.then
224
+ ; CHECK-NEXT: movq %rbx, %rdi
225
+ ; CHECK-NEXT: callq _baz
226
+ ; CHECK-NEXT: LBB5_2: ## %return
227
+ ; CHECK-NEXT: movq %rbx, %rax
228
+ ; CHECK-NEXT: popq %rbx
229
+ ; CHECK-NEXT: retq
230
+ entry:
231
+ %cmp = icmp eq ptr %ret_val , null
232
+ br i1 %cmp , label %return , label %if.then
233
+
234
+ if.then:
235
+ %rv = tail call ptr @baz (ptr %ret_val , ptr %arg )
236
+ br label %return
237
+
238
+ return:
239
+ ret ptr %ret_val
240
+ }
241
+
242
+ define ptr @memcpy_tailc (ptr %ret_val , i64 %sz , ptr %src ) nounwind {
243
+ ; CHECK-LABEL: memcpy_tailc:
244
+ ; CHECK: ## %bb.0: ## %entry
245
+ ; CHECK-NEXT: pushq %rbx
246
+ ; CHECK-NEXT: testq %rsi, %rsi
247
+ ; CHECK-NEXT: je LBB6_1
248
+ ; CHECK-NEXT: ## %bb.2: ## %if.then
249
+ ; CHECK-NEXT: movq %rsi, %rax
250
+ ; CHECK-NEXT: movq %rdi, %rbx
251
+ ; CHECK-NEXT: movq %rdx, %rsi
252
+ ; CHECK-NEXT: movq %rax, %rdx
253
+ ; CHECK-NEXT: callq _memcpy
254
+ ; CHECK-NEXT: jmp LBB6_3
255
+ ; CHECK-NEXT: LBB6_1:
256
+ ; CHECK-NEXT: movq %rdx, %rbx
257
+ ; CHECK-NEXT: LBB6_3: ## %return
258
+ ; CHECK-NEXT: movq %rbx, %rax
259
+ ; CHECK-NEXT: popq %rbx
260
+ ; CHECK-NEXT: retq
261
+ entry:
262
+ %cmp = icmp eq i64 %sz , 0
263
+ br i1 %cmp , label %return , label %if.then
264
+
265
+ if.then:
266
+ tail call void @llvm.memcpy.p0.p0.i64 (ptr align 1 %ret_val , ptr align 1 %src , i64 %sz , i1 false )
267
+ br label %return
268
+
269
+ return:
270
+ %phi = phi ptr [ %ret_val , %if.then ], [ %src , %entry ]
271
+ ret ptr %phi
272
+ }
273
+
274
+ define ptr @strcpy_legal_and_baz_illegal (ptr %arg , i64 %sz , ptr %2 ) nounwind {
275
+ ; CHECK-LABEL: strcpy_legal_and_baz_illegal:
276
+ ; CHECK: ## %bb.0: ## %entry
277
+ ; CHECK-NEXT: pushq %r15
278
+ ; CHECK-NEXT: pushq %r14
279
+ ; CHECK-NEXT: pushq %rbx
280
+ ; CHECK-NEXT: movq %rdx, %r14
281
+ ; CHECK-NEXT: movq %rsi, %r15
282
+ ; CHECK-NEXT: movq %rdi, %rbx
283
+ ; CHECK-NEXT: movq %rsi, %rdi
284
+ ; CHECK-NEXT: callq _malloc
285
+ ; CHECK-NEXT: testq %r15, %r15
286
+ ; CHECK-NEXT: je LBB7_2
287
+ ; CHECK-NEXT: ## %bb.1: ## %if.then
288
+ ; CHECK-NEXT: movq %rax, %rdi
289
+ ; CHECK-NEXT: movq %r14, %rsi
290
+ ; CHECK-NEXT: movq %rax, %rbx
291
+ ; CHECK-NEXT: callq _strcpy
292
+ ; CHECK-NEXT: jmp LBB7_3
293
+ ; CHECK-NEXT: LBB7_2: ## %if.else
294
+ ; CHECK-NEXT: movq %rbx, %rdi
295
+ ; CHECK-NEXT: movq %r14, %rsi
296
+ ; CHECK-NEXT: callq _baz
297
+ ; CHECK-NEXT: LBB7_3: ## %return
298
+ ; CHECK-NEXT: movq %rbx, %rax
299
+ ; CHECK-NEXT: popq %rbx
300
+ ; CHECK-NEXT: popq %r14
301
+ ; CHECK-NEXT: popq %r15
302
+ ; CHECK-NEXT: retq
303
+ entry:
304
+ %strcpy_ret_val = tail call noalias ptr @malloc (i64 %sz )
305
+ %cmp = icmp eq i64 %sz , 0
306
+ br i1 %cmp , label %if.else , label %if.then
307
+
308
+ if.then:
309
+ %rv_unused = tail call ptr @strcpy (ptr dereferenceable (1 ) %strcpy_ret_val , ptr dereferenceable (1 ) %2 )
310
+ br label %return
311
+
312
+ if.else:
313
+ %rv_unused_2 = tail call ptr @baz (ptr %arg , ptr %2 )
314
+ br label %return
315
+
316
+ return:
317
+ %phi = phi ptr [ %strcpy_ret_val , %if.then ], [ %arg , %if.else ]
318
+ ret ptr %phi
319
+ }
320
+
321
+ define ptr @memset_not_to_tailc (ptr %arg , i64 %sz , ptr %ret_val_1 , ptr %ret_val_2 ) nounwind {
322
+ ; CHECK-LABEL: memset_not_to_tailc:
323
+ ; CHECK: ## %bb.0: ## %entry
324
+ ; CHECK-NEXT: movq %rdx, %rax
325
+ ; CHECK-NEXT: testq %rsi, %rsi
326
+ ; CHECK-NEXT: je LBB8_2
327
+ ; CHECK-NEXT: ## %bb.1: ## %if.then
328
+ ; CHECK-NEXT: pushq %rbx
329
+ ; CHECK-NEXT: movq %rcx, %rbx
330
+ ; CHECK-NEXT: movq %rsi, %rdx
331
+ ; CHECK-NEXT: xorl %esi, %esi
332
+ ; CHECK-NEXT: callq _memset
333
+ ; CHECK-NEXT: movq %rbx, %rax
334
+ ; CHECK-NEXT: popq %rbx
335
+ ; CHECK-NEXT: LBB8_2: ## %return
336
+ ; CHECK-NEXT: retq
337
+ entry:
338
+ %cmp = icmp eq i64 %sz , 0
339
+ br i1 %cmp , label %return , label %if.then
340
+
341
+ if.then:
342
+ tail call void @llvm.memset.p0.i64 (ptr align 1 %arg , i8 0 , i64 %sz , i1 false )
343
+ br label %return
344
+
345
+ return:
346
+ %phi = phi ptr [ %ret_val_2 , %if.then ], [ %ret_val_1 , %entry ]
347
+ ret ptr %phi
348
+ }
349
+
350
+ declare void @llvm.memcpy.p0.p0.i64 (ptr noalias nocapture writeonly , ptr noalias nocapture readonly , i64 , i1 immarg)
351
+ declare void @llvm.memset.p0.i64 (ptr nocapture writeonly , i8 , i64 , i1 immarg)
352
+ declare noalias ptr @malloc (i64 )
353
+ declare ptr @strcpy (ptr noalias returned writeonly , ptr noalias nocapture readonly )
354
+ declare ptr @baz (ptr , ptr )
0 commit comments