From 46fc55e27390ea85eb34ec0367f40426197c9b9f Mon Sep 17 00:00:00 2001 From: lemon Date: Thu, 19 Mar 2026 11:51:13 +0100 Subject: regalloc & emit: explicit comparisons over memcmp of small structures The one in x86-64_emit was not portable due to relying on zero initialization of inactive union fields/padding. --- src/ir_regalloc.c | 2 +- src/t_x86-64_emit.c | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ir_regalloc.c b/src/ir_regalloc.c index ddb05e2..54f5d59 100644 --- a/src/ir_regalloc.c +++ b/src/ir_regalloc.c @@ -210,7 +210,7 @@ typedef struct { static void pmadd(PMState *pms, enum irclass k, Alloc dst, Alloc src) { - if (!memcmp(&dst, &src, sizeof dst)) return; + if (dst.bits == src.bits) return; assert(pms->npmove < MAXREGS); pms->pmove[pms->npmove++] = (struct PMove) { k, PMTOMOVE, dst, src }; } diff --git a/src/t_x86-64_emit.c b/src/t_x86-64_emit.c index e1df982..507955a 100644 --- a/src/t_x86-64_emit.c +++ b/src/t_x86-64_emit.c @@ -160,6 +160,22 @@ mkmemoper(Ref r) } } +static bool +opereql(Oper a, Oper b) +{ + if (a.t != b.t) return 0; + switch (a.t) { + case OREG: return a.reg == b.reg; + case OIMM: return a.imm == b.imm; + case OMEM: + return a.base == b.base && a.index == b.index && a.shift == b.shift && a.disp == b.disp; + case OSYM: + case OSYMGOT: + return a.cindex == b.cindex && a.cshift == b.cshift && a.con == b.con && a.disp == b.disp; + default: assert(0); + } +} + /** Instruction description tables ** * * Each instruction is a list of descs, and the first one that matches @@ -703,7 +719,7 @@ static const EncDesc imul3_imm8tab[] = { static void Ximul(uchar **pcode, enum irclass k, Oper dst, Oper s1, Oper s2) { - if (!memcmp(&dst, &s1, sizeof dst) && s2.t != OIMM) { + if (opereql(dst, s1) && s2.t != OIMM) { Ximul2(pcode, k, dst, s2); return; } @@ -908,7 +924,7 @@ gencopy(uchar **pcode, enum irclass cls, Block *blk, int curi, Oper dst, Ref val *pcode += 8; } else { Oper src = mkimmdatregoper(val); - if (memcmp(&dst, &src, sizeof dst) != 0) + if (!opereql(dst, src)) Xmov(pcode, cls == KF64 && src.t == OREG && src.reg < XMM0 ? KI64 : cls, dst, src); } } -- cgit v1.2.3