[dev.boringcrypto] all: merge master into dev.boringcrypto

Change-Id: I083d1e4e997b30d9fab10940401eaf160e36f6c1
diff --git a/src/cmd/compile/internal/gc/iimport.go b/src/cmd/compile/internal/gc/iimport.go
index f3e65ff..104b5fb 100644
--- a/src/cmd/compile/internal/gc/iimport.go
+++ b/src/cmd/compile/internal/gc/iimport.go
@@ -15,6 +15,7 @@
 	"cmd/internal/src"
 	"encoding/binary"
 	"fmt"
+	"io"
 	"math/big"
 	"os"
 	"strings"
@@ -191,7 +192,7 @@
 	}
 
 	// Fingerprint
-	n, err := in.Read(fingerprint[:])
+	n, err := io.ReadFull(in, fingerprint[:])
 	if err != nil || n != len(fingerprint) {
 		yyerror("import %s: error reading fingerprint", pkg.Path)
 		errorexit()
diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go
index 0f86179..f5d588e 100644
--- a/src/cmd/compile/internal/gc/sinit.go
+++ b/src/cmd/compile/internal/gc/sinit.go
@@ -528,6 +528,9 @@
 
 	for _, r := range n.List.Slice() {
 		a, value := splitnode(r)
+		if a == nblank && candiscard(value) {
+			continue
+		}
 
 		switch value.Op {
 		case OSLICELIT:
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
index 7538ce9..9967c7b 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules
@@ -735,18 +735,33 @@
 (ANDQ x (MOVQconst [c])) && is32Bit(c) -> (ANDQconst [c] x)
 (ANDL x (MOVLconst [c])) -> (ANDLconst [c] x)
 
-(AND(L|Q)const [c] (AND(L|Q)const [d] x)) -> (AND(L|Q)const [c & d] x)
-(BTR(L|Q)const [c] (AND(L|Q)const [d] x)) -> (AND(L|Q)const [d &^ (1<<uint32(c))] x)
-(AND(L|Q)const [c] (BTR(L|Q)const [d] x)) -> (AND(L|Q)const [c &^ (1<<uint32(d))] x)
-(BTR(L|Q)const [c] (BTR(L|Q)const [d] x)) -> (AND(L|Q)const [^(1<<uint32(c) | 1<<uint32(d))] x)
-(XOR(L|Q)const [c] (XOR(L|Q)const [d] x)) -> (XOR(L|Q)const [c ^ d] x)
-(BTC(L|Q)const [c] (XOR(L|Q)const [d] x)) -> (XOR(L|Q)const [d ^ 1<<uint32(c)] x)
-(XOR(L|Q)const [c] (BTC(L|Q)const [d] x)) -> (XOR(L|Q)const [c ^ 1<<uint32(d)] x)
-(BTC(L|Q)const [c] (BTC(L|Q)const [d] x)) -> (XOR(L|Q)const [1<<uint32(c) ^ 1<<uint32(d)] x)
-(OR(L|Q)const [c] (OR(L|Q)const [d] x)) -> (OR(L|Q)const [c | d] x)
-(OR(L|Q)const [c] (BTS(L|Q)const [d] x)) -> (OR(L|Q)const [c | 1<<uint32(d)] x)
-(BTS(L|Q)const [c] (OR(L|Q)const [d] x)) -> (OR(L|Q)const [d | 1<<uint32(c)] x)
-(BTS(L|Q)const [c] (BTS(L|Q)const [d] x)) -> (OR(L|Q)const [1<<uint32(d) | 1<<uint32(c)] x)
+(AND(L|Q)const [c] (AND(L|Q)const [d] x)) => (AND(L|Q)const [c & d] x)
+(XOR(L|Q)const [c] (XOR(L|Q)const [d] x)) => (XOR(L|Q)const [c ^ d] x)
+(OR(L|Q)const  [c] (OR(L|Q)const  [d] x)) => (OR(L|Q)const  [c | d] x)
+
+(BTRLconst [c] (ANDLconst [d] x)) => (ANDLconst [d &^ (1<<uint32(c))] x)
+(ANDLconst [c] (BTRLconst [d] x)) => (ANDLconst [c &^ (1<<uint32(d))] x)
+(BTRLconst [c] (BTRLconst [d] x)) => (ANDLconst [^(1<<uint32(c) | 1<<uint32(d))] x)
+
+(BTCLconst [c] (XORLconst [d] x)) => (XORLconst [d ^ 1<<uint32(c)] x)
+(XORLconst [c] (BTCLconst [d] x)) => (XORLconst [c ^ 1<<uint32(d)] x)
+(BTCLconst [c] (BTCLconst [d] x)) => (XORLconst [1<<uint32(c) | 1<<uint32(d)] x)
+
+(BTSLconst [c] (ORLconst  [d] x)) => (ORLconst [d | 1<<uint32(c)] x)
+(ORLconst  [c] (BTSLconst [d] x)) => (ORLconst [c | 1<<uint32(d)] x)
+(BTSLconst [c] (BTSLconst [d] x)) => (ORLconst [1<<uint32(c) | 1<<uint32(d)] x)
+
+(BTRQconst [c] (ANDQconst [d] x)) && is32Bit(int64(d) &^ (1<<uint32(c)))     => (ANDQconst [d &^ (1<<uint32(c))] x)
+(ANDQconst [c] (BTRQconst [d] x)) && is32Bit(int64(c) &^ (1<<uint32(d)))     => (ANDQconst [c &^ (1<<uint32(d))] x)
+(BTRQconst [c] (BTRQconst [d] x)) && is32Bit(^(1<<uint32(c) | 1<<uint32(d))) => (ANDQconst [^(1<<uint32(c) | 1<<uint32(d))] x)
+
+(BTCQconst [c] (XORQconst [d] x)) && is32Bit(int64(d) ^ 1<<uint32(c))     => (XORQconst [d ^ 1<<uint32(c)] x)
+(XORQconst [c] (BTCQconst [d] x)) && is32Bit(int64(c) ^ 1<<uint32(d))     => (XORQconst [c ^ 1<<uint32(d)] x)
+(BTCQconst [c] (BTCQconst [d] x)) && is32Bit(1<<uint32(c) ^ 1<<uint32(d)) => (XORQconst [1<<uint32(c) ^ 1<<uint32(d)] x)
+
+(BTSQconst [c] (ORQconst  [d] x)) && is32Bit(int64(d) | 1<<uint32(c))     => (ORQconst [d | 1<<uint32(c)] x)
+(ORQconst  [c] (BTSQconst [d] x)) && is32Bit(int64(c) | 1<<uint32(d))     => (ORQconst [c | 1<<uint32(d)] x)
+(BTSQconst [c] (BTSQconst [d] x)) && is32Bit(1<<uint32(c) | 1<<uint32(d)) => (ORQconst [1<<uint32(c) | 1<<uint32(d)] x)
 
 (MULLconst [c] (MULLconst [d] x)) -> (MULLconst [int64(int32(c * d))] x)
 (MULQconst [c] (MULQconst [d] x)) && is32Bit(c*d) -> (MULQconst [c * d] x)
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index 5f3d4e5..20eab05 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -2797,28 +2797,28 @@
 	// match: (ANDLconst [c] (ANDLconst [d] x))
 	// result: (ANDLconst [c & d] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64ANDLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ANDLconst)
-		v.AuxInt = c & d
+		v.AuxInt = int32ToAuxInt(c & d)
 		v.AddArg(x)
 		return true
 	}
 	// match: (ANDLconst [c] (BTRLconst [d] x))
 	// result: (ANDLconst [c &^ (1<<uint32(d))] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64BTRLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ANDLconst)
-		v.AuxInt = c &^ (1 << uint32(d))
+		v.AuxInt = int32ToAuxInt(c &^ (1 << uint32(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -3176,28 +3176,32 @@
 	// match: (ANDQconst [c] (ANDQconst [d] x))
 	// result: (ANDQconst [c & d] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64ANDQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ANDQconst)
-		v.AuxInt = c & d
+		v.AuxInt = int32ToAuxInt(c & d)
 		v.AddArg(x)
 		return true
 	}
 	// match: (ANDQconst [c] (BTRQconst [d] x))
+	// cond: is32Bit(int64(c) &^ (1<<uint32(d)))
 	// result: (ANDQconst [c &^ (1<<uint32(d))] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64BTRQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(int64(c) &^ (1 << uint32(d)))) {
+			break
+		}
 		v.reset(OpAMD64ANDQconst)
-		v.AuxInt = c &^ (1 << uint32(d))
+		v.AuxInt = int32ToAuxInt(c &^ (1 << uint32(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -3494,28 +3498,28 @@
 	// match: (BTCLconst [c] (XORLconst [d] x))
 	// result: (XORLconst [d ^ 1<<uint32(c)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64XORLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64XORLconst)
-		v.AuxInt = d ^ 1<<uint32(c)
+		v.AuxInt = int32ToAuxInt(d ^ 1<<uint32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (BTCLconst [c] (BTCLconst [d] x))
-	// result: (XORLconst [1<<uint32(c) ^ 1<<uint32(d)] x)
+	// result: (XORLconst [1<<uint32(c) | 1<<uint32(d)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64BTCLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64XORLconst)
-		v.AuxInt = 1<<uint32(c) ^ 1<<uint32(d)
+		v.AuxInt = int32ToAuxInt(1<<uint32(c) | 1<<uint32(d))
 		v.AddArg(x)
 		return true
 	}
@@ -3635,30 +3639,38 @@
 func rewriteValueAMD64_OpAMD64BTCQconst(v *Value) bool {
 	v_0 := v.Args[0]
 	// match: (BTCQconst [c] (XORQconst [d] x))
+	// cond: is32Bit(int64(d) ^ 1<<uint32(c))
 	// result: (XORQconst [d ^ 1<<uint32(c)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64XORQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(int64(d) ^ 1<<uint32(c))) {
+			break
+		}
 		v.reset(OpAMD64XORQconst)
-		v.AuxInt = d ^ 1<<uint32(c)
+		v.AuxInt = int32ToAuxInt(d ^ 1<<uint32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (BTCQconst [c] (BTCQconst [d] x))
+	// cond: is32Bit(1<<uint32(c) ^ 1<<uint32(d))
 	// result: (XORQconst [1<<uint32(c) ^ 1<<uint32(d)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64BTCQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(1<<uint32(c) ^ 1<<uint32(d))) {
+			break
+		}
 		v.reset(OpAMD64XORQconst)
-		v.AuxInt = 1<<uint32(c) ^ 1<<uint32(d)
+		v.AuxInt = int32ToAuxInt(1<<uint32(c) ^ 1<<uint32(d))
 		v.AddArg(x)
 		return true
 	}
@@ -3970,28 +3982,28 @@
 	// match: (BTRLconst [c] (ANDLconst [d] x))
 	// result: (ANDLconst [d &^ (1<<uint32(c))] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64ANDLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ANDLconst)
-		v.AuxInt = d &^ (1 << uint32(c))
+		v.AuxInt = int32ToAuxInt(d &^ (1 << uint32(c)))
 		v.AddArg(x)
 		return true
 	}
 	// match: (BTRLconst [c] (BTRLconst [d] x))
 	// result: (ANDLconst [^(1<<uint32(c) | 1<<uint32(d))] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64BTRLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ANDLconst)
-		v.AuxInt = ^(1<<uint32(c) | 1<<uint32(d))
+		v.AuxInt = int32ToAuxInt(^(1<<uint32(c) | 1<<uint32(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -4137,30 +4149,38 @@
 		return true
 	}
 	// match: (BTRQconst [c] (ANDQconst [d] x))
+	// cond: is32Bit(int64(d) &^ (1<<uint32(c)))
 	// result: (ANDQconst [d &^ (1<<uint32(c))] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64ANDQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(int64(d) &^ (1 << uint32(c)))) {
+			break
+		}
 		v.reset(OpAMD64ANDQconst)
-		v.AuxInt = d &^ (1 << uint32(c))
+		v.AuxInt = int32ToAuxInt(d &^ (1 << uint32(c)))
 		v.AddArg(x)
 		return true
 	}
 	// match: (BTRQconst [c] (BTRQconst [d] x))
+	// cond: is32Bit(^(1<<uint32(c) | 1<<uint32(d)))
 	// result: (ANDQconst [^(1<<uint32(c) | 1<<uint32(d))] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64BTRQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(^(1<<uint32(c) | 1<<uint32(d)))) {
+			break
+		}
 		v.reset(OpAMD64ANDQconst)
-		v.AuxInt = ^(1<<uint32(c) | 1<<uint32(d))
+		v.AuxInt = int32ToAuxInt(^(1<<uint32(c) | 1<<uint32(d)))
 		v.AddArg(x)
 		return true
 	}
@@ -4308,28 +4328,28 @@
 	// match: (BTSLconst [c] (ORLconst [d] x))
 	// result: (ORLconst [d | 1<<uint32(c)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64ORLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ORLconst)
-		v.AuxInt = d | 1<<uint32(c)
+		v.AuxInt = int32ToAuxInt(d | 1<<uint32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (BTSLconst [c] (BTSLconst [d] x))
-	// result: (ORLconst [1<<uint32(d) | 1<<uint32(c)] x)
+	// result: (ORLconst [1<<uint32(c) | 1<<uint32(d)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64BTSLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ORLconst)
-		v.AuxInt = 1<<uint32(d) | 1<<uint32(c)
+		v.AuxInt = int32ToAuxInt(1<<uint32(c) | 1<<uint32(d))
 		v.AddArg(x)
 		return true
 	}
@@ -4475,30 +4495,38 @@
 		return true
 	}
 	// match: (BTSQconst [c] (ORQconst [d] x))
+	// cond: is32Bit(int64(d) | 1<<uint32(c))
 	// result: (ORQconst [d | 1<<uint32(c)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64ORQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(int64(d) | 1<<uint32(c))) {
+			break
+		}
 		v.reset(OpAMD64ORQconst)
