1*9880d681SAndroid Build Coastguard Worker; Test 64-bit floating-point comparison. The tests assume a z10 implementation 2*9880d681SAndroid Build Coastguard Worker; of select, using conditional branches rather than LOCGR. 3*9880d681SAndroid Build Coastguard Worker; 4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \ 5*9880d681SAndroid Build Coastguard Worker; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s 6*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -verify-machineinstrs\ 7*9880d681SAndroid Build Coastguard Worker; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Workerdeclare double @foo() 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Worker; Check comparison with registers. 12*9880d681SAndroid Build Coastguard Workerdefine i64 @f1(i64 %a, i64 %b, double %f1, double %f2) { 13*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1: 14*9880d681SAndroid Build Coastguard Worker; CHECK: cdbr %f0, %f2 15*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR-NEXT: ber %r14 16*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: lgr %r2, %r3 17*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR-NEXT: locgrne %r2, %r3 18*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 19*9880d681SAndroid Build Coastguard Worker %cond = fcmp oeq double %f1, %f2 20*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %a, i64 %b 21*9880d681SAndroid Build Coastguard Worker ret i64 %res 22*9880d681SAndroid Build Coastguard Worker} 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker; Check the low end of the CDB range. 25*9880d681SAndroid Build Coastguard Workerdefine i64 @f2(i64 %a, i64 %b, double %f1, double *%ptr) { 26*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2: 27*9880d681SAndroid Build Coastguard Worker; CHECK: cdb %f0, 0(%r4) 28*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR-NEXT: ber %r14 29*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: lgr %r2, %r3 30*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR-NEXT: locgrne %r2, %r3 31*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 32*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr 33*9880d681SAndroid Build Coastguard Worker %cond = fcmp oeq double %f1, %f2 34*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %a, i64 %b 35*9880d681SAndroid Build Coastguard Worker ret i64 %res 36*9880d681SAndroid Build Coastguard Worker} 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned CDB range. 39*9880d681SAndroid Build Coastguard Workerdefine i64 @f3(i64 %a, i64 %b, double %f1, double *%base) { 40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 41*9880d681SAndroid Build Coastguard Worker; CHECK: cdb %f0, 4088(%r4) 42*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR-NEXT: ber %r14 43*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: lgr %r2, %r3 44*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR-NEXT: locgrne %r2, %r3 45*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 46*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr double, double *%base, i64 511 47*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr 48*9880d681SAndroid Build Coastguard Worker %cond = fcmp oeq double %f1, %f2 49*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %a, i64 %b 50*9880d681SAndroid Build Coastguard Worker ret i64 %res 51*9880d681SAndroid Build Coastguard Worker} 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker; Check the next doubleword up, which needs separate address logic. 54*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK. 55*9880d681SAndroid Build Coastguard Workerdefine i64 @f4(i64 %a, i64 %b, double %f1, double *%base) { 56*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 57*9880d681SAndroid Build Coastguard Worker; CHECK: aghi %r4, 4096 58*9880d681SAndroid Build Coastguard Worker; CHECK: cdb %f0, 0(%r4) 59*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR-NEXT: ber %r14 60*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: lgr %r2, %r3 61*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR-NEXT: locgrne %r2, %r3 62*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 63*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr double, double *%base, i64 512 64*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr 65*9880d681SAndroid Build Coastguard Worker %cond = fcmp oeq double %f1, %f2 66*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %a, i64 %b 67*9880d681SAndroid Build Coastguard Worker ret i64 %res 68*9880d681SAndroid Build Coastguard Worker} 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker; Check negative displacements, which also need separate address logic. 71*9880d681SAndroid Build Coastguard Workerdefine i64 @f5(i64 %a, i64 %b, double %f1, double *%base) { 72*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 73*9880d681SAndroid Build Coastguard Worker; CHECK: aghi %r4, -8 74*9880d681SAndroid Build Coastguard Worker; CHECK: cdb %f0, 0(%r4) 75*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR-NEXT: ber %r14 76*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: lgr %r2, %r3 77*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR-NEXT: locgrne %r2, %r3 78*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 79*9880d681SAndroid Build Coastguard Worker %ptr = getelementptr double, double *%base, i64 -1 80*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr 81*9880d681SAndroid Build Coastguard Worker %cond = fcmp oeq double %f1, %f2 82*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %a, i64 %b 83*9880d681SAndroid Build Coastguard Worker ret i64 %res 84*9880d681SAndroid Build Coastguard Worker} 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Worker; Check that CDB allows indices. 87*9880d681SAndroid Build Coastguard Workerdefine i64 @f6(i64 %a, i64 %b, double %f1, double *%base, i64 %index) { 88*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6: 89*9880d681SAndroid Build Coastguard Worker; CHECK: sllg %r1, %r5, 3 90*9880d681SAndroid Build Coastguard Worker; CHECK: cdb %f0, 800(%r1,%r4) 91*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR-NEXT: ber %r14 92*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: lgr %r2, %r3 93*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR-NEXT: locgrne %r2, %r3 94*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 95*9880d681SAndroid Build Coastguard Worker %ptr1 = getelementptr double, double *%base, i64 %index 96*9880d681SAndroid Build Coastguard Worker %ptr2 = getelementptr double, double *%ptr1, i64 100 97*9880d681SAndroid Build Coastguard Worker %f2 = load double , double *%ptr2 98*9880d681SAndroid Build Coastguard Worker %cond = fcmp oeq double %f1, %f2 99*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %a, i64 %b 100*9880d681SAndroid Build Coastguard Worker ret i64 %res 101*9880d681SAndroid Build Coastguard Worker} 102*9880d681SAndroid Build Coastguard Worker 103*9880d681SAndroid Build Coastguard Worker; Check that comparisons of spilled values can use CDB rather than CDBR. 104*9880d681SAndroid Build Coastguard Workerdefine double @f7(double *%ptr0) { 105*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7: 106*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT 107*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: cdb {{%f[0-9]+}}, 160(%r15) 108*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 109*9880d681SAndroid Build Coastguard Worker %ptr1 = getelementptr double, double *%ptr0, i64 2 110*9880d681SAndroid Build Coastguard Worker %ptr2 = getelementptr double, double *%ptr0, i64 4 111*9880d681SAndroid Build Coastguard Worker %ptr3 = getelementptr double, double *%ptr0, i64 6 112*9880d681SAndroid Build Coastguard Worker %ptr4 = getelementptr double, double *%ptr0, i64 8 113*9880d681SAndroid Build Coastguard Worker %ptr5 = getelementptr double, double *%ptr0, i64 10 114*9880d681SAndroid Build Coastguard Worker %ptr6 = getelementptr double, double *%ptr0, i64 12 115*9880d681SAndroid Build Coastguard Worker %ptr7 = getelementptr double, double *%ptr0, i64 14 116*9880d681SAndroid Build Coastguard Worker %ptr8 = getelementptr double, double *%ptr0, i64 16 117*9880d681SAndroid Build Coastguard Worker %ptr9 = getelementptr double, double *%ptr0, i64 18 118*9880d681SAndroid Build Coastguard Worker %ptr10 = getelementptr double, double *%ptr0, i64 20 119*9880d681SAndroid Build Coastguard Worker 120*9880d681SAndroid Build Coastguard Worker %val0 = load double , double *%ptr0 121*9880d681SAndroid Build Coastguard Worker %val1 = load double , double *%ptr1 122*9880d681SAndroid Build Coastguard Worker %val2 = load double , double *%ptr2 123*9880d681SAndroid Build Coastguard Worker %val3 = load double , double *%ptr3 124*9880d681SAndroid Build Coastguard Worker %val4 = load double , double *%ptr4 125*9880d681SAndroid Build Coastguard Worker %val5 = load double , double *%ptr5 126*9880d681SAndroid Build Coastguard Worker %val6 = load double , double *%ptr6 127*9880d681SAndroid Build Coastguard Worker %val7 = load double , double *%ptr7 128*9880d681SAndroid Build Coastguard Worker %val8 = load double , double *%ptr8 129*9880d681SAndroid Build Coastguard Worker %val9 = load double , double *%ptr9 130*9880d681SAndroid Build Coastguard Worker %val10 = load double , double *%ptr10 131*9880d681SAndroid Build Coastguard Worker 132*9880d681SAndroid Build Coastguard Worker %ret = call double @foo() 133*9880d681SAndroid Build Coastguard Worker 134*9880d681SAndroid Build Coastguard Worker %cmp0 = fcmp olt double %ret, %val0 135*9880d681SAndroid Build Coastguard Worker %cmp1 = fcmp olt double %ret, %val1 136*9880d681SAndroid Build Coastguard Worker %cmp2 = fcmp olt double %ret, %val2 137*9880d681SAndroid Build Coastguard Worker %cmp3 = fcmp olt double %ret, %val3 138*9880d681SAndroid Build Coastguard Worker %cmp4 = fcmp olt double %ret, %val4 139*9880d681SAndroid Build Coastguard Worker %cmp5 = fcmp olt double %ret, %val5 140*9880d681SAndroid Build Coastguard Worker %cmp6 = fcmp olt double %ret, %val6 141*9880d681SAndroid Build Coastguard Worker %cmp7 = fcmp olt double %ret, %val7 142*9880d681SAndroid Build Coastguard Worker %cmp8 = fcmp olt double %ret, %val8 143*9880d681SAndroid Build Coastguard Worker %cmp9 = fcmp olt double %ret, %val9 144*9880d681SAndroid Build Coastguard Worker %cmp10 = fcmp olt double %ret, %val10 145*9880d681SAndroid Build Coastguard Worker 146*9880d681SAndroid Build Coastguard Worker %sel0 = select i1 %cmp0, double %ret, double 0.0 147*9880d681SAndroid Build Coastguard Worker %sel1 = select i1 %cmp1, double %sel0, double 1.0 148*9880d681SAndroid Build Coastguard Worker %sel2 = select i1 %cmp2, double %sel1, double 2.0 149*9880d681SAndroid Build Coastguard Worker %sel3 = select i1 %cmp3, double %sel2, double 3.0 150*9880d681SAndroid Build Coastguard Worker %sel4 = select i1 %cmp4, double %sel3, double 4.0 151*9880d681SAndroid Build Coastguard Worker %sel5 = select i1 %cmp5, double %sel4, double 5.0 152*9880d681SAndroid Build Coastguard Worker %sel6 = select i1 %cmp6, double %sel5, double 6.0 153*9880d681SAndroid Build Coastguard Worker %sel7 = select i1 %cmp7, double %sel6, double 7.0 154*9880d681SAndroid Build Coastguard Worker %sel8 = select i1 %cmp8, double %sel7, double 8.0 155*9880d681SAndroid Build Coastguard Worker %sel9 = select i1 %cmp9, double %sel8, double 9.0 156*9880d681SAndroid Build Coastguard Worker %sel10 = select i1 %cmp10, double %sel9, double 10.0 157*9880d681SAndroid Build Coastguard Worker 158*9880d681SAndroid Build Coastguard Worker ret double %sel10 159*9880d681SAndroid Build Coastguard Worker} 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker; Check comparison with zero. 162*9880d681SAndroid Build Coastguard Workerdefine i64 @f8(i64 %a, i64 %b, double %f) { 163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8: 164*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: ltdbr %f0, %f0 165*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR-NEXT: ber %r14 166*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: lgr %r2, %r3 167*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR: ltdbr %f0, %f0 168*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR-NEXT: locgrne %r2, %r3 169*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 170*9880d681SAndroid Build Coastguard Worker %cond = fcmp oeq double %f, 0.0 171*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %a, i64 %b 172*9880d681SAndroid Build Coastguard Worker ret i64 %res 173*9880d681SAndroid Build Coastguard Worker} 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker; Check the comparison can be reversed if that allows CDB to be used, 176*9880d681SAndroid Build Coastguard Workerdefine i64 @f9(i64 %a, i64 %b, double %f2, double *%ptr) { 177*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9: 178*9880d681SAndroid Build Coastguard Worker; CHECK: cdb %f0, 0(%r4) 179*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR-NEXT: blr %r14 180*9880d681SAndroid Build Coastguard Worker; CHECK-SCALAR: lgr %r2, %r3 181*9880d681SAndroid Build Coastguard Worker; CHECK-VECTOR-NEXT: locgrnl %r2, %r3 182*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14 183*9880d681SAndroid Build Coastguard Worker %f1 = load double , double *%ptr 184*9880d681SAndroid Build Coastguard Worker %cond = fcmp ogt double %f1, %f2 185*9880d681SAndroid Build Coastguard Worker %res = select i1 %cond, i64 %a, i64 %b 186*9880d681SAndroid Build Coastguard Worker ret i64 %res 187*9880d681SAndroid Build Coastguard Worker} 188