aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorFabian Schuiki2021-04-16 16:18:32 +0200
committerGitHub2021-04-16 14:18:32 +0000
commite9b2946c962f91a04611e32b1a9d03f78e7edf2b (patch)
tree20f2ff423691446e3fcfcab5ce630ab2923b3c8c /src/main
parentfc86112bc09f3e804d76e329fea96acb70e4909d (diff)
Fix signedness of xor const prop with zero (#2179)
Constant propagation of the Xor op folds `xor(a, SInt(0))` to `asUInt(a)`. For comparison, Or folds to `asUInt(pad(a, W))`. This can be a problem in the following case: circuit Foo : module Foo : input a: UInt<3> output b: UInt<4> b <= asUInt(xor(asSInt(a), SInt<4>(0))) This would emit the assignment as `b = a` instead of the sign-extended `b = {{1{a[2]}},a}`. This requires adjusting the `pad(e, t)` function use in const prop, which currently just inserts a `Pad` prim op with the requested output type. However, the function advertises that it pads *to the width* of the type `t`. Some of the folds rely on this and request the padding of a SInt<N> to the width of a UInt<M>. But the current implementation then then actually returns a `Pad` op with type UInt<M>, instead of the SInt<M> that was requested.
Diffstat (limited to 'src/main')
-rw-r--r--src/main/scala/firrtl/transforms/ConstantPropagation.scala14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/main/scala/firrtl/transforms/ConstantPropagation.scala b/src/main/scala/firrtl/transforms/ConstantPropagation.scala
index 5610c7e7..bc1fc9af 100644
--- a/src/main/scala/firrtl/transforms/ConstantPropagation.scala
+++ b/src/main/scala/firrtl/transforms/ConstantPropagation.scala
@@ -29,7 +29,17 @@ object ConstantPropagation {
/** Pads e to the width of t */
def pad(e: Expression, t: Type) = (bitWidth(e.tpe), bitWidth(t)) match {
- case (we, wt) if we < wt => DoPrim(Pad, Seq(e), Seq(wt), t)
+ case (we, wt) if we < wt =>
+ DoPrim(
+ Pad,
+ Seq(e),
+ Seq(wt),
+ e.tpe match {
+ case UIntType(_) => UIntType(IntWidth(wt))
+ case SIntType(_) => SIntType(IntWidth(wt))
+ case _ => e.tpe
+ }
+ )
case (we, wt) if we == wt => e
}
@@ -252,7 +262,7 @@ class ConstantPropagation extends Transform with RegisteredTransform with Depend
}
def simplify(e: Expression, lhs: Literal, rhs: Expression) = lhs match {
case UIntLiteral(v, _) if v == BigInt(0) => rhs
- case SIntLiteral(v, _) if v == BigInt(0) => asUInt(rhs, e.tpe)
+ case SIntLiteral(v, _) if v == BigInt(0) => asUInt(pad(rhs, e.tpe), e.tpe)
case _ => e
}
def matchingArgsValue(e: DoPrim, arg: Expression) = UIntLiteral(0, getWidth(arg.tpe))