-		v.AuxInt = d | 1<<uint32(c)
+		v.AuxInt = int32ToAuxInt(d | 1<<uint32(c))
 		v.AddArg(x)
 		return true
 	}
 	// match: (BTSQconst [c] (BTSQconst [d] x))
-	// result: (ORQconst [1<<uint32(d) | 1<<uint32(c)] x)
+	// cond: is32Bit(1<<uint32(c) | 1<<uint32(d))
+	// result: (ORQconst [1<<uint32(c) | 1<<uint32(d)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt8(v.AuxInt)
 		if v_0.Op != OpAMD64BTSQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(1<<uint32(c) | 1<<uint32(d))) {
+			break
+		}
 		v.reset(OpAMD64ORQconst)
-		v.AuxInt = 1<<uint32(d) | 1<<uint32(c)
+		v.AuxInt = int32ToAuxInt(1<<uint32(c) | 1<<uint32(d))
 		v.AddArg(x)
 		return true
 	}
@@ -18127,28 +18155,28 @@
 	// match: (ORLconst [c] (ORLconst [d] x))
 	// result: (ORLconst [c | d] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64ORLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ORLconst)
-		v.AuxInt = c | d
+		v.AuxInt = int32ToAuxInt(c | d)
 		v.AddArg(x)
 		return true
 	}
 	// match: (ORLconst [c] (BTSLconst [d] x))
 	// result: (ORLconst [c | 1<<uint32(d)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64BTSLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ORLconst)
-		v.AuxInt = c | 1<<uint32(d)
+		v.AuxInt = int32ToAuxInt(c | 1<<uint32(d))
 		v.AddArg(x)
 		return true
 	}
@@ -19754,28 +19782,32 @@
 	// match: (ORQconst [c] (ORQconst [d] x))
 	// result: (ORQconst [c | d] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64ORQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64ORQconst)
-		v.AuxInt = c | d
+		v.AuxInt = int32ToAuxInt(c | d)
 		v.AddArg(x)
 		return true
 	}
 	// match: (ORQconst [c] (BTSQconst [d] x))
+	// cond: is32Bit(int64(c) | 1<<uint32(d))
 	// result: (ORQconst [c | 1<<uint32(d)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64BTSQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(int64(c) | 1<<uint32(d))) {
+			break
+		}
 		v.reset(OpAMD64ORQconst)
-		v.AuxInt = c | 1<<uint32(d)
+		v.AuxInt = int32ToAuxInt(c | 1<<uint32(d))
 		v.AddArg(x)
 		return true
 	}
@@ -27785,28 +27817,28 @@
 	// match: (XORLconst [c] (XORLconst [d] x))
 	// result: (XORLconst [c ^ d] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64XORLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64XORLconst)
-		v.AuxInt = c ^ d
+		v.AuxInt = int32ToAuxInt(c ^ d)
 		v.AddArg(x)
 		return true
 	}
 	// match: (XORLconst [c] (BTCLconst [d] x))
 	// result: (XORLconst [c ^ 1<<uint32(d)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64BTCLconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64XORLconst)
-		v.AuxInt = c ^ 1<<uint32(d)
+		v.AuxInt = int32ToAuxInt(c ^ 1<<uint32(d))
 		v.AddArg(x)
 		return true
 	}
@@ -28151,28 +28183,32 @@
 	// match: (XORQconst [c] (XORQconst [d] x))
 	// result: (XORQconst [c ^ d] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64XORQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt32(v_0.AuxInt)
 		x := v_0.Args[0]
 		v.reset(OpAMD64XORQconst)
-		v.AuxInt = c ^ d
+		v.AuxInt = int32ToAuxInt(c ^ d)
 		v.AddArg(x)
 		return true
 	}
 	// match: (XORQconst [c] (BTCQconst [d] x))
+	// cond: is32Bit(int64(c) ^ 1<<uint32(d))
 	// result: (XORQconst [c ^ 1<<uint32(d)] x)
 	for {
-		c := v.AuxInt
+		c := auxIntToInt32(v.AuxInt)
 		if v_0.Op != OpAMD64BTCQconst {
 			break
 		}
-		d := v_0.AuxInt
+		d := auxIntToInt8(v_0.AuxInt)
 		x := v_0.Args[0]
+		if !(is32Bit(int64(c) ^ 1<<uint32(d))) {
+			break
+		}
 		v.reset(OpAMD64XORQconst)
-		v.AuxInt = c ^ 1<<uint32(d)
+		v.AuxInt = int32ToAuxInt(c ^ 1<<uint32(d))
 		v.AddArg(x)
 		return true
 	}
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 8e5b598..9a1908a 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -287,8 +287,8 @@
 	{AADD, C_BITCON, C_RSP, C_NONE, C_RSP, 62, 8, 0, 0, 0},
 	{AADD, C_BITCON, C_NONE, C_NONE, C_RSP, 62, 8, 0, 0, 0},
 	{ACMP, C_BITCON, C_RSP, C_NONE, C_NONE, 62, 8, 0, 0, 0},
-	{AADD, C_ADDCON2, C_RSP, C_NONE, C_RSP, 48, 8, 0, 0, 0},
-	{AADD, C_ADDCON2, C_NONE, C_NONE, C_RSP, 48, 8, 0, 0, 0},
+	{AADD, C_ADDCON2, C_RSP, C_NONE, C_RSP, 48, 8, 0, NOTUSETMP, 0},
+	{AADD, C_ADDCON2, C_NONE, C_NONE, C_RSP, 48, 8, 0, NOTUSETMP, 0},
 	{AADD, C_MOVCON2, C_RSP, C_NONE, C_RSP, 13, 12, 0, 0, 0},
 	{AADD, C_MOVCON2, C_NONE, C_NONE, C_RSP, 13, 12, 0, 0, 0},
 	{AADD, C_MOVCON3, C_RSP, C_NONE, C_RSP, 13, 16, 0, 0, 0},
@@ -1072,16 +1072,29 @@
 	// We use REGTMP as a scratch register during call injection,
 	// so instruction sequences that use REGTMP are unsafe to
 	// preempt asynchronously.
-	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint)
+	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint, c.isRestartable)
 }
 
-// Return whether p is an unsafe point.
+// isUnsafePoint returns whether p is an unsafe point.
 func (c *ctxt7) isUnsafePoint(p *obj.Prog) bool {
-	if p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP {
-		return true
+	// If p explicitly uses REGTMP, it's unsafe to preempt, because the
+	// preemption sequence clobbers REGTMP.
+	return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
+}
+
+// isRestartable returns whether p is a multi-instruction sequence that,
+// if preempted, can be restarted.
+func (c *ctxt7) isRestartable(p *obj.Prog) bool {
+	if c.isUnsafePoint(p) {
+		return false
 	}
-	// Most of the multi-instruction sequence uses REGTMP, except
-	// ones marked safe.
+	// If p is a multi-instruction sequence with uses REGTMP inserted by
+	// the assembler in order to materialize a large constant/offset, we
+	// can restart p (at the start of the instruction sequence), recompute
+	// the content of REGTMP, upon async preemption. Currently, all cases
+	// of assembler-inserted REGTMP fall into this category.
+	// If p doesn't use REGTMP, it can be simply preempted, so we don't
+	// mark it.
 	o := c.oplook(p)
 	return o.size > 4 && o.flag&NOTUSETMP == 0
 }
@@ -3831,6 +3844,8 @@
 		o1 |= fields | uint32(rs&31)<<16 | uint32(rb&31)<<5 | uint32(rt&31)
 
 	case 48: /* ADD $C_ADDCON2, Rm, Rd */
+		// NOTE: this case does not use REGTMP. If it ever does,
+		// remove the NOTUSETMP flag in optab.
 		op := c.opirr(p, p.As)
 		if op&Sbit != 0 {
 			c.ctxt.Diag("can not break addition/subtraction when S bit is set", p)
diff --git a/src/cmd/internal/obj/mips/asm0.go b/src/cmd/internal/obj/mips/asm0.go
index 13d875e..faa12bf 100644
--- a/src/cmd/internal/obj/mips/asm0.go
+++ b/src/cmd/internal/obj/mips/asm0.go
@@ -526,16 +526,29 @@
 	// We use REGTMP as a scratch register during call injection,
 	// so instruction sequences that use REGTMP are unsafe to
 	// preempt asynchronously.
-	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint)
+	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint, c.isRestartable)
 }
 
-// Return whether p is an unsafe point.
+// isUnsafePoint returns whether p is an unsafe point.
 func (c *ctxt0) isUnsafePoint(p *obj.Prog) bool {
-	if p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP {
-		return true
+	// If p explicitly uses REGTMP, it's unsafe to preempt, because the
+	// preemption sequence clobbers REGTMP.
+	return p.From.Reg == REGTMP || p.To.Reg == REGTMP || p.Reg == REGTMP
+}
+
+// isRestartable returns whether p is a multi-instruction sequence that,
+// if preempted, can be restarted.
+func (c *ctxt0) isRestartable(p *obj.Prog) bool {
+	if c.isUnsafePoint(p) {
+		return false
 	}
-	// Most of the multi-instruction sequence uses REGTMP, except
-	// ones marked safe.
+	// If p is a multi-instruction sequence with uses REGTMP inserted by
+	// the assembler in order to materialize a large constant/offset, we
+	// can restart p (at the start of the instruction sequence), recompute
+	// the content of REGTMP, upon async preemption. Currently, all cases
+	// of assembler-inserted REGTMP fall into this category.
+	// If p doesn't use REGTMP, it can be simply preempted, so we don't
+	// mark it.
 	o := c.oplook(p)
 	return o.size > 4 && o.flag&NOTUSETMP == 0
 }
diff --git a/src/cmd/internal/obj/plist.go b/src/cmd/internal/obj/plist.go
index 44ec460..73b6e8b 100644
--- a/src/cmd/internal/obj/plist.go
+++ b/src/cmd/internal/obj/plist.go
@@ -236,13 +236,13 @@
 	pcdata.From.Type = TYPE_CONST
 	pcdata.From.Offset = objabi.PCDATA_RegMapIndex
 	pcdata.To.Type = TYPE_CONST
-	pcdata.To.Offset = -2 // pcdata -2 marks unsafe point
+	pcdata.To.Offset = objabi.PCDATA_RegMapUnsafe
 
 	return pcdata
 }
 
 // EndUnsafePoint generates PCDATA Progs after p to mark the end of an
-// unsafe point, restoring the stack map index to oldval.
+// unsafe point, restoring the register map index to oldval.
 // The unsafe point ends right after p.
 // It returns the last Prog generated.
 func (ctxt *Link) EndUnsafePoint(p *Prog, newprog ProgAlloc, oldval int64) *Prog {
@@ -253,23 +253,33 @@
 	pcdata.To.Type = TYPE_CONST
 	pcdata.To.Offset = oldval
 
-	// TODO: register map?
-
 	return pcdata
 }
 
-// MarkUnsafePoints inserts PCDATAs to mark nonpreemptible instruction
-// sequences, based on isUnsafePoint predicate. p0 is the start of the
-// instruction stream.
-func MarkUnsafePoints(ctxt *Link, p0 *Prog, newprog ProgAlloc, isUnsafePoint func(*Prog) bool) {
+// MarkUnsafePoints inserts PCDATAs to mark nonpreemptible and restartable
+// instruction sequences, based on isUnsafePoint and isRestartable predicate.
+// p0 is the start of the instruction stream.
+// isUnsafePoint(p) returns true if p is not safe for async preemption.
+// isRestartable(p) returns true if we can restart at the start of p (this Prog)
+// upon async preemption. (Currently multi-Prog restartable sequence is not
+// supported.)
+// isRestartable can be nil. In this case it is treated as always returning false.
+// If isUnsafePoint(p) and isRestartable(p) are both true, it is treated as
+// an unsafe point.
+func MarkUnsafePoints(ctxt *Link, p0 *Prog, newprog ProgAlloc, isUnsafePoint, isRestartable func(*Prog) bool) {
+	if isRestartable == nil {
+		// Default implementation: nothing is restartable.
+		isRestartable = func(*Prog) bool { return false }
+	}
 	prev := p0
-	oldval := int64(-1) // entry pcdata
+	prevPcdata := int64(-1) // entry PC data value
+	prevRestart := int64(0)
 	for p := prev.Link; p != nil; p, prev = p.Link, p {
 		if p.As == APCDATA && p.From.Offset == objabi.PCDATA_RegMapIndex {
-			oldval = p.To.Offset
+			prevPcdata = p.To.Offset
 			continue
 		}
-		if oldval == -2 {
+		if prevPcdata == objabi.PCDATA_RegMapUnsafe {
 			continue // already unsafe
 		}
 		if isUnsafePoint(p) {
@@ -283,7 +293,39 @@
 			if p.Link == nil {
 				break // Reached the end, don't bother marking the end
 			}
-			p = ctxt.EndUnsafePoint(p, newprog, oldval)
+			p = ctxt.EndUnsafePoint(p, newprog, prevPcdata)
+			p.Pc = p.Link.Pc
+			continue
+		}
+		if isRestartable(p) {
+			val := int64(objabi.PCDATA_Restart1)
+			if val == prevRestart {
+				val = objabi.PCDATA_Restart2
+			}
+			prevRestart = val
+			q := Appendp(prev, newprog)
+			q.As = APCDATA
+			q.From.Type = TYPE_CONST
+			q.From.Offset = objabi.PCDATA_RegMapIndex
+			q.To.Type = TYPE_CONST
+			q.To.Offset = val
+			q.Pc = p.Pc
+			q.Link = p
+
+			if p.Link == nil {
+				break // Reached the end, don't bother marking the end
+			}
+			if isRestartable(p.Link) {
+				// Next Prog is also restartable. No need to mark the end
+				// of this sequence. We'll just go ahead mark the next one.
+				continue
+			}
+			p = Appendp(p, newprog)
+			p.As = APCDATA
+			p.From.Type = TYPE_CONST
+			p.From.Offset = objabi.PCDATA_RegMapIndex
+			p.To.Type = TYPE_CONST
+			p.To.Offset = prevPcdata
 			p.Pc = p.Link.Pc
 		}
 	}
diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go
index 6fcde2d..2eb2935 100644
--- a/src/cmd/internal/obj/riscv/obj.go
+++ b/src/cmd/internal/obj/riscv/obj.go
@@ -2005,7 +2005,7 @@
 		ctxt.Arch.ByteOrder.PutUint32(p, symcode[i])
 	}
 
-	obj.MarkUnsafePoints(ctxt, cursym.Func.Text, newprog, isUnsafePoint)
+	obj.MarkUnsafePoints(ctxt, cursym.Func.Text, newprog, isUnsafePoint, nil)
 }
 
 func isUnsafePoint(p *obj.Prog) bool {
diff --git a/src/cmd/internal/obj/s390x/asmz.go b/src/cmd/internal/obj/s390x/asmz.go
index 30c0738..29182ea 100644
--- a/src/cmd/internal/obj/s390x/asmz.go
+++ b/src/cmd/internal/obj/s390x/asmz.go
@@ -500,7 +500,7 @@
 	// We use REGTMP as a scratch register during call injection,
 	// so instruction sequences that use REGTMP are unsafe to
 	// preempt asynchronously.
-	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint)
+	obj.MarkUnsafePoints(c.ctxt, c.cursym.Func.Text, c.newprog, c.isUnsafePoint, nil)
 }
 
 // Return whether p is an unsafe point.
