127 lines · plain
1; Test strict floating-point truncations.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 \6; RUN: | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s7 8 9declare half @llvm.experimental.constrained.fptrunc.f16.f64(double, metadata, metadata)10 11declare float @llvm.experimental.constrained.fptrunc.f32.f64(double, metadata, metadata)12declare half @llvm.experimental.constrained.fptrunc.f16.f128(fp128, metadata, metadata)13declare float @llvm.experimental.constrained.fptrunc.f32.f128(fp128, metadata, metadata)14declare double @llvm.experimental.constrained.fptrunc.f64.f128(fp128, metadata, metadata)15 16declare float @llvm.experimental.constrained.fadd.f32(float, float, metadata, metadata)17declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)18 19; Test f64->f16.20define half @f0(double %d1, double %d2) #0 {21; CHECK-LABEL: f0:22; CHECK: brasl %r14, __truncdfhf2@PLT23; CHECK: br %r1424 %res = call half @llvm.experimental.constrained.fptrunc.f16.f64(25 double %d2,26 metadata !"round.dynamic",27 metadata !"fpexcept.strict") #028 ret half %res29}30 31; Test f64->f32.32define float @f1(double %d1, double %d2) #0 {33; CHECK-LABEL: f1:34; CHECK-SCALAR: ledbr %f0, %f235; CHECK-VECTOR: ledbra %f0, 0, %f2, 036; CHECK: br %r1437 %res = call float @llvm.experimental.constrained.fptrunc.f32.f64(38 double %d2,39 metadata !"round.dynamic",40 metadata !"fpexcept.strict") #041 ret float %res42}43 44; Test f128->f16.45define half @f2_half(ptr %ptr) #0 {46; CHECK-LABEL: f2_half:47; CHECK: brasl %r14, __trunctfhf2@PLT48; CHECK: br %r1449 %val = load fp128, ptr %ptr50 %res = call half @llvm.experimental.constrained.fptrunc.f16.f128(51 fp128 %val,52 metadata !"round.dynamic",53 metadata !"fpexcept.strict") #054 ret half %res55}56 57; Test f128->f32.58define float @f2(ptr %ptr) #0 {59; CHECK-LABEL: f2:60; CHECK: lexbr %f0, %f061; CHECK: br %r1462 %val = load fp128, ptr %ptr63 %res = call float @llvm.experimental.constrained.fptrunc.f32.f128(64 fp128 %val,65 metadata !"round.dynamic",66 metadata !"fpexcept.strict") #067 ret float %res68}69 70; Make sure that we don't use %f0 as the destination of LEXBR when %f271; is still live.72define void @f3(ptr %dst, ptr %ptr, float %d1, float %d2) #0 {73; CHECK-LABEL: f3:74; CHECK: lexbr %f1, %f175; CHECK: aebr %f1, %f276; CHECK: ste %f1, 0(%r2)77; CHECK: br %r1478 %val = load fp128, ptr %ptr79 %conv = call float @llvm.experimental.constrained.fptrunc.f32.f128(80 fp128 %val,81 metadata !"round.dynamic",82 metadata !"fpexcept.strict") #083 %res = call float @llvm.experimental.constrained.fadd.f32(84 float %conv, float %d2,85 metadata !"round.dynamic",86 metadata !"fpexcept.strict") #087 store float %res, ptr %dst88 ret void89}90 91; Test f128->f64.92define double @f4(ptr %ptr) #0 {93; CHECK-LABEL: f4:94; CHECK: ldxbr %f0, %f095; CHECK: br %r1496 %val = load fp128, ptr %ptr97 %res = call double @llvm.experimental.constrained.fptrunc.f64.f128(98 fp128 %val,99 metadata !"round.dynamic",100 metadata !"fpexcept.strict") #0101 ret double %res102}103 104; Like f3, but for f128->f64.105define void @f5(ptr %dst, ptr %ptr, double %d1, double %d2) #0 {106; CHECK-LABEL: f5:107; CHECK: ldxbr %f1, %f1108; CHECK-SCALAR: adbr %f1, %f2109; CHECK-SCALAR: std %f1, 0(%r2)110; CHECK-VECTOR: wfadb [[REG:%f[0-9]+]], %f1, %f2111; CHECK-VECTOR: std [[REG]], 0(%r2)112; CHECK: br %r14113 %val = load fp128, ptr %ptr114 %conv = call double @llvm.experimental.constrained.fptrunc.f64.f128(115 fp128 %val,116 metadata !"round.dynamic",117 metadata !"fpexcept.strict") #0118 %res = call double @llvm.experimental.constrained.fadd.f64(119 double %conv, double %d2,120 metadata !"round.dynamic",121 metadata !"fpexcept.strict") #0122 store double %res, ptr %dst123 ret void124}125 126attributes #0 = { strictfp }127