From d139f340b33ce79dcb97f29b9e08f544a650e52b Mon Sep 17 00:00:00 2001 From: whitequark Date: Wed, 2 Oct 2019 07:51:49 +0000 Subject: [PATCH] back.rtlil: don't cache wires for legalized switch tests. This causes miscompilation of code such as: r = Array([self.a, self.b]) m = Module() with m.If(r[self.s]): m.d.comb += self.o.eq(1) return m --- nmigen/back/rtlil.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/nmigen/back/rtlil.py b/nmigen/back/rtlil.py index 7424c9d..eb26bf8 100644 --- a/nmigen/back/rtlil.py +++ b/nmigen/back/rtlil.py @@ -681,9 +681,17 @@ class _StatementCompiler(xfrm.StatementVisitor): def on_Switch(self, stmt): self._check_rhs(stmt.test) - if stmt not in self._test_cache: - self._test_cache[stmt] = self.rhs_compiler(stmt.test) - test_sigspec = self._test_cache[stmt] + if not self.state.expansions: + # We repeatedly translate the same switches over and over (see the LHSGroupAnalyzer + # related code below), and translating the switch test only once helps readability. + if stmt not in self._test_cache: + self._test_cache[stmt] = self.rhs_compiler(stmt.test) + test_sigspec = self._test_cache[stmt] + else: + # However, if the switch test contains an illegal value, then it may not be cached + # (since the illegal value will be repeatedly replaced with different constants), so + # don't cache anything in that case. + test_sigspec = self.rhs_compiler(stmt.test) with self._case.switch(test_sigspec, src=src(stmt.src_loc)) as switch: for values, stmts in stmt.cases.items(): -- 2.30.2