qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

commit 0384d73e8daa5c948fb08c7301144c0d7e740ef9
parent e2bc0ad3960769ba7a0f1223ac160b0d985fff35
Author: Michael Forney <mforney@mforney.org>
Date:   Sat, 27 Apr 2019 12:22:57 -0700

fold: Make sure 32-bit constants get sign extended when necessary

Diffstat:
Mfold.c | 6+++---
Atest/fold1.ssa | 25+++++++++++++++++++++++++
2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/fold.c b/fold.c @@ -371,15 +371,15 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) switch (op) { case Oadd: x = l.u + r.u; break; case Osub: x = l.u - r.u; break; - case Odiv: x = l.s / r.s; break; - case Orem: x = l.s % r.s; break; + case Odiv: x = w ? l.s / r.s : (int32_t)l.s / (int32_t)r.s; break; + case Orem: x = w ? l.s % r.s : (int32_t)l.s % (int32_t)r.s; break; case Oudiv: x = l.u / r.u; break; case Ourem: x = l.u % r.u; break; case Omul: x = l.u * r.u; break; case Oand: x = l.u & r.u; break; case Oor: x = l.u | r.u; break; case Oxor: x = l.u ^ r.u; break; - case Osar: x = l.s >> (r.u & 63); break; + case Osar: x = (w ? l.s : (int32_t)l.s) >> (r.u & 63); break; case Oshr: x = l.u >> (r.u & 63); break; case Oshl: x = l.u << (r.u & 63); break; case Oextsb: x = (int8_t)l.u; break; diff --git a/test/fold1.ssa b/test/fold1.ssa @@ -0,0 +1,25 @@ +export +function w $f1() { +@start + %x =w sar 2147483648, 31 + ret %x +} + +export +function w $f2() { +@start + %x =w div 4294967040, 8 # -256 / 8 + ret %x +} + +export +function w $f3() { +@start + %x =w rem 4294967284, 7 # -12 % 7 + ret %x +} + +# >>> driver +# extern int f1(), f2(), f3(); +# int main() { return !(f1() == -1 && f2() == -32 && f3() == -5); } +# <<<