Skip to content

Commit 1d95a6e

Browse files
authored
Merge pull request #1481 from diffblue/fix-bitand-bitor
Fix four-valued `|` and `&`
2 parents 79e6e97 + e6f6194 commit 1d95a6e

File tree

7 files changed

+107
-15
lines changed

7 files changed

+107
-15
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# EBMC 5.9
22

3+
* Verilog: fix for four-valued | and &
34
* Verilog: fix for typed parameter ports
45
* SystemVerilog: fix for type parameters
56
* SystemVerilog: type parameter ports
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
bitwise_and1.sv
33
--bound 0
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This gives wrong answers.
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
bitwise_or1.sv
33
--bound 0
44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This gives wrong answers.
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
KNOWNBUG
1+
CORE
22
equality5.sv
33

44
^EXIT=0$
55
^SIGNAL=0$
66
--
77
^warning: ignoring
88
--
9-
This gives the wrong answer.

src/verilog/aval_bval_encoding.cpp

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,85 @@ exprt aval_bval(const bitnot_exprt &expr)
450450
return combine_aval_bval(aval, op_bval, lower_to_aval_bval(expr.type()));
451451
}
452452

453-
exprt aval_bval_bitwise(const multi_ary_exprt &expr)
453+
exprt aval_bval_bitand(const bitand_exprt &expr)
454+
{
455+
auto &type = expr.type();
456+
PRECONDITION(is_four_valued(type));
457+
PRECONDITION(!expr.operands().empty());
458+
459+
for(auto &op : expr.operands())
460+
PRECONDITION(is_aval_bval(op));
461+
462+
// All result bits are computed bit-wise.
463+
// 0 is the dominating value.
464+
// Otherwise, any bit involving x/z is x.
465+
466+
// A bit is zero of both aval and bval bits are zero.
467+
exprt::operandst bit_is_zero_disjuncts;
468+
469+
for(auto &op : expr.operands())
470+
bit_is_zero_disjuncts.push_back(
471+
bitand_exprt{bitnot_exprt{aval(op)}, bitnot_exprt{bval(op)}});
472+
473+
auto bit_is_zero =
474+
bitor_exprt{bit_is_zero_disjuncts, bit_is_zero_disjuncts.front().type()};
475+
476+
// bval: one if not bit_is_zero, and any bval bit is one
477+
exprt::operandst bval_disjuncts;
478+
479+
for(auto &op : expr.operands())
480+
bval_disjuncts.push_back(bval(op));
481+
482+
auto bval = bitand_exprt{
483+
bitor_exprt{bval_disjuncts, bval_disjuncts.front().type()},
484+
bitnot_exprt{bit_is_zero}};
485+
486+
// aval: one if not bit_is_zero and bval is zero
487+
auto aval = bitand_exprt{bitnot_exprt{bit_is_zero}, bitnot_exprt{bval}};
488+
489+
return combine_aval_bval(aval, bval, lower_to_aval_bval(expr.type()));
490+
}
491+
492+
exprt aval_bval_bitor(const bitor_exprt &expr)
493+
{
494+
auto &type = expr.type();
495+
PRECONDITION(is_four_valued(type));
496+
PRECONDITION(!expr.operands().empty());
497+
498+
for(auto &op : expr.operands())
499+
PRECONDITION(is_aval_bval(op));
500+
501+
// All result bits are computed bit-wise.
502+
// 1 is the dominating value.
503+
// Otherwise, any bit involving x/z is x.
504+
505+
// A bit is one if the aval bit is one and the bval bit is zero.
506+
exprt::operandst bit_is_one_disjuncts;
507+
508+
for(auto &op : expr.operands())
509+
bit_is_one_disjuncts.push_back(
510+
bitand_exprt{aval(op), bitnot_exprt{bval(op)}});
511+
512+
auto bit_is_one =
513+
bitor_exprt{bit_is_one_disjuncts, bit_is_one_disjuncts.front().type()};
514+
515+
// bval: one if not bit_is_one, and any bval bit is one
516+
exprt::operandst bval_disjuncts;
517+
518+
for(auto &op : expr.operands())
519+
bval_disjuncts.push_back(bval(op));
520+
521+
auto bval = bitand_exprt{
522+
bitor_exprt{bval_disjuncts, bval_disjuncts.front().type()},
523+
bitnot_exprt{bit_is_one}};
524+
525+
// aval: one if bit_is_one
526+
auto aval = bit_is_one;
527+
528+
return combine_aval_bval(aval, bval, lower_to_aval_bval(expr.type()));
529+
}
530+
531+
exprt aval_bval_xor_xnor(const multi_ary_exprt &expr)
454532
{
455533
auto &type = expr.type();
456534
PRECONDITION(is_four_valued(type));

src/verilog/aval_bval_encoding.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,12 @@ exprt aval_bval(const verilog_logical_inequality_exprt &);
4949
exprt aval_bval(const not_exprt &);
5050
/// lowering for ~
5151
exprt aval_bval(const bitnot_exprt &);
52-
/// lowering for &, |, ^, ^~
53-
exprt aval_bval_bitwise(const multi_ary_exprt &);
52+
/// lowering for &
53+
exprt aval_bval_bitand(const bitand_exprt &);
54+
/// lowering for |
55+
exprt aval_bval_bitor(const bitor_exprt &);
56+
/// lowering for ^, ^~
57+
exprt aval_bval_xor_xnor(const multi_ary_exprt &);
5458
/// lowering for reduction operators
5559
exprt aval_bval_reduction(const unary_exprt &);
5660
/// lowering for replication

src/verilog/verilog_lowering.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -570,15 +570,27 @@ exprt verilog_lowering(exprt expr)
570570
else
571571
return expr; // leave as is
572572
}
573-
else if(
574-
expr.id() == ID_bitand || expr.id() == ID_bitor || expr.id() == ID_bitxor ||
575-
expr.id() == ID_bitxnor)
573+
else if(expr.id() == ID_bitand)
574+
{
575+
// encode into aval/bval
576+
if(is_four_valued(expr.type()))
577+
return aval_bval_bitand(to_bitand_expr(expr));
578+
else
579+
return expr; // leave as is
580+
}
581+
else if(expr.id() == ID_bitor)
582+
{
583+
// encode into aval/bval
584+
if(is_four_valued(expr.type()))
585+
return aval_bval_bitor(to_bitor_expr(expr));
586+
else
587+
return expr; // leave as is
588+
}
589+
else if(expr.id() == ID_bitxor || expr.id() == ID_bitxnor)
576590
{
577-
auto &multi_ary_expr = to_multi_ary_expr(expr);
578-
579591
// encode into aval/bval
580592
if(is_four_valued(expr.type()))
581-
return aval_bval_bitwise(multi_ary_expr);
593+
return aval_bval_xor_xnor(to_multi_ary_expr(expr));
582594
else
583595
return expr; // leave as is
584596
}

0 commit comments

Comments
 (0)