1*9880d681SAndroid Build Coastguard Worker; Test memcpy using MVC. 2*9880d681SAndroid Build Coastguard Worker; 3*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i32(i8 *nocapture, i8 *nocapture, i32, i32, i1) nounwind 6*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.memcpy.p0i8.p0i8.i64(i8 *nocapture, i8 *nocapture, i64, i32, i1) nounwind 7*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i8 *, i8 *) 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Worker; Test a no-op move, i32 version. 10*9880d681SAndroid Build Coastguard Workerdefine void @f1(i8 *%dest, i8 *%src) { 11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 12*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 13*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r3 14*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 15*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i32(i8 *%dest, i8 *%src, i32 0, i32 1, 16*9880d681SAndroid Build Coastguard Worker i1 false) 17*9880d681SAndroid Build Coastguard Worker ret void 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; Test a no-op move, i64 version. 21*9880d681SAndroid Build Coastguard Workerdefine void @f2(i8 *%dest, i8 *%src) { 22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 23*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2 24*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r3 25*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 26*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 0, i32 1, 27*9880d681SAndroid Build Coastguard Worker i1 false) 28*9880d681SAndroid Build Coastguard Worker ret void 29*9880d681SAndroid Build Coastguard Worker} 30*9880d681SAndroid Build Coastguard Worker 31*9880d681SAndroid Build Coastguard Worker; Test a 1-byte move, i32 version. 32*9880d681SAndroid Build Coastguard Workerdefine void @f3(i8 *%dest, i8 *%src) { 33*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 34*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(1,%r2), 0(%r3) 35*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 36*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i32(i8 *%dest, i8 *%src, i32 1, i32 1, 37*9880d681SAndroid Build Coastguard Worker i1 false) 38*9880d681SAndroid Build Coastguard Worker ret void 39*9880d681SAndroid Build Coastguard Worker} 40*9880d681SAndroid Build Coastguard Worker 41*9880d681SAndroid Build Coastguard Worker; Test a 1-byte move, i64 version. 42*9880d681SAndroid Build Coastguard Workerdefine void @f4(i8 *%dest, i8 *%src) { 43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 44*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(1,%r2), 0(%r3) 45*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 46*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 1, i32 1, 47*9880d681SAndroid Build Coastguard Worker i1 false) 48*9880d681SAndroid Build Coastguard Worker ret void 49*9880d681SAndroid Build Coastguard Worker} 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker; Test the upper range of a single MVC, i32 version. 52*9880d681SAndroid Build Coastguard Workerdefine void @f5(i8 *%dest, i8 *%src) { 53*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 54*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,%r2), 0(%r3) 55*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 56*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i32(i8 *%dest, i8 *%src, i32 256, i32 1, 57*9880d681SAndroid Build Coastguard Worker i1 false) 58*9880d681SAndroid Build Coastguard Worker ret void 59*9880d681SAndroid Build Coastguard Worker} 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker; Test the upper range of a single MVC, i64 version. 62*9880d681SAndroid Build Coastguard Workerdefine void @f6(i8 *%dest, i8 *%src) { 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 64*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,%r2), 0(%r3) 65*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 66*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 256, i32 1, 67*9880d681SAndroid Build Coastguard Worker i1 false) 68*9880d681SAndroid Build Coastguard Worker ret void 69*9880d681SAndroid Build Coastguard Worker} 70*9880d681SAndroid Build Coastguard Worker 71*9880d681SAndroid Build Coastguard Worker; Test the first case that needs two MVCs. 72*9880d681SAndroid Build Coastguard Workerdefine void @f7(i8 *%dest, i8 *%src) { 73*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 74*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,%r2), 0(%r3) 75*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 256(1,%r2), 256(%r3) 76*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 77*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i32(i8 *%dest, i8 *%src, i32 257, i32 1, 78*9880d681SAndroid Build Coastguard Worker i1 false) 79*9880d681SAndroid Build Coastguard Worker ret void 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker; Test the last-but-one case that needs two MVCs. 83*9880d681SAndroid Build Coastguard Workerdefine void @f8(i8 *%dest, i8 *%src) { 84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 85*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,%r2), 0(%r3) 86*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 256(255,%r2), 256(%r3) 87*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 88*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 511, i32 1, 89*9880d681SAndroid Build Coastguard Worker i1 false) 90*9880d681SAndroid Build Coastguard Worker ret void 91*9880d681SAndroid Build Coastguard Worker} 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker; Test the last case that needs two MVCs. 94*9880d681SAndroid Build Coastguard Workerdefine void @f9(i8 *%dest, i8 *%src) { 95*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 96*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,%r2), 0(%r3) 97*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 256(256,%r2), 256(%r3) 98*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 99*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 512, i32 1, 100*9880d681SAndroid Build Coastguard Worker i1 false) 101*9880d681SAndroid Build Coastguard Worker ret void 102*9880d681SAndroid Build Coastguard Worker} 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker; Test an arbitrary value that uses straight-line code. 105*9880d681SAndroid Build Coastguard Workerdefine void @f10(i8 *%dest, i8 *%src) { 106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 107*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,%r2), 0(%r3) 108*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 256(256,%r2), 256(%r3) 109*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 512(256,%r2), 512(%r3) 110*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 768(256,%r2), 768(%r3) 111*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 1024(255,%r2), 1024(%r3) 112*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 113*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 1279, i32 1, 114*9880d681SAndroid Build Coastguard Worker i1 false) 115*9880d681SAndroid Build Coastguard Worker ret void 116*9880d681SAndroid Build Coastguard Worker} 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker; ...and again in cases where not all parts are in range of MVC. 119*9880d681SAndroid Build Coastguard Workerdefine void @f11(i8 *%srcbase, i8 *%destbase) { 120*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 121*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 4000(256,%r2), 3500(%r3) 122*9880d681SAndroid Build Coastguard Worker; CHECK: lay [[NEWDEST:%r[1-5]]], 4256(%r2) 123*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,[[NEWDEST]]), 3756(%r3) 124*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 256(256,[[NEWDEST]]), 4012(%r3) 125*9880d681SAndroid Build Coastguard Worker; CHECK: lay [[NEWSRC:%r[1-5]]], 4268(%r3) 126*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 512(256,[[NEWDEST]]), 0([[NEWSRC]]) 127*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 768(255,[[NEWDEST]]), 256([[NEWSRC]]) 128*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 129*9880d681SAndroid Build Coastguard Worker %dest = getelementptr i8, i8 *%srcbase, i64 4000 130*9880d681SAndroid Build Coastguard Worker %src = getelementptr i8, i8* %destbase, i64 3500 131*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 1279, i32 1, 132*9880d681SAndroid Build Coastguard Worker i1 false) 133*9880d681SAndroid Build Coastguard Worker ret void 134*9880d681SAndroid Build Coastguard Worker} 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker; ...and again with a destination frame base that goes out of range. 137*9880d681SAndroid Build Coastguard Workerdefine void @f12() { 138*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 139*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 140*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 4076(256,%r15), 2100(%r15) 141*9880d681SAndroid Build Coastguard Worker; CHECK: lay [[NEWDEST:%r[1-5]]], 4332(%r15) 142*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,[[NEWDEST]]), 2356(%r15) 143*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 256(256,[[NEWDEST]]), 2612(%r15) 144*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 512(256,[[NEWDEST]]), 2868(%r15) 145*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 768(255,[[NEWDEST]]), 3124(%r15) 146*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 147*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 148*9880d681SAndroid Build Coastguard Worker %arr = alloca [6000 x i8] 149*9880d681SAndroid Build Coastguard Worker %dest = getelementptr [6000 x i8], [6000 x i8] *%arr, i64 0, i64 3900 150*9880d681SAndroid Build Coastguard Worker %src = getelementptr [6000 x i8], [6000 x i8] *%arr, i64 0, i64 1924 151*9880d681SAndroid Build Coastguard Worker call void @foo(i8 *%dest, i8 *%src) 152*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 1279, i32 1, 153*9880d681SAndroid Build Coastguard Worker i1 false) 154*9880d681SAndroid Build Coastguard Worker call void @foo(i8 *%dest, i8 *%src) 155*9880d681SAndroid Build Coastguard Worker ret void 156*9880d681SAndroid Build Coastguard Worker} 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker; ...and again with a source frame base that goes out of range. 159*9880d681SAndroid Build Coastguard Workerdefine void @f13() { 160*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13: 161*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 162*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 200(256,%r15), 3826(%r15) 163*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 456(256,%r15), 4082(%r15) 164*9880d681SAndroid Build Coastguard Worker; CHECK: lay [[NEWSRC:%r[1-5]]], 4338(%r15) 165*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 712(256,%r15), 0([[NEWSRC]]) 166*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 968(256,%r15), 256([[NEWSRC]]) 167*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 1224(255,%r15), 512([[NEWSRC]]) 168*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 169*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 170*9880d681SAndroid Build Coastguard Worker %arr = alloca [6000 x i8] 171*9880d681SAndroid Build Coastguard Worker %dest = getelementptr [6000 x i8], [6000 x i8] *%arr, i64 0, i64 24 172*9880d681SAndroid Build Coastguard Worker %src = getelementptr [6000 x i8], [6000 x i8] *%arr, i64 0, i64 3650 173*9880d681SAndroid Build Coastguard Worker call void @foo(i8 *%dest, i8 *%src) 174*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 1279, i32 1, 175*9880d681SAndroid Build Coastguard Worker i1 false) 176*9880d681SAndroid Build Coastguard Worker call void @foo(i8 *%dest, i8 *%src) 177*9880d681SAndroid Build Coastguard Worker ret void 178*9880d681SAndroid Build Coastguard Worker} 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker; Test the last case that is done using straight-line code. 181*9880d681SAndroid Build Coastguard Workerdefine void @f14(i8 *%dest, i8 *%src) { 182*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14: 183*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,%r2), 0(%r3) 184*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 256(256,%r2), 256(%r3) 185*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 512(256,%r2), 512(%r3) 186*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 768(256,%r2), 768(%r3) 187*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 1024(256,%r2), 1024(%r3) 188*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 1280(256,%r2), 1280(%r3) 189*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 190*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 1536, i32 1, 191*9880d681SAndroid Build Coastguard Worker i1 false) 192*9880d681SAndroid Build Coastguard Worker ret void 193*9880d681SAndroid Build Coastguard Worker} 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Worker; Test the first case that is done using a loop. 196*9880d681SAndroid Build Coastguard Workerdefine void @f15(i8 *%dest, i8 *%src) { 197*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15: 198*9880d681SAndroid Build Coastguard Worker; CHECK: lghi [[COUNT:%r[0-5]]], 6 199*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL:\.L[^:]*]]: 200*9880d681SAndroid Build Coastguard Worker; CHECK: pfd 2, 768(%r2) 201*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(256,%r2), 0(%r3) 202*9880d681SAndroid Build Coastguard Worker; CHECK: la %r2, 256(%r2) 203*9880d681SAndroid Build Coastguard Worker; CHECK: la %r3, 256(%r3) 204*9880d681SAndroid Build Coastguard Worker; CHECK: brctg [[COUNT]], [[LABEL]] 205*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 0(1,%r2), 0(%r3) 206*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 207*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 1537, i32 1, 208*9880d681SAndroid Build Coastguard Worker i1 false) 209*9880d681SAndroid Build Coastguard Worker ret void 210*9880d681SAndroid Build Coastguard Worker} 211*9880d681SAndroid Build Coastguard Worker 212*9880d681SAndroid Build Coastguard Worker; ...and again with frame bases, where the base must be loaded into a 213*9880d681SAndroid Build Coastguard Worker; register before the loop. 214*9880d681SAndroid Build Coastguard Workerdefine void @f16() { 215*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16: 216*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 217*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: lghi [[COUNT:%r[0-5]]], 6 218*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: la [[BASE:%r[0-5]]], 160(%r15) 219*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL:\.L[^:]*]]: 220*9880d681SAndroid Build Coastguard Worker; CHECK: pfd 2, 2368([[BASE]]) 221*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 1600(256,[[BASE]]), 0([[BASE]]) 222*9880d681SAndroid Build Coastguard Worker; CHECK: la [[BASE]], 256([[BASE]]) 223*9880d681SAndroid Build Coastguard Worker; CHECK: brctg [[COUNT]], [[LABEL]] 224*9880d681SAndroid Build Coastguard Worker; CHECK: mvc 1600(1,[[BASE]]), 0([[BASE]]) 225*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 226*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 227*9880d681SAndroid Build Coastguard Worker %arr = alloca [3200 x i8] 228*9880d681SAndroid Build Coastguard Worker %dest = getelementptr [3200 x i8], [3200 x i8] *%arr, i64 0, i64 1600 229*9880d681SAndroid Build Coastguard Worker %src = getelementptr [3200 x i8], [3200 x i8] *%arr, i64 0, i64 0 230*9880d681SAndroid Build Coastguard Worker call void @foo(i8 *%dest, i8 *%src) 231*9880d681SAndroid Build Coastguard Worker call void @llvm.memcpy.p0i8.p0i8.i64(i8 *%dest, i8 *%src, i64 1537, i32 1, 232*9880d681SAndroid Build Coastguard Worker i1 false) 233*9880d681SAndroid Build Coastguard Worker call void @foo(i8 *%dest, i8 *%src) 234*9880d681SAndroid Build Coastguard Worker ret void 235*9880d681SAndroid Build Coastguard Worker} 236