diff options
| author | Albert Magyar | 2020-08-28 18:09:18 -0700 |
|---|---|---|
| committer | GitHub | 2020-08-28 18:09:18 -0700 |
| commit | 505fc53338d61acac391d8b04b8bc99fcc92eb69 (patch) | |
| tree | c406974cfa2ca5925e14770cae485763a1a30177 /src/main | |
| parent | 318da49f7cb88ce33dcf1418f8b63c0b236be9a8 (diff) | |
| parent | 8fa7b99d3dff5f199455fa67e90a7dfa6941b8ff (diff) | |
Merge pull request #1875 from freechipsproject/fix-inline-bools
Restrict boolean inlining to avoid context-sensitive width bugs
Diffstat (limited to 'src/main')
| -rw-r--r-- | src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala b/src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala index 7c52d6ef..c02b8dd5 100644 --- a/src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala +++ b/src/main/scala/firrtl/transforms/InlineBooleanExpressions.scala @@ -83,11 +83,22 @@ class InlineBooleanExpressions extends Transform with DependencyAPIMigration { /** Whether or not an can be inlined * @param refExpr the expression to check for inlining + * @param outerExpr the parent expression of refExpr, if any */ - def canInline(refExpr: Expression): Boolean = { - refExpr match { - case _: Mux => false - case _ => refExpr.tpe == Utils.BoolType + def canInline(refExpr: Expression, outerExpr: Option[Expression]): Boolean = { + val contextInsensitiveDetOps: Set[PrimOp] = Set(Lt, Leq, Gt, Geq, Eq, Neq, Andr, Orr, Xorr) + outerExpr match { + case None => true + case Some(o) if (o.tpe == Utils.BoolType) => + refExpr match { + case _: Mux => false + case e => e.tpe == Utils.BoolType + } + case Some(o) => + refExpr match { + case DoPrim(op, _, _, Utils.BoolType) => contextInsensitiveDetOps(op) + case _ => false + } } } @@ -105,7 +116,8 @@ class InlineBooleanExpressions extends Transform with DependencyAPIMigration { netlist.get(we(ref)) match { case Some((refExpr, refInfo)) if sameFileAndLineInfo(info, refInfo) => val inlineNum = inlineCounts.getOrElse(refKey, 1) - if (!outerExpr.isDefined || canInline(refExpr) && ((inlineNum + inlineCount) <= maxInlineCount)) { + val notTooDeep = !outerExpr.isDefined || ((inlineNum + inlineCount) <= maxInlineCount) + if (canInline(refExpr, outerExpr) && notTooDeep) { inlineCount += inlineNum refExpr } else { |
