Skip to content

Commit f6ce727

Browse files
authored
Merge pull request diffblue#5812 from tautschnig/fix-vector
Fix type checking of vector expressions
2 parents b902e0b + 31f95f1 commit f6ce727

File tree

3 files changed

+92
-8
lines changed

3 files changed

+92
-8
lines changed

regression/cbmc/gcc_vector1/main.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ int main()
4747
assert(z.members[2]==~x.members[2]);
4848
assert(z.members[3]==~x.members[3]);
4949

50+
z = x;
51+
z.v <<= (v4si){1, 2, 3, 4};
52+
assert(z.members[0] == (x.members[0] << 1));
53+
assert(z.members[1] == (x.members[1] << 2));
54+
assert(z.members[2] == (x.members[2] << 3));
55+
assert(z.members[3] == (x.members[3] << 4));
56+
5057
// vector operator scalar
5158
z=x;
5259
z.v=z.v+1;
@@ -55,6 +62,41 @@ int main()
5562
assert(z.members[2]==x.members[2]+1);
5663
assert(z.members[3]==x.members[3]+1);
5764

65+
z = x;
66+
z.v += 1;
67+
assert(z.members[0] == x.members[0] + 1);
68+
assert(z.members[1] == x.members[1] + 1);
69+
assert(z.members[2] == x.members[2] + 1);
70+
assert(z.members[3] == x.members[3] + 1);
71+
72+
z = x;
73+
z.v = z.v & 1;
74+
assert(z.members[0] == (x.members[0] & 1));
75+
assert(z.members[1] == (x.members[1] & 1));
76+
assert(z.members[2] == (x.members[2] & 1));
77+
assert(z.members[3] == (x.members[3] & 1));
78+
79+
z = x;
80+
z.v &= 1;
81+
assert(z.members[0] == (x.members[0] & 1));
82+
assert(z.members[1] == (x.members[1] & 1));
83+
assert(z.members[2] == (x.members[2] & 1));
84+
assert(z.members[3] == (x.members[3] & 1));
85+
86+
z = x;
87+
z.v = z.v << 2;
88+
assert(z.members[0] == (x.members[0] << 2));
89+
assert(z.members[1] == (x.members[1] << 2));
90+
assert(z.members[2] == (x.members[2] << 2));
91+
assert(z.members[3] == (x.members[3] << 2));
92+
93+
z = x;
94+
z.v <<= 2;
95+
assert(z.members[0] == (x.members[0] << 2));
96+
assert(z.members[1] == (x.members[1] << 2));
97+
assert(z.members[2] == (x.members[2] << 2));
98+
assert(z.members[3] == (x.members[3] << 2));
99+
58100
// unary operators on vectors
59101
z=x;
60102
z.v=-z.v;

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3360,6 +3360,7 @@ void c_typecheck_baset::typecheck_expr_shifts(shift_exprt &expr)
33603360
is_number(o_type1))
33613361
{
33623362
// {a0, a1, ..., an} >> b == {a0 >> b, a1 >> b, ..., an >> b}
3363+
op1 = typecast_exprt(op1, o_type0);
33633364
expr.type()=op0.type();
33643365
return;
33653366
}
@@ -3586,6 +3587,21 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
35863587
else if(statement==ID_assign_shl ||
35873588
statement==ID_assign_shr)
35883589
{
3590+
if(o_type0.id() == ID_vector)
3591+
{
3592+
if(
3593+
o_type1.id() == ID_vector && o_type0.subtype() == o_type1.subtype() &&
3594+
is_number(o_type0.subtype()))
3595+
{
3596+
return;
3597+
}
3598+
else if(is_number(o_type0.subtype()) && is_number(o_type1))
3599+
{
3600+
op1 = typecast_exprt(op1, o_type0);
3601+
return;
3602+
}
3603+
}
3604+
35893605
implicit_typecast_arithmetic(op0);
35903606
implicit_typecast_arithmetic(op1);
35913607

@@ -3650,6 +3666,16 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
36503666
return;
36513667
}
36523668
}
3669+
else if(
3670+
o_type0.id() == ID_vector &&
3671+
(o_type1.id() == ID_bool || o_type1.id() == ID_c_bool ||
3672+
o_type1.id() == ID_c_enum_tag || o_type1.id() == ID_unsignedbv ||
3673+
o_type1.id() == ID_signedbv))
3674+
{
3675+
implicit_typecast_arithmetic(op1);
3676+
op1 = typecast_exprt(op1, o_type0);
3677+
return;
3678+
}
36533679
}
36543680
else
36553681
{
@@ -3670,6 +3696,18 @@ void c_typecheck_baset::typecheck_side_effect_assignment(
36703696
return;
36713697
}
36723698
}
3699+
else if(o_type0.id() == ID_vector)
3700+
{
3701+
implicit_typecast_arithmetic(op1);
3702+
3703+
if(
3704+
is_number(op1.type()) || op1.type().id() == ID_bool ||
3705+
op1.type().id() == ID_c_bool || op1.type().id() == ID_c_enum_tag)
3706+
{
3707+
op1 = typecast_exprt(op1, o_type0);
3708+
return;
3709+
}
3710+
}
36733711
else if(o_type0.id()==ID_bool ||
36743712
o_type0.id()==ID_c_bool)
36753713
{

src/goto-programs/remove_vector.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ static bool have_to_remove_vector(const exprt &expr)
2525
{
2626
if(expr.type().id()==ID_vector)
2727
{
28-
if(expr.id()==ID_plus || expr.id()==ID_minus ||
29-
expr.id()==ID_mult || expr.id()==ID_div ||
30-
expr.id()==ID_mod || expr.id()==ID_bitxor ||
31-
expr.id()==ID_bitand || expr.id()==ID_bitor)
28+
if(
29+
expr.id() == ID_plus || expr.id() == ID_minus || expr.id() == ID_mult ||
30+
expr.id() == ID_div || expr.id() == ID_mod || expr.id() == ID_bitxor ||
31+
expr.id() == ID_bitand || expr.id() == ID_bitor || expr.id() == ID_shl ||
32+
expr.id() == ID_lshr || expr.id() == ID_ashr)
33+
{
3234
return true;
35+
}
3336
else if(expr.id()==ID_unary_minus || expr.id()==ID_bitnot)
3437
return true;
3538
else if(expr.id()==ID_vector)
@@ -77,10 +80,11 @@ static void remove_vector(exprt &expr)
7780

7881
if(expr.type().id()==ID_vector)
7982
{
80-
if(expr.id()==ID_plus || expr.id()==ID_minus ||
81-
expr.id()==ID_mult || expr.id()==ID_div ||
82-
expr.id()==ID_mod || expr.id()==ID_bitxor ||
83-
expr.id()==ID_bitand || expr.id()==ID_bitor)
83+
if(
84+
expr.id() == ID_plus || expr.id() == ID_minus || expr.id() == ID_mult ||
85+
expr.id() == ID_div || expr.id() == ID_mod || expr.id() == ID_bitxor ||
86+
expr.id() == ID_bitand || expr.id() == ID_bitor || expr.id() == ID_shl ||
87+
expr.id() == ID_lshr || expr.id() == ID_ashr)
8488
{
8589
// FIXME plus, mult, bitxor, bitand and bitor are defined as n-ary
8690
// operations rather than binary. This code assumes that they

0 commit comments

Comments
 (0)