Skip to content

Commit 5906993

Browse files
committed
byte_extract lowering for complex_typet
It may have worked before via the fallback to flattening of the entire expression to a bitvector, but let's be on the safe side and construct appropriate expressions.
1 parent d683a70 commit 5906993

File tree

2 files changed

+69
-2
lines changed

2 files changed

+69
-2
lines changed

src/solvers/lowering/byte_operators.cpp

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,46 @@ static exprt unpack_rec(
180180
max_bytes,
181181
ns);
182182
}
183-
else if(ns.follow(src.type()).id()==ID_struct)
183+
else if(src.type().id() == ID_complex)
184+
{
185+
const complex_typet &complex_type = to_complex_type(src.type());
186+
const typet &subtype = complex_type.subtype();
187+
188+
auto subtype_bits = pointer_offset_bits(subtype, ns);
189+
CHECK_RETURN(subtype_bits.has_value());
190+
191+
exprt::operandst byte_operands;
192+
193+
exprt sub_real = unpack_rec(
194+
complex_real_exprt(src),
195+
little_endian,
196+
mp_integer{0},
197+
*subtype_bits / 8,
198+
ns,
199+
true);
200+
byte_operands.insert(
201+
byte_operands.end(),
202+
sub_real.operands().begin(),
203+
sub_real.operands().end());
204+
205+
exprt sub_imag = unpack_rec(
206+
complex_imag_exprt(src),
207+
little_endian,
208+
mp_integer{0},
209+
*subtype_bits / 8,
210+
ns,
211+
true);
212+
byte_operands.insert(
213+
byte_operands.end(),
214+
sub_imag.operands().begin(),
215+
sub_imag.operands().end());
216+
217+
const std::size_t size = byte_operands.size();
218+
return array_exprt(
219+
std::move(byte_operands),
220+
array_typet(unsignedbv_typet(8), from_integer(size, size_type())));
221+
}
222+
else if(src.type().id() == ID_struct || src.type().id() == ID_struct_tag)
184223
{
185224
const struct_typet &struct_type=to_struct_type(ns.follow(src.type()));
186225
const struct_typet::componentst &components=struct_type.components();
@@ -478,7 +517,33 @@ exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
478517
return simplify_expr(vector, ns);
479518
}
480519
}
481-
else if(ns.follow(src.type()).id()==ID_struct)
520+
else if(src.type().id() == ID_complex)
521+
{
522+
const complex_typet &complex_type = to_complex_type(src.type());
523+
const typet &subtype = complex_type.subtype();
524+
525+
auto subtype_bits = pointer_offset_bits(subtype, ns);
526+
if(subtype_bits.has_value())
527+
{
528+
byte_extract_exprt real(unpacked);
529+
real.type() = subtype;
530+
531+
const plus_exprt new_offset(
532+
unpacked.offset(),
533+
from_integer(*subtype_bits / 8, unpacked.offset().type()));
534+
byte_extract_exprt imag(unpacked);
535+
imag.type() = subtype;
536+
imag.offset() = simplify_expr(new_offset, ns);
537+
538+
return simplify_expr(
539+
complex_exprt(
540+
lower_byte_extract(real, ns),
541+
lower_byte_extract(imag, ns),
542+
complex_type),
543+
ns);
544+
}
545+
}
546+
else if(src.type().id() == ID_struct || src.type().id() == ID_struct_tag)
482547
{
483548
const struct_typet &struct_type=to_struct_type(ns.follow(src.type()));
484549
const struct_typet::componentst &components=struct_type.components();

unit/solvers/lowering/byte_operators.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ SCENARIO("byte_extract_lowering", "[core][solvers][lowering][byte_extract]")
158158
// pointer_typet(u64, 64),
159159
vector_typet(u8, size),
160160
vector_typet(u64, size),
161+
// seems to generate the correct value, but the simplifier needs to learn
162+
// about complex_exprt, complex_real_exprt, complex_imag_exprt
161163
// complex_typet(s16),
162164
// complex_typet(u64)
163165
};

0 commit comments

Comments
 (0)