1*9880d681SAndroid Build Coastguard Worker; Test that memcmp won't be converted to CLC if calls are 2*9880d681SAndroid Build Coastguard Worker; marked with nobuiltin, eg. for sanitizers. 3*9880d681SAndroid Build Coastguard Worker; 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workerdeclare signext i32 @memcmp(i8 *%src1, i8 *%src2, i64 %size) 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; Zero-length comparisons should be optimized away. 9*9880d681SAndroid Build Coastguard Workerdefine i32 @f1(i8 *%src1, i8 *%src2) { 10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 11*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clc 12*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 13*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 14*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 0) nobuiltin 15*9880d681SAndroid Build Coastguard Worker ret i32 %res 16*9880d681SAndroid Build Coastguard Worker} 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker; Check a case where the result is used as an integer. 19*9880d681SAndroid Build Coastguard Workerdefine i32 @f2(i8 *%src1, i8 *%src2) { 20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 21*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clc 22*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 23*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 24*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 2) nobuiltin 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-NOT: clc 32*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 33*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 34*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 3) nobuiltin 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-NOT: clc 50*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 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) nobuiltin 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-NOT: clc 69*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 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) nobuiltin 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-NOT: clc 88*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 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) nobuiltin 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-NOT: clc 108*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 109*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 110*9880d681SAndroid Build Coastguard Workerentry: 111*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 256) nobuiltin 112*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %res, 0 113*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %store 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Workerstore: 116*9880d681SAndroid Build Coastguard Worker store i32 0, i32 *%dest 117*9880d681SAndroid Build Coastguard Worker br label %exit 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Workerexit: 120*9880d681SAndroid Build Coastguard Worker ret i32 %res 121*9880d681SAndroid Build Coastguard Worker} 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker; 257 bytes needs two CLCs. 124*9880d681SAndroid Build Coastguard Workerdefine i32 @f8(i8 *%src1, i8 *%src2) { 125*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 126*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clc 127*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 128*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 129*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) nobuiltin 130*9880d681SAndroid Build Coastguard Worker ret i32 %res 131*9880d681SAndroid Build Coastguard Worker} 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker; Test a comparison of 258 bytes in which the CC result can be used directly. 134*9880d681SAndroid Build Coastguard Workerdefine void @f9(i8 *%src1, i8 *%src2, i32 *%dest) { 135*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 136*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clc 137*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 138*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 139*9880d681SAndroid Build Coastguard Workerentry: 140*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 257) nobuiltin 141*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %res, 0 142*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %exit, label %store 143*9880d681SAndroid Build Coastguard Worker 144*9880d681SAndroid Build Coastguard Workerstore: 145*9880d681SAndroid Build Coastguard Worker store i32 0, i32 *%dest 146*9880d681SAndroid Build Coastguard Worker br label %exit 147*9880d681SAndroid Build Coastguard Worker 148*9880d681SAndroid Build Coastguard Workerexit: 149*9880d681SAndroid Build Coastguard Worker ret void 150*9880d681SAndroid Build Coastguard Worker} 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker; Test the largest size that can use two CLCs. 153*9880d681SAndroid Build Coastguard Workerdefine i32 @f10(i8 *%src1, i8 *%src2) { 154*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10: 155*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clc 156*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 157*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 158*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 512) nobuiltin 159*9880d681SAndroid Build Coastguard Worker ret i32 %res 160*9880d681SAndroid Build Coastguard Worker} 161*9880d681SAndroid Build Coastguard Worker 162*9880d681SAndroid Build Coastguard Worker; Test the smallest size that needs 3 CLCs. 163*9880d681SAndroid Build Coastguard Workerdefine i32 @f11(i8 *%src1, i8 *%src2) { 164*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11: 165*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clc 166*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 167*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 168*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 513) nobuiltin 169*9880d681SAndroid Build Coastguard Worker ret i32 %res 170*9880d681SAndroid Build Coastguard Worker} 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Worker; Test the largest size than can use 3 CLCs. 173*9880d681SAndroid Build Coastguard Workerdefine i32 @f12(i8 *%src1, i8 *%src2) { 174*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12: 175*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clc 176*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 177*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 178*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 768) nobuiltin 179*9880d681SAndroid Build Coastguard Worker ret i32 %res 180*9880d681SAndroid Build Coastguard Worker} 181*9880d681SAndroid Build Coastguard Worker 182*9880d681SAndroid Build Coastguard Worker; The next size up uses a loop instead. We leave the more complicated 183*9880d681SAndroid Build Coastguard Worker; loop tests to memcpy-01.ll, which shares the same form. 184*9880d681SAndroid Build Coastguard Workerdefine i32 @f13(i8 *%src1, i8 *%src2) { 185*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13: 186*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: clc 187*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, memcmp 188*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 189*9880d681SAndroid Build Coastguard Worker %res = call i32 @memcmp(i8 *%src1, i8 *%src2, i64 769) nobuiltin 190*9880d681SAndroid Build Coastguard Worker ret i32 %res 191*9880d681SAndroid Build Coastguard Worker} 192