@@ -456,16 +456,68 @@ define void @immut_param_maycapture(ptr align 4 noalias %val) {
456456define void @immut_param_mayalias (ptr align 4 noalias %val ) {
457457; CHECK-LABEL: @immut_param_mayalias(
458458; CHECK-NEXT: [[VAL1:%.*]] = alloca i8, align 4
459+ ; CHECK-NEXT: call void @f(ptr [[VAL1]])
459460; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VAL1]], ptr align 4 [[VAL:%.*]], i64 1, i1 false)
460461; CHECK-NEXT: call void @f(ptr nocapture readonly align 4 [[VAL1]])
461462; CHECK-NEXT: ret void
462463;
463464 %val1 = alloca i8 , align 4
465+ call void @f (ptr %val1 ) ; escape
464466 call void @llvm.memcpy.p0.p0.i64 (ptr align 4 %val1 , ptr align 4 %val , i64 1 , i1 false )
465467 call void @f (ptr align 4 nocapture readonly %val1 )
466468 ret void
467469}
468470
471+ ; Can remove memcpy because alloca does not escape, so lack of noalias on the
472+ ; argument doesn't matter.
473+ define void @immut_param_unescaped_alloca (ptr align 4 noalias %val ) {
474+ ; CHECK-LABEL: @immut_param_unescaped_alloca(
475+ ; CHECK-NEXT: [[VAL1:%.*]] = alloca i8, align 4
476+ ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VAL1]], ptr align 4 [[VAL:%.*]], i64 1, i1 false)
477+ ; CHECK-NEXT: call void @f(ptr nocapture readonly align 4 [[VAL1]])
478+ ; CHECK-NEXT: ret void
479+ ;
480+ %val1 = alloca i8 , align 4
481+ call void @llvm.memcpy.p0.p0.i64 (ptr align 4 %val1 , ptr align 4 %val , i64 1 , i1 false )
482+ call void @f (ptr align 4 nocapture readonly %val1 )
483+ ret void
484+ }
485+
486+ ; Can remove memcpy because the function is argmem: read, so there cannot be
487+ ; a write to the escaped pointer.
488+ define void @immut_param_memory_argmem_read (ptr align 4 noalias %val ) {
489+ ; CHECK-LABEL: @immut_param_memory_argmem_read(
490+ ; CHECK-NEXT: [[VAL1:%.*]] = alloca i8, align 4
491+ ; CHECK-NEXT: call void @f(ptr [[VAL1]])
492+ ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VAL1]], ptr align 4 [[VAL:%.*]], i64 1, i1 false)
493+ ; CHECK-NEXT: call void @f(ptr nocapture readonly align 4 [[VAL1]]) #[[ATTR6:[0-9]+]]
494+ ; CHECK-NEXT: ret void
495+ ;
496+ %val1 = alloca i8 , align 4
497+ call void @f (ptr %val1 ) ; escape
498+ call void @llvm.memcpy.p0.p0.i64 (ptr align 4 %val1 , ptr align 4 %val , i64 1 , i1 false )
499+ call void @f (ptr align 4 nocapture readonly %val1 ) memory(argmem: read)
500+ ret void
501+ }
502+
503+ ; Can remove memcpy because the function is argmem: read, so there cannot be
504+ ; a write to the escaped pointer. The readonly on the argument is redundant in
505+ ; this case.
506+ define void @immut_param_memory_argmem_read_no_readonly (ptr align 4 noalias %val ) {
507+ ; CHECK-LABEL: @immut_param_memory_argmem_read_no_readonly(
508+ ; CHECK-NEXT: [[VAL1:%.*]] = alloca i8, align 4
509+ ; CHECK-NEXT: call void @f(ptr [[VAL1]])
510+ ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[VAL1]], ptr align 4 [[VAL:%.*]], i64 1, i1 false)
511+ ; CHECK-NEXT: call void @f(ptr nocapture align 4 [[VAL1]]) #[[ATTR6]]
512+ ; CHECK-NEXT: ret void
513+ ;
514+ %val1 = alloca i8 , align 4
515+ call void @f (ptr %val1 ) ; escape
516+ call void @llvm.memcpy.p0.p0.i64 (ptr align 4 %val1 , ptr align 4 %val , i64 1 , i1 false )
517+ call void @f (ptr align 4 nocapture %val1 ) memory(argmem: read)
518+ ret void
519+ }
520+
469521; Can't remove memcpy because dest may be written.
470522define void @immut_param_maywrite (ptr align 4 noalias %val ) {
471523; CHECK-LABEL: @immut_param_maywrite(
@@ -756,7 +808,7 @@ define void @byval_param_noalias_metadata(ptr align 4 byval(i32) %ptr) {
756808
757809define void @memcpy_memory_none (ptr %p , ptr %p2 , i64 %size ) {
758810; CHECK-LABEL: @memcpy_memory_none(
759- ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[P2:%.*]], i64 [[SIZE:%.*]], i1 false) #[[ATTR6 :[0-9]+]]
811+ ; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[P:%.*]], ptr [[P2:%.*]], i64 [[SIZE:%.*]], i1 false) #[[ATTR7 :[0-9]+]]
760812; CHECK-NEXT: ret void
761813;
762814 call void @llvm.memcpy.p0.p0.i64 (ptr %p , ptr %p2 , i64 %size , i1 false ) memory(none)
0 commit comments