• Josh Bleecher Snyder's avatar
    [dev.ssa] cmd/compile: don't combine phi vars from different blocks in CSE · 00437ebe
    Josh Bleecher Snyder authored
    Here is a concrete case in which this goes wrong.
    
    func f_ssa() int {
    	var n int
    Next:
    	for j := 0; j < 3; j++ {
    		for i := 0; i < 10; i++ {
    			if i == 6 {
    				continue Next
    			}
    			n = i
    		}
    		n += j + j + j + j + j + j + j + j + j + j // j * 10
    	}
    	return n
    }
    
    What follows is the function printout before and after CSE.
    
    Note blocks b8 and b10 in the before case.
    
    b8 is the inner loop's condition: i < 10.
    b10 is the inner loop's increment: i++.
    v82 is i. On entry to b8, it is either 0 (v19) the first time,
    or the result of incrementing v82, by way of v29.
    
    The CSE pass considered v82 and v49 to be common subexpressions,
    and eliminated v82 in favor of v49.
    
    In the after case, v82 is now dead and will shortly be eliminated.
    As a result, v29 is also dead, and we have lost the increment.
    The loop runs forever.
    
    BEFORE CSE
    
    f_ssa <nil>
      b1:
        v1 = Arg <mem>
        v2 = SP <uint64>
        v4 = Addr <*int> {~r0} v2
        v13 = Zero <mem> [8] v4 v1
        v14 = Const <int>
        v15 = Const <int>
        v17 = Const <int> [3]
        v19 = Const <int>
        v21 = Const <int> [10]
        v24 = Const <int> [6]
        v28 = Const <int> [1]
        v43 = Const <int> [1]
        Plain -> b3
      b2: <- b7
        Exit v47
      b3: <- b1
        Plain -> b4
      b4: <- b3 b6
        v49 = Phi <int> v15 v44
        v68 = Phi <int> v14 v67
        v81 = Phi <mem> v13 v81
        v18 = Less <bool> v49 v17
        If v18 -> b5 b7
      b5: <- b4
        Plain -> b8
      b6: <- b12 b11
        v67 = Phi <int> v66 v41
        v44 = Add <int> v49 v43
        Plain -> b4
      b7: <- b4
        v47 = Store <mem> v4 v68 v81
        Plain -> b2
      b8: <- b5 b10
        v66 = Phi <int> v68 v82
        v82 = Phi <int> v19 v29
        v22 = Less <bool> v82 v21
        If v22 -> b9 b11
      b9: <- b8
        v25 = Eq <bool> v82 v24
        If v25 -> b12 b13
      b10: <- b13
        v29 = Add <int> v82 v28
        Plain -> b8
      b11: <- b8
        v32 = Add <int> v49 v49
        v33 = Add <int> v32 v49
        v34 = Add <int> v33 v49
        v35 = Add <int> v34 v49
        v36 = Add <int> v35 v49
        v37 = Add <int> v36 v49
        v38 = Add <int> v37 v49
        v39 = Add <int> v38 v49
        v40 = Add <int> v39 v49
        v41 = Add <int> v66 v40
        Plain -> b6
      b12: <- b9
        Plain -> b6
      b13: <- b9
        Plain -> b10
    
    AFTER CSE
    
    f_ssa <nil>
      b1:
        v1 = Arg <mem>
        v2 = SP <uint64>
        v4 = Addr <*int> {~r0} v2
        v13 = Zero <mem> [8] v4 v1
        v14 = Const <int>
        v15 = Const <int>
        v17 = Const <int> [3]
        v19 = Const <int>
        v21 = Const <int> [10]
        v24 = Const <int> [6]
        v28 = Const <int> [1]
        v43 = Const <int> [1]
        Plain -> b3
      b2: <- b7
        Exit v47
      b3: <- b1
        Plain -> b4
      b4: <- b3 b6
        v49 = Phi <int> v19 v44
        v68 = Phi <int> v19 v67
        v81 = Phi <mem> v13 v81
        v18 = Less <bool> v49 v17
        If v18 -> b5 b7
      b5: <- b4
        Plain -> b8
      b6: <- b12 b11
        v67 = Phi <int> v66 v41
        v44 = Add <int> v49 v43
        Plain -> b4
      b7: <- b4
        v47 = Store <mem> v4 v68 v81
        Plain -> b2
      b8: <- b5 b10
        v66 = Phi <int> v68 v49
        v82 = Phi <int> v19 v29
        v22 = Less <bool> v49 v21
        If v22 -> b9 b11
      b9: <- b8
        v25 = Eq <bool> v49 v24
        If v25 -> b12 b13
      b10: <- b13
        v29 = Add <int> v49 v43
        Plain -> b8
      b11: <- b8
        v32 = Add <int> v49 v49
        v33 = Add <int> v32 v49
        v34 = Add <int> v33 v49
        v35 = Add <int> v34 v49
        v36 = Add <int> v35 v49
        v37 = Add <int> v36 v49
        v38 = Add <int> v37 v49
        v39 = Add <int> v38 v49
        v40 = Add <int> v39 v49
        v41 = Add <int> v66 v40
        Plain -> b6
      b12: <- b9
        Plain -> b6
      b13: <- b9
        Plain -> b10
    
    Change-Id: I16fc4ec527ec63f24f7d0d79d1a4a59bf37269de
    Reviewed-on: https://go-review.googlesource.com/12444Reviewed-by: 's avatarKeith Randall <khr@golang.org>
    00437ebe
Name
Last commit
Last update
api Loading commit data...
doc Loading commit data...
lib/time Loading commit data...
misc Loading commit data...
src Loading commit data...
test Loading commit data...
.gitattributes Loading commit data...
.gitignore Loading commit data...
AUTHORS Loading commit data...
CONTRIBUTING.md Loading commit data...
CONTRIBUTORS Loading commit data...
LICENSE Loading commit data...
PATENTS Loading commit data...
README.md Loading commit data...
favicon.ico Loading commit data...
robots.txt Loading commit data...