aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/nilcheck_test.go
diff options
context:
space:
mode:
authorTodd Neal <todd@tneal.org>2015-09-06 16:00:01 -0400
committerTodd Neal <todd@tneal.org>2015-09-07 20:04:59 +0000
commit6bf383c7b31c990231c2a6c148b98e035b3b1b53 (patch)
tree6d83910097bf45d498387ced5034e5c15de065be /src/cmd/compile/internal/ssa/nilcheck_test.go
parent1fc52b61f24c210514d4b14e9cc2f8e0aa3f3d9b (diff)
downloadgo-6bf383c7b31c990231c2a6c148b98e035b3b1b53.tar.gz
go-6bf383c7b31c990231c2a6c148b98e035b3b1b53.zip
[dev.ssa] cmd/compile: clean up nilcheck logic
Be more clear about the two conditions that we care about: 1) a block that performs a nil check (OpIsNonNil), which may be removed 2) a block that is the non-nil sucessor for an OpIsNonNil block Now we only care about removing nilchecks for two scenarios: - a type 1 block is dominated by a type 2 block for the same value - a block is both type 1 and type 2 for the same value Fixes math/big. Change-Id: I50018a4014830461ddfe2a2daf588468e4a8f0b4 Reviewed-on: https://go-review.googlesource.com/14325 Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa/nilcheck_test.go')
-rw-r--r--src/cmd/compile/internal/ssa/nilcheck_test.go45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/nilcheck_test.go b/src/cmd/compile/internal/ssa/nilcheck_test.go
index 1d048fbb34..cbd17e0093 100644
--- a/src/cmd/compile/internal/ssa/nilcheck_test.go
+++ b/src/cmd/compile/internal/ssa/nilcheck_test.go
@@ -382,3 +382,48 @@ func TestNilcheckUser(t *testing.T) {
}
}
}
+
+// TestNilcheckBug reproduces a bug in nilcheckelim found by compiling math/big
+func TestNilcheckBug(t *testing.T) {
+ ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing
+ c := NewConfig("amd64", DummyFrontend{t})
+ fun := Fun(c, "entry",
+ Bloc("entry",
+ Valu("mem", OpArg, TypeMem, 0, ".mem"),
+ Valu("sb", OpSB, TypeInvalid, 0, nil),
+ Goto("checkPtr")),
+ Bloc("checkPtr",
+ Valu("ptr1", OpConstPtr, ptrType, 0, nil, "sb"),
+ Valu("nilptr", OpConstNil, ptrType, 0, nil, "sb"),
+ Valu("bool1", OpNeqPtr, TypeBool, 0, nil, "ptr1", "nilptr"),
+ If("bool1", "secondCheck", "couldBeNil")),
+ Bloc("couldBeNil",
+ Goto("secondCheck")),
+ Bloc("secondCheck",
+ Valu("bool2", OpIsNonNil, TypeBool, 0, nil, "ptr1"),
+ If("bool2", "extra", "exit")),
+ Bloc("extra",
+ Goto("exit")),
+ Bloc("exit",
+ Exit("mem")))
+
+ CheckFunc(fun.f)
+ // we need the opt here to rewrite the user nilcheck
+ opt(fun.f)
+ nilcheckelim(fun.f)
+
+ // clean up the removed nil check
+ fuse(fun.f)
+ deadcode(fun.f)
+
+ CheckFunc(fun.f)
+ foundSecondCheck := false
+ for _, b := range fun.f.Blocks {
+ if b == fun.blocks["secondCheck"] && isNilCheck(b) {
+ foundSecondCheck = true
+ }
+ }
+ if !foundSecondCheck {
+ t.Errorf("secondCheck was eliminated, but shouldn't have")
+ }
+}