From 750831e3e096398856053d9cbc2701e49fe0c29e Mon Sep 17 00:00:00 2001
From: Zachary Snow <zach@zachjs.com>
Date: Sat, 26 Dec 2020 21:38:13 -0700
Subject: Fix elaboration of whole memory words used as indices

---
 frontends/ast/simplify.cc               |  9 ++++++++-
 tests/various/memory_word_as_index.data |  4 ++++
 tests/various/memory_word_as_index.v    | 21 +++++++++++++++++++++
 tests/various/memory_word_as_index.ys   | 23 +++++++++++++++++++++++
 4 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 tests/various/memory_word_as_index.data
 create mode 100644 tests/various/memory_word_as_index.v
 create mode 100644 tests/various/memory_word_as_index.ys

diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index c6d63f247..17b4d4cdc 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -3451,7 +3451,14 @@ replace_fcall_later:;
 				if (current_scope[str]->children[0]->isConst())
 					newNode = current_scope[str]->children[0]->clone();
 			}
-			else if (at_zero && current_scope.count(str) > 0 && (current_scope[str]->type == AST_WIRE || current_scope[str]->type == AST_AUTOWIRE)) {
+			else if (at_zero && current_scope.count(str) > 0) {
+				AstNode *node = current_scope[str];
+				if (node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY)
+					newNode = mkconst_int(0, sign_hint, width_hint);
+			}
+			break;
+		case AST_MEMRD:
+			if (at_zero) {
 				newNode = mkconst_int(0, sign_hint, width_hint);
 			}
 			break;
diff --git a/tests/various/memory_word_as_index.data b/tests/various/memory_word_as_index.data
new file mode 100644
index 000000000..d525c18ee
--- /dev/null
+++ b/tests/various/memory_word_as_index.data
@@ -0,0 +1,4 @@
+00 04 08 0c
+10 14 18 1c
+20 24 28 2c
+30 34 38 3c
diff --git a/tests/various/memory_word_as_index.v b/tests/various/memory_word_as_index.v
new file mode 100644
index 000000000..a99ea9566
--- /dev/null
+++ b/tests/various/memory_word_as_index.v
@@ -0,0 +1,21 @@
+`define DATA 64'h492e5c4d7747e032
+
+`define GATE(n, expr) \
+module gate``n(sel, out); \
+	input wire [3:0] sel; \
+	output wire out; \
+	reg [63:0] bits; \
+	reg [5:0] ptrs[15:0]; \
+	initial bits = `DATA; \
+	initial $readmemh("memory_word_as_index.data", ptrs); \
+	assign out = expr; \
+endmodule
+
+`GATE(1, bits[ptrs[sel]])
+`GATE(2, bits[ptrs[sel][5:0]])
+`GATE(3, bits[ptrs[sel]+:1])
+
+module gold(sel, out);
+	input wire [3:0] sel;
+	output wire out = `DATA >> (sel * 4);
+endmodule
diff --git a/tests/various/memory_word_as_index.ys b/tests/various/memory_word_as_index.ys
new file mode 100644
index 000000000..9a2dea40e
--- /dev/null
+++ b/tests/various/memory_word_as_index.ys
@@ -0,0 +1,23 @@
+read_verilog memory_word_as_index.v
+
+hierarchy
+proc
+memory
+flatten
+opt -full
+
+equiv_make gold gate1 equiv
+equiv_simple
+equiv_status -assert
+
+delete equiv
+
+equiv_make gold gate2 equiv
+equiv_simple
+equiv_status -assert
+
+delete equiv
+
+equiv_make gold gate3 equiv
+equiv_simple
+equiv_status -assert
-- 
cgit v1.2.3