From 1910d875cfcad320cbb87c5e8c846d5c53846a1a Mon Sep 17 00:00:00 2001 From: lemon Date: Sat, 15 Nov 2025 18:54:21 +0100 Subject: isel: don't incorrectly clamp constant lhs of shift operation --- amd64/isel.c | 8 ++++---- test/varargs.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/amd64/isel.c b/amd64/isel.c index 6635abc..0ed50d9 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -56,10 +56,10 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi) if (r->t == RXCON) { struct xcon *con = &conht[r->i]; - if (in_range(op, Oshl, Oslr)) { + if (in_range(op, Oshl, Oslr) && r == &ins->r) { sh = con->i; goto ShiftImm; - } else if (in_range(op, Oadd, Osub) && con->i == 2147483648) { + } else if (in_range(op, Oadd, Osub) && con->i == 2147483648 && r == &ins->r) { /* add X, INT32MAX+1 -> sub X, INT32MIN */ ins->op = Oadd + (op == Oadd); *r = mkintcon(KI4, -2147483648); @@ -89,10 +89,10 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi) *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, mkaddr((struct addr){*r}))); } else if (in_range(op, Odiv, Ourem) && kisint(ins->cls)) goto DivImm; - } else if (r->t == RICON && in_range(op, Odiv, Ourem) && kisint(ins->cls)) { + } else if (r->t == RICON && in_range(op, Odiv, Ourem) && kisint(ins->cls) && r == &ins->r) { DivImm: /* there is no division by immediate, must be copied to a register */ *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, *r)); - } else if (r->t == RICON && in_range(op, Oshl, Oslr)) { + } else if (r->t == RICON && in_range(op, Oshl, Oslr) && r == &ins->r) { sh = r->i; ShiftImm: /* shift immediate is always 8bit */ *r = mkref(RICON, sh & 255); diff --git a/test/varargs.c b/test/varargs.c index ff7d41d..89ab21c 100644 --- a/test/varargs.c +++ b/test/varargs.c @@ -13,5 +13,5 @@ int sum(int x, ...) { } int main() { - printf("%d\n", sum(1,2,3,4,5,6,7,0,0)); + printf("%d\n", sum(1,2,3,4,5,6,5.5,7,0,0)); } -- cgit v1.2.3