From dfe28f7ed0e67f2794ddc5e167bdcfaacc40d31f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 11 Jan 2025 08:48:40 -0500 Subject: [PATCH] Fix misoptimizing away `$urandom` (#5703). --- Changes | 1 + src/V3AstNodeExpr.h | 2 +- test_regress/t/t_sys_rand_seed.v | 27 ++++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Changes b/Changes index 1ab276672..a60e8b4f0 100644 --- a/Changes +++ b/Changes @@ -23,6 +23,7 @@ Verilator 5.033 devel * Fix pattern assignment to real inside struct (#5713). * Fix %p format output for real inside struct (#5713). * Fix segfault when only enum value referenced in package (#5714). [Dan Katz] +* Fix misoptimizing away `$urandom` (#5703). [Parker Schless] * Fix matching language extension options including dots. diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 13382f64b..db32a6de9 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -1820,7 +1820,6 @@ public: return "VL_RANDOM_SEEDED_%nq%lq(%li)"; } } - if (isWide()) { return "VL_RANDOM_%nq(%nw, %P)"; } else { @@ -1830,6 +1829,7 @@ public: bool cleanOut() const override { return false; } bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } + bool isPure() override { return !m_reset && !seedp(); } int instrCount() const override { return INSTR_COUNT_PLI; } bool sameNode(const AstNode* /*samep*/) const override { return true; } bool combinable(const AstRand* samep) const { diff --git a/test_regress/t/t_sys_rand_seed.v b/test_regress/t/t_sys_rand_seed.v index 549f5e8c8..3a9acec20 100644 --- a/test_regress/t/t_sys_rand_seed.v +++ b/test_regress/t/t_sys_rand_seed.v @@ -12,6 +12,9 @@ module t; int valuea; int valueb; int valuec; + int igna; + int ignb; + int ignc; initial begin // $random unlike $urandom updates the value if given @@ -32,7 +35,29 @@ module t; valuea = $urandom(10); valueb = $urandom(10); - if (valuea !== valueb) $stop; + valuec = $urandom(10); + if (valuea !== valueb && valueb != valuec) $stop; + + valuea = $urandom(10); + valueb = $urandom(11); + valuec = $urandom(12); + if (valuea == valueb && valueb == valuec) $stop; // May false fail 1 in 1^64 + + $urandom(10); + valuea = $urandom; + $urandom(10); + valueb = $urandom; + $urandom(10); + valuec = $urandom; + if (valuea != valueb && valueb != valuec) $stop; // May false fail 1 in 1^64 + + igna = $urandom(10); + valuea = $urandom; + ignb = $urandom(10); + valueb = $urandom; + ignc = $urandom(10); + valuec = $urandom; + if (valuea != valueb && valueb != valuec) $stop; // May false fail 1 in 1^64 valuea = $urandom(10); valueb = $urandom();