415 lines · plain
1; Test strict multiplication of two f32s, producing an f64 result.2;3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s4 5declare float @foo()6declare double @llvm.experimental.constrained.fmul.f64(double, double, metadata, metadata)7declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)8declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata)9declare double @llvm.experimental.constrained.fpext.f64.f32(float, metadata)10 11; Check register multiplication.12define double @f1(float %f1, float %f2) #0 {13; CHECK-LABEL: f1:14; CHECK: mdebr %f0, %f215; CHECK: br %r1416 %f1x = call double @llvm.experimental.constrained.fpext.f64.f32(17 float %f1,18 metadata !"fpexcept.strict") #019 %f2x = call double @llvm.experimental.constrained.fpext.f64.f32(20 float %f2,21 metadata !"fpexcept.strict") #022 %res = call double @llvm.experimental.constrained.fmul.f64(23 double %f1x, double %f2x,24 metadata !"round.dynamic",25 metadata !"fpexcept.strict") #026 ret double %res27}28 29; Check the low end of the MDEB range.30define double @f2(float %f1, ptr %ptr) #0 {31; CHECK-LABEL: f2:32; CHECK: mdeb %f0, 0(%r2)33; CHECK: br %r1434 %f2 = load float, ptr %ptr35 %f1x = call double @llvm.experimental.constrained.fpext.f64.f32(36 float %f1,37 metadata !"fpexcept.strict") #038 %f2x = call double @llvm.experimental.constrained.fpext.f64.f32(39 float %f2,40 metadata !"fpexcept.strict") #041 %res = call double @llvm.experimental.constrained.fmul.f64(42 double %f1x, double %f2x,43 metadata !"round.dynamic",44 metadata !"fpexcept.strict") #045 ret double %res46}47 48; Check the high end of the aligned MDEB range.49define double @f3(float %f1, ptr %base) #0 {50; CHECK-LABEL: f3:51; CHECK: mdeb %f0, 4092(%r2)52; CHECK: br %r1453 %ptr = getelementptr float, ptr %base, i64 102354 %f2 = load float, ptr %ptr55 %f1x = call double @llvm.experimental.constrained.fpext.f64.f32(56 float %f1,57 metadata !"fpexcept.strict") #058 %f2x = call double @llvm.experimental.constrained.fpext.f64.f32(59 float %f2,60 metadata !"fpexcept.strict") #061 %res = call double @llvm.experimental.constrained.fmul.f64(62 double %f1x, double %f2x,63 metadata !"round.dynamic",64 metadata !"fpexcept.strict") #065 ret double %res66}67 68; Check the next word up, which needs separate address logic.69; Other sequences besides this one would be OK.70define double @f4(float %f1, ptr %base) #0 {71; CHECK-LABEL: f4:72; CHECK: aghi %r2, 409673; CHECK: mdeb %f0, 0(%r2)74; CHECK: br %r1475 %ptr = getelementptr float, ptr %base, i64 102476 %f2 = load float, ptr %ptr77 %f1x = call double @llvm.experimental.constrained.fpext.f64.f32(78 float %f1,79 metadata !"fpexcept.strict") #080 %f2x = call double @llvm.experimental.constrained.fpext.f64.f32(81 float %f2,82 metadata !"fpexcept.strict") #083 %res = call double @llvm.experimental.constrained.fmul.f64(84 double %f1x, double %f2x,85 metadata !"round.dynamic",86 metadata !"fpexcept.strict") #087 ret double %res88}89 90; Check negative displacements, which also need separate address logic.91define double @f5(float %f1, ptr %base) #0 {92; CHECK-LABEL: f5:93; CHECK: aghi %r2, -494; CHECK: mdeb %f0, 0(%r2)95; CHECK: br %r1496 %ptr = getelementptr float, ptr %base, i64 -197 %f2 = load float, ptr %ptr98 %f1x = call double @llvm.experimental.constrained.fpext.f64.f32(99 float %f1,100 metadata !"fpexcept.strict") #0101 %f2x = call double @llvm.experimental.constrained.fpext.f64.f32(102 float %f2,103 metadata !"fpexcept.strict") #0104 %res = call double @llvm.experimental.constrained.fmul.f64(105 double %f1x, double %f2x,106 metadata !"round.dynamic",107 metadata !"fpexcept.strict") #0108 ret double %res109}110 111; Check that MDEB allows indices.112define double @f6(float %f1, ptr %base, i64 %index) #0 {113; CHECK-LABEL: f6:114; CHECK: sllg %r1, %r3, 2115; CHECK: mdeb %f0, 400(%r1,%r2)116; CHECK: br %r14117 %ptr1 = getelementptr float, ptr %base, i64 %index118 %ptr2 = getelementptr float, ptr %ptr1, i64 100119 %f2 = load float, ptr %ptr2120 %f1x = call double @llvm.experimental.constrained.fpext.f64.f32(121 float %f1,122 metadata !"fpexcept.strict") #0123 %f2x = call double @llvm.experimental.constrained.fpext.f64.f32(124 float %f2,125 metadata !"fpexcept.strict") #0126 %res = call double @llvm.experimental.constrained.fmul.f64(127 double %f1x, double %f2x,128 metadata !"round.dynamic",129 metadata !"fpexcept.strict") #0130 ret double %res131}132 133; Check that multiplications of spilled values can use MDEB rather than MDEBR.134define float @f7(ptr %ptr0) #0 {135; CHECK-LABEL: f7:136; CHECK: brasl %r14, foo@PLT137; CHECK: mdeb %f0, 16{{[04]}}(%r15)138; CHECK: br %r14139 %ptr1 = getelementptr float, ptr %ptr0, i64 2140 %ptr2 = getelementptr float, ptr %ptr0, i64 4141 %ptr3 = getelementptr float, ptr %ptr0, i64 6142 %ptr4 = getelementptr float, ptr %ptr0, i64 8143 %ptr5 = getelementptr float, ptr %ptr0, i64 10144 %ptr6 = getelementptr float, ptr %ptr0, i64 12145 %ptr7 = getelementptr float, ptr %ptr0, i64 14146 %ptr8 = getelementptr float, ptr %ptr0, i64 16147 %ptr9 = getelementptr float, ptr %ptr0, i64 18148 %ptr10 = getelementptr float, ptr %ptr0, i64 20149 150 %val0 = load float, ptr %ptr0151 %val1 = load float, ptr %ptr1152 %val2 = load float, ptr %ptr2153 %val3 = load float, ptr %ptr3154 %val4 = load float, ptr %ptr4155 %val5 = load float, ptr %ptr5156 %val6 = load float, ptr %ptr6157 %val7 = load float, ptr %ptr7158 %val8 = load float, ptr %ptr8159 %val9 = load float, ptr %ptr9160 %val10 = load float, ptr %ptr10161 162 %frob0 = call float @llvm.experimental.constrained.fadd.f32(163 float %val0, float %val0,164 metadata !"round.dynamic",165 metadata !"fpexcept.strict") #0166 %frob1 = call float @llvm.experimental.constrained.fadd.f32(167 float %val1, float %val1,168 metadata !"round.dynamic",169 metadata !"fpexcept.strict") #0170 %frob2 = call float @llvm.experimental.constrained.fadd.f32(171 float %val2, float %val2,172 metadata !"round.dynamic",173 metadata !"fpexcept.strict") #0174 %frob3 = call float @llvm.experimental.constrained.fadd.f32(175 float %val3, float %val3,176 metadata !"round.dynamic",177 metadata !"fpexcept.strict") #0178 %frob4 = call float @llvm.experimental.constrained.fadd.f32(179 float %val4, float %val4,180 metadata !"round.dynamic",181 metadata !"fpexcept.strict") #0182 %frob5 = call float @llvm.experimental.constrained.fadd.f32(183 float %val5, float %val5,184 metadata !"round.dynamic",185 metadata !"fpexcept.strict") #0186 %frob6 = call float @llvm.experimental.constrained.fadd.f32(187 float %val6, float %val6,188 metadata !"round.dynamic",189 metadata !"fpexcept.strict") #0190 %frob7 = call float @llvm.experimental.constrained.fadd.f32(191 float %val7, float %val7,192 metadata !"round.dynamic",193 metadata !"fpexcept.strict") #0194 %frob8 = call float @llvm.experimental.constrained.fadd.f32(195 float %val8, float %val8,196 metadata !"round.dynamic",197 metadata !"fpexcept.strict") #0198 %frob9 = call float @llvm.experimental.constrained.fadd.f32(199 float %val9, float %val9,200 metadata !"round.dynamic",201 metadata !"fpexcept.strict") #0202 %frob10 = call float @llvm.experimental.constrained.fadd.f32(203 float %val10, float %val10,204 metadata !"round.dynamic",205 metadata !"fpexcept.strict") #0206 207 store float %frob0, ptr %ptr0208 store float %frob1, ptr %ptr1209 store float %frob2, ptr %ptr2210 store float %frob3, ptr %ptr3211 store float %frob4, ptr %ptr4212 store float %frob5, ptr %ptr5213 store float %frob6, ptr %ptr6214 store float %frob7, ptr %ptr7215 store float %frob8, ptr %ptr8216 store float %frob9, ptr %ptr9217 store float %frob10, ptr %ptr10218 219 %ret = call float @foo() #0220 221 %accext0 = call double @llvm.experimental.constrained.fpext.f64.f32(222 float %ret,223 metadata !"fpexcept.strict") #0224 %ext0 = call double @llvm.experimental.constrained.fpext.f64.f32(225 float %frob0,226 metadata !"fpexcept.strict") #0227 %mul0 = call double @llvm.experimental.constrained.fmul.f64(228 double %accext0, double %ext0,229 metadata !"round.dynamic",230 metadata !"fpexcept.strict") #0231 %extra0 = call double @llvm.experimental.constrained.fmul.f64(232 double %mul0, double 1.01,233 metadata !"round.dynamic",234 metadata !"fpexcept.strict") #0235 %trunc0 = call float @llvm.experimental.constrained.fptrunc.f32.f64(236 double %extra0,237 metadata !"round.dynamic",238 metadata !"fpexcept.strict") #0239 240 %accext1 = call double @llvm.experimental.constrained.fpext.f64.f32(241 float %trunc0,242 metadata !"fpexcept.strict") #0243 %ext1 = call double @llvm.experimental.constrained.fpext.f64.f32(244 float %frob1,245 metadata !"fpexcept.strict") #0246 %mul1 = call double @llvm.experimental.constrained.fmul.f64(247 double %accext1, double %ext1,248 metadata !"round.dynamic",249 metadata !"fpexcept.strict") #0250 %extra1 = call double @llvm.experimental.constrained.fmul.f64(251 double %mul1, double 1.11,252 metadata !"round.dynamic",253 metadata !"fpexcept.strict") #0254 %trunc1 = call float @llvm.experimental.constrained.fptrunc.f32.f64(255 double %extra1,256 metadata !"round.dynamic",257 metadata !"fpexcept.strict") #0258 259 %accext2 = call double @llvm.experimental.constrained.fpext.f64.f32(260 float %trunc1,261 metadata !"fpexcept.strict") #0262 %ext2 = call double @llvm.experimental.constrained.fpext.f64.f32(263 float %frob2,264 metadata !"fpexcept.strict") #0265 %mul2 = call double @llvm.experimental.constrained.fmul.f64(266 double %accext2, double %ext2,267 metadata !"round.dynamic",268 metadata !"fpexcept.strict") #0269 %extra2 = call double @llvm.experimental.constrained.fmul.f64(270 double %mul2, double 1.21,271 metadata !"round.dynamic",272 metadata !"fpexcept.strict") #0273 %trunc2 = call float @llvm.experimental.constrained.fptrunc.f32.f64(274 double %extra2,275 metadata !"round.dynamic",276 metadata !"fpexcept.strict") #0277 278 %accext3 = call double @llvm.experimental.constrained.fpext.f64.f32(279 float %trunc2,280 metadata !"fpexcept.strict") #0281 %ext3 = call double @llvm.experimental.constrained.fpext.f64.f32(282 float %frob3,283 metadata !"fpexcept.strict") #0284 %mul3 = call double @llvm.experimental.constrained.fmul.f64(285 double %accext3, double %ext3,286 metadata !"round.dynamic",287 metadata !"fpexcept.strict") #0288 %extra3 = call double @llvm.experimental.constrained.fmul.f64(289 double %mul3, double 1.31,290 metadata !"round.dynamic",291 metadata !"fpexcept.strict") #0292 %trunc3 = call float @llvm.experimental.constrained.fptrunc.f32.f64(293 double %extra3,294 metadata !"round.dynamic",295 metadata !"fpexcept.strict") #0296 297 %accext4 = call double @llvm.experimental.constrained.fpext.f64.f32(298 float %trunc3,299 metadata !"fpexcept.strict") #0300 %ext4 = call double @llvm.experimental.constrained.fpext.f64.f32(301 float %frob4,302 metadata !"fpexcept.strict") #0303 %mul4 = call double @llvm.experimental.constrained.fmul.f64(304 double %accext4, double %ext4,305 metadata !"round.dynamic",306 metadata !"fpexcept.strict") #0307 %extra4 = call double @llvm.experimental.constrained.fmul.f64(308 double %mul4, double 1.41,309 metadata !"round.dynamic",310 metadata !"fpexcept.strict") #0311 %trunc4 = call float @llvm.experimental.constrained.fptrunc.f32.f64(312 double %extra4,313 metadata !"round.dynamic",314 metadata !"fpexcept.strict") #0315 316 %accext5 = call double @llvm.experimental.constrained.fpext.f64.f32(317 float %trunc4,318 metadata !"fpexcept.strict") #0319 %ext5 = call double @llvm.experimental.constrained.fpext.f64.f32(320 float %frob5,321 metadata !"fpexcept.strict") #0322 %mul5 = call double @llvm.experimental.constrained.fmul.f64(323 double %accext5, double %ext5,324 metadata !"round.dynamic",325 metadata !"fpexcept.strict") #0326 %extra5 = call double @llvm.experimental.constrained.fmul.f64(327 double %mul5, double 1.51,328 metadata !"round.dynamic",329 metadata !"fpexcept.strict") #0330 %trunc5 = call float @llvm.experimental.constrained.fptrunc.f32.f64(331 double %extra5,332 metadata !"round.dynamic",333 metadata !"fpexcept.strict") #0334 335 %accext6 = call double @llvm.experimental.constrained.fpext.f64.f32(336 float %trunc5,337 metadata !"fpexcept.strict") #0338 %ext6 = call double @llvm.experimental.constrained.fpext.f64.f32(339 float %frob6,340 metadata !"fpexcept.strict") #0341 %mul6 = call double @llvm.experimental.constrained.fmul.f64(342 double %accext6, double %ext6,343 metadata !"round.dynamic",344 metadata !"fpexcept.strict") #0345 %extra6 = call double @llvm.experimental.constrained.fmul.f64(346 double %mul6, double 1.61,347 metadata !"round.dynamic",348 metadata !"fpexcept.strict") #0349 %trunc6 = call float @llvm.experimental.constrained.fptrunc.f32.f64(350 double %extra6,351 metadata !"round.dynamic",352 metadata !"fpexcept.strict") #0353 354 %accext7 = call double @llvm.experimental.constrained.fpext.f64.f32(355 float %trunc6,356 metadata !"fpexcept.strict") #0357 %ext7 = call double @llvm.experimental.constrained.fpext.f64.f32(358 float %frob7,359 metadata !"fpexcept.strict") #0360 %mul7 = call double @llvm.experimental.constrained.fmul.f64(361 double %accext7, double %ext7,362 metadata !"round.dynamic",363 metadata !"fpexcept.strict") #0364 %extra7 = call double @llvm.experimental.constrained.fmul.f64(365 double %mul7, double 1.71,366 metadata !"round.dynamic",367 metadata !"fpexcept.strict") #0368 %trunc7 = call float @llvm.experimental.constrained.fptrunc.f32.f64(369 double %extra7,370 metadata !"round.dynamic",371 metadata !"fpexcept.strict") #0372 373 %accext8 = call double @llvm.experimental.constrained.fpext.f64.f32(374 float %trunc7,375 metadata !"fpexcept.strict") #0376 %ext8 = call double @llvm.experimental.constrained.fpext.f64.f32(377 float %frob8,378 metadata !"fpexcept.strict") #0379 %mul8 = call double @llvm.experimental.constrained.fmul.f64(380 double %accext8, double %ext8,381 metadata !"round.dynamic",382 metadata !"fpexcept.strict") #0383 %extra8 = call double @llvm.experimental.constrained.fmul.f64(384 double %mul8, double 1.81,385 metadata !"round.dynamic",386 metadata !"fpexcept.strict") #0387 %trunc8 = call float @llvm.experimental.constrained.fptrunc.f32.f64(388 double %extra8,389 metadata !"round.dynamic",390 metadata !"fpexcept.strict") #0391 392 %accext9 = call double @llvm.experimental.constrained.fpext.f64.f32(393 float %trunc8,394 metadata !"fpexcept.strict") #0395 %ext9 = call double @llvm.experimental.constrained.fpext.f64.f32(396 float %frob9,397 metadata !"fpexcept.strict") #0398 %mul9 = call double @llvm.experimental.constrained.fmul.f64(399 double %accext9, double %ext9,400 metadata !"round.dynamic",401 metadata !"fpexcept.strict") #0402 %extra9 = call double @llvm.experimental.constrained.fmul.f64(403 double %mul9, double 1.91,404 metadata !"round.dynamic",405 metadata !"fpexcept.strict") #0406 %trunc9 = call float @llvm.experimental.constrained.fptrunc.f32.f64(407 double %extra9,408 metadata !"round.dynamic",409 metadata !"fpexcept.strict") #0410 411 ret float %trunc9412}413 414attributes #0 = { strictfp }415