diff --git a/src/cmd/internal/obj/x86/asm6.go b/src/cmd/internal/obj/x86/asm6.go
index 3eaed2a..f7d81dc 100644
--- a/src/cmd/internal/obj/x86/asm6.go
+++ b/src/cmd/internal/obj/x86/asm6.go
@@ -2226,7 +2226,7 @@
 			// the first instruction.)
 			return p.From.Index == REG_TLS
 		}
-		obj.MarkUnsafePoints(ctxt, s.Func.Text, newprog, useTLS)
+		obj.MarkUnsafePoints(ctxt, s.Func.Text, newprog, useTLS, nil)
 	}
 }
 
diff --git a/src/cmd/internal/objabi/funcdata.go b/src/cmd/internal/objabi/funcdata.go
index 2a51816..d5bacb5 100644
--- a/src/cmd/internal/objabi/funcdata.go
+++ b/src/cmd/internal/objabi/funcdata.go
@@ -40,4 +40,15 @@
 	// PCDATA_UnsafePoint values.
 	PCDATA_UnsafePointSafe   = -1 // Safe for async preemption
 	PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption
+
+	// PCDATA_Restart1(2) apply on a sequence of instructions, within
+	// which if an async preemption happens, we should back off the PC
+	// to the start of the sequence when resuming.
+	// We need two so we can distinguish the start/end of the sequence
+	// in case that two sequences are next to each other.
+	PCDATA_Restart1 = -3
+	PCDATA_Restart2 = -4
+
+	// Like PCDATA_Restart1, but back to function entry if async preempted.
+	PCDATA_RestartAtEntry = -5
 )
diff --git a/src/cmd/link/internal/ld/deadcode_test.go b/src/cmd/link/internal/ld/deadcode_test.go
index 23a8685..460bc16 100644
--- a/src/cmd/link/internal/ld/deadcode_test.go
+++ b/src/cmd/link/internal/ld/deadcode_test.go
@@ -32,6 +32,7 @@
 		{"typedesc", "type.main.T"},
 	}
 	for _, test := range tests {
+		test := test
 		t.Run(test.src, func(t *testing.T) {
 			t.Parallel()
 			src := filepath.Join("testdata", "deadcode", test.src+".go")
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
index 08a0533..04738cd 100644
--- a/src/crypto/ecdsa/ecdsa.go
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -69,6 +69,9 @@
 	boring unsafe.Pointer
 }
 
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
 // Equal reports whether pub and x have the same value.
 //
 // Two keys are only considered to have the same value if they have the same Curve value.
@@ -100,6 +103,17 @@
 	return &priv.PublicKey
 }
 
+// Equal reports whether priv and x have the same value.
+//
+// See PublicKey.Equal for details on how Curve is compared.
+func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
+	xx, ok := x.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	return priv.PublicKey.Equal(&xx.PublicKey) && priv.D.Cmp(xx.D) == 0
+}
+
 // Sign signs digest with priv, reading randomness from rand. The opts argument
 // is not currently used but, in keeping with the crypto.Signer interface,
 // should be the hash function used to digest the message.
diff --git a/src/crypto/ecdsa/equal_test.go b/src/crypto/ecdsa/equal_test.go
index 9b507dd..53ac850 100644
--- a/src/crypto/ecdsa/equal_test.go
+++ b/src/crypto/ecdsa/equal_test.go
@@ -23,23 +23,32 @@
 	if !public.Equal(crypto.Signer(private).Public().(*ecdsa.PublicKey)) {
 		t.Errorf("private.Public() is not Equal to public: %q", public)
 	}
+	if !private.Equal(private) {
+		t.Errorf("private key is not equal to itself: %v", private)
+	}
 
-	enc, err := x509.MarshalPKIXPublicKey(public)
+	enc, err := x509.MarshalPKCS8PrivateKey(private)
 	if err != nil {
 		t.Fatal(err)
 	}
-	decoded, err := x509.ParsePKIXPublicKey(enc)
+	decoded, err := x509.ParsePKCS8PrivateKey(enc)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if !public.Equal(decoded) {
+	if !public.Equal(decoded.(crypto.Signer).Public()) {
 		t.Errorf("public key is not equal to itself after decoding: %v", public)
 	}
+	if !private.Equal(decoded) {
+		t.Errorf("private key is not equal to itself after decoding: %v", private)
+	}
 
 	other, _ := ecdsa.GenerateKey(c, rand.Reader)
-	if public.Equal(other) {
+	if public.Equal(other.Public()) {
 		t.Errorf("different public keys are Equal")
 	}
+	if private.Equal(other) {
+		t.Errorf("different private keys are Equal")
+	}
 
 	// Ensure that keys with the same coordinates but on different curves
 	// aren't considered Equal.
diff --git a/src/crypto/ed25519/ed25519.go b/src/crypto/ed25519/ed25519.go
index 748c039..5766970 100644
--- a/src/crypto/ed25519/ed25519.go
+++ b/src/crypto/ed25519/ed25519.go
@@ -40,6 +40,9 @@
 // PublicKey is the type of Ed25519 public keys.
 type PublicKey []byte
 
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
 // Equal reports whether pub and x have the same value.
 func (pub PublicKey) Equal(x crypto.PublicKey) bool {
 	xx, ok := x.(PublicKey)
@@ -59,6 +62,15 @@
 	return PublicKey(publicKey)
 }
 
+// Equal reports whether priv and x have the same value.
+func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
+	xx, ok := x.(PrivateKey)
+	if !ok {
+		return false
+	}
+	return bytes.Equal(priv, xx)
+}
+
 // Seed returns the private key seed corresponding to priv. It is provided for
 // interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
 // in this package.
diff --git a/src/crypto/ed25519/ed25519_test.go b/src/crypto/ed25519/ed25519_test.go
index 6b5cb9d..f77d463 100644
--- a/src/crypto/ed25519/ed25519_test.go
+++ b/src/crypto/ed25519/ed25519_test.go
@@ -113,14 +113,20 @@
 	if !public.Equal(public) {
 		t.Errorf("public key is not equal to itself: %q", public)
 	}
-	if !public.Equal(crypto.Signer(private).Public().(PublicKey)) {
+	if !public.Equal(crypto.Signer(private).Public()) {
 		t.Errorf("private.Public() is not Equal to public: %q", public)
 	}
+	if !private.Equal(private) {
+		t.Errorf("private key is not equal to itself: %q", private)
+	}
 
-	other, _, _ := GenerateKey(rand.Reader)
-	if public.Equal(other) {
+	otherPub, otherPriv, _ := GenerateKey(rand.Reader)
+	if public.Equal(otherPub) {
 		t.Errorf("different public keys are Equal")
 	}
+	if private.Equal(otherPriv) {
+		t.Errorf("different private keys are Equal")
+	}
 }
 
 func TestGolden(t *testing.T) {
diff --git a/src/crypto/rsa/equal_test.go b/src/crypto/rsa/equal_test.go
index b00d0ea..90f4bf9 100644
--- a/src/crypto/rsa/equal_test.go
+++ b/src/crypto/rsa/equal_test.go
@@ -22,21 +22,30 @@
 	if !public.Equal(crypto.Signer(private).Public().(*rsa.PublicKey)) {
 		t.Errorf("private.Public() is not Equal to public: %q", public)
 	}
+	if !private.Equal(private) {
+		t.Errorf("private key is not equal to itself: %v", private)
+	}
 
-	enc, err := x509.MarshalPKIXPublicKey(public)
+	enc, err := x509.MarshalPKCS8PrivateKey(private)
 	if err != nil {
 		t.Fatal(err)
 	}
-	decoded, err := x509.ParsePKIXPublicKey(enc)
+	decoded, err := x509.ParsePKCS8PrivateKey(enc)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if !public.Equal(decoded) {
+	if !public.Equal(decoded.(crypto.Signer).Public()) {
 		t.Errorf("public key is not equal to itself after decoding: %v", public)
 	}
+	if !private.Equal(decoded) {
+		t.Errorf("private key is not equal to itself after decoding: %v", private)
+	}
 
 	other, _ := rsa.GenerateKey(rand.Reader, 512)
-	if public.Equal(other) {
+	if public.Equal(other.Public()) {
 		t.Errorf("different public keys are Equal")
 	}
+	if private.Equal(other) {
+		t.Errorf("different private keys are Equal")
+	}
 }
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
index 4c67644..94a6621 100644
--- a/src/crypto/rsa/rsa.go
+++ b/src/crypto/rsa/rsa.go
@@ -51,6 +51,9 @@
 	boring unsafe.Pointer
 }
 
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
 // Size returns the modulus size in bytes. Raw signatures and ciphertexts
 // for or by this public key will have the same size.
 func (pub *PublicKey) Size() int {
@@ -118,6 +121,27 @@
 	return &priv.PublicKey
 }
 
+// Equal reports whether priv and x have equivalent values. It ignores
+// Precomputed values.
+func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
+	xx, ok := x.(*PrivateKey)
+	if !ok {
+		return false
+	}
+	if !priv.PublicKey.Equal(&xx.PublicKey) || priv.D.Cmp(xx.D) != 0 {
+		return false
+	}
+	if len(priv.Primes) != len(xx.Primes) {
+		return false
+	}
+	for i := range priv.Primes {
+		if priv.Primes[i].Cmp(xx.Primes[i]) != 0 {
+			return false
+		}
+	}
+	return true
+}
+
 // Sign signs digest with priv, reading randomness from rand. If opts is a
 // *PSSOptions then the PSS algorithm will be used, otherwise PKCS#1 v1.5 will
 // be used. digest must be the result of hashing the input message using
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
index 2a61dae..f6fe2d2 100644
--- a/src/crypto/tls/common.go
+++ b/src/crypto/tls/common.go
@@ -207,6 +207,10 @@
 	downgradeCanaryTLS11 = "DOWNGRD\x00"
 )
 
+// testingOnlyForceDowngradeCanary is set in tests to force the server side to
+// include downgrade canaries even if it's using its highers supported version.
+var testingOnlyForceDowngradeCanary bool
+
 // ConnectionState records basic TLS details about the connection.
 type ConnectionState struct {
 	Version                     uint16                // TLS version used by the connection (e.g. VersionTLS12)
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
index e8ffcaf..a72555f 100644
--- a/src/crypto/tls/handshake_client.go
+++ b/src/crypto/tls/handshake_client.go
@@ -54,7 +54,7 @@
 		return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
 	}
 
-	clientHelloVersion := supportedVersions[0]
+	clientHelloVersion := config.maxSupportedVersion()
 	// The version at the beginning of the ClientHello was capped at TLS 1.2
 	// for compatibility reasons. The supported_versions extension is used
 	// to negotiate versions now. See RFC 8446, Section 4.2.1.
@@ -184,6 +184,18 @@
 		return err
 	}
 
+	// If we are negotiating a protocol version that's lower than what we
+	// support, check for the server downgrade canaries.
+	// See RFC 8446, Section 4.1.3.
+	maxVers := c.config.maxSupportedVersion()
+	tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12
+	tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11
+	if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) ||
+		maxVers == VersionTLS12 && c.vers <= VersionTLS11 && tls11Downgrade {
+		c.sendAlert(alertIllegalParameter)
+		return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox")
+	}
+
 	if c.vers == VersionTLS13 {
 		hs := &clientHandshakeStateTLS13{
 			c:           c,
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
index 8632d98..35d7136 100644
--- a/src/crypto/tls/handshake_client_test.go
+++ b/src/crypto/tls/handshake_client_test.go
@@ -1984,3 +1984,48 @@
 		t.Errorf("Error expected, but no error returned")
 	}
 }
