scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 3b5e9eb7079be6f946a66c2b751921723680a5aa
parent eaf2b18533e87462e71e588fd6edd96d937622b2
Author: Roberto E. Vargas Caballero <k0ga@shike2.net>
Date:   Sat, 31 Jan 2026 09:50:03 +0100

cc2/qbe: Fix bug introduced in b83ec8ed

The commit b83ec8ed modified the code of binary operations because in
the case of comparisions we have a cmp node with float type, but the
result is integer. The intermediate language used cannot express cases
like this one, because it assumes that the operand and the result have
the same type. The commit b83ec8ed assumes that the piece of code
modified applied only to comparisions, but in fact, it affected to
any binary operation, producing that all the binary operations were
casted to int32type.

Diffstat:
Msrc/cmd/scc-cc/cc2/qbe/cgen.c | 22++++++++++++++--------
Atests/cc/execute/0237-down.c | 14++++++++++++++
Mtests/cc/execute/scc-tests.lst | 1+
3 files changed, 29 insertions(+), 8 deletions(-)

diff --git a/src/cmd/scc-cc/cc2/qbe/cgen.c b/src/cmd/scc-cc/cc2/qbe/cgen.c @@ -531,7 +531,7 @@ rhs(Node *np) Node *tmp, aux1, aux2; Node *phi, *l = np->left, *r = np->right; Type *tp; - int sign, size, isfloat, op; + int cmp, sign, size, isfloat, op; Symbol *true, *false; tp = &np->type; @@ -544,6 +544,14 @@ rhs(Node *np) case OREG: case OAUTO: return load(tp, np); + case OLT: + case OGT: + case OLE: + case OGE: + case OEQ: + case ONE: + cmp = 1; + goto binary; case OMOD: case OSHL: case OBAND: @@ -552,15 +560,11 @@ rhs(Node *np) case OSHR: assert(tp->flags & INTF); case ODIV: - case OLT: - case OGT: - case OLE: - case OGE: case OADD: case OSUB: case OMUL: - case OEQ: - case ONE: + cmp = 0; + binary: assert(tp->size == 4 || tp->size == 8); sign = (tp->flags & SIGNF) == 0; @@ -568,7 +572,9 @@ rhs(Node *np) isfloat = (tp->flags & FLOATF) != 0; op = opbin[isfloat][size][np->op][sign]; rhs_rhs(&l, &r); - tmp = tmpnode(&int32type, NULL); + if (cmp) + tp = &int32type; + tmp = tmpnode(tp, NULL); code(op, tmp, l, r); return tmp; case OCALL: diff --git a/tests/cc/execute/0237-down.c b/tests/cc/execute/0237-down.c @@ -0,0 +1,14 @@ +/* + * Regression test for incorrect typing in binary operations + * in the qbe backend. + */ + +int +main(void) +{ + long long l = 1ll < 34; + + l = l + 1; + + return l == 1; +} diff --git a/tests/cc/execute/scc-tests.lst b/tests/cc/execute/scc-tests.lst @@ -227,3 +227,4 @@ 0234-macro.c 0235-comment.c 0236-sizeof.c +0237-down.c