From 1f3ebe69478f245f69cd6f77db946226557085d2 Mon Sep 17 00:00:00 2001 From: lemon Date: Wed, 11 Mar 2026 11:37:19 +0100 Subject: x86_64/isel: fix edge case with branch on float add result In `if (x + 1)` the implicit `!= 0` can be omitted for integers, because the x86 `add` instruction sets the zero flag accordingly. But for floats it doesn't, so applying that optimization there was wrong. Luckily it was caught by a nullptr dereference later in `emit::Xjcc()` for the (missing) unordered branch target, instead of miscompiling. --- test/12-flt.c | 5 +++++ x86_64/isel.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/test/12-flt.c b/test/12-flt.c index 36f4e90..5077026 100644 --- a/test/12-flt.c +++ b/test/12-flt.c @@ -40,6 +40,11 @@ double nummod(double a, double b) { return m; } +double branch(double a) { + if (a + 1.1) return 0.0; + return -a; +} + int main() { NAN/=0.0; assert(_(1.0) < _(2.0)); diff --git a/x86_64/isel.c b/x86_64/isel.c index 3a753e6..ded1a52 100644 --- a/x86_64/isel.c +++ b/x86_64/isel.c @@ -577,7 +577,7 @@ seljmp(struct function *fn, struct block *blk) && (oiscmp(instrtab[c.i].op) || instrtab[c.i].op == Oand || instrtab[c.i].op == Osub)) { instrtab[c.i].keep = 1; } else { - if (!(opflags[instrtab[c.i].op] & ZF) || blk->ins.n == 0 || c.i != blk->ins.p[blk->ins.n - 1]) { + if (kisflt(instrtab[c.i].cls) || !(opflags[instrtab[c.i].op] & ZF) || blk->ins.n == 0 || c.i != blk->ins.p[blk->ins.n - 1]) { struct instr *ins; int curi = blk->ins.n; blk->jmp.arg[0] = insertinstr(blk, blk->ins.n, mkinstr(Oneq, insrescls(instrtab[c.i]), c, ZEROREF)); -- cgit v1.2.3