// removeSucc removes the ith output edge from b.
// It is the responsibility of the caller to remove
// the corresponding predecessor edge.
+// Note that this potentially reorders successors of b, so it
+// must be used very carefully.
func (b *Block) removeSucc(i int) {
n := len(b.Succs) - 1
if i != n {
b.Likely *= -1
}
+// Swaps b.Succs[x] and b.Succs[y].
+func (b *Block) swapSuccessorsByIdx(x, y int) {
+ if x == y {
+ return
+ }
+ ex := b.Succs[x]
+ ey := b.Succs[y]
+ b.Succs[x] = ey
+ b.Succs[y] = ex
+ ex.b.Preds[ex.i].i = y
+ ey.b.Preds[ey.i].i = x
+}
+
// removePhiArg removes the ith arg from phi.
// It must be called after calling b.removePred(i) to
// adjust the corresponding phi value of the block:
func (b *Block) removePhiArg(phi *Value, i int) {
n := len(b.Preds)
if numPhiArgs := len(phi.Args); numPhiArgs-1 != n {
- b.Fatalf("inconsistent state, num predecessors: %d, num phi args: %d", n, numPhiArgs)
+ b.Fatalf("inconsistent state for %v, num predecessors: %d, num phi args: %d", phi, n, numPhiArgs)
}
phi.Args[i].Uses--
phi.Args[i] = phi.Args[n]
// removeEdge removes the i'th outgoing edge from b (and
// the corresponding incoming edge from b.Succs[i].b).
+// Note that this potentially reorders successors of b, so it
+// must be used very carefully.
func (b *Block) removeEdge(i int) {
e := b.Succs[i]
c := e.b
block.ResetControls()
return true
case BlockJumpTable:
+ // Remove everything but the known taken branch.
idx := int(constVal.AuxInt)
- targetBlock := block.Succs[idx].b
- for len(block.Succs) > 0 {
- block.removeEdge(0)
+ block.swapSuccessorsByIdx(0, idx)
+ for len(block.Succs) > 1 {
+ block.removeEdge(1)
}
- block.AddEdgeTo(targetBlock)
block.Kind = BlockPlain
block.Likely = BranchUnknown
block.ResetControls()
--- /dev/null
+// build -race
+
+//go:build race
+
+// Copyright 2023 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.
+
+package main
+
+func main() {
+ var o any = uint64(5)
+ switch o.(type) {
+ case int:
+ goto ret
+ case int8:
+ goto ret
+ case int16:
+ goto ret
+ case int32:
+ goto ret
+ case int64:
+ goto ret
+ case float32:
+ goto ret
+ case float64:
+ goto ret
+ default:
+ goto ret
+ }
+ret:
+}