@@ -35,6 +35,13 @@ static bool have_to_remove_vector(const exprt &expr)
3535 }
3636 else if (expr.id ()==ID_unary_minus || expr.id ()==ID_bitnot)
3737 return true ;
38+ else if (
39+ expr.id () == ID_vector_equal || expr.id () == ID_vector_notequal ||
40+ expr.id () == ID_vector_lt || expr.id () == ID_vector_le ||
41+ expr.id () == ID_vector_gt || expr.id () == ID_vector_ge)
42+ {
43+ return true ;
44+ }
3845 else if (expr.id ()==ID_vector)
3946 return true ;
4047 }
@@ -143,6 +150,66 @@ static void remove_vector(exprt &expr)
143150
144151 expr=array_expr;
145152 }
153+ else if (
154+ expr.id () == ID_vector_equal || expr.id () == ID_vector_notequal ||
155+ expr.id () == ID_vector_lt || expr.id () == ID_vector_le ||
156+ expr.id () == ID_vector_gt || expr.id () == ID_vector_ge)
157+ {
158+ // component-wise and generate 0 (false) or -1 (true)
159+ // x ~ y -> vector(x[0] ~ y[0] ? -1 : 0, x[1] ~ y[1] ? -1 : 0, ...)
160+
161+ auto const &binary_expr = to_binary_expr (expr);
162+ const vector_typet &vector_type = to_vector_type (expr.type ());
163+ const auto dimension = numeric_cast_v<std::size_t >(vector_type.size ());
164+
165+ const typet &subtype = vector_type.subtype ();
166+ PRECONDITION (subtype.id () == ID_signedbv);
167+ exprt minus_one = from_integer (-1 , subtype);
168+ exprt zero = from_integer (0 , subtype);
169+
170+ exprt::operandst operands;
171+ operands.reserve (dimension);
172+
173+ const bool is_float =
174+ binary_expr.lhs ().type ().subtype ().id () == ID_floatbv;
175+ irep_idt new_id;
176+ if (binary_expr.id () == ID_vector_notequal)
177+ {
178+ if (is_float)
179+ new_id = ID_ieee_float_notequal;
180+ else
181+ new_id = ID_notequal;
182+ }
183+ else if (binary_expr.id () == ID_vector_equal)
184+ {
185+ if (is_float)
186+ new_id = ID_ieee_float_equal;
187+ else
188+ new_id = ID_equal;
189+ }
190+ else
191+ {
192+ // just strip the "vector-" prefix
193+ new_id = id2string (binary_expr.id ()).substr (7 );
194+ }
195+
196+ for (std::size_t i = 0 ; i < dimension; ++i)
197+ {
198+ exprt index = from_integer (i, vector_type.size ().type ());
199+
200+ operands.push_back (
201+ if_exprt{binary_relation_exprt{index_exprt{binary_expr.lhs (), index},
202+ new_id,
203+ index_exprt{binary_expr.rhs (), index}},
204+ minus_one,
205+ zero});
206+ }
207+
208+ source_locationt source_location = expr.source_location ();
209+ expr = array_exprt{std::move (operands),
210+ array_typet{subtype, vector_type.size ()}};
211+ expr.add_source_location () = std::move (source_location);
212+ }
146213 else if (expr.id ()==ID_vector)
147214 {
148215 expr.id (ID_array);
0 commit comments