Commit f134742f authored by Rémy Oudompheng's avatar Rémy Oudompheng

cmd/5g, cmd/8g: fix internal error on 64-bit indices statically bounded

Fixes #4448.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6855100
parent e781b20a
...@@ -521,7 +521,7 @@ ret: ...@@ -521,7 +521,7 @@ ret:
* returns Prog* to patch to panic call. * returns Prog* to patch to panic call.
*/ */
Prog* Prog*
cgenindex(Node *n, Node *res) cgenindex(Node *n, Node *res, int bounded)
{ {
Node tmp, lo, hi, zero, n1, n2; Node tmp, lo, hi, zero, n1, n2;
...@@ -534,7 +534,7 @@ cgenindex(Node *n, Node *res) ...@@ -534,7 +534,7 @@ cgenindex(Node *n, Node *res)
cgen(n, &tmp); cgen(n, &tmp);
split64(&tmp, &lo, &hi); split64(&tmp, &lo, &hi);
gmove(&lo, res); gmove(&lo, res);
if(debug['B']) { if(bounded) {
splitclean(); splitclean();
return nil; return nil;
} }
...@@ -889,6 +889,7 @@ agenr(Node *n, Node *a, Node *res) ...@@ -889,6 +889,7 @@ agenr(Node *n, Node *a, Node *res)
Prog *p1, *p2; Prog *p1, *p2;
uint32 w; uint32 w;
uint64 v; uint64 v;
int bounded;
if(debug['g']) if(debug['g'])
dump("agenr-n", n); dump("agenr-n", n);
...@@ -915,13 +916,14 @@ agenr(Node *n, Node *a, Node *res) ...@@ -915,13 +916,14 @@ agenr(Node *n, Node *a, Node *res)
case OINDEX: case OINDEX:
p2 = nil; // to be patched to panicindex. p2 = nil; // to be patched to panicindex.
w = n->type->width; w = n->type->width;
bounded = debug['B'] || n->bounded;
if(nr->addable) { if(nr->addable) {
if(!isconst(nr, CTINT)) if(!isconst(nr, CTINT))
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
if(!isconst(nl, CTSTR)) if(!isconst(nl, CTSTR))
agenr(nl, &n3, res); agenr(nl, &n3, res);
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
p2 = cgenindex(nr, &tmp); p2 = cgenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
...@@ -929,7 +931,7 @@ agenr(Node *n, Node *a, Node *res) ...@@ -929,7 +931,7 @@ agenr(Node *n, Node *a, Node *res)
if(nl->addable) { if(nl->addable) {
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp); p2 = cgenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
...@@ -938,7 +940,7 @@ agenr(Node *n, Node *a, Node *res) ...@@ -938,7 +940,7 @@ agenr(Node *n, Node *a, Node *res)
} }
} else { } else {
tempname(&tmp, types[TINT32]); tempname(&tmp, types[TINT32]);
p2 = cgenindex(nr, &tmp); p2 = cgenindex(nr, &tmp, bounded);
nr = &tmp; nr = &tmp;
if(!isconst(nl, CTSTR)) if(!isconst(nl, CTSTR))
agenr(nl, &n3, res); agenr(nl, &n3, res);
......
...@@ -88,7 +88,7 @@ void ginscall(Node*, int); ...@@ -88,7 +88,7 @@ void ginscall(Node*, int);
* cgen * cgen
*/ */
void agen(Node*, Node*); void agen(Node*, Node*);
Prog* cgenindex(Node *, Node *); Prog* cgenindex(Node *, Node *, int);
void igen(Node*, Node*, Node*); void igen(Node*, Node*, Node*);
void agenr(Node *n, Node *a, Node *res); void agenr(Node *n, Node *a, Node *res);
vlong fieldoffset(Type*, Node*); vlong fieldoffset(Type*, Node*);
......
...@@ -1937,7 +1937,7 @@ oindex: ...@@ -1937,7 +1937,7 @@ oindex:
t = types[TINT32]; t = types[TINT32];
regalloc(reg1, t, N); regalloc(reg1, t, N);
regalloc(&n3, types[TINT32], reg1); regalloc(&n3, types[TINT32], reg1);
p2 = cgenindex(r, &n3); p2 = cgenindex(r, &n3, debug['B'] || n->bounded);
gmove(&n3, reg1); gmove(&n3, reg1);
regfree(&n3); regfree(&n3);
......
...@@ -464,8 +464,8 @@ flt2: // binary ...@@ -464,8 +464,8 @@ flt2: // binary
* n is an array index, and might be any size; res width is <= 32-bit. * n is an array index, and might be any size; res width is <= 32-bit.
* returns Prog* to patch to panic call. * returns Prog* to patch to panic call.
*/ */
Prog* static Prog*
igenindex(Node *n, Node *res) igenindex(Node *n, Node *res, int bounded)
{ {
Node tmp, lo, hi, zero; Node tmp, lo, hi, zero;
...@@ -485,7 +485,7 @@ igenindex(Node *n, Node *res) ...@@ -485,7 +485,7 @@ igenindex(Node *n, Node *res)
split64(&tmp, &lo, &hi); split64(&tmp, &lo, &hi);
tempname(res, types[TUINT32]); tempname(res, types[TUINT32]);
gmove(&lo, res); gmove(&lo, res);
if(debug['B']) { if(bounded) {
splitclean(); splitclean();
return nil; return nil;
} }
...@@ -508,6 +508,7 @@ agen(Node *n, Node *res) ...@@ -508,6 +508,7 @@ agen(Node *n, Node *res)
uint32 w; uint32 w;
uint64 v; uint64 v;
Prog *p1, *p2; Prog *p1, *p2;
int bounded;
if(debug['g']) { if(debug['g']) {
dump("\nagen-res", res); dump("\nagen-res", res);
...@@ -584,26 +585,27 @@ agen(Node *n, Node *res) ...@@ -584,26 +585,27 @@ agen(Node *n, Node *res)
case OINDEX: case OINDEX:
p2 = nil; // to be patched to panicindex. p2 = nil; // to be patched to panicindex.
w = n->type->width; w = n->type->width;
bounded = debug['B'] || n->bounded;
if(nr->addable) { if(nr->addable) {
// Generate &nl first, and move nr into register. // Generate &nl first, and move nr into register.
if(!isconst(nl, CTSTR)) if(!isconst(nl, CTSTR))
igen(nl, &n3, res); igen(nl, &n3, res);
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
p2 = igenindex(nr, &tmp); p2 = igenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
} else if(nl->addable) { } else if(nl->addable) {
// Generate nr first, and move &nl into register. // Generate nr first, and move &nl into register.
if(!isconst(nr, CTINT)) { if(!isconst(nr, CTINT)) {
p2 = igenindex(nr, &tmp); p2 = igenindex(nr, &tmp, bounded);
regalloc(&n1, tmp.type, N); regalloc(&n1, tmp.type, N);
gmove(&tmp, &n1); gmove(&tmp, &n1);
} }
if(!isconst(nl, CTSTR)) if(!isconst(nl, CTSTR))
igen(nl, &n3, res); igen(nl, &n3, res);
} else { } else {
p2 = igenindex(nr, &tmp); p2 = igenindex(nr, &tmp, bounded);
nr = &tmp; nr = &tmp;
if(!isconst(nl, CTSTR)) if(!isconst(nl, CTSTR))
igen(nl, &n3, res); igen(nl, &n3, res);
......
// run
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Issue 4448: 64-bit indices that are statically known
// to be bounded make 5g and 8g generate a dangling branch.
package main
const b26 uint64 = 0x022fdd63cc95386d
var bitPos [64]int
func init() {
for p := uint(0); p < 64; p++ {
bitPos[b26<<p>>58] = int(p)
}
}
func MinPos(w uint64) int {
if w == 0 {
panic("bit: MinPos(0) undefined")
}
return bitPos[((w&-w)*b26)>>58]
}
func main() {
const one = uint64(1)
for i := 0; i < 64; i++ {
if MinPos(1<<uint(i)) != i {
println("i =", i)
panic("MinPos(1<<uint(i)) != i")
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment