-
Notifications
You must be signed in to change notification settings - Fork 366
Description
I was trying the new firtool-1.123.0
release, and am running into an issue with the FIRRTL generated by RocketChip, and its interaction with a new check added in #8557. The code in question is here:
circt/lib/Dialect/FIRRTL/FIRRTLOps.cpp
Lines 5099 to 5116 in 211c3fa
FIRRTLType CatPrimOp::inferReturnType(ValueRange operands, DictionaryAttr attrs, | |
OpaqueProperties properties, | |
mlir::RegionRange regions, | |
std::optional<Location> loc) { | |
// If no operands, return a 0-bit UInt | |
if (operands.empty()) | |
return UIntType::get(attrs.getContext(), 0); | |
// Check that all operands are Int types with same signedness | |
bool isSigned = type_isa<SIntType>(operands[0].getType()); | |
for (auto operand : operands) { | |
auto type = type_dyn_cast<IntType>(operand.getType()); | |
if (!type) | |
return emitInferRetTypeError(loc, "all operands must be Int type"); | |
if (type.isSigned() != isSigned) | |
return emitInferRetTypeError(loc, | |
"all operands must have same signedness"); | |
} |
I'm getting this error message:
generators/rocket-chip/src/main/scala/rocket/RocketCore.scala:1385:8: error: all operands must have same signedness
generators/rocket-chip/src/main/scala/rocket/RocketCore.scala:1385:8: error: 'firrtl.cat' op failed to infer returned types
generators/rocket-chip/src/main/scala/rocket/RocketCore.scala:1385:8: note: see current operation: %1737 = "firrtl.cat"(%1697, %1702, %1709, %1719, %1722, %1731, %1736) {name = "_ex_imm_T"} : (!firrtl.sint<1>, !firrtl.sint<11>, !firrtl.sint<8>, !firrtl.sint<1>, !firrtl.uint<6>, !firrtl.uint<4>, !firrtl.uint<1>) -> !firrtl.uint<32>
The Chisel code which causes this issue can be found here: https://github.com/chipsalliance/rocket-chip/blob/c357a0f32ecec9ee046ca1d6378c21ec7fec179b/src/main/scala/rocket/RocketCore.scala#L1369-L1387
I'm on Chisel 7.0.0-RC1+37-f8a2dec3-SNAPSHOT.
Is this a situation where Chisel is generating illegal FIRRTL? Or a situation where the new variadic form of firrtl.cat
is interacting with a weird edge-case in FIRRTL? The FIRRTL Spec says that the cat
function has two legal signatures: (UInt, UInt) -> SInt
or (SInt, SInt) -> UInt
. I can imagine that, since each two-operand cat
generates a UInt
, so long as you create the appropriate tree of cat
operators, you can get a legal cat
result from many arguments which have mixed signedness. For example: cat(cat(SInt, SInt), UInt) -> cat(UInt, UInt) -> UInt
. But if you fold this into a 3-input cat
, you get cat(SInt, SInt, UInt)
which fails this check.
Any idea how to resolve this?