MCPcopy Create free account
hub / github.com/AliveToolkit/alive2 / fromFloat

Method fromFloat

ir/type.cpp:451–518  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

449}
450
451expr FloatType::fromFloat(State &s, const expr &fp, const Type &from_type0,
452 unsigned nary, const expr &a, const expr &b,
453 const expr &c) const {
454 expr isnan = fp.isNaN();
455 expr val = fp.float2BV();
456
457 if (isnan.isFalse())
458 return val;
459
460 unsigned fraction_bits = fractionBits();
461
462 // sign bit, exponent (-1), qnan bit (1) or snan (0), rest of fraction
463 expr var = s.getFreshNondetVar("#NaN", expr::mkUInt(0, 2));
464
465 ChoiceExpr<expr> exprs;
466
467 // 1) preferred QNaN (1000..00)
468 exprs.add(expr::mkUInt(1, 1).concat_zeros(fraction_bits-1), expr(true));
469
470 // 2) input NaN
471 // 3) quieted input NaN
472 const FloatType *from_type = from_type0.getAsFloatType();
473
474 auto add_maybe_quiet = [&](const expr &e) {
475 // account for fpext/fptruc
476 auto orig_bw = from_type->fractionBits();
477 expr fraction = e.trunc(orig_bw);
478 expr truncated_is_nan = true;
479
480 if (orig_bw > fraction_bits) {
481 fraction = fraction.extract(orig_bw-1, orig_bw - fraction_bits);
482 truncated_is_nan = fraction != 0;
483 } else if (orig_bw < fraction_bits) {
484 fraction = fraction.concat_zeros(fraction_bits - fraction.bits());
485 }
486 assert(!fraction.isValid() || fraction.bits() == fraction_bits);
487
488 expr qnan = fraction.sign();
489 expr quieted = var.extract(0, 0);
490 qnan = expr::mkIf(truncated_is_nan, qnan | quieted, expr::mkUInt(1, 1));
491 exprs.add(qnan.concat(fraction.trunc(fraction_bits - 1)),
492 from_type->getFloat(e).isNaN());
493 };
494 if (nary >= 1) {
495 add_maybe_quiet(a);
496 if (nary >= 2) {
497 add_maybe_quiet(b);
498 if (nary >= 3)
499 add_maybe_quiet(c);
500 }
501 }
502
503 // 4) target specific preferred QNaN (a set, possibly empty)
504 // approximated by adding just one more value
505 auto preferred_qnan_fraction
506 = expr::mkVar("#preferred_qnan", expr::mkUInt(0, fraction_bits - 1));
507 exprs.add(expr::mkUInt(1, 1).concat(preferred_qnan_fraction), expr(true));
508

Callers 2

fm_poisonFunction · 0.80
toSMTMethod · 0.80

Calls 15

mkVarFunction · 0.85
float2BVMethod · 0.80
isFalseMethod · 0.80
getFreshNondetVarMethod · 0.80
concat_zerosMethod · 0.80
getAsFloatTypeMethod · 0.80
fractionBitsMethod · 0.80
signMethod · 0.80
getFloatMethod · 0.80
addNonDetVarMethod · 0.80
addPreMethod · 0.80
exprClass · 0.70

Tested by

no test coverage detected