1*f4a2713aSLionel Sambuc; Test 64-bit square root. 2*f4a2713aSLionel Sambuc; 3*f4a2713aSLionel Sambuc; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s 4*f4a2713aSLionel Sambuc 5*f4a2713aSLionel Sambucdeclare double @llvm.sqrt.f64(double %f) 6*f4a2713aSLionel Sambucdeclare double @sqrt(double) 7*f4a2713aSLionel Sambuc 8*f4a2713aSLionel Sambuc; Check register square root. 9*f4a2713aSLionel Sambucdefine double @f1(double %val) { 10*f4a2713aSLionel Sambuc; CHECK-LABEL: f1: 11*f4a2713aSLionel Sambuc; CHECK: sqdbr %f0, %f0 12*f4a2713aSLionel Sambuc; CHECK: br %r14 13*f4a2713aSLionel Sambuc %res = call double @llvm.sqrt.f64(double %val) 14*f4a2713aSLionel Sambuc ret double %res 15*f4a2713aSLionel Sambuc} 16*f4a2713aSLionel Sambuc 17*f4a2713aSLionel Sambuc; Check the low end of the SQDB range. 18*f4a2713aSLionel Sambucdefine double @f2(double *%ptr) { 19*f4a2713aSLionel Sambuc; CHECK-LABEL: f2: 20*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 0(%r2) 21*f4a2713aSLionel Sambuc; CHECK: br %r14 22*f4a2713aSLionel Sambuc %val = load double *%ptr 23*f4a2713aSLionel Sambuc %res = call double @llvm.sqrt.f64(double %val) 24*f4a2713aSLionel Sambuc ret double %res 25*f4a2713aSLionel Sambuc} 26*f4a2713aSLionel Sambuc 27*f4a2713aSLionel Sambuc; Check the high end of the aligned SQDB range. 28*f4a2713aSLionel Sambucdefine double @f3(double *%base) { 29*f4a2713aSLionel Sambuc; CHECK-LABEL: f3: 30*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 4088(%r2) 31*f4a2713aSLionel Sambuc; CHECK: br %r14 32*f4a2713aSLionel Sambuc %ptr = getelementptr double *%base, i64 511 33*f4a2713aSLionel Sambuc %val = load double *%ptr 34*f4a2713aSLionel Sambuc %res = call double @llvm.sqrt.f64(double %val) 35*f4a2713aSLionel Sambuc ret double %res 36*f4a2713aSLionel Sambuc} 37*f4a2713aSLionel Sambuc 38*f4a2713aSLionel Sambuc; Check the next doubleword up, which needs separate address logic. 39*f4a2713aSLionel Sambuc; Other sequences besides this one would be OK. 40*f4a2713aSLionel Sambucdefine double @f4(double *%base) { 41*f4a2713aSLionel Sambuc; CHECK-LABEL: f4: 42*f4a2713aSLionel Sambuc; CHECK: aghi %r2, 4096 43*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 0(%r2) 44*f4a2713aSLionel Sambuc; CHECK: br %r14 45*f4a2713aSLionel Sambuc %ptr = getelementptr double *%base, i64 512 46*f4a2713aSLionel Sambuc %val = load double *%ptr 47*f4a2713aSLionel Sambuc %res = call double @llvm.sqrt.f64(double %val) 48*f4a2713aSLionel Sambuc ret double %res 49*f4a2713aSLionel Sambuc} 50*f4a2713aSLionel Sambuc 51*f4a2713aSLionel Sambuc; Check negative displacements, which also need separate address logic. 52*f4a2713aSLionel Sambucdefine double @f5(double *%base) { 53*f4a2713aSLionel Sambuc; CHECK-LABEL: f5: 54*f4a2713aSLionel Sambuc; CHECK: aghi %r2, -8 55*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 0(%r2) 56*f4a2713aSLionel Sambuc; CHECK: br %r14 57*f4a2713aSLionel Sambuc %ptr = getelementptr double *%base, i64 -1 58*f4a2713aSLionel Sambuc %val = load double *%ptr 59*f4a2713aSLionel Sambuc %res = call double @llvm.sqrt.f64(double %val) 60*f4a2713aSLionel Sambuc ret double %res 61*f4a2713aSLionel Sambuc} 62*f4a2713aSLionel Sambuc 63*f4a2713aSLionel Sambuc; Check that SQDB allows indices. 64*f4a2713aSLionel Sambucdefine double @f6(double *%base, i64 %index) { 65*f4a2713aSLionel Sambuc; CHECK-LABEL: f6: 66*f4a2713aSLionel Sambuc; CHECK: sllg %r1, %r3, 3 67*f4a2713aSLionel Sambuc; CHECK: sqdb %f0, 800(%r1,%r2) 68*f4a2713aSLionel Sambuc; CHECK: br %r14 69*f4a2713aSLionel Sambuc %ptr1 = getelementptr double *%base, i64 %index 70*f4a2713aSLionel Sambuc %ptr2 = getelementptr double *%ptr1, i64 100 71*f4a2713aSLionel Sambuc %val = load double *%ptr2 72*f4a2713aSLionel Sambuc %res = call double @llvm.sqrt.f64(double %val) 73*f4a2713aSLionel Sambuc ret double %res 74*f4a2713aSLionel Sambuc} 75*f4a2713aSLionel Sambuc 76*f4a2713aSLionel Sambuc; Test a case where we spill the source of at least one SQDBR. We want 77*f4a2713aSLionel Sambuc; to use SQDB if possible. 78*f4a2713aSLionel Sambucdefine void @f7(double *%ptr) { 79*f4a2713aSLionel Sambuc; CHECK-LABEL: f7: 80*f4a2713aSLionel Sambuc; CHECK: sqdb {{%f[0-9]+}}, 160(%r15) 81*f4a2713aSLionel Sambuc; CHECK: br %r14 82*f4a2713aSLionel Sambuc %val0 = load volatile double *%ptr 83*f4a2713aSLionel Sambuc %val1 = load volatile double *%ptr 84*f4a2713aSLionel Sambuc %val2 = load volatile double *%ptr 85*f4a2713aSLionel Sambuc %val3 = load volatile double *%ptr 86*f4a2713aSLionel Sambuc %val4 = load volatile double *%ptr 87*f4a2713aSLionel Sambuc %val5 = load volatile double *%ptr 88*f4a2713aSLionel Sambuc %val6 = load volatile double *%ptr 89*f4a2713aSLionel Sambuc %val7 = load volatile double *%ptr 90*f4a2713aSLionel Sambuc %val8 = load volatile double *%ptr 91*f4a2713aSLionel Sambuc %val9 = load volatile double *%ptr 92*f4a2713aSLionel Sambuc %val10 = load volatile double *%ptr 93*f4a2713aSLionel Sambuc %val11 = load volatile double *%ptr 94*f4a2713aSLionel Sambuc %val12 = load volatile double *%ptr 95*f4a2713aSLionel Sambuc %val13 = load volatile double *%ptr 96*f4a2713aSLionel Sambuc %val14 = load volatile double *%ptr 97*f4a2713aSLionel Sambuc %val15 = load volatile double *%ptr 98*f4a2713aSLionel Sambuc %val16 = load volatile double *%ptr 99*f4a2713aSLionel Sambuc 100*f4a2713aSLionel Sambuc %sqrt0 = call double @llvm.sqrt.f64(double %val0) 101*f4a2713aSLionel Sambuc %sqrt1 = call double @llvm.sqrt.f64(double %val1) 102*f4a2713aSLionel Sambuc %sqrt2 = call double @llvm.sqrt.f64(double %val2) 103*f4a2713aSLionel Sambuc %sqrt3 = call double @llvm.sqrt.f64(double %val3) 104*f4a2713aSLionel Sambuc %sqrt4 = call double @llvm.sqrt.f64(double %val4) 105*f4a2713aSLionel Sambuc %sqrt5 = call double @llvm.sqrt.f64(double %val5) 106*f4a2713aSLionel Sambuc %sqrt6 = call double @llvm.sqrt.f64(double %val6) 107*f4a2713aSLionel Sambuc %sqrt7 = call double @llvm.sqrt.f64(double %val7) 108*f4a2713aSLionel Sambuc %sqrt8 = call double @llvm.sqrt.f64(double %val8) 109*f4a2713aSLionel Sambuc %sqrt9 = call double @llvm.sqrt.f64(double %val9) 110*f4a2713aSLionel Sambuc %sqrt10 = call double @llvm.sqrt.f64(double %val10) 111*f4a2713aSLionel Sambuc %sqrt11 = call double @llvm.sqrt.f64(double %val11) 112*f4a2713aSLionel Sambuc %sqrt12 = call double @llvm.sqrt.f64(double %val12) 113*f4a2713aSLionel Sambuc %sqrt13 = call double @llvm.sqrt.f64(double %val13) 114*f4a2713aSLionel Sambuc %sqrt14 = call double @llvm.sqrt.f64(double %val14) 115*f4a2713aSLionel Sambuc %sqrt15 = call double @llvm.sqrt.f64(double %val15) 116*f4a2713aSLionel Sambuc %sqrt16 = call double @llvm.sqrt.f64(double %val16) 117*f4a2713aSLionel Sambuc 118*f4a2713aSLionel Sambuc store volatile double %val0, double *%ptr 119*f4a2713aSLionel Sambuc store volatile double %val1, double *%ptr 120*f4a2713aSLionel Sambuc store volatile double %val2, double *%ptr 121*f4a2713aSLionel Sambuc store volatile double %val3, double *%ptr 122*f4a2713aSLionel Sambuc store volatile double %val4, double *%ptr 123*f4a2713aSLionel Sambuc store volatile double %val5, double *%ptr 124*f4a2713aSLionel Sambuc store volatile double %val6, double *%ptr 125*f4a2713aSLionel Sambuc store volatile double %val7, double *%ptr 126*f4a2713aSLionel Sambuc store volatile double %val8, double *%ptr 127*f4a2713aSLionel Sambuc store volatile double %val9, double *%ptr 128*f4a2713aSLionel Sambuc store volatile double %val10, double *%ptr 129*f4a2713aSLionel Sambuc store volatile double %val11, double *%ptr 130*f4a2713aSLionel Sambuc store volatile double %val12, double *%ptr 131*f4a2713aSLionel Sambuc store volatile double %val13, double *%ptr 132*f4a2713aSLionel Sambuc store volatile double %val14, double *%ptr 133*f4a2713aSLionel Sambuc store volatile double %val15, double *%ptr 134*f4a2713aSLionel Sambuc store volatile double %val16, double *%ptr 135*f4a2713aSLionel Sambuc 136*f4a2713aSLionel Sambuc store volatile double %sqrt0, double *%ptr 137*f4a2713aSLionel Sambuc store volatile double %sqrt1, double *%ptr 138*f4a2713aSLionel Sambuc store volatile double %sqrt2, double *%ptr 139*f4a2713aSLionel Sambuc store volatile double %sqrt3, double *%ptr 140*f4a2713aSLionel Sambuc store volatile double %sqrt4, double *%ptr 141*f4a2713aSLionel Sambuc store volatile double %sqrt5, double *%ptr 142*f4a2713aSLionel Sambuc store volatile double %sqrt6, double *%ptr 143*f4a2713aSLionel Sambuc store volatile double %sqrt7, double *%ptr 144*f4a2713aSLionel Sambuc store volatile double %sqrt8, double *%ptr 145*f4a2713aSLionel Sambuc store volatile double %sqrt9, double *%ptr 146*f4a2713aSLionel Sambuc store volatile double %sqrt10, double *%ptr 147*f4a2713aSLionel Sambuc store volatile double %sqrt11, double *%ptr 148*f4a2713aSLionel Sambuc store volatile double %sqrt12, double *%ptr 149*f4a2713aSLionel Sambuc store volatile double %sqrt13, double *%ptr 150*f4a2713aSLionel Sambuc store volatile double %sqrt14, double *%ptr 151*f4a2713aSLionel Sambuc store volatile double %sqrt15, double *%ptr 152*f4a2713aSLionel Sambuc store volatile double %sqrt16, double *%ptr 153*f4a2713aSLionel Sambuc 154*f4a2713aSLionel Sambuc ret void 155*f4a2713aSLionel Sambuc} 156*f4a2713aSLionel Sambuc 157*f4a2713aSLionel Sambuc; Check that a call to the normal sqrt function is lowered. 158*f4a2713aSLionel Sambucdefine double @f8(double %dummy, double %val) { 159*f4a2713aSLionel Sambuc; CHECK-LABEL: f8: 160*f4a2713aSLionel Sambuc; CHECK: sqdbr %f0, %f2 161*f4a2713aSLionel Sambuc; CHECK: cdbr %f0, %f0 162*f4a2713aSLionel Sambuc; CHECK: jo [[LABEL:\.L.*]] 163*f4a2713aSLionel Sambuc; CHECK: br %r14 164*f4a2713aSLionel Sambuc; CHECK: [[LABEL]]: 165*f4a2713aSLionel Sambuc; CHECK: ldr %f0, %f2 166*f4a2713aSLionel Sambuc; CHECK: jg sqrt@PLT 167*f4a2713aSLionel Sambuc %res = tail call double @sqrt(double %val) 168*f4a2713aSLionel Sambuc ret double %res 169*f4a2713aSLionel Sambuc} 170