@@ -652,3 +652,85 @@ TEST_CASE("Simplify quantifier", "[core][util]")
652652 REQUIRE (simplify_expr (forall_exprt{a, true_exprt{}}, ns) == true_exprt{});
653653 }
654654}
655+
656+
657+ TEST_CASE (" Simplify double typecast over bv types" , " [core][util]" )
658+ {
659+ const symbol_tablet symbol_table;
660+ const namespacet ns{symbol_table};
661+
662+ // (unsigned)(signed)x where x is unsigned and same width -> x
663+ const unsignedbv_typet u32 {32 };
664+ const signedbv_typet s32{32 };
665+ const symbol_exprt x{" x" , u32 };
666+ const typecast_exprt inner{x, s32};
667+ const typecast_exprt outer{inner, u32 };
668+ REQUIRE (simplify_expr (outer, ns) == x);
669+ }
670+
671+
672+ TEST_CASE (" Simplify (x * n) % n" , " [core][util]" )
673+ {
674+ const symbol_tablet symbol_table;
675+ const namespacet ns{symbol_table};
676+
677+ const unsignedbv_typet u32 {32 };
678+ const symbol_exprt x{" x" , u32 };
679+ const constant_exprt n = from_integer (7 , u32 );
680+ const mult_exprt mul{x, n};
681+ const mod_exprt mod{mul, n};
682+ const auto result = simplify_expr (mod, ns);
683+ REQUIRE (result == from_integer (0 , u32 ));
684+ }
685+
686+
687+ TEST_CASE (" Simplify all-zero constant in bitand" , " [core][util]" )
688+ {
689+ const symbol_tablet symbol_table;
690+ const namespacet ns{symbol_table};
691+
692+ const bv_typet bv8{8 };
693+ const symbol_exprt x{" x" , bv8};
694+ const constant_exprt zero = bv8.all_zeros_expr ();
695+ const bitand_exprt band{x, zero};
696+ const auto result = simplify_expr (band, ns);
697+ REQUIRE (result == zero);
698+ }
699+
700+
701+ TEST_CASE (" Simplify bitand over concatenation and constant" , " [core][util]" )
702+ {
703+ const symbol_tablet symbol_table;
704+ const namespacet ns{symbol_table};
705+
706+ // (concat(a, b)) & 0x00FF -> concat(0x00, b & 0xFF)
707+ const bv_typet bv8{8 };
708+ const bv_typet bv16{16 };
709+ const symbol_exprt a{" a" , bv8};
710+ const symbol_exprt b{" b" , bv8};
711+ const concatenation_exprt cat{{a, b}, bv16};
712+ const constant_exprt mask = from_integer (0xFF , bv16);
713+ const bitand_exprt band{cat, mask};
714+ const auto result = simplify_expr (band, ns);
715+ // Result should not contain the original bitand over concatenation
716+ REQUIRE ((result.id () != ID_bitand || result != band));
717+ }
718+
719+
720+ TEST_CASE (" Simplify shift of concatenation" , " [core][util]" )
721+ {
722+ const symbol_tablet symbol_table;
723+ const namespacet ns{symbol_table};
724+
725+ // (concat(a, b)) >> 8 where a and b are 8-bit
726+ const unsignedbv_typet u8 {8 };
727+ const unsignedbv_typet u16 {16 };
728+ const symbol_exprt a{" a" , u8 };
729+ const symbol_exprt b{" b" , u8 };
730+ const concatenation_exprt cat{{a, b}, u16 };
731+ const lshr_exprt shift{cat, from_integer (8 , u16 )};
732+ const auto result = simplify_expr (shift, ns);
733+ // Should simplify — the result should not be a shift of a concatenation
734+ REQUIRE (result.id () != ID_lshr);
735+ }
736+
0 commit comments