Skip to content

Commit eace402

Browse files
committed
Support ==,!=,<,<=,>,>= over vectors
These need to be rewritten to point-wise applications and return -1 (true) or 0 (false) per element. Fixes: diffblue#5930
1 parent 314a2f7 commit eace402

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

regression/cbmc/gcc_vector1/main.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,20 @@ int main()
105105
assert(z.members[2]==-x.members[2]);
106106
assert(z.members[3]==-x.members[3]);
107107

108+
// Boolean operators on vectors
109+
z = x;
110+
y.v = z.v == x.v;
111+
assert(y.members[0]);
112+
assert(y.members[1]);
113+
assert(y.members[2]);
114+
assert(y.members[3]);
115+
116+
y.v = x.v <= z.v;
117+
assert(y.members[0]);
118+
assert(y.members[1]);
119+
assert(y.members[2]);
120+
assert(y.members[3]);
121+
108122
// build vector with typecast
109123
z.v=(v4si){ 0, 1, 2, 3 };
110124
assert(z.members[0]==0 && z.members[1]==1 && z.members[2]==2 && z.members[3]==3);

src/goto-programs/remove_vector.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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,65 @@ 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 = binary_expr.lhs().subtype().id() == ID_floatbv;
174+
irep_idt new_id;
175+
if(binary_expr.id() == ID_vector_notequal)
176+
{
177+
if(is_float)
178+
new_id = ID_ieee_float_notequal;
179+
else
180+
new_id == ID_notequal;
181+
}
182+
else if(binary_expr.id() == ID_vector_equal)
183+
{
184+
if(is_float)
185+
new_id = ID_ieee_float_equal;
186+
else
187+
new_id == ID_equal;
188+
}
189+
else
190+
{
191+
// just strip the "vector-" prefix
192+
new_id = id2string(binary_expr.id()).substring(7);
193+
}
194+
195+
for(std::size_t i = 0; i < dimension; ++i)
196+
{
197+
exprt index = from_integer(i, vector_type.size().type());
198+
199+
operands.push_back(
200+
if_exprt{binary_relation_exprt{index_exprt{binary_expr.lhs(), index},
201+
new_id,
202+
index_exprt{binary_expr.rhs(), index}},
203+
minus_one,
204+
zero});
205+
}
206+
207+
source_locationt source_location = expr.source_location();
208+
expr = array_exprt{std::move(operands),
209+
array_typet{subtype, vector_type.size()}};
210+
expr.add_source_location() = std::move(source_location);
211+
}
146212
else if(expr.id()==ID_vector)
147213
{
148214
expr.id(ID_array);

0 commit comments

Comments
 (0)