diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 928224cee69a8a5a3985b141fe981fa44f33b0b9..96b3f2d977c73d8ed3bb71364fe30c11b901d66e 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -2801,3 +2801,11 @@ func TestGoGetUpdateAllDoesNotTryToLoadDuplicates(t *testing.T) {
 	tg.run("get", "-u", ".../")
 	tg.grepStderrNot("duplicate loads of", "did not remove old packages from cache")
 }
+
+func TestFatalInBenchmarkCauseNonZeroExitStatus(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.runFail("test", "-bench", ".", "./testdata/src/benchfatal")
+	tg.grepBothNot("^ok", "test passed unexpectedly")
+	tg.grepBoth("FAIL.*benchfatal", "test did not run everything")
+}
diff --git a/src/cmd/go/testdata/src/benchfatal/x_test.go b/src/cmd/go/testdata/src/benchfatal/x_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..8d3a5deced86161f16d113e16049508cb03ce251
--- /dev/null
+++ b/src/cmd/go/testdata/src/benchfatal/x_test.go
@@ -0,0 +1,7 @@
+package benchfatal
+
+import "testing"
+
+func BenchmarkThatCallsFatal(b *testing.B) {
+	b.Fatal("called by benchmark")
+}
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go
index 85178c2f867adddfe7c22d9e34004430eb6a2bba..39b8cff4d358898dd3f23d37e81d406bea183404 100644
--- a/src/testing/benchmark.go
+++ b/src/testing/benchmark.go
@@ -302,9 +302,13 @@ func benchmarkName(name string, n int) string {
 // An internal function but exported because it is cross-package; part of the implementation
 // of the "go test" command.
 func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) {
+	runBenchmarksInternal(matchString, benchmarks)
+}
+
+func runBenchmarksInternal(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) bool {
 	// If no flag was specified, don't run benchmarks.
 	if len(*matchBenchmarks) == 0 {
-		return
+		return true
 	}
 	// Collect matching benchmarks and determine longest name.
 	maxprocs := 1
@@ -329,6 +333,7 @@ func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks [
 			}
 		}
 	}
+	ok := true
 	for _, Benchmark := range bs {
 		for _, procs := range cpuList {
 			runtime.GOMAXPROCS(procs)
@@ -342,6 +347,7 @@ func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks [
 			fmt.Printf("%-*s\t", maxlen, benchName)
 			r := b.run()
 			if b.failed {
+				ok = false
 				// The output could be very long here, but probably isn't.
 				// We print it all, regardless, because we don't want to trim the reason
 				// the benchmark failed.
@@ -364,6 +370,7 @@ func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks [
 			}
 		}
 	}
+	return ok
 }
 
 // trimOutput shortens the output from a benchmark, which can be very long.
diff --git a/src/testing/testing.go b/src/testing/testing.go
index e4c4772fed2a8fc91cfaa5c1109257887a189b97..95182076ef11b0b8af39a96ca5465b57e3d627ec 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -515,13 +515,12 @@ func (m *M) Run() int {
 	testOk := RunTests(m.matchString, m.tests)
 	exampleOk := RunExamples(m.matchString, m.examples)
 	stopAlarm()
-	if !testOk || !exampleOk {
+	if !testOk || !exampleOk || !runBenchmarksInternal(m.matchString, m.benchmarks) {
 		fmt.Println("FAIL")
 		after()
 		return 1
 	}
 	fmt.Println("PASS")
-	RunBenchmarks(m.matchString, m.benchmarks)
 	after()
 	return 0
 }