+
+func testDowngradeCanary(t *testing.T, clientVersion, serverVersion uint16) error {
+	defer func() { testingOnlyForceDowngradeCanary = false }()
+	testingOnlyForceDowngradeCanary = true
+
+	clientConfig := testConfig.Clone()
+	clientConfig.MaxVersion = clientVersion
+	serverConfig := testConfig.Clone()
+	serverConfig.MaxVersion = serverVersion
+	_, _, err := testHandshake(t, clientConfig, serverConfig)
+	return err
+}
+
+func TestDowngradeCanary(t *testing.T) {
+	if err := testDowngradeCanary(t, VersionTLS13, VersionTLS12); err == nil {
+		t.Errorf("downgrade from TLS 1.3 to TLS 1.2 was not detected")
+	}
+	if testing.Short() {
+		t.Skip("skipping the rest of the checks in short mode")
+	}
+	if err := testDowngradeCanary(t, VersionTLS13, VersionTLS11); err == nil {
+		t.Errorf("downgrade from TLS 1.3 to TLS 1.1 was not detected")
+	}
+	if err := testDowngradeCanary(t, VersionTLS13, VersionTLS10); err == nil {
+		t.Errorf("downgrade from TLS 1.3 to TLS 1.0 was not detected")
+	}
+	if err := testDowngradeCanary(t, VersionTLS12, VersionTLS11); err == nil {
+		t.Errorf("downgrade from TLS 1.2 to TLS 1.1 was not detected")
+	}
+	if err := testDowngradeCanary(t, VersionTLS12, VersionTLS10); err == nil {
+		t.Errorf("downgrade from TLS 1.2 to TLS 1.0 was not detected")
+	}
+	if err := testDowngradeCanary(t, VersionTLS13, VersionTLS13); err != nil {
+		t.Errorf("server unexpectedly sent downgrade canary for TLS 1.3")
+	}
+	if err := testDowngradeCanary(t, VersionTLS12, VersionTLS12); err != nil {
+		t.Errorf("client didn't ignore expected TLS 1.2 canary")
+	}
+	if err := testDowngradeCanary(t, VersionTLS11, VersionTLS11); err != nil {
+		t.Errorf("client unexpectedly reacted to a canary in TLS 1.1")
+	}
+	if err := testDowngradeCanary(t, VersionTLS10, VersionTLS10); err != nil {
+		t.Errorf("client unexpectedly reacted to a canary in TLS 1.0")
+	}
+}
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
index 8e3b6e6..c454d7f 100644
--- a/src/crypto/tls/handshake_client_tls13.go
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -180,51 +180,62 @@
 	c := hs.c
 
 	// The first ClientHello gets double-hashed into the transcript upon a
-	// HelloRetryRequest. See RFC 8446, Section 4.4.1.
+	// HelloRetryRequest. (The idea is that the server might offload transcript
+	// storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
 	chHash := hs.transcript.Sum(nil)
 	hs.transcript.Reset()
 	hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
 	hs.transcript.Write(chHash)
 	hs.transcript.Write(hs.serverHello.marshal())
 
+	// The only HelloRetryRequest extensions we support are key_share and
+	// cookie, and clients must abort the handshake if the HRR would not result
+	// in any change in the ClientHello.
+	if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil {
+		c.sendAlert(alertIllegalParameter)
+		return errors.New("tls: server sent an unnecessary HelloRetryRequest message")
+	}
+
+	if hs.serverHello.cookie != nil {
+		hs.hello.cookie = hs.serverHello.cookie
+	}
+
 	if hs.serverHello.serverShare.group != 0 {
 		c.sendAlert(alertDecodeError)
 		return errors.New("tls: received malformed key_share extension")
 	}
 
-	curveID := hs.serverHello.selectedGroup
-	if curveID == 0 {
-		c.sendAlert(alertMissingExtension)
-		return errors.New("tls: received HelloRetryRequest without selected group")
-	}
-	curveOK := false
-	for _, id := range hs.hello.supportedCurves {
-		if id == curveID {
-			curveOK = true
-			break
+	// If the server sent a key_share extension selecting a group, ensure it's
+	// a group we advertised but did not send a key share for, and send a key
+	// share for it this time.
+	if curveID := hs.serverHello.selectedGroup; curveID != 0 {
+		curveOK := false
+		for _, id := range hs.hello.supportedCurves {
+			if id == curveID {
+				curveOK = true
+				break
+			}
 		}
+		if !curveOK {
+			c.sendAlert(alertIllegalParameter)
+			return errors.New("tls: server selected unsupported group")
+		}
+		if hs.ecdheParams.CurveID() == curveID {
+			c.sendAlert(alertIllegalParameter)
+			return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
+		}
+		if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+			c.sendAlert(alertInternalError)
+			return errors.New("tls: CurvePreferences includes unsupported curve")
+		}
+		params, err := generateECDHEParameters(c.config.rand(), curveID)
+		if err != nil {
+			c.sendAlert(alertInternalError)
+			return err
+		}
+		hs.ecdheParams = params
+		hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
 	}
-	if !curveOK {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server selected unsupported group")
-	}
-	if hs.ecdheParams.CurveID() == curveID {
-		c.sendAlert(alertIllegalParameter)
-		return errors.New("tls: server sent an unnecessary HelloRetryRequest message")
-	}
-	if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
-		c.sendAlert(alertInternalError)
-		return errors.New("tls: CurvePreferences includes unsupported curve")
-	}
-	params, err := generateECDHEParameters(c.config.rand(), curveID)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-	hs.ecdheParams = params
-	hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
-
-	hs.hello.cookie = hs.serverHello.cookie
 
 	hs.hello.raw = nil
 	if len(hs.hello.pskIdentities) > 0 {
diff --git a/src/crypto/tls/handshake_messages_test.go b/src/crypto/tls/handshake_messages_test.go
index c54a0f8..49fd42d 100644
--- a/src/crypto/tls/handshake_messages_test.go
+++ b/src/crypto/tls/handshake_messages_test.go
@@ -308,11 +308,9 @@
 	s := &sessionState{}
 	s.vers = uint16(rand.Intn(10000))
 	s.cipherSuite = uint16(rand.Intn(10000))
-	s.masterSecret = randomBytes(rand.Intn(100), rand)
-	numCerts := rand.Intn(20)
-	s.certificates = make([][]byte, numCerts)
-	for i := 0; i < numCerts; i++ {
-		s.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
+	s.masterSecret = randomBytes(rand.Intn(100)+1, rand)
+	for i := 0; i < rand.Intn(20); i++ {
+		s.certificates = append(s.certificates, randomBytes(rand.Intn(500)+1, rand))
 	}
 	return reflect.ValueOf(s)
 }
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
index ca98a30..0e0856c 100644
--- a/src/crypto/tls/handshake_server.go
+++ b/src/crypto/tls/handshake_server.go
@@ -193,7 +193,7 @@
 	serverRandom := hs.hello.random
 	// Downgrade protection canaries. See RFC 8446, Section 4.1.3.
 	maxVers := c.config.maxSupportedVersion()
-	if maxVers >= VersionTLS12 && c.vers < maxVers {
+	if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
 		if c.vers == VersionTLS12 {
 			copy(serverRandom[24:], downgradeCanaryTLS12)
 		} else {
diff --git a/src/crypto/tls/ticket.go b/src/crypto/tls/ticket.go
index c873e43..dda0443 100644
--- a/src/crypto/tls/ticket.go
+++ b/src/crypto/tls/ticket.go
@@ -12,8 +12,9 @@
 	"crypto/sha256"
 	"crypto/subtle"
 	"errors"
-	"golang.org/x/crypto/cryptobyte"
 	"io"
+
+	"golang.org/x/crypto/cryptobyte"
 )
 
 // sessionState contains the information that is serialized into a session
@@ -21,88 +22,56 @@
 type sessionState struct {
 	vers         uint16
 	cipherSuite  uint16
-	masterSecret []byte
-	certificates [][]byte
+	masterSecret []byte // opaque master_secret<1..2^16-1>;
+	// struct { opaque certificate<1..2^32-1> } Certificate;
+	certificates [][]byte // Certificate certificate_list<0..2^16-1>;
+
 	// usedOldKey is true if the ticket from which this session came from
 	// was encrypted with an older key and thus should be refreshed.
 	usedOldKey bool
 }
 
-func (s *sessionState) marshal() []byte {
-	length := 2 + 2 + 2 + len(s.masterSecret) + 2
-	for _, cert := range s.certificates {
-		length += 4 + len(cert)
-	}
-
-	ret := make([]byte, length)
-	x := ret
-	x[0] = byte(s.vers >> 8)
-	x[1] = byte(s.vers)
-	x[2] = byte(s.cipherSuite >> 8)
-	x[3] = byte(s.cipherSuite)
-	x[4] = byte(len(s.masterSecret) >> 8)
-	x[5] = byte(len(s.masterSecret))
-	x = x[6:]
-	copy(x, s.masterSecret)
-	x = x[len(s.masterSecret):]
-
-	x[0] = byte(len(s.certificates) >> 8)
-	x[1] = byte(len(s.certificates))
-	x = x[2:]
-
-	for _, cert := range s.certificates {
-		x[0] = byte(len(cert) >> 24)
-		x[1] = byte(len(cert) >> 16)
-		x[2] = byte(len(cert) >> 8)
-		x[3] = byte(len(cert))
-		copy(x[4:], cert)
-		x = x[4+len(cert):]
-	}
-
-	return ret
+func (m *sessionState) marshal() []byte {
+	var b cryptobyte.Builder
+	b.AddUint16(m.vers)
+	b.AddUint16(m.cipherSuite)
+	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+		b.AddBytes(m.masterSecret)
+	})
+	b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+		for _, cert := range m.certificates {
+			b.AddUint32LengthPrefixed(func(b *cryptobyte.Builder) {
+				b.AddBytes(cert)
+			})
+		}
+	})
+	return b.BytesOrPanic()
 }
 
