Skip to content

Commit 79d0ed7

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 f649c47 commit 79d0ed7

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-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: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ 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_equal || expr.id() == ID_notequal || expr.id() == ID_lt ||
40+
expr.id() == ID_le || expr.id() == ID_gt || expr.id() == ID_ge)
41+
{
42+
return true;
43+
}
3844
else if(expr.id()==ID_vector)
3945
return true;
4046
}
@@ -141,6 +147,39 @@ static void remove_vector(exprt &expr)
141147

142148
expr=array_expr;
143149
}
150+
else if(
151+
expr.id() == ID_equal || expr.id() == ID_notequal || expr.id() == ID_lt ||
152+
expr.id() == ID_le || expr.id() == ID_gt || expr.id() == ID_ge)
153+
{
154+
// component-wise and generate 0 (false) or -1 (true)
155+
// x ~ y -> vector(x[0] ~ y[0] ? -1 : 0, x[1] ~ y[1] ? -1 : 0, ...)
156+
157+
auto const &binary_expr = to_binary_expr(expr);
158+
const vector_typet &vector_type = to_vector_type(expr.type());
159+
const auto dimension = numeric_cast_v<std::size_t>(vector_type.size());
160+
161+
const typet &subtype = vector_type.subtype();
162+
exprt minus_one = from_integer(-1, subtype);
163+
exprt zero = from_integer(0, subtype);
164+
165+
exprt::operandst operands;
166+
operands.reserve(dimension);
167+
168+
for(std::size_t i = 0; i < dimension; ++i)
169+
{
170+
exprt index = from_integer(i, vector_type.size().type());
171+
172+
operands.push_back(
173+
if_exprt{binary_relation_exprt{index_exprt{binary_expr.lhs(), index},
174+
binary_expr.id(),
175+
index_exprt{binary_expr.rhs(), index}},
176+
minus_one,
177+
zero});
178+
}
179+
180+
expr = array_exprt{std::move(operands),
181+
array_typet{subtype, vector_type.size()}};
182+
}
144183
else if(expr.id()==ID_vector)
145184
{
146185
expr.id(ID_array);

0 commit comments

Comments
 (0)