1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=memcpyopt < %s | FileCheck %s 3 4define void @test_copy_uninit(ptr %arg) { 5; CHECK-LABEL: @test_copy_uninit( 6; CHECK-NEXT: start: 7; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [1000 x i32], align 4 8; CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [1000 x [1000 x i32]], ptr [[ARG:%.*]], i64 0, i64 1000 9; CHECK-NEXT: br label [[LOOP:%.*]] 10; CHECK: loop: 11; CHECK-NEXT: [[CURRENT:%.*]] = phi ptr [ [[ARG]], [[START:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ] 12; CHECK-NEXT: [[NEXT]] = getelementptr inbounds [1000 x i32], ptr [[CURRENT]], i64 1 13; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[NEXT]], [[END]] 14; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 15; CHECK: exit: 16; CHECK-NEXT: ret void 17; 18start: 19 %alloca = alloca [1000 x i32], align 4 20 %end = getelementptr inbounds [1000 x [1000 x i32]], ptr %arg, i64 0, i64 1000 21 br label %loop 22 23loop: ; preds = %loop, %start 24 %current = phi ptr [ %arg, %start ], [ %next, %loop ] 25 call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 dereferenceable(4000) %current, ptr nonnull align 4 dereferenceable(4000) %alloca, i64 4000, i1 false) 26 %next = getelementptr inbounds [1000 x i32], ptr %current, i64 1 27 %cond = icmp eq ptr %next, %end 28 br i1 %cond, label %exit, label %loop 29 30exit: ; preds = %loop 31 ret void 32} 33 34define void @test_copy_zero(ptr %arg) { 35; CHECK-LABEL: @test_copy_zero( 36; CHECK-NEXT: start: 37; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [1000 x i32], align 4 38; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr nonnull align 4 dereferenceable(4000) [[ALLOCA]], i8 0, i64 4000, i1 false) 39; CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [1000 x [1000 x i32]], ptr [[ARG:%.*]], i64 0, i64 1000 40; CHECK-NEXT: br label [[LOOP:%.*]] 41; CHECK: loop: 42; CHECK-NEXT: [[CURRENT:%.*]] = phi ptr [ [[ARG]], [[START:%.*]] ], [ [[NEXT:%.*]], [[LOOP]] ] 43; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[CURRENT]], i8 0, i64 4000, i1 false) 44; CHECK-NEXT: [[NEXT]] = getelementptr inbounds [1000 x i32], ptr [[CURRENT]], i64 1 45; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[NEXT]], [[END]] 46; CHECK-NEXT: br i1 [[COND]], label [[EXIT:%.*]], label [[LOOP]] 47; CHECK: exit: 48; CHECK-NEXT: ret void 49; 50start: 51 %alloca = alloca [1000 x i32], align 4 52 call void @llvm.memset.p0.i64(ptr nonnull align 4 dereferenceable(4000) %alloca, i8 0, i64 4000, i1 false) 53 %end = getelementptr inbounds [1000 x [1000 x i32]], ptr %arg, i64 0, i64 1000 54 br label %loop 55 56loop: ; preds = %loop, %start 57 %current = phi ptr [ %arg, %start ], [ %next, %loop ] 58 call void @llvm.memcpy.p0.p0.i64(ptr nonnull align 4 dereferenceable(4000) %current, ptr nonnull align 4 dereferenceable(4000) %alloca, i64 4000, i1 false) 59 %next = getelementptr inbounds [1000 x i32], ptr %current, i64 1 60 %cond = icmp eq ptr %next, %end 61 br i1 %cond, label %exit, label %loop 62 63exit: ; preds = %loop 64 ret void 65} 66 67declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) 68declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) 69