-func (s *sessionState) unmarshal(data []byte) bool {
-	if len(data) < 8 {
+func (m *sessionState) unmarshal(data []byte) bool {
+	*m = sessionState{usedOldKey: m.usedOldKey}
+	s := cryptobyte.String(data)
+	if ok := s.ReadUint16(&m.vers) &&
+		m.vers != VersionTLS13 &&
+		s.ReadUint16(&m.cipherSuite) &&
+		readUint16LengthPrefixed(&s, &m.masterSecret) &&
+		len(m.masterSecret) != 0; !ok {
 		return false
 	}
-
-	s.vers = uint16(data[0])<<8 | uint16(data[1])
-	s.cipherSuite = uint16(data[2])<<8 | uint16(data[3])
-	masterSecretLen := int(data[4])<<8 | int(data[5])
-	data = data[6:]
-	if len(data) < masterSecretLen {
+	var certList cryptobyte.String
+	if !s.ReadUint16LengthPrefixed(&certList) {
 		return false
 	}
-
-	s.masterSecret = data[:masterSecretLen]
-	data = data[masterSecretLen:]
-
-	if len(data) < 2 {
-		return false
+	for !certList.Empty() {
+		var certLen uint32
+		certList.ReadUint32(&certLen)
+		var cert []byte
+		if certLen == 0 || !certList.ReadBytes(&cert, int(certLen)) {
+			return false
+		}
+		m.certificates = append(m.certificates, cert)
 	}
-
-	numCerts := int(data[0])<<8 | int(data[1])
-	data = data[2:]
-
-	s.certificates = make([][]byte, numCerts)
-	for i := range s.certificates {
-		if len(data) < 4 {
-			return false
-		}
-		certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3])
-		data = data[4:]
-		if certLen < 0 {
-			return false
-		}
-		if len(data) < certLen {
-			return false
-		}
-		s.certificates[i] = data[:certLen]
-		data = data[certLen:]
-	}
-
-	return len(data) == 0
+	return s.Empty()
 }
 
 // sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first
diff --git a/src/crypto/x509/root_unix.go b/src/crypto/x509/root_unix.go
index 1be4058..b48e618 100644
--- a/src/crypto/x509/root_unix.go
+++ b/src/crypto/x509/root_unix.go
@@ -9,6 +9,7 @@
 import (
 	"io/ioutil"
 	"os"
+	"path/filepath"
 	"strings"
 )
 
@@ -69,7 +70,7 @@
 	}
 
 	for _, directory := range dirs {
-		fis, err := ioutil.ReadDir(directory)
+		fis, err := readUniqueDirectoryEntries(directory)
 		if err != nil {
 			if firstErr == nil && !os.IsNotExist(err) {
 				firstErr = err
@@ -90,3 +91,29 @@
 
 	return nil, firstErr
 }
+
+// readUniqueDirectoryEntries is like ioutil.ReadDir but omits
+// symlinks that point within the directory.
+func readUniqueDirectoryEntries(dir string) ([]os.FileInfo, error) {
+	fis, err := ioutil.ReadDir(dir)
+	if err != nil {
+		return nil, err
+	}
+	uniq := fis[:0]
+	for _, fi := range fis {
+		if !isSameDirSymlink(fi, dir) {
+			uniq = append(uniq, fi)
+		}
+	}
+	return uniq, nil
+}
+
+// isSameDirSymlink reports whether fi in dir is a symlink with a
+// target not containing a slash.
+func isSameDirSymlink(fi os.FileInfo, dir string) bool {
+	if fi.Mode()&os.ModeSymlink == 0 {
+		return false
+	}
+	target, err := os.Readlink(filepath.Join(dir, fi.Name()))
+	return err == nil && !strings.Contains(target, "/")
+}
diff --git a/src/crypto/x509/root_unix_test.go b/src/crypto/x509/root_unix_test.go
index 5a27d63..39556ae 100644
--- a/src/crypto/x509/root_unix_test.go
+++ b/src/crypto/x509/root_unix_test.go
@@ -202,3 +202,30 @@
 		t.Fatalf("Mismatched certPools\nGot:\n%s\n\nWant:\n%s", g, w)
 	}
 }
+
+func TestReadUniqueDirectoryEntries(t *testing.T) {
+	temp := func(base string) string { return filepath.Join(t.TempDir(), base) }
+	if f, err := os.Create(temp("file")); err != nil {
+		t.Fatal(err)
+	} else {
+		f.Close()
+	}
+	if err := os.Symlink("target-in", temp("link-in")); err != nil {
+		t.Fatal(err)
+	}
+	if err := os.Symlink("../target-out", temp("link-out")); err != nil {
+		t.Fatal(err)
+	}
+	got, err := readUniqueDirectoryEntries(t.TempDir())
+	if err != nil {
+		t.Fatal(err)
+	}
+	gotNames := []string{}
+	for _, fi := range got {
+		gotNames = append(gotNames, fi.Name())
+	}
+	wantNames := []string{"file", "link-out"}
+	if !reflect.DeepEqual(gotNames, wantNames) {
+		t.Errorf("got %q; want %q", gotNames, wantNames)
+	}
+}
diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go
index df7aade..e01f557 100644
--- a/src/crypto/x509/verify.go
+++ b/src/crypto/x509/verify.go
@@ -185,18 +185,29 @@
 // verified. Platform-specific verification needs the ASN.1 contents.
 var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
 
-// VerifyOptions contains parameters for Certificate.Verify. It's a structure
-// because other PKIX verification APIs have ended up needing many options.
+// VerifyOptions contains parameters for Certificate.Verify.
 type VerifyOptions struct {
 	// IsBoring is a validity check for BoringCrypto.
 	// If not nil, it will be called to check whether a given certificate
 	// can be used for constructing verification chains.
 	IsBoring func(*Certificate) bool
 
-	DNSName       string
+	// DNSName, if set, is checked against the leaf certificate with
+	// Certificate.VerifyHostname.
+	DNSName string
+
+	// Intermediates is an optional pool of certificates that are not trust
+	// anchors, but can be used to form a chain from the leaf certificate to a
+	// root certificate.
 	Intermediates *CertPool
-	Roots         *CertPool // if nil, the system roots are used
-	CurrentTime   time.Time // if zero, the current time is used
+	// Roots is the set of trusted root certificates the leaf certificate needs
+	// to chain up to. If nil, the system roots or the platform verifier are used.
+	Roots *CertPool
+
+	// CurrentTime is used to check the validity of all certificates in the
+	// chain. If zero, the current time is used.
+	CurrentTime time.Time
+
 	// KeyUsage specifies which Extended Key Usage values are acceptable. A leaf
 	// certificate is accepted if it contains any of the listed values. An empty
 	// list means ExtKeyUsageServerAuth. To accept any key usage, include
@@ -205,6 +216,7 @@
 	// Certificate chains are required to nest these extended key usage values.
 	// (This matches the Windows CryptoAPI behavior, but not the spec.)
 	KeyUsages []ExtKeyUsage
+
 	// MaxConstraintComparisions is the maximum number of comparisons to
 	// perform when checking a given certificate's name constraints. If
 	// zero, a sensible default is used. This limit prevents pathological
@@ -1015,6 +1027,16 @@
 
 // VerifyHostname returns nil if c is a valid certificate for the named host.
 // Otherwise it returns an error describing the mismatch.
+//
+// IP addresses can be optionally enclosed in square brackets and are checked
+// against the IPAddresses field. Other names are checked case insensitively
+// against the DNSNames field, with support for only one wildcard as the whole
+// left-most label.
+//
+// If the Common Name field is a valid hostname, and the certificate doesn't
+// have any Subject Alternative Names, the name will also be checked against the
+// Common Name. This legacy behavior can be disabled by setting the GODEBUG
+// environment variable to "x509ignoreCN=1" and might be removed in the future.
 func (c *Certificate) VerifyHostname(h string) error {
 	// IP addresses may be written in [ ].
 	candidateIP := h
diff --git a/src/encoding/csv/writer.go b/src/encoding/csv/writer.go
index 3f34bc5..ac64b4d 100644
--- a/src/encoding/csv/writer.go
+++ b/src/encoding/csv/writer.go
@@ -158,10 +158,24 @@
 	if field == "" {
 		return false
 	}
-	if field == `\.` || strings.ContainsRune(field, w.Comma) || strings.ContainsAny(field, "\"\r\n") {
+
+	if field == `\.` {
 		return true
 	}
 
+	if w.Comma < utf8.RuneSelf {
+		for i := 0; i < len(field); i++ {
+			c := field[i]
+			if c == '\n' || c == '\r' || c == '"' || c == byte(w.Comma) {
+				return true
+			}
+		}
+	} else {
+		if strings.ContainsRune(field, w.Comma) || strings.ContainsAny(field, "\"\r\n") {
+			return true
+		}
+	}
+
 	r1, _ := utf8.DecodeRuneInString(field)
 	return unicode.IsSpace(r1)
 }
diff --git a/src/encoding/csv/writer_test.go b/src/encoding/csv/writer_test.go
index 011f01c..ab28b0d 100644
--- a/src/encoding/csv/writer_test.go
+++ b/src/encoding/csv/writer_test.go
@@ -93,3 +93,20 @@
 		t.Error("Error should not be nil")
 	}
 }
+
+var benchmarkWriteData = [][]string{
+	{"abc", "def", "12356", "1234567890987654311234432141542132"},
+	{"abc", "def", "12356", "1234567890987654311234432141542132"},
+	{"abc", "def", "12356", "1234567890987654311234432141542132"},
+}
+
+func BenchmarkWrite(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		w := NewWriter(&bytes.Buffer{})
+		err := w.WriteAll(benchmarkWriteData)
+		if err != nil {
+			b.Fatal(err)
+		}
+		w.Flush()
+	}
+}
diff --git a/src/net/http/cgi/host.go b/src/net/http/cgi/host.go
index 215bb83..a038575 100644
--- a/src/net/http/cgi/host.go
+++ b/src/net/http/cgi/host.go
@@ -21,6 +21,7 @@
 	"log"
 	"net"
 	"net/http"
+	"net/textproto"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -276,8 +277,8 @@
 			continue
 		}
 		header, val := parts[0], parts[1]
-		header = strings.TrimSpace(header)
-		val = strings.TrimSpace(val)
+		header = textproto.TrimString(header)
+		val = textproto.TrimString(val)
 		switch {
 		case header == "Status":
 			if len(val) < 3 {
diff --git a/src/net/http/cookie.go b/src/net/http/cookie.go
index 5c572d6..d7a8f5e 100644
--- a/src/net/http/cookie.go
+++ b/src/net/http/cookie.go
@@ -7,6 +7,7 @@
 import (
 	"log"
 	"net"
+	"net/textproto"
 	"strconv"
 	"strings"
 	"time"
@@ -60,11 +61,11 @@
 	}
 	cookies := make([]*Cookie, 0, cookieCount)
 	for _, line := range h["Set-Cookie"] {
-		parts := strings.Split(strings.TrimSpace(line), ";")
+		parts := strings.Split(textproto.TrimString(line), ";")
 		if len(parts) == 1 && parts[0] == "" {
 			continue
 		}
-		parts[0] = strings.TrimSpace(parts[0])
+		parts[0] = textproto.TrimString(parts[0])
 		j := strings.Index(parts[0], "=")
 		if j < 0 {
 			continue
@@ -83,7 +84,7 @@
 			Raw:   line,
 		}
 		for i := 1; i < len(parts); i++ {
-			parts[i] = strings.TrimSpace(parts[i])
+			parts[i] = textproto.TrimString(parts[i])
 			if len(parts[i]) == 0 {
 				continue
 			}
@@ -242,7 +243,7 @@
 
 	cookies := make([]*Cookie, 0, len(lines)+strings.Count(lines[0], ";"))
 	for _, line := range lines {
-		line = strings.TrimSpace(line)
+		line = textproto.TrimString(line)
 
 		var part string
 		for len(line) > 0 { // continue since we have rest
@@ -251,7 +252,7 @@
 			} else {
 				part, line = line, ""
 			}
-			part = strings.TrimSpace(part)
+			part = textproto.TrimString(part)
 			if len(part) == 0 {
 				continue
 			}
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index d214485..f95f242 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -756,7 +756,7 @@
 	var ranges []httpRange
 	noOverlap := false
 	for _, ra := range strings.Split(s[len(b):], ",") {
-		ra = strings.TrimSpace(ra)
+		ra = textproto.TrimString(ra)
 		if ra == "" {
 			continue
 		}
@@ -764,7 +764,7 @@
 		if i < 0 {
 			return nil, errors.New("invalid range")
 		}
-		start, end := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:])
+		start, end := textproto.TrimString(ra[:i]), textproto.TrimString(ra[i+1:])
 		var r httpRange
 		if start == "" {
 			// If no start is specified, end specifies the
diff --git a/src/net/http/httptest/recorder.go b/src/net/http/httptest/recorder.go
index d0bc0fa..1369745 100644
--- a/src/net/http/httptest/recorder.go
+++ b/src/net/http/httptest/recorder.go
@@ -9,6 +9,7 @@
 	"fmt"
 	"io/ioutil"
 	"net/http"
+	"net/textproto"
 	"strconv"
 	"strings"
 
@@ -221,7 +222,7 @@
 // This a modified version of same function found in net/http/transfer.go. This
 // one just ignores an invalid header.
 func parseContentLength(cl string) int64 {
-	cl = strings.TrimSpace(cl)
+	cl = textproto.TrimString(cl)
 	if cl == "" {
 		return -1
 	}
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
index 70de7b1..3f48fab 100644
--- a/src/net/http/httputil/reverseproxy.go
+++ b/src/net/http/httputil/reverseproxy.go
@@ -13,6 +13,7 @@
 	"log"
 	"net"
 	"net/http"
+	"net/textproto"
 	"net/url"
 	"strings"
 	"sync"
@@ -387,7 +388,7 @@
 func removeConnectionHeaders(h http.Header) {
 	for _, f := range h["Connection"] {
 		for _, sf := range strings.Split(f, ",") {
-			if sf = strings.TrimSpace(sf); sf != "" {
+			if sf = textproto.TrimString(sf); sf != "" {
 				h.Del(sf)
 			}
 		}
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 6a3a1c5..764939f 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -1224,13 +1224,22 @@
 
 		for i := 0; i < n; i++ {
 			if _, err := bufrw.WriteString(nthResponse(i)); err != nil {
-				t.Errorf("Writing response #%d failed: %v", i, err)
+				select {
+				case <-triggerCancelCh:
+				default:
+					t.Errorf("Writing response #%d failed: %v", i, err)
+				}
+				return
 			}
 			bufrw.Flush()
 			time.Sleep(time.Second)
 		}
 		if _, err := bufrw.WriteString(terminalMsg); err != nil {
-			t.Errorf("Failed to write terminal message: %v", err)
+			select {
+			case <-triggerCancelCh:
+			default:
+				t.Errorf("Failed to write terminal message: %v", err)
+			}
 		}
 		bufrw.Flush()
 	}))
diff --git a/src/net/http/response_test.go b/src/net/http/response_test.go
index 0c78df6..ce87260 100644
--- a/src/net/http/response_test.go
+++ b/src/net/http/response_test.go
@@ -734,6 +734,7 @@
 }
 
 func diff(t *testing.T, prefix string, have, want interface{}) {
+	t.Helper()
 	hv := reflect.ValueOf(have).Elem()
 	wv := reflect.ValueOf(want).Elem()
 	if hv.Type() != wv.Type() {
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index 49f6941..5f56932 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -1347,37 +1347,6 @@
 	}
 }
 
-func TestIdentityResponseHeaders(t *testing.T) {
-	// Not parallel; changes log output.
-	defer afterTest(t)
-	log.SetOutput(ioutil.Discard) // is noisy otherwise
-	defer log.SetOutput(os.Stderr)
-
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Transfer-Encoding", "identity")
-		w.(Flusher).Flush()
-		fmt.Fprintf(w, "I am an identity response.")
-	}))
-	defer ts.Close()
-
-	c := ts.Client()
-	res, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatalf("Get error: %v", err)
-	}
-	defer res.Body.Close()
-
-	if g, e := res.TransferEncoding, []string(nil); !reflect.DeepEqual(g, e) {
-		t.Errorf("expected TransferEncoding of %v; got %v", e, g)
-	}
-	if _, haveCL := res.Header["Content-Length"]; haveCL {
-		t.Errorf("Unexpected Content-Length")
-	}
-	if !res.Close {
-		t.Errorf("expected Connection: close; got %v", res.Close)
-	}
-}
-
 // TestHeadResponses verifies that all MIME type sniffing and Content-Length
 // counting of GET requests also happens on HEAD requests.
 func TestHeadResponses_h1(t *testing.T) { testHeadResponses(t, h1Mode) }
diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go
index 960f8ac..6d5ea05 100644
--- a/src/net/http/transfer.go
+++ b/src/net/http/transfer.go
@@ -425,11 +425,11 @@
 	ProtoMajor    int
 	ProtoMinor    int
 	// Output
-	Body             io.ReadCloser
-	ContentLength    int64
-	TransferEncoding []string
-	Close            bool
-	Trailer          Header
+	Body          io.ReadCloser
+	ContentLength int64
+	Chunked       bool
+	Close         bool
+	Trailer       Header
 }
 
 func (t *transferReader) protoAtLeast(m, n int) bool {
@@ -501,13 +501,12 @@
 		t.ProtoMajor, t.ProtoMinor = 1, 1
 	}
 
-	// Transfer encoding, content length
-	err = t.fixTransferEncoding()
-	if err != nil {
+	// Transfer-Encoding: chunked, and overriding Content-Length.
+	if err := t.parseTransferEncoding(); err != nil {
 		return err
 	}
 
-	realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding)
+	realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.Chunked)
 	if err != nil {
 		return err
 	}
@@ -522,7 +521,7 @@
 	}
 
 	// Trailer
-	t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding)
+	t.Trailer, err = fixTrailer(t.Header, t.Chunked)
 	if err != nil {
 		return err
 	}
