diff options
Diffstat (limited to 'src/cmd/compile/internal/gc/walk.go')
-rw-r--r-- | src/cmd/compile/internal/gc/walk.go | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index ab2e38208d..7909072340 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -1272,6 +1272,13 @@ opswitch: } if cs != nil { cmp := Op(n.Etype) + // Our comparison below assumes that the non-constant string + // is on the left hand side, so rewrite "" cmp x to x cmp "". + // See issue 24817. + if Isconst(n.Left, CTSTR) { + cmp = brrev(cmp) + } + // maxRewriteLen was chosen empirically. // It is the value that minimizes cmd/go file size // across most architectures. @@ -3390,18 +3397,23 @@ func walkcompare(n *Node, init *Nodes) *Node { i++ remains -= t.Elem().Width } else { + elemType := t.Elem().ToUnsigned() cmplw := nod(OINDEX, cmpl, nodintconst(int64(i))) - cmplw = conv(cmplw, convType) + cmplw = conv(cmplw, elemType) // convert to unsigned + cmplw = conv(cmplw, convType) // widen cmprw := nod(OINDEX, cmpr, nodintconst(int64(i))) + cmprw = conv(cmprw, elemType) cmprw = conv(cmprw, convType) // For code like this: uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ... // ssa will generate a single large load. for offset := int64(1); offset < step; offset++ { lb := nod(OINDEX, cmpl, nodintconst(int64(i+offset))) + lb = conv(lb, elemType) lb = conv(lb, convType) lb = nod(OLSH, lb, nodintconst(int64(8*t.Elem().Width*offset))) cmplw = nod(OOR, cmplw, lb) rb := nod(OINDEX, cmpr, nodintconst(int64(i+offset))) + rb = conv(rb, elemType) rb = conv(rb, convType) rb = nod(OLSH, rb, nodintconst(int64(8*t.Elem().Width*offset))) cmprw = nod(OOR, cmprw, rb) |