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