gotools/go/ssa/interp/testdata/fixedbugs/issue69929.go

package main

// This is a regression test for a bug (#69929) in
// the SSA interpreter in which it would not execute phis in parallel.
//
// The insert function below has interdependent phi nodes:
//
//	  entry:
//		t0 = *root       // t0 is x or y before loop
//		jump test
//	  body:
//		print(t5)      // t5 is x at loop entry
//		t3 = t5.Child    // t3 is x after loop
//		jump test
//	  test:
//		t5 = phi(t0, t3) // t5 is x at loop entry
//		t6 = phi(t0, t5) // t6 is y at loop entry
//		if t5 != nil goto body else done
//	  done:
//		print(t6)
//		return
//
// The two phis:
//
//	t5 = phi(t0, t3)
//	t6 = phi(t0, t5)
//
// must be executed in parallel as if they were written in Go
// as:
//
//	t5, t6 = phi(t0, t3), phi(t0, t5)
//
// with the second phi node observing the original, not
// updated, value of t5. (In more complex examples, the phi
// nodes may be mutually recursive, breaking partial solutions
// based on simple reordering of the phi instructions. See the
// Briggs paper for detail.)
//
// The correct behavior is print(1, root); print(2, root); print(3, root).
// The previous incorrect behavior had print(2, nil).

func main() {
	insert()
	print(3, root)
}

var root = new(node)

type node struct{ child *node }

func insert() {
	x := root
	y := x
	for x != nil {
		y = x
		print(1, y)
		x = x.child
	}
	print(2, y)
}

func print(order int, ptr *node) {
	println(order, ptr)
	if ptr != root {
		panic(ptr)
	}
}