From 9c5349cbd2a7ccc26ab7c1c1a5fce44d50554704 Mon Sep 17 00:00:00 2001 From: Shane Date: Tue, 10 Mar 2026 21:01:36 -0500 Subject: [PATCH] Fix eel2 regNN*regNN optimizer bug: x*y incorrectly optimized to sqr(x) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nseel_resolve_named_symbol clears sname[0] for regNN variables (line 983), which makes the x*x → sqr(x) optimizer treat ALL regNN vars as identical (it compares relname strings, which are now all empty). This causes expressions like `reg10*reg20` to be compiled as `sqr(reg10)`. Two fixes: 1. Remove `sname[0]=0` — the comment already says "this shouldn't be needed anyway", and it breaks the optimizer's string comparison. 2. Add valuePtr comparison as primary check in the VARPTR case of the sqr() optimization, consistent with the existing VARPTRPTR case (line 2464). Also guard the string fallback with relname[0] check to prevent empty-string false matches. Discovered in MilkDrop preset rendering where rotation matrices using different regNN variables produced incorrect results (squaring one operand instead of multiplying two distinct registers). --- WDL/eel2/nseel-compiler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/eel2/nseel-compiler.c b/WDL/eel2/nseel-compiler.c index d68946321..72649eea6 100644 --- a/WDL/eel2/nseel-compiler.c +++ b/WDL/eel2/nseel-compiler.c @@ -980,7 +980,6 @@ opcodeRec *nseel_resolve_named_symbol(compileContext *ctx, opcodeRec *rec, int p if (a) { rec->parms.dv.valuePtr = a; - sname[0]=0; // for dump_ops compat really, but this shouldn't be needed anyway } return rec; } @@ -2458,7 +2457,8 @@ goto start_over; if (first_parm->namespaceidx != second_parm->namespaceidx) break; WDL_FALLTHROUGH; // fall through case OPCODETYPE_VARPTR: - if (first_parm->relname && second_parm->relname && !stricmp(second_parm->relname,first_parm->relname)) second_parm=NULL; + if (first_parm->parms.dv.valuePtr && first_parm->parms.dv.valuePtr==second_parm->parms.dv.valuePtr) second_parm=NULL; + else if (first_parm->relname && second_parm->relname && first_parm->relname[0] && !stricmp(second_parm->relname,first_parm->relname)) second_parm=NULL; break; case OPCODETYPE_VARPTRPTR: if (first_parm->parms.dv.valuePtr && first_parm->parms.dv.valuePtr==second_parm->parms.dv.valuePtr) second_parm=NULL;