Skip to content

Commit 36a3616

Browse files
committed
No unnecessary carry
1 parent 70a505a commit 36a3616

File tree

2 files changed

+43
-17
lines changed

2 files changed

+43
-17
lines changed

src/solvers/flattening/bv_utils.cpp

+42-16
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,37 @@ literalt bv_utilst::carry(literalt a, literalt b, literalt c)
290290
}
291291
}
292292

293-
literalt bv_utilst::adder(
293+
static literalt carry_out_of_sum(
294+
propt &prop,
295+
const bvt &op0,
296+
const bvt &op1,
297+
const bvt &sum)
298+
{
299+
literalt a = op0.back();
300+
literalt b = op1.back();
301+
literalt s = sum.back();
302+
303+
const auto const_count =
304+
a.is_constant() + b.is_constant() + s.is_constant();
305+
306+
if(const_count >= 2 || true)
307+
{
308+
return
309+
prop.lor(
310+
prop.land(a, b),
311+
prop.land(!s, prop.lor(a, b)));
312+
}
313+
314+
literalt c = prop.new_variable();
315+
316+
// TODO
317+
assert(false);
318+
prop.lcnf({a, b, s, c});
319+
320+
return c;
321+
}
322+
323+
void bv_utilst::adder(
294324
bvt &sum,
295325
const bvt &op,
296326
literalt carry_in)
@@ -305,8 +335,6 @@ literalt bv_utilst::adder(
305335
{
306336
sum[i] = full_adder(sum[i], op[i], carry_out, carry_out);
307337
}
308-
309-
return carry_out;
310338
}
311339
else
312340
{
@@ -376,10 +404,6 @@ literalt bv_utilst::adder(
376404
prop.lcnf({!sum[i], !first_op[i], !op[i], !sum[i-1], first_op[i-1]});
377405
prop.lcnf({!sum[i], !first_op[i], !op[i], !sum[i-1], op[i-1]});
378406
}
379-
380-
return prop.lor(
381-
prop.land(first_op.back(), op.back()),
382-
prop.land(!sum.back(), prop.lor(first_op.back(), op.back())));
383407
}
384408
}
385409

@@ -418,8 +442,7 @@ bvt bv_utilst::add_sub(const bvt &op0, const bvt &op1, bool subtract)
418442
bvt result=op0;
419443
bvt tmp_op1=subtract?inverted(op1):op1;
420444

421-
// we ignore the carry-out
422-
(void)adder(result, tmp_op1, carry_in);
445+
adder(result, tmp_op1, carry_in);
423446

424447
return result;
425448
}
@@ -431,8 +454,7 @@ bvt bv_utilst::add_sub(const bvt &op0, const bvt &op1, literalt subtract)
431454

432455
bvt result=op0;
433456

434-
// we ignore the carry-out
435-
(void)adder(result, op1_sign_applied, subtract);
457+
adder(result, op1_sign_applied, subtract);
436458

437459
return result;
438460
}
@@ -452,7 +474,8 @@ bvt bv_utilst::saturating_add_sub(
452474
bvt add_sub_result = op0;
453475
bvt tmp_op1 = subtract ? inverted(op1) : op1;
454476

455-
literalt carry_out = adder(add_sub_result, tmp_op1, carry_in);
477+
adder(add_sub_result, tmp_op1, carry_in);
478+
literalt carry_out = carry_out_of_sum(prop, op0, tmp_op1, add_sub_result);
456479

457480
bvt result;
458481
result.reserve(add_sub_result.size());
@@ -572,8 +595,7 @@ void bv_utilst::adder_no_overflow(
572595
literalt sign_the_same=
573596
prop.lequal(sum[sum.size()-1], tmp_op[tmp_op.size()-1]);
574597

575-
// we ignore the carry-out
576-
(void)adder(sum, tmp_op, const_literal(subtract));
598+
adder(sum, tmp_op, const_literal(subtract));
577599

578600
// result of addition in sum
579601
prop.l_set_to_false(
@@ -584,14 +606,18 @@ void bv_utilst::adder_no_overflow(
584606
INVARIANT(
585607
rep == representationt::UNSIGNED,
586608
"representation has either value signed or unsigned");
587-
literalt carry_out = adder(sum, tmp_op, const_literal(subtract));
609+
bvt op0 = sum;
610+
adder(sum, tmp_op, const_literal(subtract));
611+
literalt carry_out = carry_out_of_sum(prop, op0, tmp_op, sum);
588612
prop.l_set_to(carry_out, subtract);
589613
}
590614
}
591615

592616
void bv_utilst::adder_no_overflow(bvt &sum, const bvt &op)
593617
{
594-
literalt carry_out = adder(sum, op, const_literal(false));
618+
bvt op0 = sum;
619+
adder(sum, op, const_literal(false));
620+
literalt carry_out = carry_out_of_sum(prop, op0, op, sum);
595621
prop.l_set_to_false(carry_out); // enforce no overflow
596622
}
597623

src/solvers/flattening/bv_utils.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ class bv_utilst
223223
protected:
224224
propt ∝
225225

226-
literalt adder(
226+
void adder(
227227
bvt &sum,
228228
const bvt &op,
229229
literalt carry_in);

0 commit comments

Comments
 (0)