@@ -532,9 +531,7 @@
 	// See RFC 7230, section 3.3.
 	switch msg.(type) {
 	case *Response:
-		if realLength == -1 &&
-			!chunked(t.TransferEncoding) &&
-			bodyAllowedForStatus(t.StatusCode) {
+		if realLength == -1 && !t.Chunked && bodyAllowedForStatus(t.StatusCode) {
 			// Unbounded body.
 			t.Close = true
 		}
@@ -543,7 +540,7 @@
 	// Prepare body reader. ContentLength < 0 means chunked encoding
 	// or close connection when finished, since multipart is not supported yet
 	switch {
-	case chunked(t.TransferEncoding):
+	case t.Chunked:
 		if noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode) {
 			t.Body = NoBody
 		} else {
@@ -569,13 +566,17 @@
 	case *Request:
 		rr.Body = t.Body
 		rr.ContentLength = t.ContentLength
-		rr.TransferEncoding = t.TransferEncoding
+		if t.Chunked {
+			rr.TransferEncoding = []string{"chunked"}
+		}
 		rr.Close = t.Close
 		rr.Trailer = t.Trailer
 	case *Response:
 		rr.Body = t.Body
 		rr.ContentLength = t.ContentLength
-		rr.TransferEncoding = t.TransferEncoding
+		if t.Chunked {
+			rr.TransferEncoding = []string{"chunked"}
+		}
 		rr.Close = t.Close
 		rr.Trailer = t.Trailer
 	}
@@ -605,8 +606,8 @@
 	return ok
 }
 
-// fixTransferEncoding sanitizes t.TransferEncoding, if needed.
-func (t *transferReader) fixTransferEncoding() error {
+// parseTransferEncoding sets t.Chunked based on the Transfer-Encoding header.
+func (t *transferReader) parseTransferEncoding() error {
 	raw, present := t.Header["Transfer-Encoding"]
 	if !present {
 		return nil
@@ -618,56 +619,38 @@
 		return nil
 	}
 
-	encodings := strings.Split(raw[0], ",")
-	te := make([]string, 0, len(encodings))
-	// TODO: Even though we only support "identity" and "chunked"
-	// encodings, the loop below is designed with foresight. One
-	// invariant that must be maintained is that, if present,
-	// chunked encoding must always come first.
-	for _, encoding := range encodings {
-		encoding = strings.ToLower(strings.TrimSpace(encoding))
-		// "identity" encoding is not recorded
-		if encoding == "identity" {
-			break
-		}
-		if encoding != "chunked" {
-			return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", encoding)}
-		}
-		te = te[0 : len(te)+1]
-		te[len(te)-1] = encoding
+	// Like nginx, we only support a single Transfer-Encoding header field, and
+	// only if set to "chunked". This is one of the most security sensitive
+	// surfaces in HTTP/1.1 due to the risk of request smuggling, so we keep it
+	// strict and simple.
+	if len(raw) != 1 {
+		return &unsupportedTEError{fmt.Sprintf("too many transfer encodings: %q", raw)}
 	}
-	if len(te) > 1 {
-		return badStringError("too many transfer encodings", strings.Join(te, ","))
-	}
-	if len(te) > 0 {
-		// RFC 7230 3.3.2 says "A sender MUST NOT send a
-		// Content-Length header field in any message that
-		// contains a Transfer-Encoding header field."
-		//
-		// but also:
-		// "If a message is received with both a
-		// Transfer-Encoding and a Content-Length header
-		// field, the Transfer-Encoding overrides the
-		// Content-Length. Such a message might indicate an
-		// attempt to perform request smuggling (Section 9.5)
-		// or response splitting (Section 9.4) and ought to be
-		// handled as an error. A sender MUST remove the
-		// received Content-Length field prior to forwarding
-		// such a message downstream."
-		//
-		// Reportedly, these appear in the wild.
-		delete(t.Header, "Content-Length")
-		t.TransferEncoding = te
-		return nil
+	if strings.ToLower(textproto.TrimString(raw[0])) != "chunked" {
+		return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", raw[0])}
 	}
 
+	// RFC 7230 3.3.2 says "A sender MUST NOT send a Content-Length header field
+	// in any message that contains a Transfer-Encoding header field."
+	//
+	// but also: "If a message is received with both a Transfer-Encoding and a
+	// Content-Length header field, the Transfer-Encoding overrides the
+	// Content-Length. Such a message might indicate an attempt to perform
+	// request smuggling (Section 9.5) or response splitting (Section 9.4) and
+	// ought to be handled as an error. A sender MUST remove the received
+	// Content-Length field prior to forwarding such a message downstream."
+	//
+	// Reportedly, these appear in the wild.
+	delete(t.Header, "Content-Length")
+
+	t.Chunked = true
 	return nil
 }
 
 // Determine the expected body length, using RFC 7230 Section 3.3. This
 // function is not a method, because ultimately it should be shared by
 // ReadResponse and ReadRequest.
-func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) {
+func fixLength(isResponse bool, status int, requestMethod string, header Header, chunked bool) (int64, error) {
 	isRequest := !isResponse
 	contentLens := header["Content-Length"]
 
@@ -677,9 +660,9 @@
 		// Content-Length headers if they differ in value.
 		// If there are dups of the value, remove the dups.
 		// See Issue 16490.
-		first := strings.TrimSpace(contentLens[0])
+		first := textproto.TrimString(contentLens[0])
 		for _, ct := range contentLens[1:] {
-			if first != strings.TrimSpace(ct) {
+			if first != textproto.TrimString(ct) {
 				return 0, fmt.Errorf("http: message cannot contain multiple Content-Length headers; got %q", contentLens)
 			}
 		}
@@ -711,14 +694,14 @@
 	}
 
 	// Logic based on Transfer-Encoding
-	if chunked(te) {
+	if chunked {
 		return -1, nil
 	}
 
 	// Logic based on Content-Length
 	var cl string
 	if len(contentLens) == 1 {
-		cl = strings.TrimSpace(contentLens[0])
+		cl = textproto.TrimString(contentLens[0])
 	}
 	if cl != "" {
 		n, err := parseContentLength(cl)
@@ -766,12 +749,12 @@
 }
 
 // Parse the trailer header
-func fixTrailer(header Header, te []string) (Header, error) {
+func fixTrailer(header Header, chunked bool) (Header, error) {
 	vv, ok := header["Trailer"]
 	if !ok {
 		return nil, nil
 	}
-	if !chunked(te) {
+	if !chunked {
 		// Trailer and no chunking:
 		// this is an invalid use case for trailer header.
 		// Nevertheless, no error will be returned and we
@@ -1049,7 +1032,7 @@
 // parseContentLength trims whitespace from s and returns -1 if no value
 // is set, or the value if it's >= 0.
 func parseContentLength(cl string) (int64, error) {
-	cl = strings.TrimSpace(cl)
+	cl = textproto.TrimString(cl)
 	if cl == "" {
 		return -1, nil
 	}
diff --git a/src/net/http/transfer_test.go b/src/net/http/transfer_test.go
index a6846f7..e27d34d 100644
--- a/src/net/http/transfer_test.go
+++ b/src/net/http/transfer_test.go
@@ -279,7 +279,7 @@
 	}
 }
 
-func TestFixTransferEncoding(t *testing.T) {
+func TestParseTransferEncoding(t *testing.T) {
 	tests := []struct {
 		hdr     Header
 		wantErr error
@@ -290,7 +290,23 @@
 		},
 		{
 			hdr:     Header{"Transfer-Encoding": {"chunked, chunked", "identity", "chunked"}},
-			wantErr: badStringError("too many transfer encodings", "chunked,chunked"),
+			wantErr: &unsupportedTEError{`too many transfer encodings: ["chunked, chunked" "identity" "chunked"]`},
+		},
+		{
+			hdr:     Header{"Transfer-Encoding": {""}},
+			wantErr: &unsupportedTEError{`unsupported transfer encoding: ""`},
+		},
+		{
+			hdr:     Header{"Transfer-Encoding": {"chunked, identity"}},
+			wantErr: &unsupportedTEError{`unsupported transfer encoding: "chunked, identity"`},
+		},
+		{
+			hdr:     Header{"Transfer-Encoding": {"chunked", "identity"}},
+			wantErr: &unsupportedTEError{`too many transfer encodings: ["chunked" "identity"]`},
+		},
+		{
+			hdr:     Header{"Transfer-Encoding": {"\x0bchunked"}},
+			wantErr: &unsupportedTEError{`unsupported transfer encoding: "\vchunked"`},
 		},
 		{
 			hdr:     Header{"Transfer-Encoding": {"chunked"}},
@@ -304,7 +320,7 @@
 			ProtoMajor: 1,
 			ProtoMinor: 1,
 		}
-		gotErr := tr.fixTransferEncoding()
+		gotErr := tr.parseTransferEncoding()
 		if !reflect.DeepEqual(gotErr, tt.wantErr) {
 			t.Errorf("%d.\ngot error:\n%v\nwant error:\n%v\n\n", i, gotErr, tt.wantErr)
 		}
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
index 0c1dd1a..b1705d5 100644
--- a/src/net/http/transport.go
+++ b/src/net/http/transport.go
@@ -843,7 +843,7 @@
 	// Deliver pconn to goroutine waiting for idle connection, if any.
 	// (They may be actively dialing, but this conn is ready first.
 	// Chrome calls this socket late binding.
-	// See https://insouciant.org/tech/connection-management-in-chromium/.)
+	// See https://www.chromium.org/developers/design-documents/network-stack#TOC-Connection-Management.)
 	key := pconn.cacheKey
 	if q, ok := t.idleConnWait[key]; ok {
 		done := false
diff --git a/src/runtime/conv_wasm_test.go b/src/runtime/conv_wasm_test.go
new file mode 100644
index 0000000..5054fca
--- /dev/null
+++ b/src/runtime/conv_wasm_test.go
@@ -0,0 +1,128 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"testing"
+)
+
+var res int64
+var ures uint64
+
+func TestFloatTruncation(t *testing.T) {
+	testdata := []struct {
+		input      float64
+		convInt64  int64
+		convUInt64 uint64
+		overflow   bool
+	}{
+		// max +- 1
+		{
+			input:      0x7fffffffffffffff,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		// For out-of-bounds conversion, the result is implementation-dependent.
+		// This test verifies the implementation of wasm architecture.
+		{
+			input:      0x8000000000000000,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      0x7ffffffffffffffe,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		// neg max +- 1
+		{
+			input:      -0x8000000000000000,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      -0x8000000000000001,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      -0x7fffffffffffffff,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		// trunc point +- 1
+		{
+			input:      0x7ffffffffffffdff,
+			convInt64:  0x7ffffffffffffc00,
+			convUInt64: 0x7ffffffffffffc00,
+		},
+		{
+			input:      0x7ffffffffffffe00,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      0x7ffffffffffffdfe,
+			convInt64:  0x7ffffffffffffc00,
+			convUInt64: 0x7ffffffffffffc00,
+		},
+		// neg trunc point +- 1
+		{
+			input:      -0x7ffffffffffffdff,
+			convInt64:  -0x7ffffffffffffc00,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      -0x7ffffffffffffe00,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      -0x7ffffffffffffdfe,
+			convInt64:  -0x7ffffffffffffc00,
+			convUInt64: 0x8000000000000000,
+		},
+		// umax +- 1
+		{
+			input:      0xffffffffffffffff,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      0x10000000000000000,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      0xfffffffffffffffe,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		// umax trunc +- 1
+		{
+			input:      0xfffffffffffffbff,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0xfffffffffffff800,
+		},
+		{
+			input:      0xfffffffffffffc00,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0x8000000000000000,
+		},
+		{
+			input:      0xfffffffffffffbfe,
+			convInt64:  -0x8000000000000000,
+			convUInt64: 0xfffffffffffff800,
+		},
+	}
+	for _, item := range testdata {
+		if got, want := int64(item.input), item.convInt64; got != want {
+			t.Errorf("int64(%f): got %x, want %x", item.input, got, want)
+		}
+		if got, want := uint64(item.input), item.convUInt64; got != want {
+			t.Errorf("uint64(%f): got %x, want %x", item.input, got, want)
+		}
+	}
+}
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
index 7baba83..a584ada 100644
--- a/src/runtime/os_windows.go
+++ b/src/runtime/os_windows.go
@@ -1192,23 +1192,24 @@
 
 	// Does it want a preemption and is it safe to preempt?
 	gp := gFromTLS(mp)
-	if wantAsyncPreempt(gp) && isAsyncSafePoint(gp, c.ip(), c.sp(), c.lr()) {
-		// Inject call to asyncPreempt
-		targetPC := funcPC(asyncPreempt)
-		switch GOARCH {
-		default:
-			throw("unsupported architecture")
-		case "386", "amd64":
-			// Make it look like the thread called targetPC.
-			pc := c.ip()
-			sp := c.sp()
-			sp -= sys.PtrSize
-			*(*uintptr)(unsafe.Pointer(sp)) = pc
-			c.set_sp(sp)
-			c.set_ip(targetPC)
-		}
+	if wantAsyncPreempt(gp) {
+		if ok, newpc := isAsyncSafePoint(gp, c.ip(), c.sp(), c.lr()); ok {
+			// Inject call to asyncPreempt
+			targetPC := funcPC(asyncPreempt)
+			switch GOARCH {
+			default:
+				throw("unsupported architecture")
+			case "386", "amd64":
+				// Make it look like the thread called targetPC.
+				sp := c.sp()
+				sp -= sys.PtrSize
+				*(*uintptr)(unsafe.Pointer(sp)) = newpc
+				c.set_sp(sp)
+				c.set_ip(targetPC)
+			}
 
-		stdcall2(_SetThreadContext, thread, uintptr(unsafe.Pointer(c)))
+			stdcall2(_SetThreadContext, thread, uintptr(unsafe.Pointer(c)))
+		}
 	}
 
 	atomic.Store(&mp.preemptExtLock, 0)
diff --git a/src/runtime/preempt.go b/src/runtime/preempt.go
index 41a32fa..7618565 100644
--- a/src/runtime/preempt.go
+++ b/src/runtime/preempt.go
@@ -61,6 +61,8 @@
 // Keep in sync with cmd/compile/internal/gc/plive.go:go115ReduceLiveness.
 const go115ReduceLiveness = true
 
+const go115RestartSeq = go115ReduceLiveness && true // enable restartable sequences
+
 type suspendGState struct {
 	g *g
 
@@ -359,31 +361,35 @@
 // 3. It's generally safe to interact with the runtime, even if we're
 // in a signal handler stopped here. For example, there are no runtime
 // locks held, so acquiring a runtime lock won't self-deadlock.
-func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) bool {
+//
+// In some cases the PC is safe for asynchronous preemption but it
+// also needs to adjust the resumption PC. The new PC is returned in
+// the second result.
+func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
 	mp := gp.m
 
 	// Only user Gs can have safe-points. We check this first
 	// because it's extremely common that we'll catch mp in the
 	// scheduler processing this G preemption.
 	if mp.curg != gp {
-		return false
+		return false, 0
 	}
 
 	// Check M state.
 	if mp.p == 0 || !canPreemptM(mp) {
-		return false
+		return false, 0
 	}
 
 	// Check stack space.
 	if sp < gp.stack.lo || sp-gp.stack.lo < asyncPreemptStack {
-		return false
+		return false, 0
 	}
 
 	// Check if PC is an unsafe-point.
 	f := findfunc(pc)
 	if !f.valid() {
 		// Not Go code.
-		return false
+		return false, 0
 	}
 	if (GOARCH == "mips" || GOARCH == "mipsle" || GOARCH == "mips64" || GOARCH == "mips64le") && lr == pc+8 && funcspdelta(f, pc, nil) == 0 {
 		// We probably stopped at a half-executed CALL instruction,
@@ -394,23 +400,25 @@
 		// stack for unwinding, not the LR value. But if this is a
 		// call to morestack, we haven't created the frame, and we'll
 		// use the LR for unwinding, which will be bad.
-		return false
+		return false, 0
 	}
+	var up int32
+	var startpc uintptr
 	if !go115ReduceLiveness {
 		smi := pcdatavalue(f, _PCDATA_RegMapIndex, pc, nil)
 		if smi == -2 {
 			// Unsafe-point marked by compiler. This includes
 			// atomic sequences (e.g., write barrier) and nosplit
 			// functions (except at calls).
-			return false
+			return false, 0
 		}
 	} else {
-		up := pcdatavalue(f, _PCDATA_UnsafePoint, pc, nil)
+		up, startpc = pcdatavalue2(f, _PCDATA_UnsafePoint, pc)
 		if up != _PCDATA_UnsafePointSafe {
 			// Unsafe-point marked by compiler. This includes
 			// atomic sequences (e.g., write barrier) and nosplit
 			// functions (except at calls).
-			return false
+			return false, 0
 		}
 	}
 	if fd := funcdata(f, _FUNCDATA_LocalsPointerMaps); fd == nil || fd == unsafe.Pointer(&no_pointers_stackmap) {
@@ -422,7 +430,7 @@
 		//
 		// TODO: Are there cases that are safe but don't have a
 		// locals pointer map, like empty frame functions?
-		return false
+		return false, 0
 	}
 	name := funcname(f)
 	if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
@@ -445,10 +453,29 @@
 		//
 		// TODO(austin): We should improve this, or opt things
 		// in incrementally.
-		return false
+		return false, 0
 	}
-
-	return true
+	if go115RestartSeq {
+		switch up {
+		case _PCDATA_Restart1, _PCDATA_Restart2:
+			// Restartable instruction sequence. Back off PC to
+			// the start PC.
+			if startpc == 0 || startpc > pc || pc-startpc > 20 {
+				throw("bad restart PC")
+			}
+			return true, startpc
+		case _PCDATA_RestartAtEntry:
+			// Restart from the function entry at resumption.
+			return true, f.entry
+		}
+	} else {
+		switch up {
+		case _PCDATA_Restart1, _PCDATA_Restart2, _PCDATA_RestartAtEntry:
+			// go115RestartSeq is not enabled. Treat it as unsafe point.
+			return false, 0
+		}
+	}
+	return true, pc
 }
 
 var no_pointers_stackmap uint64 // defined in assembly, for NO_LOCAL_POINTERS macro
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 1d04c15..bd11449 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -252,7 +252,7 @@
 			throw("forcegc: phase error")
 		}
 		atomic.Store(&forcegc.idle, 1)
-		goparkunlock(&forcegc.lock, waitReasonForceGGIdle, traceEvGoBlock, 1)
+		goparkunlock(&forcegc.lock, waitReasonForceGCIdle, traceEvGoBlock, 1)
 		// this goroutine is explicitly resumed by sysmon
 		if debug.gctrace > 0 {
 			println("GC forced")
diff --git a/src/runtime/runtime2.go b/src/runtime/runtime2.go
index 89a2419..2c566b5 100644
--- a/src/runtime/runtime2.go
+++ b/src/runtime/runtime2.go
@@ -971,7 +971,7 @@
 	waitReasonChanReceive                             // "chan receive"
 	waitReasonChanSend                                // "chan send"
 	waitReasonFinalizerWait                           // "finalizer wait"
-	waitReasonForceGGIdle                             // "force gc (idle)"
+	waitReasonForceGCIdle                             // "force gc (idle)"
 	waitReasonSemacquire                              // "semacquire"
 	waitReasonSleep                                   // "sleep"
 	waitReasonSyncCondWait                            // "sync.Cond.Wait"
@@ -1001,7 +1001,7 @@
 	waitReasonChanReceive:           "chan receive",
 	waitReasonChanSend:              "chan send",
 	waitReasonFinalizerWait:         "finalizer wait",
-	waitReasonForceGGIdle:           "force gc (idle)",
+	waitReasonForceGCIdle:           "force gc (idle)",
 	waitReasonSemacquire:            "semacquire",
 	waitReasonSleep:                 "sleep",
 	waitReasonSyncCondWait:          "sync.Cond.Wait",
diff --git a/src/runtime/signal_386.go b/src/runtime/signal_386.go
index 95749d2..065aff4 100644
--- a/src/runtime/signal_386.go
+++ b/src/runtime/signal_386.go
@@ -41,19 +41,18 @@
 	sp := uintptr(c.esp())
 
 	if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
-		c.pushCall(funcPC(sigpanic))
+		c.pushCall(funcPC(sigpanic), pc)
 	} else {
 		// Not safe to push the call. Just clobber the frame.
 		c.set_eip(uint32(funcPC(sigpanic)))
 	}
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
-	// Make it look like the signaled instruction called target.
-	pc := uintptr(c.eip())
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
+	// Make it look like we called target at resumePC.
 	sp := uintptr(c.esp())
 	sp -= sys.PtrSize
-	*(*uintptr)(unsafe.Pointer(sp)) = pc
+	*(*uintptr)(unsafe.Pointer(sp)) = resumePC
 	c.set_esp(uint32(sp))
 	c.set_eip(uint32(targetPC))
 }
diff --git a/src/runtime/signal_amd64.go b/src/runtime/signal_amd64.go
index 63ffedb..6ab1f75 100644
--- a/src/runtime/signal_amd64.go
+++ b/src/runtime/signal_amd64.go
@@ -66,19 +66,18 @@
 	sp := uintptr(c.rsp())
 
 	if shouldPushSigpanic(gp, pc, *(*uintptr)(unsafe.Pointer(sp))) {
-		c.pushCall(funcPC(sigpanic))
+		c.pushCall(funcPC(sigpanic), pc)
 	} else {
 		// Not safe to push the call. Just clobber the frame.
 		c.set_rip(uint64(funcPC(sigpanic)))
 	}
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
-	// Make it look like the signaled instruction called target.
-	pc := uintptr(c.rip())
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
+	// Make it look like we called target at resumePC.
 	sp := uintptr(c.rsp())
 	sp -= sys.PtrSize
-	*(*uintptr)(unsafe.Pointer(sp)) = pc
+	*(*uintptr)(unsafe.Pointer(sp)) = resumePC
 	c.set_rsp(uint64(sp))
 	c.set_rip(uint64(targetPC))
 }
diff --git a/src/runtime/signal_arm.go b/src/runtime/signal_arm.go
index b4b3ca4..156d9d3 100644
--- a/src/runtime/signal_arm.go
+++ b/src/runtime/signal_arm.go
@@ -63,7 +63,7 @@
 	c.set_pc(uint32(funcPC(sigpanic)))
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
 	// Push the LR to stack, as we'll clobber it in order to
 	// push the call. The function being pushed is responsible
 	// for restoring the LR and setting the SP back.
@@ -72,7 +72,7 @@
 	c.set_sp(sp)
 	*(*uint32)(unsafe.Pointer(uintptr(sp))) = c.lr()
 	// Set up PC and LR to pretend the function being signaled
-	// calls targetPC at the faulting PC.
-	c.set_lr(c.pc())
+	// calls targetPC at resumePC.
+	c.set_lr(uint32(resumePC))
 	c.set_pc(uint32(targetPC))
 }
diff --git a/src/runtime/signal_arm64.go b/src/runtime/signal_arm64.go
index ef65f92..3c20139 100644
--- a/src/runtime/signal_arm64.go
+++ b/src/runtime/signal_arm64.go
@@ -79,7 +79,7 @@
 	c.set_pc(uint64(funcPC(sigpanic)))
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
 	// Push the LR to stack, as we'll clobber it in order to
 	// push the call. The function being pushed is responsible
 	// for restoring the LR and setting the SP back.
@@ -88,7 +88,7 @@
 	c.set_sp(sp)
 	*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr()
 	// Set up PC and LR to pretend the function being signaled
-	// calls targetPC at the faulting PC.
-	c.set_lr(c.pc())
+	// calls targetPC at resumePC.
+	c.set_lr(uint64(resumePC))
 	c.set_pc(uint64(targetPC))
 }
diff --git a/src/runtime/signal_linux_s390x.go b/src/runtime/signal_linux_s390x.go
index 15f5035..12d5c31 100644
--- a/src/runtime/signal_linux_s390x.go
+++ b/src/runtime/signal_linux_s390x.go
@@ -110,7 +110,7 @@
 	c.set_pc(uint64(funcPC(sigpanic)))
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
 	// Push the LR to stack, as we'll clobber it in order to
 	// push the call. The function being pushed is responsible
 	// for restoring the LR and setting the SP back.
@@ -119,7 +119,7 @@
 	c.set_sp(sp)
 	*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link()
 	// Set up PC and LR to pretend the function being signaled
-	// calls targetPC at the faulting PC.
-	c.set_link(c.pc())
+	// calls targetPC at resumePC.
+	c.set_link(uint64(resumePC))
 	c.set_pc(uint64(targetPC))
 }
diff --git a/src/runtime/signal_mips64x.go b/src/runtime/signal_mips64x.go
index 6110b1c..040c959 100644
--- a/src/runtime/signal_mips64x.go
+++ b/src/runtime/signal_mips64x.go
@@ -85,7 +85,7 @@
 	c.set_pc(sigpanicPC)
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
 	// Push the LR to stack, as we'll clobber it in order to
 	// push the call. The function being pushed is responsible
 	// for restoring the LR and setting the SP back.
@@ -94,7 +94,7 @@
 	c.set_sp(sp)
 	*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.link()
 	// Set up PC and LR to pretend the function being signaled
-	// calls targetPC at the faulting PC.
-	c.set_link(c.pc())
+	// calls targetPC at resumePC.
+	c.set_link(uint64(resumePC))
 	c.set_pc(uint64(targetPC))
 }
diff --git a/src/runtime/signal_mipsx.go b/src/runtime/signal_mipsx.go
index cdbe193..8c29f59 100644
--- a/src/runtime/signal_mipsx.go
+++ b/src/runtime/signal_mipsx.go
@@ -80,7 +80,7 @@
 	c.set_pc(uint32(funcPC(sigpanic)))
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
 	// Push the LR to stack, as we'll clobber it in order to
 	// push the call. The function being pushed is responsible
 	// for restoring the LR and setting the SP back.
@@ -89,7 +89,7 @@
 	c.set_sp(sp)
 	*(*uint32)(unsafe.Pointer(uintptr(sp))) = c.link()
 	// Set up PC and LR to pretend the function being signaled
-	// calls targetPC at the faulting PC.
-	c.set_link(c.pc())
+	// calls targetPC at resumePC.
+	c.set_link(uint32(resumePC))
 	c.set_pc(uint32(targetPC))
 }
diff --git a/src/runtime/signal_ppc64x.go b/src/runtime/signal_ppc64x.go
index 2da09d3..5de93a3 100644
--- a/src/runtime/signal_ppc64x.go
+++ b/src/runtime/signal_ppc64x.go
@@ -86,7 +86,7 @@
 	c.set_pc(uint64(funcPC(sigpanic)))
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
 	// Push the LR to stack, as we'll clobber it in order to
 	// push the call. The function being pushed is responsible
 	// for restoring the LR and setting the SP back.
@@ -104,8 +104,8 @@
 	*(*uint64)(unsafe.Pointer(uintptr(sp) + 8)) = c.r2()
 	*(*uint64)(unsafe.Pointer(uintptr(sp) + 16)) = c.r12()
 	// Set up PC and LR to pretend the function being signaled
-	// calls targetPC at the faulting PC.
-	c.set_link(c.pc())
+	// calls targetPC at resumePC.
+	c.set_link(uint64(resumePC))
 	c.set_r12(uint64(targetPC))
 	c.set_pc(uint64(targetPC))
 }
diff --git a/src/runtime/signal_riscv64.go b/src/runtime/signal_riscv64.go
index e2edaf3..93363a4 100644
--- a/src/runtime/signal_riscv64.go
+++ b/src/runtime/signal_riscv64.go
@@ -78,7 +78,7 @@
 	c.set_pc(uint64(funcPC(sigpanic)))
 }
 
-func (c *sigctxt) pushCall(targetPC uintptr) {
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
 	// Push the LR to stack, as we'll clobber it in order to
 	// push the call. The function being pushed is responsible
 	// for restoring the LR and setting the SP back.
@@ -87,7 +87,7 @@
 	c.set_sp(sp)
 	*(*uint64)(unsafe.Pointer(uintptr(sp))) = c.ra()
 	// Set up PC and LR to pretend the function being signaled
-	// calls targetPC at the faulting PC.
-	c.set_ra(c.pc())
+	// calls targetPC at resumePC.
+	c.set_ra(uint64(resumePC))
 	c.set_pc(uint64(targetPC))
 }
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
index f5d79e5..5aedbf7 100644
--- a/src/runtime/signal_unix.go
+++ b/src/runtime/signal_unix.go
@@ -326,9 +326,11 @@
 func doSigPreempt(gp *g, ctxt *sigctxt) {
 	// Check if this G wants to be preempted and is safe to
 	// preempt.
-	if wantAsyncPreempt(gp) && isAsyncSafePoint(gp, ctxt.sigpc(), ctxt.sigsp(), ctxt.siglr()) {
-		// Inject a call to asyncPreempt.
-		ctxt.pushCall(funcPC(asyncPreempt))
+	if wantAsyncPreempt(gp) {
+		if ok, newpc := isAsyncSafePoint(gp, ctxt.sigpc(), ctxt.sigsp(), ctxt.siglr()); ok {
+			// Adjust the PC and inject a call to asyncPreempt.
+			ctxt.pushCall(funcPC(asyncPreempt), newpc)
+		}
 	}
 
 	// Acknowledge the preemption.
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 04aa90e..ce2ec6d 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -287,6 +287,18 @@
 	// PCDATA_UnsafePoint values.
 	_PCDATA_UnsafePointSafe   = -1 // Safe for async preemption
 	_PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption
+
+	// _PCDATA_Restart1(2) apply on a sequence of instructions, within
+	// which if an async preemption happens, we should back off the PC
+	// to the start of the sequence when resume.
+	// We need two so we can distinguish the start/end of the sequence
+	// in case that two sequences are next to each other.
+	_PCDATA_Restart1 = -3
+	_PCDATA_Restart2 = -4
+
+	// Like _PCDATA_RestartAtEntry, but back to function entry if async
+	// preempted.
+	_PCDATA_RestartAtEntry = -5
 )
 
 // A FuncID identifies particular functions that need to be treated
@@ -708,9 +720,11 @@
 	return (targetpc / sys.PtrSize) % uintptr(len(pcvalueCache{}.entries))
 }
 
-func pcvalue(f funcInfo, off int32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
+// Returns the PCData value, and the PC where this value starts.
+// TODO: the start PC is returned only when cache is nil.
+func pcvalue(f funcInfo, off int32, targetpc uintptr, cache *pcvalueCache, strict bool) (int32, uintptr) {
 	if off == 0 {
-		return -1
+		return -1, 0
 	}
 
 	// Check the cache. This speeds up walks of deep stacks, which
@@ -729,7 +743,7 @@
 			// fail in the first clause.
 			ent := &cache.entries[x][i]
 			if ent.off == off && ent.targetpc == targetpc {
-				return ent.val
+				return ent.val, 0
 			}
 		}
 	}
@@ -739,11 +753,12 @@
 			print("runtime: no module data for ", hex(f.entry), "\n")
 			throw("no module data")
 		}
-		return -1
+		return -1, 0
 	}
 	datap := f.datap
 	p := datap.pclntable[off:]
 	pc := f.entry
+	prevpc := pc
 	val := int32(-1)
 	for {
 		var ok bool
@@ -770,14 +785,15 @@
 				}
 			}
 
-			return val
+			return val, prevpc
 		}
+		prevpc = pc
 	}
 
 	// If there was a table, it should have covered all program counters.
 	// If not, something is wrong.
 	if panicking != 0 || !strict {
-		return -1
+		return -1, 0
 	}
 
 	print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
