175 lines · plain
1; Test strict 64-bit floating-point addition.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \4; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s5; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -verify-machineinstrs | FileCheck %s6declare double @foo()7declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)8 9; Check register addition.10define double @f1(double %f1, double %f2) #0 {11; CHECK-LABEL: f1:12; CHECK: adbr %f0, %f213; CHECK: br %r1414 %res = call double @llvm.experimental.constrained.fadd.f64(15 double %f1, double %f2,16 metadata !"round.dynamic",17 metadata !"fpexcept.strict") #018 ret double %res19}20 21; Check the low end of the ADB range.22define double @f2(double %f1, ptr %ptr) #0 {23; CHECK-LABEL: f2:24; CHECK: adb %f0, 0(%r2)25; CHECK: br %r1426 %f2 = load double, ptr %ptr27 %res = call double @llvm.experimental.constrained.fadd.f64(28 double %f1, double %f2,29 metadata !"round.dynamic",30 metadata !"fpexcept.strict") #031 ret double %res32}33 34; Check the high end of the aligned ADB range.35define double @f3(double %f1, ptr %base) #0 {36; CHECK-LABEL: f3:37; CHECK: adb %f0, 4088(%r2)38; CHECK: br %r1439 %ptr = getelementptr double, ptr %base, i64 51140 %f2 = load double, ptr %ptr41 %res = call double @llvm.experimental.constrained.fadd.f64(42 double %f1, double %f2,43 metadata !"round.dynamic",44 metadata !"fpexcept.strict") #045 ret double %res46}47 48; Check the next doubleword up, which needs separate address logic.49; Other sequences besides this one would be OK.50define double @f4(double %f1, ptr %base) #0 {51; CHECK-LABEL: f4:52; CHECK: aghi %r2, 409653; CHECK: adb %f0, 0(%r2)54; CHECK: br %r1455 %ptr = getelementptr double, ptr %base, i64 51256 %f2 = load double, ptr %ptr57 %res = call double @llvm.experimental.constrained.fadd.f64(58 double %f1, double %f2,59 metadata !"round.dynamic",60 metadata !"fpexcept.strict") #061 ret double %res62}63 64; Check negative displacements, which also need separate address logic.65define double @f5(double %f1, ptr %base) #0 {66; CHECK-LABEL: f5:67; CHECK: aghi %r2, -868; CHECK: adb %f0, 0(%r2)69; CHECK: br %r1470 %ptr = getelementptr double, ptr %base, i64 -171 %f2 = load double, ptr %ptr72 %res = call double @llvm.experimental.constrained.fadd.f64(73 double %f1, double %f2,74 metadata !"round.dynamic",75 metadata !"fpexcept.strict") #076 ret double %res77}78 79; Check that ADB allows indices.80define double @f6(double %f1, ptr %base, i64 %index) #0 {81; CHECK-LABEL: f6:82; CHECK: sllg %r1, %r3, 383; CHECK: adb %f0, 800(%r1,%r2)84; CHECK: br %r1485 %ptr1 = getelementptr double, ptr %base, i64 %index86 %ptr2 = getelementptr double, ptr %ptr1, i64 10087 %f2 = load double, ptr %ptr288 %res = call double @llvm.experimental.constrained.fadd.f64(89 double %f1, double %f2,90 metadata !"round.dynamic",91 metadata !"fpexcept.strict") #092 ret double %res93}94 95; Check that additions of spilled values can use ADB rather than ADBR.96define double @f7(ptr %ptr0) #0 {97; CHECK-LABEL: f7:98; CHECK: brasl %r14, foo@PLT99; CHECK-SCALAR: adb %f0, 160(%r15)100; CHECK: br %r14101 %ptr1 = getelementptr double, ptr %ptr0, i64 2102 %ptr2 = getelementptr double, ptr %ptr0, i64 4103 %ptr3 = getelementptr double, ptr %ptr0, i64 6104 %ptr4 = getelementptr double, ptr %ptr0, i64 8105 %ptr5 = getelementptr double, ptr %ptr0, i64 10106 %ptr6 = getelementptr double, ptr %ptr0, i64 12107 %ptr7 = getelementptr double, ptr %ptr0, i64 14108 %ptr8 = getelementptr double, ptr %ptr0, i64 16109 %ptr9 = getelementptr double, ptr %ptr0, i64 18110 %ptr10 = getelementptr double, ptr %ptr0, i64 20111 112 %val0 = load double, ptr %ptr0113 %val1 = load double, ptr %ptr1114 %val2 = load double, ptr %ptr2115 %val3 = load double, ptr %ptr3116 %val4 = load double, ptr %ptr4117 %val5 = load double, ptr %ptr5118 %val6 = load double, ptr %ptr6119 %val7 = load double, ptr %ptr7120 %val8 = load double, ptr %ptr8121 %val9 = load double, ptr %ptr9122 %val10 = load double, ptr %ptr10123 124 %ret = call double @foo() #0125 126 %add0 = call double @llvm.experimental.constrained.fadd.f64(127 double %ret, double %val0,128 metadata !"round.dynamic",129 metadata !"fpexcept.strict") #0130 %add1 = call double @llvm.experimental.constrained.fadd.f64(131 double %add0, double %val1,132 metadata !"round.dynamic",133 metadata !"fpexcept.strict") #0134 %add2 = call double @llvm.experimental.constrained.fadd.f64(135 double %add1, double %val2,136 metadata !"round.dynamic",137 metadata !"fpexcept.strict") #0138 %add3 = call double @llvm.experimental.constrained.fadd.f64(139 double %add2, double %val3,140 metadata !"round.dynamic",141 metadata !"fpexcept.strict") #0142 %add4 = call double @llvm.experimental.constrained.fadd.f64(143 double %add3, double %val4,144 metadata !"round.dynamic",145 metadata !"fpexcept.strict") #0146 %add5 = call double @llvm.experimental.constrained.fadd.f64(147 double %add4, double %val5,148 metadata !"round.dynamic",149 metadata !"fpexcept.strict") #0150 %add6 = call double @llvm.experimental.constrained.fadd.f64(151 double %add5, double %val6,152 metadata !"round.dynamic",153 metadata !"fpexcept.strict") #0154 %add7 = call double @llvm.experimental.constrained.fadd.f64(155 double %add6, double %val7,156 metadata !"round.dynamic",157 metadata !"fpexcept.strict") #0158 %add8 = call double @llvm.experimental.constrained.fadd.f64(159 double %add7, double %val8,160 metadata !"round.dynamic",161 metadata !"fpexcept.strict") #0162 %add9 = call double @llvm.experimental.constrained.fadd.f64(163 double %add8, double %val9,164 metadata !"round.dynamic",165 metadata !"fpexcept.strict") #0166 %add10 = call double @llvm.experimental.constrained.fadd.f64(167 double %add9, double %val10,168 metadata !"round.dynamic",169 metadata !"fpexcept.strict") #0170 171 ret double %add10172}173 174attributes #0 = { strictfp }175