mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-14 19:25:40 +00:00
Fix wide shift count fold.
This commit is contained in:
parent
8a2499b544
commit
5628dff0bd
3 changed files with 65 additions and 1 deletions
|
|
@ -588,7 +588,7 @@ bool RTLIL::Const::convertible_to_int(bool is_signed) const
|
|||
if (size == 32) {
|
||||
if (is_signed)
|
||||
return true;
|
||||
return back() != State::S1;
|
||||
return (*this)[size - 1] != State::S1;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -114,6 +114,36 @@ select -assert-none t:$shiftx
|
|||
|
||||
design -reset
|
||||
|
||||
read_verilog <<EOT
|
||||
module top (
|
||||
input wire [3:0] in,
|
||||
output wire [7:0] shl,
|
||||
output wire [7:0] shr,
|
||||
output wire [7:0] sshl,
|
||||
output wire [7:0] sshr,
|
||||
);
|
||||
assign shl = in << 33'h0ffffffff;
|
||||
assign shr = in >> 33'h0ffffffff;
|
||||
assign sshl = in <<< 33'h0ffffffff;
|
||||
assign sshr = in >>> 33'h0ffffffff;
|
||||
endmodule
|
||||
EOT
|
||||
|
||||
select -assert-count 1 t:$shl
|
||||
select -assert-count 1 t:$shr
|
||||
select -assert-count 1 t:$sshl
|
||||
select -assert-count 1 t:$sshr
|
||||
|
||||
equiv_opt -assert opt_expr
|
||||
|
||||
design -load postopt
|
||||
select -assert-none t:$shl
|
||||
select -assert-none t:$shr
|
||||
select -assert-none t:$sshl
|
||||
select -assert-none t:$sshr
|
||||
|
||||
design -reset
|
||||
|
||||
read_verilog <<EOT
|
||||
module top (
|
||||
input wire [3:0] in,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <limits>
|
||||
#include "kernel/rtlil.h"
|
||||
|
||||
YOSYS_NAMESPACE_BEGIN
|
||||
|
|
@ -35,6 +36,39 @@ namespace RTLIL {
|
|||
EXPECT_FALSE(c2 < c3);
|
||||
}
|
||||
|
||||
TEST_F(KernelRtlilTest, ConstConvertibleToInt) {
|
||||
// A Const whose minimal unsigned size is exactly 32 bits (bit 31 set)
|
||||
// but whose full width is larger must not be reported as convertible
|
||||
// to a (signed) int when treated as unsigned
|
||||
{
|
||||
// 33 bits: bits 0..31 = 1, bit 32 = 0 => value 0xffffffff
|
||||
std::vector<State> v(33, S1);
|
||||
v[32] = S0;
|
||||
Const c(v);
|
||||
EXPECT_FALSE(c.convertible_to_int(false));
|
||||
EXPECT_EQ(c.as_int_saturating(false), std::numeric_limits<int>::max());
|
||||
EXPECT_FALSE(c.convertible_to_int(true));
|
||||
EXPECT_EQ(c.as_int_saturating(true), std::numeric_limits<int>::max());
|
||||
}
|
||||
|
||||
{
|
||||
// 32-bit unsigned 0x7fffffff fits in a signed int
|
||||
std::vector<State> v(32, S1);
|
||||
v[31] = S0;
|
||||
Const c(v);
|
||||
EXPECT_TRUE(c.convertible_to_int(false));
|
||||
EXPECT_EQ(c.as_int(false), 0x7fffffff);
|
||||
}
|
||||
|
||||
{
|
||||
// 32-bit unsigned 0xffffffff does not fit in a signed int
|
||||
std::vector<State> v(32, S1);
|
||||
Const c(v);
|
||||
EXPECT_FALSE(c.convertible_to_int(false));
|
||||
EXPECT_EQ(c.as_int_saturating(false), std::numeric_limits<int>::max());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(KernelRtlilTest, ConstStr) {
|
||||
// We have multiple distinct sections since it's annoying
|
||||
// to list multiple testcases as friends of Const in kernel/rtlil.h
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue