Closed mrt-amd closed 9 months ago
@AndrewGoodrich: Could you please have a look whether this is addressed by the new datatypes implementation in SystemC 3.0.0?
This issue is fixed in 3.0 by not using a left-shift right-shift scheme for sign propagation. For example, in sc_int_base:
void extend_sign()
{
if ( m_val & (1ull << (m_len-1)) ) {
m_val |= (~UINT_ZERO << (m_len-1));
}
else {
m_val &= ( ~UINT_ZERO >> m_ulen );
}
}
Thanks @AndrewGoodrich for the quick reply.
@lmailletcontoz: Then, we can close this PR as fixed in the SystemC 3.0.0 release.
Fixed in the SystemC 3.0.0 release.
The previous code here attempted to perform a sign extension by shifting left and then right to fill the top bits with sign bit. If the input is negative then this applies a left shift to a negative value, which is undefined behaviour in C++17 and the error is caught by ubsan. Fix this by explicitly picking out the sign bit and then filling the top bits with that value.
Visible in ubsan. For example:
/usr/include/sysc/datatypes/int/sc_int_base.h:574:22: runtime error: left shift of negative value -42
This has no effect on performance under optimisation, as compilers are clever enough to recognise the sign extension and turn it into a simple extension or logical-shift-left, arithimetic-shift-right pair. For example:
Compiles with gcc 9 to:
Observe that the
int
tosc_int<47>
conversion is still a singlemovslq
, while theint64
tosc_int<47>
conversion isshl
+sar
as in the original.