1*9880d681SAndroid Build Coastguard Worker; RUN: opt -memcpyopt -S < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-i64:64-f80:128-n8:16:32:64" 4*9880d681SAndroid Build Coastguard Workertarget triple = "x86_64-unknown-linux-gnu" 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Worker%S = type { i8*, i8, i32 } 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Workerdefine void @copy(%S* %src, %S* %dst) { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: copy 10*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 11*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memmove.p0i8.p0i8.i64 12*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 13*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 14*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst 15*9880d681SAndroid Build Coastguard Worker ret void 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Workerdefine void @noaliassrc(%S* noalias %src, %S* %dst) { 19*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: noaliassrc 20*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 21*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 22*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 23*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 24*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst 25*9880d681SAndroid Build Coastguard Worker ret void 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Workerdefine void @noaliasdst(%S* %src, %S* noalias %dst) { 29*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: noaliasdst 30*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 31*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 32*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 33*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 34*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst 35*9880d681SAndroid Build Coastguard Worker ret void 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Workerdefine void @destroysrc(%S* %src, %S* %dst) { 39*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: destroysrc 40*9880d681SAndroid Build Coastguard Worker; CHECK: load %S, %S* %src 41*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memset.p0i8.i64 42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store %S %1, %S* %dst 43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 44*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 45*9880d681SAndroid Build Coastguard Worker store %S zeroinitializer, %S* %src 46*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst 47*9880d681SAndroid Build Coastguard Worker ret void 48*9880d681SAndroid Build Coastguard Worker} 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Workerdefine void @destroynoaliassrc(%S* noalias %src, %S* %dst) { 51*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: destroynoaliassrc 52*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 53*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 54*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @llvm.memset.p0i8.i64 55*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 56*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 57*9880d681SAndroid Build Coastguard Worker store %S zeroinitializer, %S* %src 58*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst 59*9880d681SAndroid Build Coastguard Worker ret void 60*9880d681SAndroid Build Coastguard Worker} 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Workerdefine void @copyalias(%S* %src, %S* %dst) { 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: copyalias 64*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[LOAD:%[a-z0-9\.]+]] = load %S, %S* %src 65*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load 66*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memmove.p0i8.p0i8.i64 67*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store %S [[LOAD]], %S* %dst 68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 69*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 70*9880d681SAndroid Build Coastguard Worker %2 = load %S, %S* %src 71*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst 72*9880d681SAndroid Build Coastguard Worker store %S %2, %S* %dst 73*9880d681SAndroid Build Coastguard Worker ret void 74*9880d681SAndroid Build Coastguard Worker} 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; If the store address is computed ina complex manner, make 77*9880d681SAndroid Build Coastguard Worker; sure we lift the computation as well if needed and possible. 78*9880d681SAndroid Build Coastguard Workerdefine void @addrproducer(%S* %src, %S* %dst) { 79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: addrproducer 80*9880d681SAndroid Build Coastguard Worker; CHECK: %dst2 = getelementptr %S, %S* %dst, i64 1 81*9880d681SAndroid Build Coastguard Worker; CHECK: call void @llvm.memmove.p0i8.p0i8.i64 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: store %S undef, %S* %dst 83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret void 84*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 85*9880d681SAndroid Build Coastguard Worker store %S undef, %S* %dst 86*9880d681SAndroid Build Coastguard Worker %dst2 = getelementptr %S , %S* %dst, i64 1 87*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst2 88*9880d681SAndroid Build Coastguard Worker ret void 89*9880d681SAndroid Build Coastguard Worker} 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Workerdefine void @aliasaddrproducer(%S* %src, %S* %dst, i32* %dstidptr) { 92*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: aliasaddrproducer 93*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 94*9880d681SAndroid Build Coastguard Worker store %S undef, %S* %dst 95*9880d681SAndroid Build Coastguard Worker %dstindex = load i32, i32* %dstidptr 96*9880d681SAndroid Build Coastguard Worker %dst2 = getelementptr %S , %S* %dst, i32 %dstindex 97*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst2 98*9880d681SAndroid Build Coastguard Worker ret void 99*9880d681SAndroid Build Coastguard Worker} 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Workerdefine void @noaliasaddrproducer(%S* %src, %S* noalias %dst, i32* noalias %dstidptr) { 102*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: noaliasaddrproducer 103*9880d681SAndroid Build Coastguard Worker %1 = load %S, %S* %src 104*9880d681SAndroid Build Coastguard Worker store %S undef, %S* %src 105*9880d681SAndroid Build Coastguard Worker %2 = load i32, i32* %dstidptr 106*9880d681SAndroid Build Coastguard Worker %dstindex = or i32 %2, 1 107*9880d681SAndroid Build Coastguard Worker %dst2 = getelementptr %S , %S* %dst, i32 %dstindex 108*9880d681SAndroid Build Coastguard Worker store %S %1, %S* %dst2 109*9880d681SAndroid Build Coastguard Worker ret void 110*9880d681SAndroid Build Coastguard Worker} 111