From 46fcfdaa7dc4c35cf593df2b883db28814e641fe Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9my=20Oudompheng?= Date: Sun, 7 Oct 2012 00:30:29 +0200 Subject: [PATCH] cmd/6g: fix out of registers when chaining integer divisions. Fixes #4201. R=golang-dev, rsc CC=golang-dev, remy https://golang.org/cl/6622055 --- src/cmd/6g/cgen.c | 18 +++++++++++++++++- test/torture.go | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c index 8d6ffb087b..f2be7d1ae9 100644 --- a/src/cmd/6g/cgen.c +++ b/src/cmd/6g/cgen.c @@ -402,7 +402,23 @@ cgen(Node *n, Node *res) a = optoas(n->op, nl->type); goto abop; } - cgen_div(n->op, nl, nr, res); + + if(nl->ullman >= nr->ullman) { + regalloc(&n1, nl->type, res); + cgen(nl, &n1); + cgen_div(n->op, &n1, nr, res); + regfree(&n1); + } else { + if(!smallintconst(nr)) { + regalloc(&n2, nr->type, res); + cgen(nr, &n2); + } else { + n2 = *nr; + } + cgen_div(n->op, nl, &n2, res); + if(n2.op != OLITERAL) + regfree(&n2); + } break; case OLSH: diff --git a/test/torture.go b/test/torture.go index fdc5ddae0f..dd8ff59a03 100644 --- a/test/torture.go +++ b/test/torture.go @@ -169,3 +169,25 @@ func ChainUNoAssert(u *U) *U { Child(0). Child(0).(*U) } + +// Chains of divisions. See issue 4201. + +func ChainDiv(a, b int) int { + return a / b / a / b / a / b / a / b / + a / b / a / b / a / b / a / b / + a / b / a / b / a / b / a / b +} + +func ChainDivRight(a, b int) int { + return a / (b / (a / (b / + (a / (b / (a / (b / + (a / (b / (a / (b / + (a / (b / (a / (b / + (a / (b / (a / b)))))))))))))))))) +} + +func ChainDivConst(a int) int { + return a / 17 / 17 / 17 / + 17 / 17 / 17 / 17 / + 17 / 17 / 17 / 17 +} -- 2.50.0