Skip to content

Commit db0c363

Browse files
committed
Fix typechecking of relational expressions over vectors
As specified in GCC's documentation, the result type is a vector of signed integers of the same width as the operand subtypes. As the semantics are different from relational expressions over scalars, introduce a different expression id: each operation is now prefixed with vector-.
1 parent 5acadac commit db0c363

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

src/ansi-c/c_typecheck_base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class c_typecheck_baset:
182182
virtual void typecheck_expr_member(exprt &expr);
183183
virtual void typecheck_expr_ptrmember(exprt &expr);
184184
virtual void typecheck_expr_rel(binary_relation_exprt &expr);
185-
virtual void typecheck_expr_rel_vector(binary_relation_exprt &expr);
185+
virtual void typecheck_expr_rel_vector(binary_exprt &expr);
186186
virtual void adjust_float_rel(binary_relation_exprt &);
187187
static void add_rounding_mode(exprt &);
188188
virtual void typecheck_expr_index(exprt &expr);

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,18 +1417,12 @@ void c_typecheck_baset::typecheck_expr_rel(
14171417
throw 0;
14181418
}
14191419

1420-
void c_typecheck_baset::typecheck_expr_rel_vector(
1421-
binary_relation_exprt &expr)
1420+
void c_typecheck_baset::typecheck_expr_rel_vector(binary_exprt &expr)
14221421
{
1423-
exprt &op0=expr.op0();
1424-
exprt &op1=expr.op1();
1422+
const typet &o_type0 = as_const(expr).op0().type();
1423+
const typet &o_type1 = as_const(expr).op1().type();
14251424

1426-
const typet o_type0 = op0.type();
1427-
const typet o_type1 = op1.type();
1428-
1429-
if(
1430-
o_type0.id() != ID_vector || o_type1.id() != ID_vector ||
1431-
o_type0.subtype() != o_type1.subtype())
1425+
if(o_type0.id() != ID_vector || o_type0 != o_type1)
14321426
{
14331427
error().source_location = expr.source_location();
14341428
error() << "vector operator '" << expr.id() << "' not defined for types '"
@@ -1437,9 +1431,18 @@ void c_typecheck_baset::typecheck_expr_rel_vector(
14371431
throw 0;
14381432
}
14391433

1440-
// Comparisons between vectors produce a vector
1441-
// of integers with the same dimension.
1442-
expr.type()=vector_typet(signed_int_type(), to_vector_type(o_type0).size());
1434+
// Comparisons between vectors produce a vector of integers of the same width
1435+
// with the same dimension.
1436+
auto subtype_width = to_bitvector_type(o_type0.subtype()).get_width();
1437+
expr.type() =
1438+
vector_typet{signedbv_typet{subtype_width}, to_vector_type(o_type0).size()};
1439+
1440+
// Replace the id as the semantics of these are point-wise application (and
1441+
// the result is not of bool type).
1442+
if(expr.id() == ID_notequal)
1443+
expr.id(ID_vector_notequal);
1444+
else
1445+
expr.id("vector-" + id2string(expr.id()));
14431446
}
14441447

14451448
void c_typecheck_baset::typecheck_expr_ptrmember(exprt &expr)

src/util/irep_ids.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,12 @@ IREP_ID_ONE(min)
843843
IREP_ID_ONE(constant_interval)
844844
IREP_ID_TWO(C_bounds_check, #bounds_check)
845845
IREP_ID_ONE(count_leading_zeros)
846+
IREP_ID_TWO(vector_equal, vector-=)
847+
IREP_ID_TWO(vector_notequal, vector-!=)
848+
IREP_ID_TWO(vector_ge, vector->=)
849+
IREP_ID_TWO(vector_le, vector-<=)
850+
IREP_ID_TWO(vector_gt, vector->)
851+
IREP_ID_TWO(vector_lt, vector-<)
846852

847853
// Projects depending on this code base that wish to extend the list of
848854
// available ids should provide a file local_irep_ids.def in their source tree

0 commit comments

Comments
 (0)