1*9880d681SAndroid Build Coastguard Worker; Test memcmp using CLC, with i32 results. 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 signext i32 @memcmp(i8 *%src1, i8 *%src2, i64 %size) 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; Zero-length comparisons should be optimized away. 8*9880d681SAndroid Build Coastguard Workerdefine i32 @f1(i8 *%src1, i8 *%src2) { 9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 10*9880d681SAndroid Build Coastguard Worker; CHECK: lhi %r2, 0 11*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 12*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 0) 13*9880d681SAndroid Build Coastguard Worker ret i32 %res 14*9880d681SAndroid Build Coastguard Worker} 15*9880d681SAndroid Build Coastguard Worker 16*9880d681SAndroid Build Coastguard Worker; Check a case where the result is used as an integer. 17*9880d681SAndroid Build Coastguard Workerdefine i32 @f2(i8 *%src1, i8 *%src2) { 18*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 19*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(2,%r2), 0(%r3) 20*9880d681SAndroid Build Coastguard Worker; CHECK: ipm [[REG:%r[0-5]]] 21*9880d681SAndroid Build Coastguard Worker; CHECK: srl [[REG]], 28 22*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, [[REG]], 31 23*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 24*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 2) 25*9880d681SAndroid Build Coastguard Worker ret i32 %res 26*9880d681SAndroid Build Coastguard Worker} 27*9880d681SAndroid Build Coastguard Worker 28*9880d681SAndroid Build Coastguard Worker; Check a case where the result is tested for equality. 29*9880d681SAndroid Build Coastguard Workerdefine void @f3(i8 *%src1, i8 *%src2, i32 *%dest) { 30*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 31*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(3,%r2), 0(%r3) 32*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ber %r14 33*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 34*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 3) 35*9880d681SAndroid Build Coastguard Worker %cmp = icmp eq i32 %res, 0 36*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %store 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Workerstore: 39*9880d681SAndroid Build Coastguard Worker store i32 0, i32 *%dest 40*9880d681SAndroid Build Coastguard Worker br label %exit 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Workerexit: 43*9880d681SAndroid Build Coastguard Worker ret void 44*9880d681SAndroid Build Coastguard Worker} 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker; Check a case where the result is tested for inequality. 47*9880d681SAndroid Build Coastguard Workerdefine void @f4(i8 *%src1, i8 *%src2, i32 *%dest) { 48*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 49*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(4,%r2), 0(%r3) 50*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blhr %r14 51*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 52*9880d681SAndroid Build Coastguard Workerentry: 53*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 4) 54*9880d681SAndroid Build Coastguard Worker %cmp = icmp ne i32 %res, 0 55*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %store 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Workerstore: 58*9880d681SAndroid Build Coastguard Worker store i32 0, i32 *%dest 59*9880d681SAndroid Build Coastguard Worker br label %exit 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Workerexit: 62*9880d681SAndroid Build Coastguard Worker ret void 63*9880d681SAndroid Build Coastguard Worker} 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker; Check a case where the result is tested via slt. 66*9880d681SAndroid Build Coastguard Workerdefine void @f5(i8 *%src1, i8 *%src2, i32 *%dest) { 67*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 68*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(5,%r2), 0(%r3) 69*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 70*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 71*9880d681SAndroid Build Coastguard Workerentry: 72*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 5) 73*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %res, 0 74*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %store 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Workerstore: 77*9880d681SAndroid Build Coastguard Worker store i32 0, i32 *%dest 78*9880d681SAndroid Build Coastguard Worker br label %exit 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Workerexit: 81*9880d681SAndroid Build Coastguard Worker ret void 82*9880d681SAndroid Build Coastguard Worker} 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Worker; Check a case where the result is tested for sgt. 85*9880d681SAndroid Build Coastguard Workerdefine void @f6(i8 *%src1, i8 *%src2, i32 *%dest) { 86*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 87*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(6,%r2), 0(%r3) 88*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bhr %r14 89*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 90*9880d681SAndroid Build Coastguard Workerentry: 91*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 6) 92*9880d681SAndroid Build Coastguard Worker %cmp = icmp sgt i32 %res, 0 93*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %store 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Workerstore: 96*9880d681SAndroid Build Coastguard Worker store i32 0, i32 *%dest 97*9880d681SAndroid Build Coastguard Worker br label %exit 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Workerexit: 100*9880d681SAndroid Build Coastguard Worker ret void 101*9880d681SAndroid Build Coastguard Worker} 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; Check the upper end of the CLC range. Here the result is used both as 104*9880d681SAndroid Build Coastguard Worker; an integer and for branching. 105*9880d681SAndroid Build Coastguard Workerdefine i32 @f7(i8 *%src1, i8 *%src2, i32 *%dest) { 106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 107*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(256,%r2), 0(%r3) 108*9880d681SAndroid Build Coastguard Worker; CHECK: ipm [[REG:%r[0-5]]] 109*9880d681SAndroid Build Coastguard Worker; CHECK: srl [[REG]], 28 110*9880d681SAndroid Build Coastguard Worker; CHECK: rll %r2, [[REG]], 31 111*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14 112*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 113*9880d681SAndroid Build Coastguard Workerentry: 114*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 256) 115*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %res, 0 116*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %store 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Workerstore: 119*9880d681SAndroid Build Coastguard Worker store i32 0, i32 *%dest 120*9880d681SAndroid Build Coastguard Worker br label %exit 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerexit: 123*9880d681SAndroid Build Coastguard Worker ret i32 %res 124*9880d681SAndroid Build Coastguard Worker} 125*9880d681SAndroid Build Coastguard Worker 126*9880d681SAndroid Build Coastguard Worker; 257 bytes needs two CLCs. 127*9880d681SAndroid Build Coastguard Workerdefine i32 @f8(i8 *%src1, i8 *%src2) { 128*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 129*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(256,%r2), 0(%r3) 130*9880d681SAndroid Build Coastguard Worker; CHECK: jlh [[LABEL:\..*]] 131*9880d681SAndroid Build Coastguard Worker; CHECK: clc 256(1,%r2), 256(%r3) 132*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 133*9880d681SAndroid Build Coastguard Worker; CHECK: ipm [[REG:%r[0-5]]] 134*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 135*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) 136*9880d681SAndroid Build Coastguard Worker ret i32 %res 137*9880d681SAndroid Build Coastguard Worker} 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker; Test a comparison of 258 bytes in which the CC result can be used directly. 140*9880d681SAndroid Build Coastguard Workerdefine void @f9(i8 *%src1, i8 *%src2, i32 *%dest) { 141*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 142*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(256,%r2), 0(%r3) 143*9880d681SAndroid Build Coastguard Worker; CHECK: jlh [[LABEL:\..*]] 144*9880d681SAndroid Build Coastguard Worker; CHECK: clc 256(1,%r2), 256(%r3) 145*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 146*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: blr %r14 147*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 148*9880d681SAndroid Build Coastguard Workerentry: 149*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) 150*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %res, 0 151*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %store 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Workerstore: 154*9880d681SAndroid Build Coastguard Worker store i32 0, i32 *%dest 155*9880d681SAndroid Build Coastguard Worker br label %exit 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Workerexit: 158*9880d681SAndroid Build Coastguard Worker ret void 159*9880d681SAndroid Build Coastguard Worker} 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker; Test the largest size that can use two CLCs. 162*9880d681SAndroid Build Coastguard Workerdefine i32 @f10(i8 *%src1, i8 *%src2) { 163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 164*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(256,%r2), 0(%r3) 165*9880d681SAndroid Build Coastguard Worker; CHECK: jlh [[LABEL:\..*]] 166*9880d681SAndroid Build Coastguard Worker; CHECK: clc 256(256,%r2), 256(%r3) 167*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 168*9880d681SAndroid Build Coastguard Worker; CHECK: ipm [[REG:%r[0-5]]] 169*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 170*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 512) 171*9880d681SAndroid Build Coastguard Worker ret i32 %res 172*9880d681SAndroid Build Coastguard Worker} 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker; Test the smallest size that needs 3 CLCs. 175*9880d681SAndroid Build Coastguard Workerdefine i32 @f11(i8 *%src1, i8 *%src2) { 176*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 177*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(256,%r2), 0(%r3) 178*9880d681SAndroid Build Coastguard Worker; CHECK: jlh [[LABEL:\..*]] 179*9880d681SAndroid Build Coastguard Worker; CHECK: clc 256(256,%r2), 256(%r3) 180*9880d681SAndroid Build Coastguard Worker; CHECK: jlh [[LABEL]] 181*9880d681SAndroid Build Coastguard Worker; CHECK: clc 512(1,%r2), 512(%r3) 182*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 183*9880d681SAndroid Build Coastguard Worker; CHECK: ipm [[REG:%r[0-5]]] 184*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 185*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 513) 186*9880d681SAndroid Build Coastguard Worker ret i32 %res 187*9880d681SAndroid Build Coastguard Worker} 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Worker; Test the largest size than can use 3 CLCs. 190*9880d681SAndroid Build Coastguard Workerdefine i32 @f12(i8 *%src1, i8 *%src2) { 191*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 192*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(256,%r2), 0(%r3) 193*9880d681SAndroid Build Coastguard Worker; CHECK: jlh [[LABEL:\..*]] 194*9880d681SAndroid Build Coastguard Worker; CHECK: clc 256(256,%r2), 256(%r3) 195*9880d681SAndroid Build Coastguard Worker; CHECK: jlh [[LABEL]] 196*9880d681SAndroid Build Coastguard Worker; CHECK: clc 512(256,%r2), 512(%r3) 197*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 198*9880d681SAndroid Build Coastguard Worker; CHECK: ipm [[REG:%r[0-5]]] 199*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 200*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 768) 201*9880d681SAndroid Build Coastguard Worker ret i32 %res 202*9880d681SAndroid Build Coastguard Worker} 203*9880d681SAndroid Build Coastguard Worker 204*9880d681SAndroid Build Coastguard Worker; The next size up uses a loop instead. We leave the more complicated 205*9880d681SAndroid Build Coastguard Worker; loop tests to memcpy-01.ll, which shares the same form. 206*9880d681SAndroid Build Coastguard Workerdefine i32 @f13(i8 *%src1, i8 *%src2) { 207*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13: 208*9880d681SAndroid Build Coastguard Worker; CHECK: lghi [[COUNT:%r[0-5]]], 3 209*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:.L[^:]*]]: 210*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(256,%r2), 0(%r3) 211*9880d681SAndroid Build Coastguard Worker; CHECK: jlh [[LABEL:\..*]] 212*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: la %r2, 256(%r2) 213*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: la %r3, 256(%r3) 214*9880d681SAndroid Build Coastguard Worker; CHECK: brctg [[COUNT]], [[LOOP]] 215*9880d681SAndroid Build Coastguard Worker; CHECK: clc 0(1,%r2), 0(%r3) 216*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]: 217*9880d681SAndroid Build Coastguard Worker; CHECK: ipm [[REG:%r[0-5]]] 218*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 219*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 769) 220*9880d681SAndroid Build Coastguard Worker ret i32 %res 221*9880d681SAndroid Build Coastguard Worker} 222