@@ -184,3 +184,196 @@ 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 @memcpy_tailc (ptr %ret_val , i64 %sz , ptr %src ) nounwind {
217
+ ; CHECK-LABEL: memcpy_tailc:
218
+ ; CHECK: ## %bb.0: ## %entry
219
+ ; CHECK-NEXT: pushq %rbx
220
+ ; CHECK-NEXT: testq %rsi, %rsi
221
+ ; CHECK-NEXT: je LBB5_1
222
+ ; CHECK-NEXT: ## %bb.2: ## %if.then
223
+ ; CHECK-NEXT: movq %rsi, %rax
224
+ ; CHECK-NEXT: movq %rdi, %rbx
225
+ ; CHECK-NEXT: movq %rdx, %rsi
226
+ ; CHECK-NEXT: movq %rax, %rdx
227
+ ; CHECK-NEXT: callq _memcpy
228
+ ; CHECK-NEXT: jmp LBB5_3
229
+ ; CHECK-NEXT: LBB5_1:
230
+ ; CHECK-NEXT: movq %rdx, %rbx
231
+ ; CHECK-NEXT: LBB5_3: ## %return
232
+ ; CHECK-NEXT: movq %rbx, %rax
233
+ ; CHECK-NEXT: popq %rbx
234
+ ; CHECK-NEXT: retq
235
+ entry:
236
+ %cmp = icmp eq i64 %sz , 0
237
+ br i1 %cmp , label %return , label %if.then
238
+
239
+ if.then:
240
+ tail call void @llvm.memcpy.p0.p0.i64 (ptr align 1 %ret_val , ptr align 1 %src , i64 %sz , i1 false )
241
+ br label %return
242
+
243
+ return:
244
+ %phi = phi ptr [ %ret_val , %if.then ], [ %src , %entry ]
245
+ ret ptr %phi
246
+ }
247
+
248
+ define ptr @strcpy_legal_and_baz_illegal (ptr %arg , i64 %sz , ptr %2 ) nounwind {
249
+ ; CHECK-LABEL: strcpy_legal_and_baz_illegal:
250
+ ; CHECK: ## %bb.0: ## %entry
251
+ ; CHECK-NEXT: pushq %r15
252
+ ; CHECK-NEXT: pushq %r14
253
+ ; CHECK-NEXT: pushq %rbx
254
+ ; CHECK-NEXT: movq %rdx, %r14
255
+ ; CHECK-NEXT: movq %rsi, %r15
256
+ ; CHECK-NEXT: movq %rdi, %rbx
257
+ ; CHECK-NEXT: movq %rsi, %rdi
258
+ ; CHECK-NEXT: callq _malloc
259
+ ; CHECK-NEXT: testq %r15, %r15
260
+ ; CHECK-NEXT: je LBB6_2
261
+ ; CHECK-NEXT: ## %bb.1: ## %if.then
262
+ ; CHECK-NEXT: movq %rax, %rdi
263
+ ; CHECK-NEXT: movq %r14, %rsi
264
+ ; CHECK-NEXT: movq %rax, %rbx
265
+ ; CHECK-NEXT: callq _strcpy
266
+ ; CHECK-NEXT: jmp LBB6_3
267
+ ; CHECK-NEXT: LBB6_2: ## %if.else
268
+ ; CHECK-NEXT: movq %rbx, %rdi
269
+ ; CHECK-NEXT: movq %r14, %rsi
270
+ ; CHECK-NEXT: callq _baz
271
+ ; CHECK-NEXT: LBB6_3: ## %return
272
+ ; CHECK-NEXT: movq %rbx, %rax
273
+ ; CHECK-NEXT: popq %rbx
274
+ ; CHECK-NEXT: popq %r14
275
+ ; CHECK-NEXT: popq %r15
276
+ ; CHECK-NEXT: retq
277
+ entry:
278
+ %strcpy_ret_val = tail call noalias ptr @malloc (i64 %sz )
279
+ %cmp = icmp eq i64 %sz , 0
280
+ br i1 %cmp , label %if.else , label %if.then
281
+
282
+ if.then:
283
+ %rv_unused = tail call ptr @strcpy (ptr dereferenceable (1 ) %strcpy_ret_val , ptr dereferenceable (1 ) %2 )
284
+ br label %return
285
+
286
+ if.else:
287
+ %rv_unused_2 = tail call ptr @baz (ptr %arg , ptr %2 )
288
+ br label %return
289
+
290
+ return:
291
+ %phi = phi ptr [ %strcpy_ret_val , %if.then ], [ %arg , %if.else ]
292
+ ret ptr %phi
293
+ }
294
+
295
+ define ptr @baz_illegal_tailc (ptr %ret_val , ptr %arg ) nounwind {
296
+ ; CHECK-LABEL: baz_illegal_tailc:
297
+ ; CHECK: ## %bb.0: ## %entry
298
+ ; CHECK-NEXT: pushq %rbx
299
+ ; CHECK-NEXT: movq %rdi, %rbx
300
+ ; CHECK-NEXT: testq %rdi, %rdi
301
+ ; CHECK-NEXT: je LBB7_2
302
+ ; CHECK-NEXT: ## %bb.1: ## %if.then
303
+ ; CHECK-NEXT: movq %rbx, %rdi
304
+ ; CHECK-NEXT: callq _baz
305
+ ; CHECK-NEXT: LBB7_2: ## %return
306
+ ; CHECK-NEXT: movq %rbx, %rax
307
+ ; CHECK-NEXT: popq %rbx
308
+ ; CHECK-NEXT: retq
309
+ entry:
310
+ %cmp = icmp eq ptr %ret_val , null
311
+ br i1 %cmp , label %return , label %if.then
312
+
313
+ if.then:
314
+ %rv = tail call ptr @baz (ptr %ret_val , ptr %arg )
315
+ br label %return
316
+
317
+ return:
318
+ ret ptr %ret_val
319
+ }
320
+
321
+ define ptr @memset_illegal_tailc (ptr %arg , i64 %sz , ptr %ret_val_1 , ptr %ret_val_2 ) nounwind {
322
+ ; CHECK-LABEL: memset_illegal_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
+ define ptr @strcpy_illegal_tailc (ptr %dest , i64 %sz , ptr readonly returned %src ) nounwind {
351
+ ; CHECK-LABEL: strcpy_illegal_tailc:
352
+ ; CHECK: ## %bb.0:
353
+ ; CHECK-NEXT: pushq %rbx
354
+ ; CHECK-NEXT: movq %rdx, %rbx
355
+ ; CHECK-NEXT: testq %rsi, %rsi
356
+ ; CHECK-NEXT: je LBB9_2
357
+ ; CHECK-NEXT: ## %bb.1: ## %if.then
358
+ ; CHECK-NEXT: movq %rbx, %rsi
359
+ ; CHECK-NEXT: callq _strcpy
360
+ ; CHECK-NEXT: LBB9_2: ## %return
361
+ ; CHECK-NEXT: movq %rbx, %rax
362
+ ; CHECK-NEXT: popq %rbx
363
+ ; CHECK-NEXT: retq
364
+ %cmp = icmp eq i64 %sz , 0
365
+ br i1 %cmp , label %return , label %if.then
366
+
367
+ if.then:
368
+ %6 = tail call ptr @strcpy (ptr dereferenceable (1 ) %dest , ptr dereferenceable (1 ) %src )
369
+ br label %return
370
+
371
+ return:
372
+ ret ptr %src
373
+ }
374
+
375
+ declare void @llvm.memcpy.p0.p0.i64 (ptr noalias nocapture writeonly , ptr noalias nocapture readonly , i64 , i1 )
376
+ declare void @llvm.memset.p0.i64 (ptr nocapture writeonly , i8 , i64 , i1 )
377
+ declare noalias ptr @malloc (i64 )
378
+ declare ptr @strcpy (ptr noalias returned writeonly , ptr noalias nocapture readonly )
379
+ declare ptr @baz (ptr , ptr )
0 commit comments