Home | History | Annotate | Download | only in testdata
      1 // Copyright 2015 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package main
      6 
      7 import "fmt"
      8 
      9 var output string
     10 
     11 func mypanic(s string) {
     12 	fmt.Printf(output)
     13 	panic(s)
     14 }
     15 
     16 func assertEqual(x, y int) {
     17 	if x != y {
     18 		mypanic("assertEqual failed")
     19 	}
     20 }
     21 
     22 func main() {
     23 	x := f1_ssa(2, 3)
     24 	output += fmt.Sprintln("*x is", *x)
     25 	output += fmt.Sprintln("Gratuitously use some stack")
     26 	output += fmt.Sprintln("*x is", *x)
     27 	assertEqual(*x, 9)
     28 
     29 	w := f3a_ssa(6)
     30 	output += fmt.Sprintln("*w is", *w)
     31 	output += fmt.Sprintln("Gratuitously use some stack")
     32 	output += fmt.Sprintln("*w is", *w)
     33 	assertEqual(*w, 6)
     34 
     35 	y := f3b_ssa(12)
     36 	output += fmt.Sprintln("*y.(*int) is", *y.(*int))
     37 	output += fmt.Sprintln("Gratuitously use some stack")
     38 	output += fmt.Sprintln("*y.(*int) is", *y.(*int))
     39 	assertEqual(*y.(*int), 12)
     40 
     41 	z := f3c_ssa(8)
     42 	output += fmt.Sprintln("*z.(*int) is", *z.(*int))
     43 	output += fmt.Sprintln("Gratuitously use some stack")
     44 	output += fmt.Sprintln("*z.(*int) is", *z.(*int))
     45 	assertEqual(*z.(*int), 8)
     46 
     47 	args()
     48 	test_autos()
     49 }
     50 
     51 //go:noinline
     52 func f1_ssa(x, y int) *int {
     53 	x = x*y + y
     54 	return &x
     55 }
     56 
     57 //go:noinline
     58 func f3a_ssa(x int) *int {
     59 	return &x
     60 }
     61 
     62 //go:noinline
     63 func f3b_ssa(x int) interface{} { // ./foo.go:15: internal error: f3b_ssa ~r1 (type interface {}) recorded as live on entry
     64 	return &x
     65 }
     66 
     67 //go:noinline
     68 func f3c_ssa(y int) interface{} {
     69 	x := y
     70 	return &x
     71 }
     72 
     73 type V struct {
     74 	p    *V
     75 	w, x int64
     76 }
     77 
     78 func args() {
     79 	v := V{p: nil, w: 1, x: 1}
     80 	a := V{p: &v, w: 2, x: 2}
     81 	b := V{p: &v, w: 0, x: 0}
     82 	i := v.args_ssa(a, b)
     83 	output += fmt.Sprintln("i=", i)
     84 	assertEqual(int(i), 2)
     85 }
     86 
     87 //go:noinline
     88 func (v V) args_ssa(a, b V) int64 {
     89 	if v.w == 0 {
     90 		return v.x
     91 	}
     92 	if v.w == 1 {
     93 		return a.x
     94 	}
     95 	if v.w == 2 {
     96 		return b.x
     97 	}
     98 	b.p.p = &a // v.p in caller = &a
     99 
    100 	return -1
    101 }
    102 
    103 func test_autos() {
    104 	test(11)
    105 	test(12)
    106 	test(13)
    107 	test(21)
    108 	test(22)
    109 	test(23)
    110 	test(31)
    111 	test(32)
    112 }
    113 
    114 func test(which int64) {
    115 	output += fmt.Sprintln("test", which)
    116 	v1 := V{w: 30, x: 3, p: nil}
    117 	v2, v3 := v1.autos_ssa(which, 10, 1, 20, 2)
    118 	if which != v2.val() {
    119 		output += fmt.Sprintln("Expected which=", which, "got v2.val()=", v2.val())
    120 		mypanic("Failure of expected V value")
    121 	}
    122 	if v2.p.val() != v3.val() {
    123 		output += fmt.Sprintln("Expected v2.p.val()=", v2.p.val(), "got v3.val()=", v3.val())
    124 		mypanic("Failure of expected V.p value")
    125 	}
    126 	if which != v3.p.p.p.p.p.p.p.val() {
    127 		output += fmt.Sprintln("Expected which=", which, "got v3.p.p.p.p.p.p.p.val()=", v3.p.p.p.p.p.p.p.val())
    128 		mypanic("Failure of expected V.p value")
    129 	}
    130 }
    131 
    132 func (v V) val() int64 {
    133 	return v.w + v.x
    134 }
    135 
    136 // autos_ssa uses contents of v and parameters w1, w2, x1, x2
    137 // to initialize a bunch of locals, all of which have their
    138 // address taken to force heap allocation, and then based on
    139 // the value of which a pair of those locals are copied in
    140 // various ways to the two results y, and z, which are also
    141 // addressed. Which is expected to be one of 11-13, 21-23, 31, 32,
    142 // and y.val() should be equal to which and y.p.val() should
    143 // be equal to z.val().  Also, x(.p)**8 == x; that is, the
    144 // autos are all linked into a ring.
    145 //go:noinline
    146 func (v V) autos_ssa(which, w1, x1, w2, x2 int64) (y, z V) {
    147 	fill_ssa(v.w, v.x, &v, v.p) // gratuitous no-op to force addressing
    148 	var a, b, c, d, e, f, g, h V
    149 	fill_ssa(w1, x1, &a, &b)
    150 	fill_ssa(w1, x2, &b, &c)
    151 	fill_ssa(w1, v.x, &c, &d)
    152 	fill_ssa(w2, x1, &d, &e)
    153 	fill_ssa(w2, x2, &e, &f)
    154 	fill_ssa(w2, v.x, &f, &g)
    155 	fill_ssa(v.w, x1, &g, &h)
    156 	fill_ssa(v.w, x2, &h, &a)
    157 	switch which {
    158 	case 11:
    159 		y = a
    160 		z.getsI(&b)
    161 	case 12:
    162 		y.gets(&b)
    163 		z = c
    164 	case 13:
    165 		y.gets(&c)
    166 		z = d
    167 	case 21:
    168 		y.getsI(&d)
    169 		z.gets(&e)
    170 	case 22:
    171 		y = e
    172 		z = f
    173 	case 23:
    174 		y.gets(&f)
    175 		z.getsI(&g)
    176 	case 31:
    177 		y = g
    178 		z.gets(&h)
    179 	case 32:
    180 		y.getsI(&h)
    181 		z = a
    182 	default:
    183 
    184 		panic("")
    185 	}
    186 	return
    187 }
    188 
    189 // gets is an address-mentioning way of implementing
    190 // structure assignment.
    191 //go:noinline
    192 func (to *V) gets(from *V) {
    193 	*to = *from
    194 }
    195 
    196 // gets is an address-and-interface-mentioning way of
    197 // implementing structure assignment.
    198 //go:noinline
    199 func (to *V) getsI(from interface{}) {
    200 	*to = *from.(*V)
    201 }
    202 
    203 // fill_ssa initializes r with V{w:w, x:x, p:p}
    204 //go:noinline
    205 func fill_ssa(w, x int64, r, p *V) {
    206 	*r = V{w: w, x: x, p: p}
    207 }
    208