@@ -795,7 +811,7 @@
 	}
 
 	throw("invalid runtime symbol table")
-	return -1
+	return -1, 0
 }
 
 func cfuncname(f funcInfo) *byte {
@@ -833,9 +849,9 @@
 	if !f.valid() {
 		return "?", 0
 	}
-	fileno := int(pcvalue(f, f.pcfile, targetpc, nil, strict))
-	line = pcvalue(f, f.pcln, targetpc, nil, strict)
-	if fileno == -1 || line == -1 || fileno >= len(datap.filetab) {
+	fileno, _ := pcvalue(f, f.pcfile, targetpc, nil, strict)
+	line, _ = pcvalue(f, f.pcln, targetpc, nil, strict)
+	if fileno == -1 || line == -1 || int(fileno) >= len(datap.filetab) {
 		// print("looking for ", hex(targetpc), " in ", funcname(f), " got file=", fileno, " line=", lineno, "\n")
 		return "?", 0
 	}
@@ -848,7 +864,7 @@
 }
 
 func funcspdelta(f funcInfo, targetpc uintptr, cache *pcvalueCache) int32 {
-	x := pcvalue(f, f.pcsp, targetpc, cache, true)
+	x, _ := pcvalue(f, f.pcsp, targetpc, cache, true)
 	if x&(sys.PtrSize-1) != 0 {
 		print("invalid spdelta ", funcname(f), " ", hex(f.entry), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
 	}
@@ -882,14 +898,25 @@
 	if table < 0 || table >= f.npcdata {
 		return -1
 	}
-	return pcvalue(f, pcdatastart(f, table), targetpc, cache, true)
+	r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, true)
+	return r
 }
 
 func pcdatavalue1(f funcInfo, table int32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
 	if table < 0 || table >= f.npcdata {
 		return -1
 	}
-	return pcvalue(f, pcdatastart(f, table), targetpc, cache, strict)
+	r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, strict)
+	return r
+}
+
+// Like pcdatavalue, but also return the start PC of this PCData value.
+// It doesn't take a cache.
+func pcdatavalue2(f funcInfo, table int32, targetpc uintptr) (int32, uintptr) {
+	if table < 0 || table >= f.npcdata {
+		return -1, 0
+	}
+	return pcvalue(f, pcdatastart(f, table), targetpc, nil, true)
 }
 
 func funcdata(f funcInfo, i uint8) unsafe.Pointer {
diff --git a/src/runtime/sys_wasm.s b/src/runtime/sys_wasm.s
index 41260bd..e7a6570 100644
--- a/src/runtime/sys_wasm.s
+++ b/src/runtime/sys_wasm.s
@@ -99,7 +99,7 @@
 	End
 
 	Get R0
-	F64Const $9223372036854775807.
+	F64Const $0x7ffffffffffffc00p0 // Maximum truncated representation of 0x7fffffffffffffff
 	F64Gt
 	If
 		I64Const $0x8000000000000000
@@ -107,7 +107,7 @@
 	End
 
 	Get R0
-	F64Const $-9223372036854775808.
+	F64Const $-0x7ffffffffffffc00p0 // Minimum truncated representation of -0x8000000000000000
 	F64Lt
 	If
 		I64Const $0x8000000000000000
@@ -128,7 +128,7 @@
 	End
 
 	Get R0
-	F64Const $18446744073709551615.
+	F64Const $0xfffffffffffff800p0 // Maximum truncated representation of 0xffffffffffffffff
 	F64Gt
 	If
 		I64Const $0x8000000000000000
diff --git a/src/testing/helper_test.go b/src/testing/helper_test.go
index fe8ff05..7ce58c6 100644
--- a/src/testing/helper_test.go
+++ b/src/testing/helper_test.go
@@ -33,6 +33,8 @@
 helperfuncs_test.go:21: 6
 helperfuncs_test.go:44: 7
 helperfuncs_test.go:56: 8
+helperfuncs_test.go:64: 9
+helperfuncs_test.go:60: 10
 `
 	lines := strings.Split(buf.String(), "\n")
 	durationRE := regexp.MustCompile(`\(.*\)$`)
diff --git a/src/testing/helperfuncs_test.go b/src/testing/helperfuncs_test.go
index f2d54b3..df0476e 100644
--- a/src/testing/helperfuncs_test.go
+++ b/src/testing/helperfuncs_test.go
@@ -54,6 +54,17 @@
 	// has no effect.
 	t.Helper()
 	t.Error("8")
+
+	// Check that right caller is reported for func passed to Cleanup when
+	// multiple cleanup functions have been registered.
+	t.Cleanup(func() {
+		t.Helper()
+		t.Error("10")
+	})
+	t.Cleanup(func() {
+		t.Helper()
+		t.Error("9")
+	})
 }
 
 func parallelTestHelper(t *T) {
diff --git a/src/testing/testing.go b/src/testing/testing.go
index ed88ba5..90c15a2 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -338,15 +338,17 @@
 // common holds the elements common between T and B and
 // captures common methods such as Errorf.
 type common struct {
-	mu      sync.RWMutex        // guards this group of fields
-	output  []byte              // Output generated by test or benchmark.
-	w       io.Writer           // For flushToParent.
-	ran     bool                // Test or benchmark (or one of its subtests) was executed.
-	failed  bool                // Test or benchmark has failed.
-	skipped bool                // Test of benchmark has been skipped.
-	done    bool                // Test is finished and all subtests have completed.
-	helpers map[string]struct{} // functions to be skipped when writing file/line info
-	cleanup func()              // optional function to be called at the end of the test
+	mu          sync.RWMutex        // guards this group of fields
+	output      []byte              // Output generated by test or benchmark.
+	w           io.Writer           // For flushToParent.
+	ran         bool                // Test or benchmark (or one of its subtests) was executed.
+	failed      bool                // Test or benchmark has failed.
+	skipped     bool                // Test of benchmark has been skipped.
+	done        bool                // Test is finished and all subtests have completed.
+	helpers     map[string]struct{} // functions to be skipped when writing file/line info
+	cleanup     func()              // optional function to be called at the end of the test
+	cleanupName string              // Name of the cleanup function.
+	cleanupPc   []uintptr           // The stack trace at the point where Cleanup was called.
 
 	chatty     bool   // A copy of the chatty flag.
 	finished   bool   // Test function has completed.
@@ -426,6 +428,10 @@
 	var firstFrame, prevFrame, frame runtime.Frame
 	for more := true; more; prevFrame = frame {
 		frame, more = frames.Next()
+		if frame.Function == c.cleanupName {
+			frames = runtime.CallersFrames(c.cleanupPc)
+			continue
+		}
 		if firstFrame.PC == 0 {
 			firstFrame = frame
 		}
@@ -789,12 +795,21 @@
 	c.mu.Lock()
 	defer c.mu.Unlock()
 	oldCleanup := c.cleanup
+	oldCleanupPc := c.cleanupPc
 	c.cleanup = func() {
 		if oldCleanup != nil {
-			defer oldCleanup()
+			defer func() {
+				c.cleanupPc = oldCleanupPc
+				oldCleanup()
+			}()
 		}
+		c.cleanupName = callerName(0)
 		f()
 	}
+	var pc [maxStackLen]uintptr
+	// Skip two extra frames to account for this function and runtime.Callers itself.
+	n := runtime.Callers(2, pc[:])
+	c.cleanupPc = pc[:n]
 }
 
 var tempDirReplacer struct {
diff --git a/test/fixedbugs/issue38690.go b/test/fixedbugs/issue38690.go
new file mode 100644
index 0000000..af8688d
--- /dev/null
+++ b/test/fixedbugs/issue38690.go
@@ -0,0 +1,65 @@
+// compile
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure that literal value can be passed to struct
+// blank field of array/struct type, see issue #38690.
+
+package main
+
+type A1 = [0]int
+type A2 = [1]int
+
+type S1 struct{}
+
+type S2 struct {
+	x int
+}
+
+type S3 = struct{}
+
+type S4 = struct{ x int }
+
+type S struct {
+	x int
+	_ [0]int
+	_ [1]int
+	_ A1
+	_ A2
+	_ S1
+	_ S2
+	_ S3
+	_ S4
+	_ [1]S4
+}
+
+var s = S{1, [0]int{}, [1]int{1}, A1{}, A2{1}, S1{}, S2{1}, S3{}, S4{1}, [1]S4{}}
+
+func main() {
+	f1()
+	mustPanic(f2)
+	mustPanic(f3)
+}
+
+func f1() {
+	_ = S{1, [0]int{}, [1]int{1}, A1{}, A2{1}, S1{}, S2{1}, S3{}, S4{1}, [1]S4{}}
+}
+
+func f2() {
+	_ = S{1, [0]int{}, [1]int{1}, A1{}, A2{1}, S1{}, S2{1}, S3{}, func() S4 { panic("") }(), [1]S4{}}
+}
+
+func f3() {
+	_ = S{1, [0]int{}, [1]int{1}, A1{}, A2{1}, S1{}, S2{1}, S3{}, S4{1}, func() [1]S4 { panic("") }()}
+}
+
+func mustPanic(f func()) {
+	defer func() {
+		if recover() == nil {
+			panic("expected panic, got nil")
+		}
+	}()
+	f()
+}
diff --git a/test/fixedbugs/issue38746.go b/test/fixedbugs/issue38746.go
new file mode 100644
index 0000000..c670349
--- /dev/null
+++ b/test/fixedbugs/issue38746.go
@@ -0,0 +1,17 @@
+// compile
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var g *uint64
+
+func main() {
+	var v uint64
+	g = &v
+	v &^= (1 << 31)
+	v |= 1 << 63
+	v &^= (1 << 63)
+}