Skip to content

Commit b6c740c

Browse files
committed
fix(floats): Fix FPToI encoding, restrict on domain of definition
1 parent ca6f0f1 commit b6c740c

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

Diff for: lib/Solver/BitwuzlaBuilder.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,21 @@ Term BitwuzlaBuilder::constructActual(ref<Expr> e, int *width_out) {
619619
Term src = castToFloat(construct(ce->src, &srcWidth));
620620
*width_out = ce->getWidth();
621621
FPCastWidthAssert(width_out, "Invalid FPToUI width");
622+
auto fp_widths = getFloatSortFromBitWidth(srcWidth);
623+
Term maxBound = ctx->mk_term(
624+
Kind::FP_LEQ,
625+
{src, ctx->mk_term(Kind::FP_TO_FP_FROM_UBV,
626+
{getRoundingModeSort(ce->roundingMode),
627+
ctx->mk_bv_ones(ctx->mk_bv_sort(*width_out))},
628+
{fp_widths.first, fp_widths.second})});
629+
sideConstraints.push_back(maxBound);
630+
Term minBound = ctx->mk_term(
631+
Kind::FP_GEQ,
632+
{src, ctx->mk_term(Kind::FP_TO_FP_FROM_UBV,
633+
{getRoundingModeSort(ce->roundingMode),
634+
ctx->mk_bv_zero(ctx->mk_bv_sort(*width_out))},
635+
{fp_widths.first, fp_widths.second})});
636+
sideConstraints.push_back(minBound);
622637
return ctx->mk_term(Kind::FP_TO_UBV,
623638
{getRoundingModeSort(ce->roundingMode), src},
624639
{ce->getWidth()});
@@ -630,6 +645,21 @@ Term BitwuzlaBuilder::constructActual(ref<Expr> e, int *width_out) {
630645
Term src = castToFloat(construct(ce->src, &srcWidth));
631646
*width_out = ce->getWidth();
632647
FPCastWidthAssert(width_out, "Invalid FPToSI width");
648+
auto fp_widths = getFloatSortFromBitWidth(srcWidth);
649+
Term maxBound = ctx->mk_term(
650+
Kind::FP_LEQ,
651+
{src, ctx->mk_term(Kind::FP_TO_FP_FROM_SBV,
652+
{getRoundingModeSort(ce->roundingMode),
653+
ctx->mk_bv_max_signed(ctx->mk_bv_sort(*width_out))},
654+
{fp_widths.first, fp_widths.second})});
655+
sideConstraints.push_back(maxBound);
656+
Term minBound = ctx->mk_term(
657+
Kind::FP_GEQ,
658+
{src, ctx->mk_term(Kind::FP_TO_FP_FROM_SBV,
659+
{getRoundingModeSort(ce->roundingMode),
660+
ctx->mk_bv_min_signed(ctx->mk_bv_sort(*width_out))},
661+
{fp_widths.first, fp_widths.second})});
662+
sideConstraints.push_back(minBound);
633663
return ctx->mk_term(Kind::FP_TO_SBV,
634664
{getRoundingModeSort(ce->roundingMode), src},
635665
{ce->getWidth()});

Diff for: lib/Solver/Z3BitvectorBuilder.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,21 @@ Z3ASTHandle Z3BitvectorBuilder::constructActual(ref<Expr> e, int *width_out) {
419419
Z3ASTHandle src = castToFloat(construct(ce->src, &srcWidth));
420420
*width_out = ce->getWidth();
421421
FPCastWidthAssert(width_out, "Invalid FPToUI width");
422+
auto fp_width = getFloatSortFromBitWidth(srcWidth);
423+
Z3ASTHandle maxBound = Z3ASTHandle(
424+
Z3_mk_fpa_leq(
425+
ctx, src,
426+
Z3_mk_fpa_to_fp_unsigned(ctx, getRoundingModeSort(ce->roundingMode),
427+
bvMinusOne(*width_out), fp_width)),
428+
ctx);
429+
sideConstraints.push_back(maxBound);
430+
Z3ASTHandle minBound = Z3ASTHandle(
431+
Z3_mk_fpa_geq(
432+
ctx, src,
433+
Z3_mk_fpa_to_fp_unsigned(ctx, getRoundingModeSort(ce->roundingMode),
434+
bvZero(*width_out), fp_width)),
435+
ctx);
436+
sideConstraints.push_back(minBound);
422437
return Z3ASTHandle(Z3_mk_fpa_to_ubv(ctx,
423438
getRoundingModeSort(ce->roundingMode),
424439
src, *width_out),
@@ -431,6 +446,23 @@ Z3ASTHandle Z3BitvectorBuilder::constructActual(ref<Expr> e, int *width_out) {
431446
Z3ASTHandle src = castToFloat(construct(ce->src, &srcWidth));
432447
*width_out = ce->getWidth();
433448
FPCastWidthAssert(width_out, "Invalid FPToSI width");
449+
auto fp_width = getFloatSortFromBitWidth(srcWidth);
450+
Z3ASTHandle smax = Z3ASTHandle(
451+
Z3_mk_concat(ctx, bvZero(1), bvMinusOne(*width_out - 1)), ctx);
452+
Z3ASTHandle fpsmax = Z3ASTHandle(
453+
Z3_mk_fpa_to_fp_signed(ctx, getRoundingModeSort(ce->roundingMode), smax,
454+
fp_width),
455+
ctx);
456+
Z3ASTHandle maxBound = Z3ASTHandle(Z3_mk_fpa_leq(ctx, src, fpsmax), ctx);
457+
sideConstraints.push_back(maxBound);
458+
Z3ASTHandle smin =
459+
Z3ASTHandle(Z3_mk_concat(ctx, bvOne(1), bvZero(*width_out - 1)), ctx);
460+
Z3ASTHandle fpsmin = Z3ASTHandle(
461+
Z3_mk_fpa_to_fp_signed(ctx, getRoundingModeSort(ce->roundingMode), smin,
462+
fp_width),
463+
ctx);
464+
Z3ASTHandle minBound = Z3ASTHandle(Z3_mk_fpa_geq(ctx, src, fpsmin), ctx);
465+
sideConstraints.push_back(maxBound);
434466
return Z3ASTHandle(Z3_mk_fpa_to_sbv(ctx,
435467
getRoundingModeSort(ce->roundingMode),
436468
src, *width_out),

0 commit comments

Comments
 (0)