[dev.link] all: merge master to dev.link

Change-Id: Ia30d70096e740d012e4d9e070bbc4347805527a7
diff --git a/AUTHORS b/AUTHORS
index d79d4ed..69e35a1 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1142,6 +1142,7 @@
 Piyush Mishra <piyush@codeitout.com>
 Platform.sh
 Pontus Leitzler <leitzler@gmail.com>
+Prasanga Siripala <pj@pjebs.com.au>
 Prashant Varanasi <prashant@prashantv.com>
 Pravendra Singh <hackpravj@gmail.com>
 Preetam Jinka <pj@preet.am>
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 07bdb4c..934834f 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -1788,6 +1788,7 @@
 Piyush Mishra <piyush@codeitout.com>
 Plekhanov Maxim <kishtatix@gmail.com>
 Pontus Leitzler <leitzler@gmail.com>
+Prasanga Siripala <pj@pjebs.com.au>
 Prasanna Swaminathan <prasanna@mediamath.com>
 Prashant Agrawal <prashant.a.vjti@gmail.com>
 Prashant Varanasi <prashant@prashantv.com>
diff --git a/misc/wasm/wasm_exec.js b/misc/wasm/wasm_exec.js
index a99aaed..8501ae7 100644
--- a/misc/wasm/wasm_exec.js
+++ b/misc/wasm/wasm_exec.js
@@ -175,37 +175,19 @@
 			const storeValue = (addr, v) => {
 				const nanHead = 0x7FF80000;
 
-				if (typeof v === "number") {
+				if (typeof v === "number" && v !== 0) {
 					if (isNaN(v)) {
 						this.mem.setUint32(addr + 4, nanHead, true);
 						this.mem.setUint32(addr, 0, true);
 						return;
 					}
-					if (v === 0) {
-						this.mem.setUint32(addr + 4, nanHead, true);
-						this.mem.setUint32(addr, 1, true);
-						return;
-					}
 					this.mem.setFloat64(addr, v, true);
 					return;
 				}
 
-				switch (v) {
-					case undefined:
-						this.mem.setFloat64(addr, 0, true);
-						return;
-					case null:
-						this.mem.setUint32(addr + 4, nanHead, true);
-						this.mem.setUint32(addr, 2, true);
-						return;
-					case true:
-						this.mem.setUint32(addr + 4, nanHead, true);
-						this.mem.setUint32(addr, 3, true);
-						return;
-					case false:
-						this.mem.setUint32(addr + 4, nanHead, true);
-						this.mem.setUint32(addr, 4, true);
-						return;
+				if (v === undefined) {
+					this.mem.setFloat64(addr, 0, true);
+					return;
 				}
 
 				let id = this._ids.get(v);
@@ -219,8 +201,13 @@
 					this._ids.set(v, id);
 				}
 				this._goRefCounts[id]++;
-				let typeFlag = 1;
+				let typeFlag = 0;
 				switch (typeof v) {
+					case "object":
+						if (v !== null) {
+							typeFlag = 1;
+						}
+						break;
 					case "string":
 						typeFlag = 2;
 						break;
@@ -493,10 +480,17 @@
 				global,
 				this,
 			];
-			this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
-			this._ids = new Map();  // mapping from JS values to reference ids
-			this._idPool = [];      // unused ids that have been garbage collected
-			this.exited = false;    // whether the Go program has exited
+			this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id
+			this._ids = new Map([ // mapping from JS values to reference ids
+				[0, 1],
+				[null, 2],
+				[true, 3],
+				[false, 4],
+				[global, 5],
+				[this, 6],
+			]);
+			this._idPool = [];   // unused ids that have been garbage collected
+			this.exited = false; // whether the Go program has exited
 
 			// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
 			let offset = 4096;
diff --git a/src/cmd/asm/internal/asm/testdata/arm64.s b/src/cmd/asm/internal/asm/testdata/arm64.s
index c0e2fb7..69267bf 100644
--- a/src/cmd/asm/internal/asm/testdata/arm64.s
+++ b/src/cmd/asm/internal/asm/testdata/arm64.s
@@ -274,6 +274,9 @@
 	ADDW	$0x60060, R2                        // ADDW	$393312, R2                     // 4280011142804111
 	CMPW	$0x60060, R2                        // CMPW	$393312, R2                     // 1b0c8052db00a0725f001b6b
 
+	// TODO: this could have better encoding
+	ANDW	$-1, R10 // 1b0080124a011b0a
+
 	AND	$8, R0, RSP // 1f007d92
 	ORR	$8, R0, RSP // 1f007db2
 	EOR	$8, R0, RSP // 1f007dd2
diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go
index 31fe46a..802aab2 100644
--- a/src/cmd/compile/internal/gc/noder.go
+++ b/src/cmd/compile/internal/gc/noder.go
@@ -44,7 +44,7 @@
 
 			f, err := os.Open(filename)
 			if err != nil {
-				p.error(syntax.Error{Pos: syntax.MakePos(base, 0, 0), Msg: err.Error()})
+				p.error(syntax.Error{Msg: err.Error()})
 				return
 			}
 			defer f.Close()
diff --git a/src/cmd/compile/internal/gc/subr.go b/src/cmd/compile/internal/gc/subr.go
index 2bbc5e4..9362c74 100644
--- a/src/cmd/compile/internal/gc/subr.go
+++ b/src/cmd/compile/internal/gc/subr.go
@@ -60,9 +60,15 @@
 }
 
 func adderr(pos src.XPos, format string, args ...interface{}) {
+	msg := fmt.Sprintf(format, args...)
+	// Only add the position if know the position.
+	// See issue golang.org/issue/11361.
+	if pos.IsKnown() {
+		msg = fmt.Sprintf("%v: %s", linestr(pos), msg)
+	}
 	errors = append(errors, Error{
 		pos: pos,
-		msg: fmt.Sprintf("%v: %s\n", linestr(pos), fmt.Sprintf(format, args...)),
+		msg: msg + "\n",
 	})
 }
 
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index 8132aee..dec4b96 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -2967,6 +2967,8 @@
 					if ci := lookdot1(nil, l.Sym, t, t.Fields(), 2); ci != nil { // Case-insensitive lookup.
 						if visible(ci.Sym) {
 							yyerror("unknown field '%v' in struct literal of type %v (but does have %v)", l.Sym, t, ci.Sym)
+						} else if nonexported(l.Sym) && l.Sym.Name == ci.Sym.Name { // Ensure exactness before the suggestion.
+							yyerror("cannot refer to unexported field '%v' in struct literal of type %v", l.Sym, t)
 						} else {
 							yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
 						}
@@ -3070,6 +3072,11 @@
 	return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == localpkg)
 }
 
+// nonexported reports whether sym is an unexported field.
+func nonexported(sym *types.Sym) bool {
+	return sym != nil && !types.IsExported(sym.Name)
+}
+
 // lvalue etc
 func islvalue(n *Node) bool {
 	switch n.Op {
diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go
index 15dfe6d..6bfd296 100644
--- a/src/cmd/compile/internal/ssa/cse.go
+++ b/src/cmd/compile/internal/ssa/cse.go
@@ -190,43 +190,6 @@
 		}
 	}
 
-	// if we rewrite a tuple generator to a new one in a different block,
-	// copy its selectors to the new generator's block, so tuple generator
-	// and selectors stay together.
-	// be careful not to copy same selectors more than once (issue 16741).
-	copiedSelects := make(map[ID][]*Value)
-	for _, b := range f.Blocks {
-	out:
-		for _, v := range b.Values {
-			// New values are created when selectors are copied to
-			// a new block. We can safely ignore those new values,
-			// since they have already been copied (issue 17918).
-			if int(v.ID) >= len(rewrite) || rewrite[v.ID] != nil {
-				continue
-			}
-			if v.Op != OpSelect0 && v.Op != OpSelect1 {
-				continue
-			}
-			if !v.Args[0].Type.IsTuple() {
-				f.Fatalf("arg of tuple selector %s is not a tuple: %s", v.String(), v.Args[0].LongString())
-			}
-			t := rewrite[v.Args[0].ID]
-			if t != nil && t.Block != b {
-				// v.Args[0] is tuple generator, CSE'd into a different block as t, v is left behind
-				for _, c := range copiedSelects[t.ID] {
-					if v.Op == c.Op {
-						// an equivalent selector is already copied
-						rewrite[v.ID] = c
-						continue out
-					}
-				}
-				c := v.copyInto(t.Block)
-				rewrite[v.ID] = c
-				copiedSelects[t.ID] = append(copiedSelects[t.ID], c)
-			}
-		}
-	}
-
 	rewrites := int64(0)
 
 	// Apply substitutions
@@ -259,6 +222,61 @@
 			}
 		}
 	}
+
+	// Fixup tuple selectors.
+	//
+	// If we have rewritten a tuple generator to a new one in a different
+	// block, copy its selectors to the new generator's block, so tuple
+	// generator and selectors stay together.
+	//
+	// Note: that there must be only one selector of each type per tuple
+	// generator. CSE may have left us with more than one so we de-duplicate
+	// them using a map. See issue 16741.
+	selectors := make(map[struct {
+		id ID
+		op Op
+	}]*Value)
+	for _, b := range f.Blocks {
+		for _, selector := range b.Values {
+			if selector.Op != OpSelect0 && selector.Op != OpSelect1 {
+				continue
+			}
+
+			// Get the tuple generator to use as a key for de-duplication.
+			tuple := selector.Args[0]
+			if !tuple.Type.IsTuple() {
+				f.Fatalf("arg of tuple selector %s is not a tuple: %s", selector.String(), tuple.LongString())
+			}
+
+			// If there is a pre-existing selector in the target block then
+			// use that. Do this even if the selector is already in the
+			// target block to avoid duplicate tuple selectors.
+			key := struct {
+				id ID
+				op Op
+			}{tuple.ID, selector.Op}
+			if t := selectors[key]; t != nil {
+				if selector != t {
+					selector.copyOf(t)
+				}
+				continue
+			}
+
+			// If the selector is in the wrong block copy it into the target
+			// block.
+			if selector.Block != tuple.Block {
+				t := selector.copyInto(tuple.Block)
+				selector.copyOf(t)
+				selectors[key] = t
+				continue
+			}
+
+			// The selector is in the target block. Add it to the map so it
+			// cannot be duplicated.
+			selectors[key] = selector
+		}
+	}
+
 	if f.pass.stats > 0 {
 		f.LogStat("CSE REWRITES", rewrites)
 	}
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64.rules b/src/cmd/compile/internal/ssa/gen/PPC64.rules
index 761ffa2..fd28e10 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64.rules
+++ b/src/cmd/compile/internal/ssa/gen/PPC64.rules
@@ -153,18 +153,18 @@
 (Rsh8x64   x (MOVDconst [c])) && uint64(c) < 8  => (SRAWconst (SignExt8to32  x) [c])
 (Rsh8Ux64  x (MOVDconst [c])) && uint64(c) < 8  => (SRWconst (ZeroExt8to32  x) [c])
 
-(Lsh64x32  x (MOVDconst [c])) && uint32(c) < 64 => (SLDconst x [c])
-(Rsh64x32  x (MOVDconst [c])) && uint32(c) < 64 => (SRADconst x [c])
-(Rsh64Ux32 x (MOVDconst [c])) && uint32(c) < 64 => (SRDconst x [c])
-(Lsh32x32  x (MOVDconst [c])) && uint32(c) < 32 => (SLWconst x [c])
-(Rsh32x32  x (MOVDconst [c])) && uint32(c) < 32 => (SRAWconst x [c])
-(Rsh32Ux32 x (MOVDconst [c])) && uint32(c) < 32 => (SRWconst x [c])
-(Lsh16x32  x (MOVDconst [c])) && uint32(c) < 16 => (SLWconst x [c])
-(Rsh16x32  x (MOVDconst [c])) && uint32(c) < 16 => (SRAWconst (SignExt16to32 x) [c])
-(Rsh16Ux32 x (MOVDconst [c])) && uint32(c) < 16 => (SRWconst (ZeroExt16to32 x) [c])
-(Lsh8x32   x (MOVDconst [c])) && uint32(c) < 8  => (SLWconst x [c])
-(Rsh8x32   x (MOVDconst [c])) && uint32(c) < 8  => (SRAWconst (SignExt8to32  x) [c])
-(Rsh8Ux32  x (MOVDconst [c])) && uint32(c) < 8  => (SRWconst (ZeroExt8to32  x) [c])
+(Lsh64x32  x (MOVDconst [c])) && uint32(c) < 64 => (SLDconst x [c&63])
+(Rsh64x32  x (MOVDconst [c])) && uint32(c) < 64 => (SRADconst x [c&63])
+(Rsh64Ux32 x (MOVDconst [c])) && uint32(c) < 64 => (SRDconst x [c&63])
+(Lsh32x32  x (MOVDconst [c])) && uint32(c) < 32 => (SLWconst x [c&31])
+(Rsh32x32  x (MOVDconst [c])) && uint32(c) < 32 => (SRAWconst x [c&31])
+(Rsh32Ux32 x (MOVDconst [c])) && uint32(c) < 32 => (SRWconst x [c&31])
+(Lsh16x32  x (MOVDconst [c])) && uint32(c) < 16 => (SLWconst x [c&31])
+(Rsh16x32  x (MOVDconst [c])) && uint32(c) < 16 => (SRAWconst (SignExt16to32 x) [c&15])
+(Rsh16Ux32 x (MOVDconst [c])) && uint32(c) < 16 => (SRWconst (ZeroExt16to32 x) [c&15])
+(Lsh8x32   x (MOVDconst [c])) && uint32(c) < 8  => (SLWconst x [c&7])
+(Rsh8x32   x (MOVDconst [c])) && uint32(c) < 8  => (SRAWconst (SignExt8to32  x) [c&7])
+(Rsh8Ux32  x (MOVDconst [c])) && uint32(c) < 8  => (SRWconst (ZeroExt8to32  x) [c&7])
 
 // Lower bounded shifts first. No need to check shift value.
 (Lsh64x(64|32|16|8)  x y) && shiftIsBounded(v) => (SLD x y)
@@ -285,7 +285,8 @@
 (MaskIfNotCarry (FlagCarrySet)) => (MOVDconst [0])
 (MaskIfNotCarry (FlagCarryClear)) => (MOVDconst [-1])
 
-(S(RAD|RAW|RD|RW|LD|LW) x (MOVDconst [c])) => (S(RAD|RAW|RD|RW|LD|LW)const [c] x)
+(S(RAD|RD|LD) x (MOVDconst [c])) => (S(RAD|RD|LD)const [c&63 | (c>>6&1*63)] x)
+(S(RAW|RW|LW) x (MOVDconst [c])) => (S(RAW|RW|LW)const [c&31 | (c>>5&1*31)] x)
 
 (Addr {sym} base) => (MOVDaddr {sym} [0] base)
 (LocalAddr {sym} base _) => (MOVDaddr {sym} base)
diff --git a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
index a665734..f8bc6cb 100644
--- a/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/PPC64Ops.go
@@ -194,12 +194,12 @@
 		{name: "FMSUB", argLength: 3, reg: fp31, asm: "FMSUB"},   // arg0*arg1 - arg2
 		{name: "FMSUBS", argLength: 3, reg: fp31, asm: "FMSUBS"}, // arg0*arg1 - arg2
 
-		{name: "SRAD", argLength: 2, reg: gp21, asm: "SRAD"}, // arg0 >>a arg1, 64 bits (all sign if arg1 & 64 != 0)
-		{name: "SRAW", argLength: 2, reg: gp21, asm: "SRAW"}, // arg0 >>a arg1, 32 bits (all sign if arg1 & 32 != 0)
-		{name: "SRD", argLength: 2, reg: gp21, asm: "SRD"},   // arg0 >> arg1, 64 bits  (0 if arg1 & 64 != 0)
-		{name: "SRW", argLength: 2, reg: gp21, asm: "SRW"},   // arg0 >> arg1, 32 bits  (0 if arg1 & 32 != 0)
-		{name: "SLD", argLength: 2, reg: gp21, asm: "SLD"},   // arg0 << arg1, 64 bits  (0 if arg1 & 64 != 0)
-		{name: "SLW", argLength: 2, reg: gp21, asm: "SLW"},   // arg0 << arg1, 32 bits  (0 if arg1 & 32 != 0)
+		{name: "SRAD", argLength: 2, reg: gp21, asm: "SRAD"}, // signed arg0 >> (arg1&127), 64 bit width (note: 127, not 63!)
+		{name: "SRAW", argLength: 2, reg: gp21, asm: "SRAW"}, // signed arg0 >> (arg1&63), 32 bit width
+		{name: "SRD", argLength: 2, reg: gp21, asm: "SRD"},   // unsigned arg0 >> (arg1&127), 64 bit width
+		{name: "SRW", argLength: 2, reg: gp21, asm: "SRW"},   // unsigned arg0 >> (arg1&63), 32 bit width
+		{name: "SLD", argLength: 2, reg: gp21, asm: "SLD"},   // arg0 << (arg1&127), 64 bit width
+		{name: "SLW", argLength: 2, reg: gp21, asm: "SLW"},   // arg0 << (arg1&63), 32 bit width
 
 		{name: "ROTL", argLength: 2, reg: gp21, asm: "ROTL"},   // arg0 rotate left by arg1 mod 64
 		{name: "ROTLW", argLength: 2, reg: gp21, asm: "ROTLW"}, // uint32(arg0) rotate left by arg1 mod 32
@@ -208,12 +208,12 @@
 		{name: "ADDconstForCarry", argLength: 1, reg: regInfo{inputs: []regMask{gp | sp | sb}, clobbers: tmp}, aux: "Int16", asm: "ADDC", typ: "Flags"}, // _, carry := arg0 + auxint
 		{name: "MaskIfNotCarry", argLength: 1, reg: crgp, asm: "ADDME", typ: "Int64"},                                                                   // carry - 1 (if carry then 0 else -1)
 
-		{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int64"}, // arg0 >>a aux, 64 bits
-		{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int64"}, // arg0 >>a aux, 32 bits
-		{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int64"},   // arg0 >> aux, 64 bits
-		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int64"},   // arg0 >> aux, 32 bits
-		{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int64"},   // arg0 << aux, 64 bits
-		{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int64"},   // arg0 << aux, 32 bits
+		{name: "SRADconst", argLength: 1, reg: gp11, asm: "SRAD", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
+		{name: "SRAWconst", argLength: 1, reg: gp11, asm: "SRAW", aux: "Int64"}, // signed arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
+		{name: "SRDconst", argLength: 1, reg: gp11, asm: "SRD", aux: "Int64"},   // unsigned arg0 >> auxInt, 0 <= auxInt < 64, 64 bit width
+		{name: "SRWconst", argLength: 1, reg: gp11, asm: "SRW", aux: "Int64"},   // unsigned arg0 >> auxInt, 0 <= auxInt < 32, 32 bit width
+		{name: "SLDconst", argLength: 1, reg: gp11, asm: "SLD", aux: "Int64"},   // arg0 << auxInt, 0 <= auxInt < 64, 64 bit width
+		{name: "SLWconst", argLength: 1, reg: gp11, asm: "SLW", aux: "Int64"},   // arg0 << auxInt, 0 <= auxInt < 32, 32 bit width
 
 		{name: "ROTLconst", argLength: 1, reg: gp11, asm: "ROTL", aux: "Int64"},   // arg0 rotate left by auxInt bits
 		{name: "ROTLWconst", argLength: 1, reg: gp11, asm: "ROTLW", aux: "Int64"}, // uint32(arg0) rotate left by auxInt bits
diff --git a/src/cmd/compile/internal/ssa/gen/RISCV64.rules b/src/cmd/compile/internal/ssa/gen/RISCV64.rules
index fbd8736..9437c8e 100644
--- a/src/cmd/compile/internal/ssa/gen/RISCV64.rules
+++ b/src/cmd/compile/internal/ssa/gen/RISCV64.rules
@@ -445,16 +445,6 @@
 (Addr {sym} base) => (MOVaddr {sym} [0] base)
 (LocalAddr {sym} base _) => (MOVaddr {sym} base)
 
-// Conditional branches
-//
-// cond is 1 if true.
-//
-// TODO(prattmic): RISCV branch instructions take two operands to compare,
-// so we could generate more efficient code by computing the condition in the
-// branch itself. This should be revisited now that the compiler has support
-// for two control values (https://golang.org/cl/196557).
-(If cond yes no) => (BNEZ cond yes no)
-
 // Calls
 (StaticCall  ...) => (CALLstatic  ...)
 (ClosureCall ...) => (CALLclosure ...)
@@ -480,11 +470,31 @@
 (AtomicExchange32 ...) => (LoweredAtomicExchange32 ...)
 (AtomicExchange64 ...) => (LoweredAtomicExchange64 ...)
 
+// Conditional branches
+(If cond yes no) => (BNEZ cond yes no)
+
 // Optimizations
 
-// Absorb SNEZ into branch.
+// Absorb SEQZ/SNEZ into branch.
+(BEQZ (SEQZ x) yes no) => (BNEZ x yes no)
+(BEQZ (SNEZ x) yes no) => (BEQZ x yes no)
+(BNEZ (SEQZ x) yes no) => (BEQZ x yes no)
 (BNEZ (SNEZ x) yes no) => (BNEZ x yes no)
 
+// Convert BEQZ/BNEZ into more optimal branch conditions.
+(BEQZ (SUB x y) yes no) => (BEQ x y yes no)
+(BNEZ (SUB x y) yes no) => (BNE x y yes no)
+(BEQZ (SLT x y) yes no) => (BGE x y yes no)
+(BNEZ (SLT x y) yes no) => (BLT x y yes no)
+(BEQZ (SLTU x y) yes no) => (BGEU x y yes no)
+(BNEZ (SLTU x y) yes no) => (BLTU x y yes no)
+
+// Convert branch with zero to BEQZ/BNEZ.
+(BEQ (MOVDconst [0]) cond yes no) => (BEQZ cond yes no)
+(BEQ cond (MOVDconst [0]) yes no) => (BEQZ cond yes no)
+(BNE (MOVDconst [0]) cond yes no) => (BNEZ cond yes no)
+(BNE cond (MOVDconst [0]) yes no) => (BNEZ cond yes no)
+
 // Store zero
 (MOVBstore [off] {sym} ptr (MOVBconst [0]) mem) => (MOVBstorezero [off] {sym} ptr mem)
 (MOVHstore [off] {sym} ptr (MOVHconst [0]) mem) => (MOVHstorezero [off] {sym} ptr mem)
diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go
index 12c2580..a8e43d0 100644
--- a/src/cmd/compile/internal/ssa/prove.go
+++ b/src/cmd/compile/internal/ssa/prove.go
@@ -1189,15 +1189,38 @@
 				}
 				v.Op = ctzNonZeroOp[v.Op]
 			}
-
+		case OpRsh8x8, OpRsh8x16, OpRsh8x32, OpRsh8x64,
+			OpRsh16x8, OpRsh16x16, OpRsh16x32, OpRsh16x64,
+			OpRsh32x8, OpRsh32x16, OpRsh32x32, OpRsh32x64,
+			OpRsh64x8, OpRsh64x16, OpRsh64x32, OpRsh64x64:
+			// Check whether, for a >> b, we know that a is non-negative
+			// and b is all of a's bits except the MSB. If so, a is shifted to zero.
+			bits := 8 * v.Type.Size()
+			if v.Args[1].isGenericIntConst() && v.Args[1].AuxInt >= bits-1 && ft.isNonNegative(v.Args[0]) {
+				if b.Func.pass.debug > 0 {
+					b.Func.Warnl(v.Pos, "Proved %v shifts to zero", v.Op)
+				}
+				switch bits {
+				case 64:
+					v.reset(OpConst64)
+				case 32:
+					v.reset(OpConst32)
+				case 16:
+					v.reset(OpConst16)
+				case 8:
+					v.reset(OpConst8)
+				default:
+					panic("unexpected integer size")
+				}
+				v.AuxInt = 0
+				continue // Be sure not to fallthrough - this is no longer OpRsh.
+			}
+			// If the Rsh hasn't been replaced with 0, still check if it is bounded.
+			fallthrough
 		case OpLsh8x8, OpLsh8x16, OpLsh8x32, OpLsh8x64,
 			OpLsh16x8, OpLsh16x16, OpLsh16x32, OpLsh16x64,
 			OpLsh32x8, OpLsh32x16, OpLsh32x32, OpLsh32x64,
 			OpLsh64x8, OpLsh64x16, OpLsh64x32, OpLsh64x64,
-			OpRsh8x8, OpRsh8x16, OpRsh8x32, OpRsh8x64,
-			OpRsh16x8, OpRsh16x16, OpRsh16x32, OpRsh16x64,
-			OpRsh32x8, OpRsh32x16, OpRsh32x32, OpRsh32x64,
-			OpRsh64x8, OpRsh64x16, OpRsh64x32, OpRsh64x64,
 			OpRsh8Ux8, OpRsh8Ux16, OpRsh8Ux32, OpRsh8Ux64,
 			OpRsh16Ux8, OpRsh16Ux16, OpRsh16Ux32, OpRsh16Ux64,
 			OpRsh32Ux8, OpRsh32Ux16, OpRsh32Ux32, OpRsh32Ux64,
diff --git a/src/cmd/compile/internal/ssa/rewritePPC64.go b/src/cmd/compile/internal/ssa/rewritePPC64.go
index 6a2c164..37b75cc 100644
--- a/src/cmd/compile/internal/ssa/rewritePPC64.go
+++ b/src/cmd/compile/internal/ssa/rewritePPC64.go
@@ -2351,7 +2351,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Lsh16x32 x (MOVDconst [c]))
 	// cond: uint32(c) < 16
-	// result: (SLWconst x [c])
+	// result: (SLWconst x [c&31])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -2362,7 +2362,7 @@
 			break
 		}
 		v.reset(OpPPC64SLWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 31)
 		v.AddArg(x)
 		return true
 	}
@@ -2552,7 +2552,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Lsh32x32 x (MOVDconst [c]))
 	// cond: uint32(c) < 32
-	// result: (SLWconst x [c])
+	// result: (SLWconst x [c&31])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -2563,7 +2563,7 @@
 			break
 		}
 		v.reset(OpPPC64SLWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 31)
 		v.AddArg(x)
 		return true
 	}
@@ -2792,7 +2792,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Lsh64x32 x (MOVDconst [c]))
 	// cond: uint32(c) < 64
-	// result: (SLDconst x [c])
+	// result: (SLDconst x [c&63])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -2803,7 +2803,7 @@
 			break
 		}
 		v.reset(OpPPC64SLDconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 63)
 		v.AddArg(x)
 		return true
 	}
@@ -3032,7 +3032,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Lsh8x32 x (MOVDconst [c]))
 	// cond: uint32(c) < 8
-	// result: (SLWconst x [c])
+	// result: (SLWconst x [c&7])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -3043,7 +3043,7 @@
 			break
 		}
 		v.reset(OpPPC64SLWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 7)
 		v.AddArg(x)
 		return true
 	}
@@ -12046,7 +12046,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (SLD x (MOVDconst [c]))
-	// result: (SLDconst [c] x)
+	// result: (SLDconst [c&63 | (c>>6&1*63)] x)
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -12054,7 +12054,7 @@
 		}
 		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpPPC64SLDconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c&63 | (c >> 6 & 1 * 63))
 		v.AddArg(x)
 		return true
 	}
@@ -12064,7 +12064,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (SLW x (MOVDconst [c]))
-	// result: (SLWconst [c] x)
+	// result: (SLWconst [c&31 | (c>>5&1*31)] x)
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -12072,7 +12072,7 @@
 		}
 		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpPPC64SLWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c&31 | (c >> 5 & 1 * 31))
 		v.AddArg(x)
 		return true
 	}
@@ -12082,7 +12082,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (SRAD x (MOVDconst [c]))
-	// result: (SRADconst [c] x)
+	// result: (SRADconst [c&63 | (c>>6&1*63)] x)
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -12090,7 +12090,7 @@
 		}
 		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpPPC64SRADconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c&63 | (c >> 6 & 1 * 63))
 		v.AddArg(x)
 		return true
 	}
@@ -12100,7 +12100,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (SRAW x (MOVDconst [c]))
-	// result: (SRAWconst [c] x)
+	// result: (SRAWconst [c&31 | (c>>5&1*31)] x)
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -12108,7 +12108,7 @@
 		}
 		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpPPC64SRAWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c&31 | (c >> 5 & 1 * 31))
 		v.AddArg(x)
 		return true
 	}
@@ -12118,7 +12118,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (SRD x (MOVDconst [c]))
-	// result: (SRDconst [c] x)
+	// result: (SRDconst [c&63 | (c>>6&1*63)] x)
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -12126,7 +12126,7 @@
 		}
 		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpPPC64SRDconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c&63 | (c >> 6 & 1 * 63))
 		v.AddArg(x)
 		return true
 	}
@@ -12136,7 +12136,7 @@
 	v_1 := v.Args[1]
 	v_0 := v.Args[0]
 	// match: (SRW x (MOVDconst [c]))
-	// result: (SRWconst [c] x)
+	// result: (SRWconst [c&31 | (c>>5&1*31)] x)
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -12144,7 +12144,7 @@
 		}
 		c := auxIntToInt64(v_1.AuxInt)
 		v.reset(OpPPC64SRWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c&31 | (c >> 5 & 1 * 31))
 		v.AddArg(x)
 		return true
 	}
@@ -12630,7 +12630,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Rsh16Ux32 x (MOVDconst [c]))
 	// cond: uint32(c) < 16
-	// result: (SRWconst (ZeroExt16to32 x) [c])
+	// result: (SRWconst (ZeroExt16to32 x) [c&15])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -12641,7 +12641,7 @@
 			break
 		}
 		v.reset(OpPPC64SRWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 15)
 		v0 := b.NewValue0(v.Pos, OpZeroExt16to32, typ.UInt32)
 		v0.AddArg(x)
 		v.AddArg(v0)
@@ -12851,7 +12851,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Rsh16x32 x (MOVDconst [c]))
 	// cond: uint32(c) < 16
-	// result: (SRAWconst (SignExt16to32 x) [c])
+	// result: (SRAWconst (SignExt16to32 x) [c&15])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -12862,7 +12862,7 @@
 			break
 		}
 		v.reset(OpPPC64SRAWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 15)
 		v0 := b.NewValue0(v.Pos, OpSignExt16to32, typ.Int32)
 		v0.AddArg(x)
 		v.AddArg(v0)
@@ -13072,7 +13072,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Rsh32Ux32 x (MOVDconst [c]))
 	// cond: uint32(c) < 32
-	// result: (SRWconst x [c])
+	// result: (SRWconst x [c&31])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -13083,7 +13083,7 @@
 			break
 		}
 		v.reset(OpPPC64SRWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 31)
 		v.AddArg(x)
 		return true
 	}
@@ -13377,7 +13377,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Rsh32x32 x (MOVDconst [c]))
 	// cond: uint32(c) < 32
-	// result: (SRAWconst x [c])
+	// result: (SRAWconst x [c&31])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -13388,7 +13388,7 @@
 			break
 		}
 		v.reset(OpPPC64SRAWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 31)
 		v.AddArg(x)
 		return true
 	}
@@ -13684,7 +13684,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Rsh64Ux32 x (MOVDconst [c]))
 	// cond: uint32(c) < 64
-	// result: (SRDconst x [c])
+	// result: (SRDconst x [c&63])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -13695,7 +13695,7 @@
 			break
 		}
 		v.reset(OpPPC64SRDconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 63)
 		v.AddArg(x)
 		return true
 	}
@@ -13989,7 +13989,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Rsh64x32 x (MOVDconst [c]))
 	// cond: uint32(c) < 64
-	// result: (SRADconst x [c])
+	// result: (SRADconst x [c&63])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -14000,7 +14000,7 @@
 			break
 		}
 		v.reset(OpPPC64SRADconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 63)
 		v.AddArg(x)
 		return true
 	}
@@ -14300,7 +14300,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Rsh8Ux32 x (MOVDconst [c]))
 	// cond: uint32(c) < 8
-	// result: (SRWconst (ZeroExt8to32 x) [c])
+	// result: (SRWconst (ZeroExt8to32 x) [c&7])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -14311,7 +14311,7 @@
 			break
 		}
 		v.reset(OpPPC64SRWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 7)
 		v0 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
 		v0.AddArg(x)
 		v.AddArg(v0)
@@ -14521,7 +14521,7 @@
 	typ := &b.Func.Config.Types
 	// match: (Rsh8x32 x (MOVDconst [c]))
 	// cond: uint32(c) < 8
-	// result: (SRAWconst (SignExt8to32 x) [c])
+	// result: (SRAWconst (SignExt8to32 x) [c&7])
 	for {
 		x := v_0
 		if v_1.Op != OpPPC64MOVDconst {
@@ -14532,7 +14532,7 @@
 			break
 		}
 		v.reset(OpPPC64SRAWconst)
-		v.AuxInt = int64ToAuxInt(c)
+		v.AuxInt = int64ToAuxInt(c & 7)
 		v0 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
 		v0.AddArg(x)
 		v.AddArg(v0)
diff --git a/src/cmd/compile/internal/ssa/rewriteRISCV64.go b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
index 6b91c08..c178290 100644
--- a/src/cmd/compile/internal/ssa/rewriteRISCV64.go
+++ b/src/cmd/compile/internal/ssa/rewriteRISCV64.go
@@ -5120,7 +5120,105 @@
 }
 func rewriteBlockRISCV64(b *Block) bool {
 	switch b.Kind {
+	case BlockRISCV64BEQ:
+		// match: (BEQ (MOVDconst [0]) cond yes no)
+		// result: (BEQZ cond yes no)
+		for b.Controls[0].Op == OpRISCV64MOVDconst {
+			v_0 := b.Controls[0]
+			if auxIntToInt64(v_0.AuxInt) != 0 {
+				break
+			}
+			cond := b.Controls[1]
+			b.resetWithControl(BlockRISCV64BEQZ, cond)
+			return true
+		}
+		// match: (BEQ cond (MOVDconst [0]) yes no)
+		// result: (BEQZ cond yes no)
+		for b.Controls[1].Op == OpRISCV64MOVDconst {
+			cond := b.Controls[0]
+			v_1 := b.Controls[1]
+			if auxIntToInt64(v_1.AuxInt) != 0 {
+				break
+			}
+			b.resetWithControl(BlockRISCV64BEQZ, cond)
+			return true
+		}
+	case BlockRISCV64BEQZ:
+		// match: (BEQZ (SEQZ x) yes no)
+		// result: (BNEZ x yes no)
+		for b.Controls[0].Op == OpRISCV64SEQZ {
+			v_0 := b.Controls[0]
+			x := v_0.Args[0]
+			b.resetWithControl(BlockRISCV64BNEZ, x)
+			return true
+		}
+		// match: (BEQZ (SNEZ x) yes no)
+		// result: (BEQZ x yes no)
+		for b.Controls[0].Op == OpRISCV64SNEZ {
+			v_0 := b.Controls[0]
+			x := v_0.Args[0]
+			b.resetWithControl(BlockRISCV64BEQZ, x)
+			return true
+		}
+		// match: (BEQZ (SUB x y) yes no)
+		// result: (BEQ x y yes no)
+		for b.Controls[0].Op == OpRISCV64SUB {
+			v_0 := b.Controls[0]
+			y := v_0.Args[1]
+			x := v_0.Args[0]
+			b.resetWithControl2(BlockRISCV64BEQ, x, y)
+			return true
+		}
+		// match: (BEQZ (SLT x y) yes no)
+		// result: (BGE x y yes no)
+		for b.Controls[0].Op == OpRISCV64SLT {
+			v_0 := b.Controls[0]
+			y := v_0.Args[1]
+			x := v_0.Args[0]
+			b.resetWithControl2(BlockRISCV64BGE, x, y)
+			return true
+		}
+		// match: (BEQZ (SLTU x y) yes no)
+		// result: (BGEU x y yes no)
+		for b.Controls[0].Op == OpRISCV64SLTU {
+			v_0 := b.Controls[0]
+			y := v_0.Args[1]
+			x := v_0.Args[0]
+			b.resetWithControl2(BlockRISCV64BGEU, x, y)
+			return true
+		}
+	case BlockRISCV64BNE:
+		// match: (BNE (MOVDconst [0]) cond yes no)
+		// result: (BNEZ cond yes no)
+		for b.Controls[0].Op == OpRISCV64MOVDconst {
+			v_0 := b.Controls[0]
+			if auxIntToInt64(v_0.AuxInt) != 0 {
+				break
+			}
+			cond := b.Controls[1]
+			b.resetWithControl(BlockRISCV64BNEZ, cond)
+			return true
+		}
+		// match: (BNE cond (MOVDconst [0]) yes no)
+		// result: (BNEZ cond yes no)
+		for b.Controls[1].Op == OpRISCV64MOVDconst {
+			cond := b.Controls[0]
+			v_1 := b.Controls[1]
+			if auxIntToInt64(v_1.AuxInt) != 0 {
+				break
+			}
+			b.resetWithControl(BlockRISCV64BNEZ, cond)
+			return true
+		}
 	case BlockRISCV64BNEZ:
+		// match: (BNEZ (SEQZ x) yes no)
+		// result: (BEQZ x yes no)
+		for b.Controls[0].Op == OpRISCV64SEQZ {
+			v_0 := b.Controls[0]
+			x := v_0.Args[0]
+			b.resetWithControl(BlockRISCV64BEQZ, x)
+			return true
+		}
 		// match: (BNEZ (SNEZ x) yes no)
 		// result: (BNEZ x yes no)
 		for b.Controls[0].Op == OpRISCV64SNEZ {
@@ -5129,6 +5227,33 @@
 			b.resetWithControl(BlockRISCV64BNEZ, x)
 			return true
 		}
+		// match: (BNEZ (SUB x y) yes no)
+		// result: (BNE x y yes no)
+		for b.Controls[0].Op == OpRISCV64SUB {
+			v_0 := b.Controls[0]
+			y := v_0.Args[1]
+			x := v_0.Args[0]
+			b.resetWithControl2(BlockRISCV64BNE, x, y)
+			return true
+		}
+		// match: (BNEZ (SLT x y) yes no)
+		// result: (BLT x y yes no)
+		for b.Controls[0].Op == OpRISCV64SLT {
+			v_0 := b.Controls[0]
+			y := v_0.Args[1]
+			x := v_0.Args[0]
+			b.resetWithControl2(BlockRISCV64BLT, x, y)
+			return true
+		}
+		// match: (BNEZ (SLTU x y) yes no)
+		// result: (BLTU x y yes no)
+		for b.Controls[0].Op == OpRISCV64SLTU {
+			v_0 := b.Controls[0]
+			y := v_0.Args[1]
+			x := v_0.Args[0]
+			b.resetWithControl2(BlockRISCV64BLTU, x, y)
+			return true
+		}
 	case BlockIf:
 		// match: (If cond yes no)
 		// result: (BNEZ cond yes no)
diff --git a/src/cmd/go.mod b/src/cmd/go.mod
index 1302449..9c78cd1 100644
--- a/src/cmd/go.mod
+++ b/src/cmd/go.mod
@@ -5,7 +5,7 @@
 require (
 	github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3
 	github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 // indirect
-	golang.org/x/arch v0.0.0-20200312215426-ff8b605520f4
+	golang.org/x/arch v0.0.0-20200511175325-f7c78586839d
 	golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79
 	golang.org/x/mod v0.2.1-0.20200429172858-859b3ef565e2
 	golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 // indirect
diff --git a/src/cmd/go.sum b/src/cmd/go.sum
index e66011d..f1b3754 100644
--- a/src/cmd/go.sum
+++ b/src/cmd/go.sum
@@ -7,8 +7,8 @@
 github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340 h1:S1+yTUaFPXuDZnPDbO+TrDFIjPzQraYH8/CwSlu9Fac=
 github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-golang.org/x/arch v0.0.0-20200312215426-ff8b605520f4 h1:cZG+Ns0n5bdEEsURGnDinFswSebRNMqspbLvxrLZoIc=
-golang.org/x/arch v0.0.0-20200312215426-ff8b605520f4/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
+golang.org/x/arch v0.0.0-20200511175325-f7c78586839d h1:YvwchuJby5xEAPdBGmdAVSiVME50C+RJfJJwJJsGEV8=
+golang.org/x/arch v0.0.0-20200511175325-f7c78586839d/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 81b4687..5c1f725 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -1313,10 +1313,10 @@
 // and its test source files to identify significant problems. If go vet
 // finds any problems, go test reports those and does not run the test
 // binary. Only a high-confidence subset of the default go vet checks are
-// used. That subset is: 'atomic', 'bool', 'buildtags', 'nilfunc', and
-// 'printf'. You can see the documentation for these and other vet tests
-// via "go doc cmd/vet". To disable the running of go vet, use the
-// -vet=off flag.
+// used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas',
+// 'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see
+// the documentation for these and other vet tests via "go doc cmd/vet".
+// To disable the running of go vet, use the -vet=off flag.
 //
 // All test output and summary lines are printed to the go command's
 // standard output, even if the test printed them to its own standard
diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index d7f6b47..4c30de4 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -6,7 +6,6 @@
 
 import (
 	"bytes"
-	"context"
 	"debug/elf"
 	"debug/macho"
 	"debug/pe"
@@ -114,12 +113,6 @@
 var testTmpDir string
 var testBin string
 
-// testCtx is canceled when the test binary is about to time out.
-//
-// If https://golang.org/issue/28135 is accepted, uses of this variable in test
-// functions should be replaced by t.Context().
-var testCtx = context.Background()
-
 // The TestMain function creates a go command for testing purposes and
 // deletes it after the tests have been run.
 func TestMain(m *testing.M) {
@@ -135,19 +128,6 @@
 
 	flag.Parse()
 
-	timeoutFlag := flag.Lookup("test.timeout")
-	if timeoutFlag != nil {
-		// TODO(golang.org/issue/28147): The go command does not pass the
-		// test.timeout flag unless either -timeout or -test.timeout is explicitly
-		// set on the command line.
-		if d := timeoutFlag.Value.(flag.Getter).Get().(time.Duration); d != 0 {
-			aBitShorter := d * 95 / 100
-			var cancel context.CancelFunc
-			testCtx, cancel = context.WithTimeout(testCtx, aBitShorter)
-			defer cancel()
-		}
-	}
-
 	if *proxyAddr != "" {
 		StartProxy()
 		select {}
@@ -829,10 +809,9 @@
 	// module cache has 0444 directories;
 	// make them writable in order to remove content.
 	filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
-		if err != nil {
-			return nil // ignore errors walking in file system
-		}
-		if info.IsDir() {
+		// chmod not only directories, but also things that we couldn't even stat
+		// due to permission errors: they may also be unreadable directories.
+		if err != nil || info.IsDir() {
 			os.Chmod(path, 0777)
 		}
 		return nil
diff --git a/src/cmd/go/internal/modget/get.go b/src/cmd/go/internal/modget/get.go
index 8d74047..4c69824 100644
--- a/src/cmd/go/internal/modget/get.go
+++ b/src/cmd/go/internal/modget/get.go
@@ -350,11 +350,15 @@
 			// package in the main module. If the path contains wildcards but
 			// matches no packages, we'll warn after package loading.
 			if !strings.Contains(path, "...") {
-				var pkgs []string
+				m := search.NewMatch(path)
 				if pkgPath := modload.DirImportPath(path); pkgPath != "." {
-					pkgs = modload.TargetPackages(pkgPath)
+					m = modload.TargetPackages(pkgPath)
 				}
-				if len(pkgs) == 0 {
+				if len(m.Pkgs) == 0 {
+					for _, err := range m.Errs {
+						base.Errorf("go get %s: %v", arg, err)
+					}
+
 					abs, err := filepath.Abs(path)
 					if err != nil {
 						abs = path
@@ -394,7 +398,7 @@
 		default:
 			// The argument is a package or module path.
 			if modload.HasModRoot() {
-				if pkgs := modload.TargetPackages(path); len(pkgs) != 0 {
+				if m := modload.TargetPackages(path); len(m.Pkgs) != 0 {
 					// The path is in the main module. Nothing to query.
 					if vers != "upgrade" && vers != "patch" {
 						base.Errorf("go get %s: can't request explicit version of path in main module", arg)
diff --git a/src/cmd/go/internal/modload/import.go b/src/cmd/go/internal/modload/import.go
index 162c29d..4d2bc80 100644
--- a/src/cmd/go/internal/modload/import.go
+++ b/src/cmd/go/internal/modload/import.go
@@ -126,7 +126,9 @@
 	pathIsStd := search.IsStandardImportPath(path)
 	if pathIsStd && goroot.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, path) {
 		if targetInGorootSrc {
-			if dir, ok := dirInModule(path, targetPrefix, ModRoot(), true); ok {
+			if dir, ok, err := dirInModule(path, targetPrefix, ModRoot(), true); err != nil {
+				return module.Version{}, dir, err
+			} else if ok {
 				return Target, dir, nil
 			}
 		}
@@ -137,8 +139,8 @@
 	// -mod=vendor is special.
 	// Everything must be in the main module or the main module's vendor directory.
 	if cfg.BuildMod == "vendor" {
-		mainDir, mainOK := dirInModule(path, targetPrefix, ModRoot(), true)
-		vendorDir, vendorOK := dirInModule(path, "", filepath.Join(ModRoot(), "vendor"), false)
+		mainDir, mainOK, mainErr := dirInModule(path, targetPrefix, ModRoot(), true)
+		vendorDir, vendorOK, _ := dirInModule(path, "", filepath.Join(ModRoot(), "vendor"), false)
 		if mainOK && vendorOK {
 			return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: []string{mainDir, vendorDir}}
 		}
@@ -148,6 +150,9 @@
 		if !vendorOK && mainDir != "" {
 			return Target, mainDir, nil
 		}
+		if mainErr != nil {
+			return module.Version{}, "", mainErr
+		}
 		readVendorList()
 		return vendorPkgModule[path], vendorDir, nil
 	}
@@ -170,8 +175,9 @@
 			// not ambiguous.
 			return module.Version{}, "", err
 		}
-		dir, ok := dirInModule(path, m.Path, root, isLocal)
-		if ok {
+		if dir, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil {
+			return module.Version{}, "", err
+		} else if ok {
 			mods = append(mods, m)
 			dirs = append(dirs, dir)
 		}
@@ -247,8 +253,9 @@
 				// Report fetch error as above.
 				return module.Version{}, "", err
 			}
-			_, ok := dirInModule(path, m.Path, root, isLocal)
-			if ok {
+			if _, ok, err := dirInModule(path, m.Path, root, isLocal); err != nil {
+				return m, "", err
+			} else if ok {
 				return m, "", &ImportMissingError{Path: path, Module: m}
 			}
 		}
@@ -319,19 +326,29 @@
 		len(path) > len(mpath) && path[len(mpath)] == '/' && path[:len(mpath)] == mpath
 }
 
-var haveGoModCache, haveGoFilesCache par.Cache
+var (
+	haveGoModCache   par.Cache // dir → bool
+	haveGoFilesCache par.Cache // dir → goFilesEntry
+)
+
+type goFilesEntry struct {
+	haveGoFiles bool
+	err         error
+}
 
 // dirInModule locates the directory that would hold the package named by the given path,
 // if it were in the module with module path mpath and root mdir.
 // If path is syntactically not within mpath,
 // or if mdir is a local file tree (isLocal == true) and the directory
 // that would hold path is in a sub-module (covered by a go.mod below mdir),
-// dirInModule returns "", false.
+// dirInModule returns "", false, nil.
 //
 // Otherwise, dirInModule returns the name of the directory where
 // Go source files would be expected, along with a boolean indicating
 // whether there are in fact Go source files in that directory.
-func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFiles bool) {
+// A non-nil error indicates that the existence of the directory and/or
+// source files could not be determined, for example due to a permission error.
+func dirInModule(path, mpath, mdir string, isLocal bool) (dir string, haveGoFiles bool, err error) {
 	// Determine where to expect the package.
 	if path == mpath {
 		dir = mdir
@@ -340,7 +357,7 @@
 	} else if len(path) > len(mpath) && path[len(mpath)] == '/' && path[:len(mpath)] == mpath {
 		dir = filepath.Join(mdir, path[len(mpath)+1:])
 	} else {
-		return "", false
+		return "", false, nil
 	}
 
 	// Check that there aren't other modules in the way.
@@ -357,7 +374,7 @@
 			}).(bool)
 
 			if haveGoMod {
-				return "", false
+				return "", false, nil
 			}
 			parent := filepath.Dir(d)
 			if parent == d {
@@ -374,23 +391,58 @@
 	// Are there Go source files in the directory?
 	// We don't care about build tags, not even "+build ignore".
 	// We're just looking for a plausible directory.
-	haveGoFiles = haveGoFilesCache.Do(dir, func() interface{} {
-		f, err := os.Open(dir)
-		if err != nil {
-			return false
+	res := haveGoFilesCache.Do(dir, func() interface{} {
+		ok, err := isDirWithGoFiles(dir)
+		return goFilesEntry{haveGoFiles: ok, err: err}
+	}).(goFilesEntry)
+
+	return dir, res.haveGoFiles, res.err
+}
+
+func isDirWithGoFiles(dir string) (bool, error) {
+	f, err := os.Open(dir)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return false, nil
 		}
-		defer f.Close()
-		names, _ := f.Readdirnames(-1)
-		for _, name := range names {
-			if strings.HasSuffix(name, ".go") {
-				info, err := os.Stat(filepath.Join(dir, name))
-				if err == nil && info.Mode().IsRegular() {
-					return true
+		return false, err
+	}
+	defer f.Close()
+
+	names, firstErr := f.Readdirnames(-1)
+	if firstErr != nil {
+		if fi, err := f.Stat(); err == nil && !fi.IsDir() {
+			return false, nil
+		}
+
+		// Rewrite the error from ReadDirNames to include the path if not present.
+		// See https://golang.org/issue/38923.
+		var pe *os.PathError
+		if !errors.As(firstErr, &pe) {
+			firstErr = &os.PathError{Op: "readdir", Path: dir, Err: firstErr}
+		}
+	}
+
+	for _, name := range names {
+		if strings.HasSuffix(name, ".go") {
+			info, err := os.Stat(filepath.Join(dir, name))
+			if err == nil && info.Mode().IsRegular() {
+				// If any .go source file exists, the package exists regardless of
+				// errors for other source files. Leave further error reporting for
+				// later.
+				return true, nil
+			}
+			if firstErr == nil {
+				if os.IsNotExist(err) {
+					// If the file was concurrently deleted, or was a broken symlink,
+					// convert the error to an opaque error instead of one matching
+					// os.IsNotExist.
+					err = errors.New(err.Error())
 				}
+				firstErr = err
 			}
 		}
-		return false
-	}).(bool)
+	}
 
-	return dir, haveGoFiles
+	return false, firstErr
 }
diff --git a/src/cmd/go/internal/modload/load.go b/src/cmd/go/internal/modload/load.go
index 8a02c75..30992e0 100644
--- a/src/cmd/go/internal/modload/load.go
+++ b/src/cmd/go/internal/modload/load.go
@@ -99,14 +99,16 @@
 				m.Pkgs = []string{m.Pattern()}
 
 			case strings.Contains(m.Pattern(), "..."):
-				m.Pkgs = matchPackages(m.Pattern(), loaded.tags, true, buildList)
+				m.Errs = m.Errs[:0]
+				matchPackages(m, loaded.tags, includeStd, buildList)
 
 			case m.Pattern() == "all":
 				loaded.testAll = true
 				if iterating {
 					// Enumerate the packages in the main module.
 					// We'll load the dependencies as we find them.
-					m.Pkgs = matchPackages("...", loaded.tags, false, []module.Version{Target})
+					m.Errs = m.Errs[:0]
+					matchPackages(m, loaded.tags, omitStd, []module.Version{Target})
 				} else {
 					// Starting with the packages in the main module,
 					// enumerate the full list of "all".
@@ -273,7 +275,9 @@
 		}
 
 		pkg := targetPrefix + suffix
-		if _, ok := dirInModule(pkg, targetPrefix, modRoot, true); !ok {
+		if _, ok, err := dirInModule(pkg, targetPrefix, modRoot, true); err != nil {
+			return "", err
+		} else if !ok {
 			return "", &PackageNotInModuleError{Mod: Target, Pattern: pkg}
 		}
 		return pkg, nil
@@ -422,7 +426,7 @@
 		loaded.testRoots = true
 	}
 	all := TargetPackages("...")
-	loaded.load(func() []string { return all })
+	loaded.load(func() []string { return all.Pkgs })
 	checkMultiplePaths()
 	WriteGoMod()
 
@@ -434,6 +438,9 @@
 		}
 		paths = append(paths, pkg.path)
 	}
+	for _, err := range all.Errs {
+		base.Errorf("%v", err)
+	}
 	base.ExitIfErrors()
 	return paths
 }
@@ -441,12 +448,14 @@
 // TargetPackages returns the list of packages in the target (top-level) module
 // matching pattern, which may be relative to the working directory, under all
 // build tag settings.
-func TargetPackages(pattern string) []string {
+func TargetPackages(pattern string) *search.Match {
 	// TargetPackages is relative to the main module, so ensure that the main
 	// module is a thing that can contain packages.
 	ModRoot()
 
-	return matchPackages(pattern, imports.AnyTags(), false, []module.Version{Target})
+	m := search.NewMatch(pattern)
+	matchPackages(m, imports.AnyTags(), omitStd, []module.Version{Target})
+	return m
 }
 
 // BuildList returns the module build list,
diff --git a/src/cmd/go/internal/modload/query.go b/src/cmd/go/internal/modload/query.go
index 5e9cfdc..acc886b 100644
--- a/src/cmd/go/internal/modload/query.go
+++ b/src/cmd/go/internal/modload/query.go
@@ -403,30 +403,42 @@
 // possible modules.
 func QueryPattern(pattern, query string, allowed func(module.Version) bool) ([]QueryResult, error) {
 	base := pattern
-	var match func(m module.Version, root string, isLocal bool) (pkgs []string)
+
+	firstError := func(m *search.Match) error {
+		if len(m.Errs) == 0 {
+			return nil
+		}
+		return m.Errs[0]
+	}
+
+	var match func(mod module.Version, root string, isLocal bool) *search.Match
 
 	if i := strings.Index(pattern, "..."); i >= 0 {
 		base = pathpkg.Dir(pattern[:i+3])
-		match = func(m module.Version, root string, isLocal bool) []string {
-			return matchPackages(pattern, imports.AnyTags(), false, []module.Version{m})
+		match = func(mod module.Version, root string, isLocal bool) *search.Match {
+			m := search.NewMatch(pattern)
+			matchPackages(m, imports.AnyTags(), omitStd, []module.Version{mod})
+			return m
 		}
 	} else {
-		match = func(m module.Version, root string, isLocal bool) []string {
-			prefix := m.Path
-			if m == Target {
+		match = func(mod module.Version, root string, isLocal bool) *search.Match {
+			m := search.NewMatch(pattern)
+			prefix := mod.Path
+			if mod == Target {
 				prefix = targetPrefix
 			}
-			if _, ok := dirInModule(pattern, prefix, root, isLocal); ok {
-				return []string{pattern}
-			} else {
-				return nil
+			if _, ok, err := dirInModule(pattern, prefix, root, isLocal); err != nil {
+				m.AddError(err)
+			} else if ok {
+				m.Pkgs = []string{pattern}
 			}
+			return m
 		}
 	}
 
 	if HasModRoot() {
-		pkgs := match(Target, modRoot, true)
-		if len(pkgs) > 0 {
+		m := match(Target, modRoot, true)
+		if len(m.Pkgs) > 0 {
 			if query != "latest" {
 				return nil, fmt.Errorf("can't query specific version for package %s in the main module (%s)", pattern, Target.Path)
 			}
@@ -436,9 +448,12 @@
 			return []QueryResult{{
 				Mod:      Target,
 				Rev:      &modfetch.RevInfo{Version: Target.Version},
-				Packages: pkgs,
+				Packages: m.Pkgs,
 			}}, nil
 		}
+		if err := firstError(m); err != nil {
+			return nil, err
+		}
 	}
 
 	var (
@@ -466,8 +481,12 @@
 			if err != nil {
 				return r, err
 			}
-			r.Packages = match(r.Mod, root, isLocal)
+			m := match(r.Mod, root, isLocal)
+			r.Packages = m.Pkgs
 			if len(r.Packages) == 0 {
+				if err := firstError(m); err != nil {
+					return r, err
+				}
 				return r, &PackageNotInModuleError{
 					Mod:         r.Mod,
 					Replacement: Replacement(r.Mod),
@@ -684,8 +703,8 @@
 	if err != nil {
 		return false, err
 	}
-	_, ok := dirInModule(m.Path, m.Path, root, isLocal)
-	return ok, nil
+	_, ok, err := dirInModule(m.Path, m.Path, root, isLocal)
+	return ok, err
 }
 
 func versionHasGoMod(m module.Version) (bool, error) {
diff --git a/src/cmd/go/internal/modload/search.go b/src/cmd/go/internal/modload/search.go
index a303f51..c28e7c0 100644
--- a/src/cmd/go/internal/modload/search.go
+++ b/src/cmd/go/internal/modload/search.go
@@ -10,7 +10,6 @@
 	"path/filepath"
 	"strings"
 
-	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/imports"
 	"cmd/go/internal/search"
@@ -18,14 +17,24 @@
 	"golang.org/x/mod/module"
 )
 
-// matchPackages returns a list of packages in the list of modules
-// matching the pattern. Package loading assumes the given set of tags.
-func matchPackages(pattern string, tags map[string]bool, useStd bool, modules []module.Version) []string {
-	match := func(string) bool { return true }
+type stdFilter int8
+
+const (
+	omitStd = stdFilter(iota)
+	includeStd
+)
+
+// matchPackages is like m.MatchPackages, but uses a local variable (rather than
+// a global) for tags, can include or exclude packages in the standard library,
+// and is restricted to the given list of modules.
+func matchPackages(m *search.Match, tags map[string]bool, filter stdFilter, modules []module.Version) {
+	m.Pkgs = []string{}
+
+	isMatch := func(string) bool { return true }
 	treeCanMatch := func(string) bool { return true }
-	if !search.IsMetaPackage(pattern) {
-		match = search.MatchPattern(pattern)
-		treeCanMatch = search.TreeCanMatchPattern(pattern)
+	if !m.IsMeta() {
+		isMatch = search.MatchPattern(m.Pattern())
+		treeCanMatch = search.TreeCanMatchPattern(m.Pattern())
 	}
 
 	have := map[string]bool{
@@ -34,7 +43,6 @@
 	if !cfg.BuildContext.CgoEnabled {
 		have["runtime/cgo"] = true // ignore during walk
 	}
-	var pkgs []string
 
 	type pruning int8
 	const (
@@ -44,8 +52,9 @@
 
 	walkPkgs := func(root, importPathRoot string, prune pruning) {
 		root = filepath.Clean(root)
-		filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
+		err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
 			if err != nil {
+				m.AddError(err)
 				return nil
 			}
 
@@ -94,9 +103,9 @@
 
 			if !have[name] {
 				have[name] = true
-				if match(name) {
+				if isMatch(name) {
 					if _, _, err := scanDir(path, tags); err != imports.ErrNoGo {
-						pkgs = append(pkgs, name)
+						m.Pkgs = append(m.Pkgs, name)
 					}
 				}
 			}
@@ -106,9 +115,12 @@
 			}
 			return nil
 		})
+		if err != nil {
+			m.AddError(err)
+		}
 	}
 
-	if useStd {
+	if filter == includeStd {
 		walkPkgs(cfg.GOROOTsrc, "", pruneGoMod)
 		if treeCanMatch("cmd") {
 			walkPkgs(filepath.Join(cfg.GOROOTsrc, "cmd"), "cmd", pruneGoMod)
@@ -120,7 +132,7 @@
 			walkPkgs(ModRoot(), targetPrefix, pruneGoMod|pruneVendor)
 			walkPkgs(filepath.Join(ModRoot(), "vendor"), "", pruneVendor)
 		}
-		return pkgs
+		return
 	}
 
 	for _, mod := range modules {
@@ -143,7 +155,7 @@
 			var err error
 			root, isLocal, err = fetch(mod)
 			if err != nil {
-				base.Errorf("go: %v", err)
+				m.AddError(err)
 				continue
 			}
 			modPrefix = mod.Path
@@ -156,5 +168,5 @@
 		walkPkgs(root, modPrefix, prune)
 	}
 
-	return pkgs
+	return
 }
diff --git a/src/cmd/go/internal/search/search.go b/src/cmd/go/internal/search/search.go
index b588c3e..4efef24 100644
--- a/src/cmd/go/internal/search/search.go
+++ b/src/cmd/go/internal/search/search.go
@@ -128,8 +128,11 @@
 			root += "cmd" + string(filepath.Separator)
 		}
 		err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
-			if err != nil || path == src {
-				return nil
+			if err != nil {
+				return err // Likely a permission error, which could interfere with matching.
+			}
+			if path == src {
+				return nil // GOROOT/src and GOPATH/src cannot contain packages.
 			}
 
 			want := true
@@ -261,7 +264,10 @@
 	}
 
 	err := filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
-		if err != nil || !fi.IsDir() {
+		if err != nil {
+			return err // Likely a permission error, which could interfere with matching.
+		}
+		if !fi.IsDir() {
 			return nil
 		}
 		top := false
diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go
index 48a873e..880da28 100644
--- a/src/cmd/go/internal/test/test.go
+++ b/src/cmd/go/internal/test/test.go
@@ -73,10 +73,10 @@
 and its test source files to identify significant problems. If go vet
 finds any problems, go test reports those and does not run the test
 binary. Only a high-confidence subset of the default go vet checks are
-used. That subset is: 'atomic', 'bool', 'buildtags', 'nilfunc', and
-'printf'. You can see the documentation for these and other vet tests
-via "go doc cmd/vet". To disable the running of go vet, use the
--vet=off flag.
+used. That subset is: 'atomic', 'bool', 'buildtags', 'errorsas',
+'ifaceassert', 'nilfunc', 'printf', and 'stringintconv'. You can see
+the documentation for these and other vet tests via "go doc cmd/vet".
+To disable the running of go vet, use the -vet=off flag.
 
 All test output and summary lines are printed to the go command's
 standard output, even if the test printed them to its own standard
@@ -548,12 +548,14 @@
 	// "-copylocks",
 	"-errorsas",
 	// "-httpresponse",
+	"-ifaceassert",
 	// "-lostcancel",
 	// "-methods",
 	"-nilfunc",
 	"-printf",
 	// "-rangeloops",
 	// "-shift",
+	"-stringintconv",
 	// "-structtags",
 	// "-tests",
 	// "-unreachable",
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index ebadce8..a49a705 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -10,6 +10,7 @@
 import (
 	"bytes"
 	"context"
+	"errors"
 	"fmt"
 	"go/build"
 	"internal/testenv"
@@ -77,13 +78,16 @@
 	stderr     string            // standard error from last 'go' command; for 'stderr' command
 	stopped    bool              // test wants to stop early
 	start      time.Time         // time phase started
-	background []backgroundCmd   // backgrounded 'exec' and 'go' commands
+	background []*backgroundCmd  // backgrounded 'exec' and 'go' commands
 }
 
 type backgroundCmd struct {
-	cmd  *exec.Cmd
-	wait <-chan struct{}
-	want simpleStatus
+	want           simpleStatus
+	args           []string
+	cancel         context.CancelFunc
+	done           <-chan struct{}
+	err            error
+	stdout, stderr strings.Builder
 }
 
 type simpleStatus string
@@ -193,10 +197,10 @@
 		// before we print PASS. If we return early (e.g., due to a test failure),
 		// don't print anything about the processes that were still running.
 		for _, bg := range ts.background {
-			interruptProcess(bg.cmd.Process)
+			bg.cancel()
 		}
 		for _, bg := range ts.background {
-			<-bg.wait
+			<-bg.done
 		}
 		ts.background = nil
 
@@ -347,7 +351,7 @@
 	}
 
 	for _, bg := range ts.background {
-		interruptProcess(bg.cmd.Process)
+		bg.cancel()
 	}
 	ts.cmdWait(success, nil)
 
@@ -633,40 +637,35 @@
 		ts.fatalf("usage: exec program [args...] [&]")
 	}
 
-	var err error
+	background := false
 	if len(args) > 0 && args[len(args)-1] == "&" {
-		var cmd *exec.Cmd
-		cmd, err = ts.execBackground(args[0], args[1:len(args)-1]...)
-		if err == nil {
-			wait := make(chan struct{})
-			go func() {
-				ctxWait(testCtx, cmd)
-				close(wait)
-			}()
-			ts.background = append(ts.background, backgroundCmd{cmd, wait, want})
-		}
-		ts.stdout, ts.stderr = "", ""
-	} else {
-		ts.stdout, ts.stderr, err = ts.exec(args[0], args[1:]...)
-		if ts.stdout != "" {
-			fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout)
-		}
-		if ts.stderr != "" {
-			fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr)
-		}
-		if err == nil && want == failure {
-			ts.fatalf("unexpected command success")
-		}
+		background = true
+		args = args[:len(args)-1]
 	}
 
+	bg, err := ts.startBackground(want, args[0], args[1:]...)
 	if err != nil {
-		fmt.Fprintf(&ts.log, "[%v]\n", err)
-		if testCtx.Err() != nil {
-			ts.fatalf("test timed out while running command")
-		} else if want == success {
-			ts.fatalf("unexpected command failure")
-		}
+		ts.fatalf("unexpected error starting command: %v", err)
 	}
+	if background {
+		ts.stdout, ts.stderr = "", ""
+		ts.background = append(ts.background, bg)
+		return
+	}
+
+	<-bg.done
+	ts.stdout = bg.stdout.String()
+	ts.stderr = bg.stderr.String()
+	if ts.stdout != "" {
+		fmt.Fprintf(&ts.log, "[stdout]\n%s", ts.stdout)
+	}
+	if ts.stderr != "" {
+		fmt.Fprintf(&ts.log, "[stderr]\n%s", ts.stderr)
+	}
+	if bg.err != nil {
+		fmt.Fprintf(&ts.log, "[%v]\n", bg.err)
+	}
+	ts.checkCmd(bg)
 }
 
 // exists checks that the list of files exists.
@@ -759,7 +758,7 @@
 	// Before we mark the test as skipped, shut down any background processes and
 	// make sure they have returned the correct status.
 	for _, bg := range ts.background {
-		interruptProcess(bg.cmd.Process)
+		bg.cancel()
 	}
 	ts.cmdWait(success, nil)
 
@@ -932,34 +931,24 @@
 
 	var stdouts, stderrs []string
 	for _, bg := range ts.background {
-		<-bg.wait
+		<-bg.done
 
-		args := append([]string{filepath.Base(bg.cmd.Args[0])}, bg.cmd.Args[1:]...)
-		fmt.Fprintf(&ts.log, "[background] %s: %v\n", strings.Join(args, " "), bg.cmd.ProcessState)
+		args := append([]string{filepath.Base(bg.args[0])}, bg.args[1:]...)
+		fmt.Fprintf(&ts.log, "[background] %s: %v\n", strings.Join(args, " "), bg.err)
 
-		cmdStdout := bg.cmd.Stdout.(*strings.Builder).String()
+		cmdStdout := bg.stdout.String()
 		if cmdStdout != "" {
 			fmt.Fprintf(&ts.log, "[stdout]\n%s", cmdStdout)
 			stdouts = append(stdouts, cmdStdout)
 		}
 
-		cmdStderr := bg.cmd.Stderr.(*strings.Builder).String()
+		cmdStderr := bg.stderr.String()
 		if cmdStderr != "" {
 			fmt.Fprintf(&ts.log, "[stderr]\n%s", cmdStderr)
 			stderrs = append(stderrs, cmdStderr)
 		}
 
-		if bg.cmd.ProcessState.Success() {
-			if bg.want == failure {
-				ts.fatalf("unexpected command success")
-			}
-		} else {
-			if testCtx.Err() != nil {
-				ts.fatalf("test timed out while running command")
-			} else if bg.want == success {
-				ts.fatalf("unexpected command failure")
-			}
-		}
+		ts.checkCmd(bg)
 	}
 
 	ts.stdout = strings.Join(stdouts, "")
@@ -987,58 +976,176 @@
 	}
 }
 
+func (ts *testScript) checkCmd(bg *backgroundCmd) {
+	select {
+	case <-bg.done:
+	default:
+		panic("checkCmd called when not done")
+	}
+
+	if bg.err == nil {
+		if bg.want == failure {
+			ts.fatalf("unexpected command success")
+		}
+		return
+	}
+
+	if errors.Is(bg.err, context.DeadlineExceeded) {
+		ts.fatalf("test timed out while running command")
+	}
+
+	if errors.Is(bg.err, context.Canceled) {
+		// The process was still running at the end of the test.
+		// The test must not depend on its exit status.
+		if bg.want != successOrFailure {
+			ts.fatalf("unexpected background command remaining at test end")
+		}
+		return
+	}
+
+	if bg.want == success {
+		ts.fatalf("unexpected command failure")
+	}
+}
+
 // exec runs the given command line (an actual subprocess, not simulated)
 // in ts.cd with environment ts.env and then returns collected standard output and standard error.
 func (ts *testScript) exec(command string, args ...string) (stdout, stderr string, err error) {
-	cmd := exec.Command(command, args...)
-	cmd.Dir = ts.cd
-	cmd.Env = append(ts.env, "PWD="+ts.cd)
-	var stdoutBuf, stderrBuf strings.Builder
-	cmd.Stdout = &stdoutBuf
-	cmd.Stderr = &stderrBuf
-	if err = cmd.Start(); err == nil {
-		err = ctxWait(testCtx, cmd)
+	bg, err := ts.startBackground(success, command, args...)
+	if err != nil {
+		return "", "", err
 	}
-	return stdoutBuf.String(), stderrBuf.String(), err
+	<-bg.done
+	return bg.stdout.String(), bg.stderr.String(), bg.err
 }
 
-// execBackground starts the given command line (an actual subprocess, not simulated)
+// startBackground starts the given command line (an actual subprocess, not simulated)
 // in ts.cd with environment ts.env.
-func (ts *testScript) execBackground(command string, args ...string) (*exec.Cmd, error) {
+func (ts *testScript) startBackground(want simpleStatus, command string, args ...string) (*backgroundCmd, error) {
+	done := make(chan struct{})
+	bg := &backgroundCmd{
+		want:   want,
+		args:   append([]string{command}, args...),
+		done:   done,
+		cancel: func() {},
+	}
+
+	ctx := context.Background()
+	gracePeriod := 100 * time.Millisecond
+	if deadline, ok := ts.t.Deadline(); ok {
+		timeout := time.Until(deadline)
+		// If time allows, increase the termination grace period to 5% of the
+		// remaining time.
+		if gp := timeout / 20; gp > gracePeriod {
+			gracePeriod = gp
+		}
+
+		// Send the first termination signal with two grace periods remaining.
+		// If it still hasn't finished after the first period has elapsed,
+		// we'll escalate to os.Kill with a second period remaining until the
+		// test deadline..
+		timeout -= 2 * gracePeriod
+
+		if timeout <= 0 {
+			// The test has less than the grace period remaining. There is no point in
+			// even starting the command, because it will be terminated immediately.
+			// Save the expense of starting it in the first place.
+			bg.err = context.DeadlineExceeded
+			close(done)
+			return bg, nil
+		}
+
+		ctx, bg.cancel = context.WithTimeout(ctx, timeout)
+	}
+
 	cmd := exec.Command(command, args...)
 	cmd.Dir = ts.cd
 	cmd.Env = append(ts.env, "PWD="+ts.cd)
-	var stdoutBuf, stderrBuf strings.Builder
-	cmd.Stdout = &stdoutBuf
-	cmd.Stderr = &stderrBuf
-	return cmd, cmd.Start()
-}
-
-// ctxWait is like cmd.Wait, but terminates cmd with os.Interrupt if ctx becomes done.
-//
-// This differs from exec.CommandContext in that it prefers os.Interrupt over os.Kill.
-// (See https://golang.org/issue/21135.)
-func ctxWait(ctx context.Context, cmd *exec.Cmd) error {
-	errc := make(chan error, 1)
-	go func() { errc <- cmd.Wait() }()
-
-	select {
-	case err := <-errc:
-		return err
-	case <-ctx.Done():
-		interruptProcess(cmd.Process)
-		return <-errc
+	cmd.Stdout = &bg.stdout
+	cmd.Stderr = &bg.stderr
+	if err := cmd.Start(); err != nil {
+		bg.cancel()
+		return nil, err
 	}
+
+	go func() {
+		bg.err = waitOrStop(ctx, cmd, stopSignal(), gracePeriod)
+		close(done)
+	}()
+	return bg, nil
 }
 
-// interruptProcess sends os.Interrupt to p if supported, or os.Kill otherwise.
-func interruptProcess(p *os.Process) {
-	if err := p.Signal(os.Interrupt); err != nil {
+// stopSignal returns the appropriate signal to use to request that a process
+// stop execution.
+func stopSignal() os.Signal {
+	if runtime.GOOS == "windows" {
 		// Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on
 		// Windows; using it with os.Process.Signal will return an error.”
 		// Fall back to Kill instead.
-		p.Kill()
+		return os.Kill
 	}
+	return os.Interrupt
+}
+
+// waitOrStop waits for the already-started command cmd by calling its Wait method.
+//
+// If cmd does not return before ctx is done, waitOrStop sends it the given interrupt signal.
+// If killDelay is positive, waitOrStop waits that additional period for Wait to return before sending os.Kill.
+//
+// This function is copied from the one added to x/playground/internal in
+// http://golang.org/cl/228438.
+func waitOrStop(ctx context.Context, cmd *exec.Cmd, interrupt os.Signal, killDelay time.Duration) error {
+	if cmd.Process == nil {
+		panic("waitOrStop called with a nil cmd.Process — missing Start call?")
+	}
+	if interrupt == nil {
+		panic("waitOrStop requires a non-nil interrupt signal")
+	}
+
+	errc := make(chan error)
+	go func() {
+		select {
+		case errc <- nil:
+			return
+		case <-ctx.Done():
+		}
+
+		err := cmd.Process.Signal(interrupt)
+		if err == nil {
+			err = ctx.Err() // Report ctx.Err() as the reason we interrupted.
+		} else if err.Error() == "os: process already finished" {
+			errc <- nil
+			return
+		}
+
+		if killDelay > 0 {
+			timer := time.NewTimer(killDelay)
+			select {
+			// Report ctx.Err() as the reason we interrupted the process...
+			case errc <- ctx.Err():
+				timer.Stop()
+				return
+			// ...but after killDelay has elapsed, fall back to a stronger signal.
+			case <-timer.C:
+			}
+
+			// Wait still hasn't returned.
+			// Kill the process harder to make sure that it exits.
+			//
+			// Ignore any error: if cmd.Process has already terminated, we still
+			// want to send ctx.Err() (or the error from the Interrupt call)
+			// to properly attribute the signal that may have terminated it.
+			_ = cmd.Process.Kill()
+		}
+
+		errc <- err
+	}()
+
+	waitErr := cmd.Wait()
+	if interruptErr := <-errc; interruptErr != nil {
+		return interruptErr
+	}
+	return waitErr
 }
 
 // expand applies environment variable expansion to the string s.
diff --git a/src/cmd/go/testdata/script/README b/src/cmd/go/testdata/script/README
index e22ddca..c7fa7cf 100644
--- a/src/cmd/go/testdata/script/README
+++ b/src/cmd/go/testdata/script/README
@@ -138,8 +138,9 @@
   output and standard error of the previous command is cleared, but the output
   of the background process is buffered — and checking of its exit status is
   delayed — until the next call to 'wait', 'skip', or 'stop' or the end of the
-  test. At the end of the test, any remaining background processes are
-  terminated using os.Interrupt (if supported) or os.Kill.
+  test. If any background processes remain at the end of the test, they
+  are terminated using os.Interrupt (if supported) or os.Kill and the test
+  must not depend upon their exit status.
 
 - [!] exists [-readonly] [-exec] file...
   Each of the listed files or directories must (or must not) exist.
diff --git a/src/cmd/go/testdata/script/list_dedup_packages.txt b/src/cmd/go/testdata/script/list_dedup_packages.txt
index ab7068c..ebd497b 100644
--- a/src/cmd/go/testdata/script/list_dedup_packages.txt
+++ b/src/cmd/go/testdata/script/list_dedup_packages.txt
@@ -6,7 +6,7 @@
 cd $WORK
 
 # Check output of go list to ensure no duplicates
-go list xtestonly ./testdata/src/xtestonly/...
+go list xtestonly ./tmp/testdata/src/xtestonly/...
 cmp stdout $WORK/gopath/src/wantstdout
 
 -- wantstdout --
diff --git a/src/cmd/go/testdata/script/list_gofile_in_goroot.txt b/src/cmd/go/testdata/script/list_gofile_in_goroot.txt
index 604d8b4..6e48d7b 100644
--- a/src/cmd/go/testdata/script/list_gofile_in_goroot.txt
+++ b/src/cmd/go/testdata/script/list_gofile_in_goroot.txt
@@ -69,5 +69,8 @@
 package foo
 -- $WORK/goroot/src/fmt/fmt.go --
 package fmt
+-- $WORK/goroot/src/cmd/README --
+This directory must exist in order for the 'cmd' pattern to have something to
+match against.
 -- $GOPATH/src/foo.go --
 package foo
diff --git a/src/cmd/go/testdata/script/list_permissions.txt b/src/cmd/go/testdata/script/list_permissions.txt
new file mode 100644
index 0000000..f65896c
--- /dev/null
+++ b/src/cmd/go/testdata/script/list_permissions.txt
@@ -0,0 +1,84 @@
+env GO111MODULE=on
+
+# Establish baseline behavior, before mucking with file permissions.
+
+go list ./noread/...
+stdout '^example.com/noread$'
+
+go list example.com/noread/...
+stdout '^example.com/noread$'
+
+go list ./empty/...
+stderr 'matched no packages'
+
+[root] stop # Root typically ignores file permissions.
+
+# Make the directory ./noread unreadable, and verify that 'go list' reports an
+# explicit error for a pattern that should match it (rather than treating it as
+# equivalent to an empty directory).
+
+[windows] skip # Does not have Unix-style directory permissions.
+[plan9] skip   # Might not have Unix-style directory permissions.
+
+chmod 000 noread
+
+# Check explicit paths.
+
+! go list ./noread
+! stdout '^example.com/noread$'
+! stderr 'matched no packages'
+
+! go list example.com/noread
+! stdout '^example.com/noread$'
+! stderr 'matched no packages'
+
+# Check filesystem-relative patterns.
+
+! go list ./...
+! stdout '^example.com/noread$'
+! stderr 'matched no packages'
+stderr '^pattern ./...: '
+
+! go list ./noread/...
+! stdout '^example.com/noread$'
+! stderr 'matched no packages'
+stderr '^pattern ./noread/...: '
+
+
+# Check module-prefix patterns.
+
+! go list example.com/...
+! stdout '^example.com/noread$'
+! stderr 'matched no packages'
+stderr '^pattern example.com/...: '
+
+! go list example.com/noread/...
+! stdout '^example.com/noread$'
+! stderr 'matched no packages'
+stderr '^pattern example.com/noread/...: '
+
+
+[short] stop
+
+# Check global patterns, which should still
+# fail due to errors in the local module.
+
+! go list all
+! stdout '^example.com/noread$'
+! stderr 'matched no packages'
+stderr '^pattern all: '
+
+! go list ...
+! stdout '^example.com/noread$'
+! stderr 'matched no packages'
+stderr '^pattern ...: '
+
+
+-- go.mod --
+module example.com
+go 1.15
+-- noread/noread.go --
+// Package noread exists, but will be made unreadable.
+package noread
+-- empty/README.txt --
+This directory intentionally left empty.
diff --git a/src/cmd/go/testdata/script/script_wait.txt b/src/cmd/go/testdata/script/script_wait.txt
index 3cd4ded..acaccfe 100644
--- a/src/cmd/go/testdata/script/script_wait.txt
+++ b/src/cmd/go/testdata/script/script_wait.txt
@@ -19,6 +19,7 @@
 stdout 'foo\nbar'
 
 # The end of the test should interrupt or kill any remaining background
-# programs.
-[!exec:sleep] skip
-! exec sleep 86400 &
+# programs, but that should not cause the test to fail if it does not
+# care about the exit status of those programs.
+[!exec:sleep] stop
+? exec sleep 86400 &
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index 9a1908a..7f5cba6 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -1639,12 +1639,12 @@
 	}
 	if isaddcon(int64(v)) {
 		if v <= 0xFFF {
-			if isbitcon(uint64(v)) {
+			if isbitcon(uint64(a.Offset)) {
 				return C_ABCON0
 			}
 			return C_ADDCON0
 		}
-		if isbitcon(uint64(v)) {
+		if isbitcon(uint64(a.Offset)) {
 			return C_ABCON
 		}
 		if movcon(int64(v)) >= 0 {
@@ -1658,7 +1658,7 @@
 
 	t := movcon(int64(v))
 	if t >= 0 {
-		if isbitcon(uint64(v)) {
+		if isbitcon(uint64(a.Offset)) {
 			return C_MBCON
 		}
 		return C_MOVCON
@@ -1666,13 +1666,13 @@
 
 	t = movcon(int64(^v))
 	if t >= 0 {
-		if isbitcon(uint64(v)) {
+		if isbitcon(uint64(a.Offset)) {
 			return C_MBCON
 		}
 		return C_MOVCON
 	}
 
-	if isbitcon(uint64(v)) {
+	if isbitcon(uint64(a.Offset)) {
 		return C_BITCON
 	}
 
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index 09f603a..b046685 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -33,6 +33,7 @@
 import (
 	"cmd/internal/obj"
 	"cmd/internal/objabi"
+	"cmd/internal/src"
 	"cmd/internal/sys"
 	"math"
 )
@@ -593,6 +594,8 @@
 				p = c.stacksplit(p, c.autosize) // emit split check
 			}
 
+			var prologueEnd *obj.Prog
+
 			aoffset := c.autosize
 			if aoffset > 0xF0 {
 				aoffset = 0xF0
@@ -619,6 +622,8 @@
 				q.To.Type = obj.TYPE_REG
 				q.To.Reg = REGTMP
 
+				prologueEnd = q
+
 				q = obj.Appendp(q, c.newprog)
 				q.Pos = p.Pos
 				q.As = AMOVD
@@ -662,8 +667,12 @@
 				q1.To.Offset = int64(-aoffset)
 				q1.To.Reg = REGSP
 				q1.Spadj = aoffset
+
+				prologueEnd = q1
 			}
 
+			prologueEnd.Pos = prologueEnd.Pos.WithXlogue(src.PosPrologueEnd)
+
 			if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
 				q1 = obj.Appendp(q1, c.newprog)
 				q1.Pos = p.Pos
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index badb388..2f402f3 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -779,7 +779,7 @@
 			continue
 		}
 		t := ldr.SymType(s)
-		if t >= sym.SELFRXSECT && t < sym.SXREF { // data sections handled in dodata
+		if t >= sym.SELFRXSECT && t < sym.SXREF || t == sym.SCONST { // data sections handled in dodata
 			if t == sym.STLSBSS {
 				// TLSBSS is not used on darwin. See data.go:allocateDataSections
 				continue
@@ -791,7 +791,7 @@
 		}
 
 		switch t {
-		case sym.SDYNIMPORT, sym.SHOSTOBJ, sym.SUNDEFEXT, sym.SCONST:
+		case sym.SDYNIMPORT, sym.SHOSTOBJ, sym.SUNDEFEXT:
 			addsym(s)
 		}
 
diff --git a/src/cmd/link/internal/ld/outbuf_linux.go b/src/cmd/link/internal/ld/outbuf_linux.go
index 93e621a..bd9a0c6 100644
--- a/src/cmd/link/internal/ld/outbuf_linux.go
+++ b/src/cmd/link/internal/ld/outbuf_linux.go
@@ -7,5 +7,5 @@
 import "syscall"
 
 func (out *OutBuf) fallocate(size uint64) error {
-	return syscall.Fallocate(int(out.f.Fd()), outbufMode, 0, int64(size))
+	return syscall.Fallocate(int(out.f.Fd()), 0, 0, int64(size))
 }
diff --git a/src/cmd/link/internal/ld/outbuf_mmap.go b/src/cmd/link/internal/ld/outbuf_mmap.go
index f5ccfc9..41c436e 100644
--- a/src/cmd/link/internal/ld/outbuf_mmap.go
+++ b/src/cmd/link/internal/ld/outbuf_mmap.go
@@ -10,8 +10,12 @@
 	"syscall"
 )
 
-func (out *OutBuf) Mmap(filesize uint64) error {
-	err := out.fallocate(filesize)
+func (out *OutBuf) Mmap(filesize uint64) (err error) {
+	for {
+		if err = out.fallocate(filesize); err != syscall.EINTR {
+			break
+		}
+	}
 	if err != nil {
 		// Some file systems do not support fallocate. We ignore that error as linking
 		// can still take place, but you might SIGBUS when you write to the mmapped
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
index fc29164..1849a29 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/gnu.go
@@ -134,6 +134,19 @@
 			buf.WriteString("spr")
 		}
 
+	case "sync":
+		switch arg := inst.Args[0].(type) {
+		case Imm:
+			switch arg {
+			case 0:
+				buf.WriteString("hwsync")
+			case 1:
+				buf.WriteString("lwsync")
+			case 2:
+				buf.WriteString("ptesync")
+			}
+		}
+		startArg = 2
 	default:
 		buf.WriteString(inst.Op.String())
 	}
@@ -262,6 +275,8 @@
 		return true
 	case LHBRX, LWBRX, STHBRX, STWBRX:
 		return true
+	case LBARX, LWARX, LHARX, LDARX:
+		return true
 	}
 	return false
 }
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
index d039d9d..858f9ac 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/plan9.go
@@ -55,10 +55,24 @@
 	// laid out the instruction
 	switch inst.Op {
 	default: // dst, sA, sB, ...
-		if len(args) == 0 {
+		switch len(args) {
+		case 0:
 			return op
-		} else if len(args) == 1 {
+		case 1:
 			return fmt.Sprintf("%s %s", op, args[0])
+		case 2:
+			if inst.Op == COPY || inst.Op == PASTECC || inst.Op == FCMPO || inst.Op == FCMPU {
+				return op + " " + args[0] + "," + args[1]
+			}
+			return op + " " + args[1] + "," + args[0]
+		case 3:
+			if reverseOperandOrder(inst.Op) {
+				return op + " " + args[2] + "," + args[1] + "," + args[0]
+			}
+		case 4:
+			if reverseMiddleOps(inst.Op) {
+				return op + " " + args[1] + "," + args[3] + "," + args[2] + "," + args[0]
+			}
 		}
 		args = append(args, args[0])
 		return op + " " + strings.Join(args[1:], ",")
@@ -77,7 +91,7 @@
 		STH, STHU,
 		STW, STWU,
 		STD, STDU,
-		STQ:
+		STQ, STFD, STFDU, STFS, STFSU:
 		return op + " " + strings.Join(args, ",")
 
 	case CMPD, CMPDI, CMPLD, CMPLDI, CMPW, CMPWI, CMPLW, CMPLWI:
@@ -92,28 +106,41 @@
 		return "ADDIS $0," + args[1] + "," + args[0]
 	// store instructions with index registers
 	case STBX, STBUX, STHX, STHUX, STWX, STWUX, STDX, STDUX,
-		STHBRX, STWBRX, STDBRX, STSWX, STFSX, STFSUX, STFDX, STFDUX, STFIWX, STFDPX:
+		STHBRX, STWBRX, STDBRX, STSWX, STFIWX:
 		return "MOV" + op[2:len(op)-1] + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")"
 
 	case STDCXCC, STWCXCC, STHCXCC, STBCXCC:
 		return op + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")"
 
-	case STXVD2X, STXVW4X:
+	case STXVD2X, STXVW4X, STXSDX, STVX, STVXL, STVEBX, STVEHX, STVEWX, STXSIWX, STFDX, STFDUX, STFDPX, STFSX, STFSUX:
 		return op + " " + args[0] + ",(" + args[2] + ")(" + args[1] + ")"
 
-	// load instructions with index registers
-	case LBZX, LBZUX, LHZX, LHZUX, LWZX, LWZUX, LDX, LDUX,
-		LHBRX, LWBRX, LDBRX, LSWX, LFSX, LFSUX, LFDX, LFDUX, LFIWAX, LFIWZX:
-		return "MOV" + op[1:len(op)-1] + " (" + args[2] + ")(" + args[1] + ")," + args[0]
+	case STXV:
+		return op + " " + args[0] + "," + args[1]
 
-	case LDARX, LWARX, LHARX, LBARX:
+	case STXVL, STXVLL:
+		return op + " " + args[0] + "," + args[1] + "," + args[2]
+
+	case LWAX, LWAUX, LWZX, LHZX, LBZX, LDX, LHAX, LHAUX, LDARX, LWARX, LHARX, LBARX, LFDX, LFDUX, LFSX, LFSUX, LDBRX, LWBRX, LHBRX, LDUX, LWZUX, LHZUX, LBZUX:
+		if args[1] == "0" {
+			return op + " (" + args[2] + ")," + args[0]
+		}
 		return op + " (" + args[2] + ")(" + args[1] + ")," + args[0]
 
-	case LXVD2X, LXVW4X:
+	case LXVD2X, LXVW4X, LVX, LVXL, LVSR, LVSL, LVEBX, LVEHX, LVEWX, LXSDX, LXSIWAX:
 		return op + " (" + args[2] + ")(" + args[1] + ")," + args[0]
 
-	case DCBT, DCBTST, DCBZ, DCBST:
-		return op + " (" + args[1] + ")"
+	case LXV:
+		return op + " " + args[1] + "," + args[0]
+
+	case LXVL, LXVLL:
+		return op + " " + args[1] + "," + args[2] + "," + args[0]
+
+	case DCBT, DCBTST, DCBZ, DCBST, DCBI, ICBI:
+		if args[0] == "0" || args[0] == "R0" {
+			return op + " (" + args[1] + ")"
+		}
+		return op + " (" + args[1] + ")(" + args[0] + ")"
 
 	// branch instructions needs additional handling
 	case BCLR:
@@ -173,12 +200,15 @@
 		if inst.Op == ISEL {
 			return fmt.Sprintf("$%d", (arg - Cond0LT))
 		}
-		if arg == CR0 && strings.HasPrefix(inst.Op.String(), "cmp") {
+		if arg == CR0 && (strings.HasPrefix(inst.Op.String(), "cmp") || strings.HasPrefix(inst.Op.String(), "fcmp")) {
 			return "" // don't show cr0 for cmp instructions
 		} else if arg >= CR0 {
 			return fmt.Sprintf("CR%d", int(arg-CR0))
 		}
 		bit := [4]string{"LT", "GT", "EQ", "SO"}[(arg-Cond0LT)%4]
+		if strings.HasPrefix(inst.Op.String(), "cr") {
+			return fmt.Sprintf("CR%d%s", int(arg-Cond0LT)/4, bit)
+		}
 		if arg <= Cond0SO {
 			return bit
 		}
@@ -212,6 +242,37 @@
 	return fmt.Sprintf("???(%v)", arg)
 }
 
+func reverseMiddleOps(op Op) bool {
+	switch op {
+	case FMADD, FMADDCC, FMADDS, FMADDSCC, FMSUB, FMSUBCC, FMSUBS, FMSUBSCC, FNMADD, FNMADDCC, FNMADDS, FNMADDSCC, FNMSUB, FNMSUBCC, FNMSUBS, FNMSUBSCC, FSEL, FSELCC:
+		return true
+	}
+	return false
+}
+
+func reverseOperandOrder(op Op) bool {
+	switch op {
+	// Special case for SUBF, SUBFC: not reversed
+	case ADD, ADDC, ADDE, ADDCC, ADDCCC:
+		return true
+	case MULLW, MULLWCC, MULHW, MULHWCC, MULLD, MULLDCC, MULHD, MULHDCC, MULLWO, MULLWOCC, MULHWU, MULHWUCC, MULLDO, MULLDOCC:
+		return true
+	case DIVD, DIVDCC, DIVDU, DIVDUCC, DIVDE, DIVDECC, DIVDEU, DIVDEUCC, DIVDO, DIVDOCC, DIVDUO, DIVDUOCC:
+		return true
+	case MODUD, MODSD, MODUW, MODSW:
+		return true
+	case FADD, FADDS, FSUB, FSUBS, FMUL, FMULS, FDIV, FDIVS, FMADD, FMADDS, FMSUB, FMSUBS, FNMADD, FNMADDS, FNMSUB, FNMSUBS, FMULSCC:
+		return true
+	case FADDCC, FADDSCC, FSUBCC, FMULCC, FDIVCC, FDIVSCC:
+		return true
+	case OR, ORC, AND, ANDC, XOR, NAND, EQV, NOR, ANDCC, ORCC, XORCC, EQVCC, NORCC, NANDCC:
+		return true
+	case SLW, SLWCC, SLD, SLDCC, SRW, SRAW, SRWCC, SRAWCC, SRD, SRDCC, SRAD, SRADCC:
+		return true
+	}
+	return false
+}
+
 // revCondMap maps a conditional register bit to its inverse, if possible.
 var revCondMap = map[string]string{
 	"LT": "GE", "GT": "LE", "EQ": "NE",
@@ -219,15 +280,65 @@
 
 // plan9OpMap maps an Op to its Plan 9 mnemonics, if different than its GNU mnemonics.
 var plan9OpMap = map[Op]string{
-	LWARX: "LWAR",
-	LDARX: "LDAR",
-	LHARX: "LHAR",
-	LBARX: "LBAR",
-	ADDI:  "ADD",
-	SRADI: "SRAD",
-	SUBF:  "SUB",
-	LI:    "MOVD",
-	LBZ:   "MOVBZ", STB: "MOVB",
+	LWARX:     "LWAR",
+	LDARX:     "LDAR",
+	LHARX:     "LHAR",
+	LBARX:     "LBAR",
+	LWAX:      "MOVW",
+	LHAX:      "MOVH",
+	LWAUX:     "MOVWU",
+	LHAU:      "MOVHU",
+	LHAUX:     "MOVHU",
+	LDX:       "MOVD",
+	LDUX:      "MOVDU",
+	LWZX:      "MOVWZ",
+	LWZUX:     "MOVWZU",
+	LHZX:      "MOVHZ",
+	LHZUX:     "MOVHZU",
+	LBZX:      "MOVBZ",
+	LBZUX:     "MOVBZU",
+	LDBRX:     "MOVDBR",
+	LWBRX:     "MOVWBR",
+	LHBRX:     "MOVHBR",
+	MCRF:      "MOVFL",
+	XORI:      "XOR",
+	ORI:       "OR",
+	ANDICC:    "ANDCC",
+	ANDC:      "ANDN",
+	ADDEO:     "ADDEV",
+	ADDEOCC:   "ADDEVCC",
+	ADDO:      "ADDV",
+	ADDOCC:    "ADDVCC",
+	ADDMEO:    "ADDMEV",
+	ADDMEOCC:  "ADDMEVCC",
+	ADDCO:     "ADDCV",
+	ADDCOCC:   "ADDCVCC",
+	ADDZEO:    "ADDZEV",
+	ADDZEOCC:  "ADDZEVCC",
+	SUBFME:    "SUBME",
+	SUBFMECC:  "SUBMECC",
+	SUBFZE:    "SUBZE",
+	SUBFZECC:  "SUBZECC",
+	SUBFZEO:   "SUBZEV",
+	SUBFZEOCC: "SUBZEVCC",
+	SUBFC:     "SUBC",
+	ORC:       "ORN",
+	MULLWO:    "MULLWV",
+	MULLWOCC:  "MULLWVCC",
+	MULLDO:    "MULLDV",
+	MULLDOCC:  "MULLDVCC",
+	DIVDO:     "DIVDV",
+	DIVDOCC:   "DIVDVCC",
+	DIVDUO:    "DIVDUV",
+	DIVDUOCC:  "DIVDUVCC",
+	ADDI:      "ADD",
+	SRADI:     "SRAD",
+	SUBF:      "SUB",
+	STBCXCC:   "STBCCC",
+	STWCXCC:   "STWCCC",
+	STDCXCC:   "STDCCC",
+	LI:        "MOVD",
+	LBZ:       "MOVBZ", STB: "MOVB",
 	LBZU: "MOVBZU", STBU: "MOVBU",
 	LHZ: "MOVHZ", LHA: "MOVH", STH: "MOVH",
 	LHZU: "MOVHZU", STHU: "MOVHU",
@@ -235,6 +346,14 @@
 	LWZU: "MOVWZU", STWU: "MOVWU",
 	LD: "MOVD", STD: "MOVD",
 	LDU: "MOVDU", STDU: "MOVDU",
+	LFD: "FMOVD", STFD: "FMOVD",
+	LFS: "FMOVS", STFS: "FMOVS",
+	LFDX: "FMOVD", STFDX: "FMOVD",
+	LFDU: "FMOVDU", STFDU: "FMOVDU",
+	LFDUX: "FMOVDU", STFDUX: "FMOVDU",
+	LFSX: "FMOVS", STFSX: "FMOVS",
+	LFSU: "FMOVSU", STFSU: "FMOVSU",
+	LFSUX: "FMOVSU", STFSUX: "FMOVSU",
 	CMPD: "CMP", CMPDI: "CMP",
 	CMPW: "CMPW", CMPWI: "CMPW",
 	CMPLD: "CMPU", CMPLDI: "CMPU",
diff --git a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
index f536926..250d3b7 100644
--- a/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
+++ b/src/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/tables.go
@@ -186,6 +186,10 @@
 	DIVDEUCC
 	DIVDEUO
 	DIVDEUOCC
+	MODSD
+	MODUD
+	MODSW
+	MODUW
 	CMPWI
 	CMPDI
 	CMPW
@@ -466,6 +470,7 @@
 	VSPLTISH
 	VSPLTISW
 	VPERM
+	VPERMR
 	VSEL
 	VSL
 	VSLDOI
@@ -524,6 +529,7 @@
 	VMSUMSHS
 	VMSUMUHM
 	VMSUMUHS
+	VMSUMUDM
 	VSUMSWS
 	VSUM2SWS
 	VSUM4SBS
@@ -559,6 +565,18 @@
 	VCMPEQUWCC
 	VCMPEQUD
 	VCMPEQUDCC
+	VCMPNEB
+	VCMPNEBCC
+	VCMPNEZB
+	VCMPNEZBCC
+	VCMPNEH
+	VCMPNEHCC
+	VCMPNEZH
+	VCMPNEZHCC
+	VCMPNEW
+	VCMPNEWCC
+	VCMPNEZW
+	VCMPNEZWCC
 	VCMPGTSB
 	VCMPGTSBCC
 	VCMPGTSD
@@ -647,6 +665,7 @@
 	VPOPCNTH
 	VPOPCNTW
 	VBPERMQ
+	VBPERMD
 	BCDADDCC
 	BCDSUBCC
 	MTVSCR
@@ -708,11 +727,17 @@
 	LXVD2X
 	LXVDSX
 	LXVW4X
+	LXV
+	LXVL
+	LXVLL
 	STXSDX
 	STXSIWX
 	STXSSPX
 	STXVD2X
 	STXVW4X
+	STXV
+	STXVL
+	STXVLL
 	XSABSDP
 	XSADDDP
 	XSADDSP
@@ -852,6 +877,7 @@
 	XXMRGHW
 	XXMRGLW
 	XXPERMDI
+	XXPERM
 	XXSEL
 	XXSLDWI
 	XXSPLTW
@@ -1528,6 +1554,10 @@
 	DIVDEUCC:      "divdeu.",
 	DIVDEUO:       "divdeuo",
 	DIVDEUOCC:     "divdeuo.",
+	MODSD:         "modsd",
+	MODUD:         "modud",
+	MODSW:         "modsw",
+	MODUW:         "moduw",
 	CMPWI:         "cmpwi",
 	CMPDI:         "cmpdi",
 	CMPW:          "cmpw",
@@ -1808,6 +1838,7 @@
 	VSPLTISH:      "vspltish",
 	VSPLTISW:      "vspltisw",
 	VPERM:         "vperm",
+	VPERMR:        "vpermr",
 	VSEL:          "vsel",
 	VSL:           "vsl",
 	VSLDOI:        "vsldoi",
@@ -1866,6 +1897,7 @@
 	VMSUMSHS:      "vmsumshs",
 	VMSUMUHM:      "vmsumuhm",
 	VMSUMUHS:      "vmsumuhs",
+	VMSUMUDM:      "vmsumudm",
 	VSUMSWS:       "vsumsws",
 	VSUM2SWS:      "vsum2sws",
 	VSUM4SBS:      "vsum4sbs",
@@ -1901,6 +1933,18 @@
 	VCMPEQUWCC:    "vcmpequw.",
 	VCMPEQUD:      "vcmpequd",
 	VCMPEQUDCC:    "vcmpequd.",
+	VCMPNEB:       "vcmpneb",
+	VCMPNEBCC:     "vcmpneb.",
+	VCMPNEZB:      "vcmpnezb",
+	VCMPNEZBCC:    "vcmpnezb.",
+	VCMPNEH:       "vcmpneh",
+	VCMPNEHCC:     "vcmpneh.",
+	VCMPNEZH:      "vcmpnezh",
+	VCMPNEZHCC:    "vcmpnezh.",
+	VCMPNEW:       "vcmpnew",
+	VCMPNEWCC:     "vcmpnew.",
+	VCMPNEZW:      "vcmpnezw",
+	VCMPNEZWCC:    "vcmpnezw.",
 	VCMPGTSB:      "vcmpgtsb",
 	VCMPGTSBCC:    "vcmpgtsb.",
 	VCMPGTSD:      "vcmpgtsd",
@@ -1989,6 +2033,7 @@
 	VPOPCNTH:      "vpopcnth",
 	VPOPCNTW:      "vpopcntw",
 	VBPERMQ:       "vbpermq",
+	VBPERMD:       "vbpermd",
 	BCDADDCC:      "bcdadd.",
 	BCDSUBCC:      "bcdsub.",
 	MTVSCR:        "mtvscr",
@@ -2050,11 +2095,17 @@
 	LXVD2X:        "lxvd2x",
 	LXVDSX:        "lxvdsx",
 	LXVW4X:        "lxvw4x",
+	LXV:           "lxv",
+	LXVL:          "lxvl",
+	LXVLL:         "lxvll",
 	STXSDX:        "stxsdx",
 	STXSIWX:       "stxsiwx",
 	STXSSPX:       "stxsspx",
 	STXVD2X:       "stxvd2x",
 	STXVW4X:       "stxvw4x",
+	STXV:          "stxv",
+	STXVL:         "stxvl",
+	STXVLL:        "stxvll",
 	XSABSDP:       "xsabsdp",
 	XSADDDP:       "xsadddp",
 	XSADDSP:       "xsaddsp",
@@ -2194,6 +2245,7 @@
 	XXMRGHW:       "xxmrghw",
 	XXMRGLW:       "xxmrglw",
 	XXPERMDI:      "xxpermdi",
+	XXPERM:        "xxperm",
 	XXSEL:         "xxsel",
 	XXSLDWI:       "xxsldwi",
 	XXSPLTW:       "xxspltw",
@@ -2745,6 +2797,7 @@
 	ap_ImmUnsigned_21_22       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{21, 2}}}
 	ap_ImmUnsigned_11_12       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 2}}}
 	ap_ImmUnsigned_11_11       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{11, 1}}}
+	ap_VecSReg_28_28_6_10      = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{28, 1}, {6, 5}}}
 	ap_VecSReg_30_30_16_20     = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{30, 1}, {16, 5}}}
 	ap_VecSReg_29_29_11_15     = &argField{Type: TypeVecSReg, Shift: 0, BitFields: BitFields{{29, 1}, {11, 5}}}
 	ap_ImmUnsigned_22_23       = &argField{Type: TypeImmUnsigned, Shift: 0, BitFields: BitFields{{22, 2}}}
@@ -3125,6 +3178,14 @@
 		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
 	{DIVDEUOCC, 0xfc0007ff, 0x7c000713, 0x0, // Divide Doubleword Extended Unsigned XO-form (divdeuo. RT,RA,RB)
 		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MODSD, 0xfc0007fe, 0x7c000612, 0x1, // Modulo Signed Doubleword X-form (modsd RT,RA,RB)
+		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MODUD, 0xfc0007fe, 0x7c000212, 0x1, // Modulo Unsigned Doubleword X-form (modud RT,RA,RB)
+		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MODSW, 0xfc0007fe, 0x7c000616, 0x1, // Modulo Signed Word X-form (modsw RT,RA,RB)
+		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{MODUW, 0xfc0007fe, 0x7c000216, 0x1, // Modulo Unsigned Word X-form (moduw RT,RA,RB)
+		[5]*argField{ap_Reg_6_10, ap_Reg_11_15, ap_Reg_16_20}},
 	{CMPWI, 0xfc200000, 0x2c000000, 0x400000, // Compare Immediate D-form (cmpwi BF,RA,SI)
 		[5]*argField{ap_CondRegField_6_8, ap_Reg_11_15, ap_ImmSigned_16_31}},
 	{CMPDI, 0xfc200000, 0x2c200000, 0x400000, // Compare Immediate D-form (cmpdi BF,RA,SI)
@@ -3685,6 +3746,8 @@
 		[5]*argField{ap_VecReg_6_10, ap_ImmSigned_11_15}},
 	{VPERM, 0xfc00003f, 0x1000002b, 0x0, // Vector Permute VA-form (vperm VRT,VRA,VRB,VRC)
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VPERMR, 0xfc00003f, 0x1000003b, 0x0, // Vector Permute Right-indexed VA-form (vpermr VRT,VRA,VRB,VRC)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
 	{VSEL, 0xfc00003f, 0x1000002a, 0x0, // Vector Select VA-form (vsel VRT,VRA,VRB,VRC)
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
 	{VSL, 0xfc0007ff, 0x100001c4, 0x0, // Vector Shift Left VX-form (vsl VRT,VRA,VRB)
@@ -3801,6 +3864,8 @@
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
 	{VMSUMUHS, 0xfc00003f, 0x10000027, 0x0, // Vector Multiply-Sum Unsigned Halfword Saturate VA-form (vmsumuhs VRT,VRA,VRB,VRC)
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
+	{VMSUMUDM, 0xfc00003f, 0x10000023, 0x0, // Vector Multiply-Sum Unsigned Doubleword Modulo VA-form (vmsumudm VRT,VRA,VRB,VRC)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_VecReg_21_25}},
 	{VSUMSWS, 0xfc0007ff, 0x10000788, 0x0, // Vector Sum across Signed Word Saturate VX-form (vsumsws VRT,VRA,VRB)
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
 	{VSUM2SWS, 0xfc0007ff, 0x10000688, 0x0, // Vector Sum across Half Signed Word Saturate VX-form (vsum2sws VRT,VRA,VRB)
@@ -3871,6 +3936,30 @@
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
 	{VCMPEQUDCC, 0xfc0007ff, 0x100004c7, 0x0, // Vector Compare Equal To Unsigned Doubleword VX-form (vcmpequd. VRT,VRA,VRB)
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEB, 0xfc0007ff, 0x10000007, 0x0, // Vector Compare Not Equal Byte VX-form (vcmpneb VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEBCC, 0xfc0007ff, 0x10000407, 0x0, // Vector Compare Not Equal Byte VX-form (vcmpneb. VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZB, 0xfc0007ff, 0x10000107, 0x0, // Vector Compare Not Equal or Zero Byte VX-form (vcmpnezb VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZBCC, 0xfc0007ff, 0x10000507, 0x0, // Vector Compare Not Equal or Zero Byte VX-form (vcmpnezb. VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEH, 0xfc0007ff, 0x10000047, 0x0, // Vector Compare Not Equal Halfword VX-form (vcmpneh VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEHCC, 0xfc0007ff, 0x10000447, 0x0, // Vector Compare Not Equal Halfword VX-form (vcmpneh. VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZH, 0xfc0007ff, 0x10000147, 0x0, // Vector Compare Not Equal or Zero Halfword VX-form (vcmpnezh VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZHCC, 0xfc0007ff, 0x10000547, 0x0, // Vector Compare Not Equal or Zero Halfword VX-form (vcmpnezh. VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEW, 0xfc0007ff, 0x10000087, 0x0, // Vector Compare Not Equal Word VX-form (vcmpnew VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEWCC, 0xfc0007ff, 0x10000487, 0x0, // Vector Compare Not Equal Word VX-form (vcmpnew. VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZW, 0xfc0007ff, 0x10000187, 0x0, // Vector Compare Not Equal or Zero Word VX-form (vcmpnezw VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VCMPNEZWCC, 0xfc0007ff, 0x10000587, 0x0, // Vector Compare Not Equal or Zero Word VX-form (vcmpnezw. VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
 	{VCMPGTSB, 0xfc0007ff, 0x10000306, 0x0, // Vector Compare Greater Than Signed Byte VC-form (vcmpgtsb VRT,VRA,VRB)
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
 	{VCMPGTSBCC, 0xfc0007ff, 0x10000706, 0x0, // Vector Compare Greater Than Signed Byte VC-form (vcmpgtsb. VRT,VRA,VRB)
@@ -4047,6 +4136,8 @@
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_16_20}},
 	{VBPERMQ, 0xfc0007ff, 0x1000054c, 0x0, // Vector Bit Permute Quadword VX-form (vbpermq VRT,VRA,VRB)
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
+	{VBPERMD, 0xfc0007ff, 0x100005cc, 0x0, // Vector Bit Permute Doubleword VX-form (vbpermd VRT,VRA,VRB)
+		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20}},
 	{BCDADDCC, 0xfc0005ff, 0x10000401, 0x0, // Decimal Add Modulo VX-form (bcdadd. VRT,VRA,VRB,PS)
 		[5]*argField{ap_VecReg_6_10, ap_VecReg_11_15, ap_VecReg_16_20, ap_ImmUnsigned_22_22}},
 	{BCDSUBCC, 0xfc0005ff, 0x10000441, 0x0, // Decimal Subtract Modulo VX-form (bcdsub. VRT,VRA,VRB,PS)
@@ -4169,6 +4260,12 @@
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
 	{LXVW4X, 0xfc0007fe, 0x7c000618, 0x0, // Load VSX Vector Word*4 Indexed XX1-form (lxvw4x XT,RA,RB)
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXV, 0xfc000007, 0xf4000001, 0x0, // Load VSX Vector DQ-form (lxv XT,DQ(RA))
+		[5]*argField{ap_VecSReg_28_28_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}},
+	{LXVL, 0xfc0007fe, 0x7c00021a, 0x0, // Load VSX Vector with Length X-form (lxvl XT,RA,RB)
+		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{LXVLL, 0xfc0007fe, 0x7c00025a, 0x0, // Load VSX Vector Left-justified with Length X-form (lxvll XT,RA,RB)
+		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
 	{STXSDX, 0xfc0007fe, 0x7c000598, 0x0, // Store VSX Scalar Doubleword Indexed XX1-form (stxsdx XS,RA,RB)
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
 	{STXSIWX, 0xfc0007fe, 0x7c000118, 0x0, // Store VSX Scalar as Integer Word Indexed XX1-form (stxsiwx XS,RA,RB)
@@ -4179,6 +4276,12 @@
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
 	{STXVW4X, 0xfc0007fe, 0x7c000718, 0x0, // Store VSX Vector Word*4 Indexed XX1-form (stxvw4x XS,RA,RB)
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXV, 0xfc000007, 0xf4000005, 0x0, // Store VSX Vector DQ-form (stxv XS,DQ(RA))
+		[5]*argField{ap_VecSReg_28_28_6_10, ap_Offset_16_27_shift4, ap_Reg_11_15}},
+	{STXVL, 0xfc0007fe, 0x7c00031a, 0x0, // Store VSX Vector with Length X-form (stxvl XS,RA,RB)
+		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
+	{STXVLL, 0xfc0007fe, 0x7c00035a, 0x0, // Store VSX Vector Left-justified with Length X-form (stxvll XS,RA,RB)
+		[5]*argField{ap_VecSReg_31_31_6_10, ap_Reg_11_15, ap_Reg_16_20}},
 	{XSABSDP, 0xfc0007fc, 0xf0000564, 0x1f0000, // VSX Scalar Absolute Value Double-Precision XX2-form (xsabsdp XT,XB)
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_30_30_16_20}},
 	{XSADDDP, 0xfc0007f8, 0xf0000100, 0x0, // VSX Scalar Add Double-Precision XX3-form (xsadddp XT,XA,XB)
@@ -4457,6 +4560,8 @@
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
 	{XXPERMDI, 0xfc0004f8, 0xf0000050, 0x0, // VSX Permute Doubleword Immediate XX3-form (xxpermdi XT,XA,XB,DM)
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_ImmUnsigned_22_23}},
+	{XXPERM, 0xfc0007f8, 0xf00000d0, 0x0, // VSX Permute XX3-form (xxperm XT,XA,XB)
+		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20}},
 	{XXSEL, 0xfc000030, 0xf0000030, 0x0, // VSX Select XX4-form (xxsel XT,XA,XB,XC)
 		[5]*argField{ap_VecSReg_31_31_6_10, ap_VecSReg_29_29_11_15, ap_VecSReg_30_30_16_20, ap_VecSReg_28_28_21_25}},
 	{XXSLDWI, 0xfc0004f8, 0xf0000010, 0x0, // VSX Shift Left Double by Word Immediate XX3-form (xxsldwi XT,XA,XB,SHW)
diff --git a/src/cmd/vendor/modules.txt b/src/cmd/vendor/modules.txt
index 10d7d4b..0a3ea66 100644
--- a/src/cmd/vendor/modules.txt
+++ b/src/cmd/vendor/modules.txt
@@ -18,7 +18,7 @@
 # github.com/ianlancetaylor/demangle v0.0.0-20200414190113-039b1ae3a340
 ## explicit
 github.com/ianlancetaylor/demangle
-# golang.org/x/arch v0.0.0-20200312215426-ff8b605520f4
+# golang.org/x/arch v0.0.0-20200511175325-f7c78586839d
 ## explicit
 golang.org/x/arch/arm/armasm
 golang.org/x/arch/arm64/arm64asm
diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go
index 5f34af4..5acc6d8 100644
--- a/src/encoding/json/decode.go
+++ b/src/encoding/json/decode.go
@@ -677,7 +677,6 @@
 		return nil
 	}
 
-	var mapElem reflect.Value
 	origErrorContext := d.errorContext
 
 	for {
@@ -701,17 +700,66 @@
 		}
 
 		// Figure out field corresponding to key.
-		var subv reflect.Value
+		var kv, subv reflect.Value
 		destring := false // whether the value is wrapped in a string to be decoded first
 
 		if v.Kind() == reflect.Map {
-			elemType := t.Elem()
-			if !mapElem.IsValid() {
-				mapElem = reflect.New(elemType).Elem()
-			} else {
-				mapElem.Set(reflect.Zero(elemType))
+			// First, figure out the key value from the input.
+			kt := t.Key()
+			switch {
+			case reflect.PtrTo(kt).Implements(textUnmarshalerType):
+				kv = reflect.New(kt)
+				if err := d.literalStore(item, kv, true); err != nil {
+					return err
+				}
+				kv = kv.Elem()
+			case kt.Kind() == reflect.String:
+				kv = reflect.ValueOf(key).Convert(kt)
+			default:
+				switch kt.Kind() {
+				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+					s := string(key)
+					n, err := strconv.ParseInt(s, 10, 64)
+					if err != nil || reflect.Zero(kt).OverflowInt(n) {
+						d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
+						break
+					}
+					kv = reflect.ValueOf(n).Convert(kt)
+				case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+					s := string(key)
+					n, err := strconv.ParseUint(s, 10, 64)
+					if err != nil || reflect.Zero(kt).OverflowUint(n) {
+						d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
+						break
+					}
+					kv = reflect.ValueOf(n).Convert(kt)
+				default:
+					panic("json: Unexpected key type") // should never occur
+				}
 			}
-			subv = mapElem
+
+			// Then, decide what element value we'll decode into.
+			et := t.Elem()
+			if kv.IsValid() {
+				if existing := v.MapIndex(kv); !existing.IsValid() {
+					// Nothing to reuse.
+				} else if et.Kind() == reflect.Ptr {
+					// Pointer; decode directly into it if non-nil.
+					if !existing.IsNil() {
+						subv = existing
+					}
+				} else {
+					// Non-pointer. Make a copy and decode into the
+					// addressable copy. Don't just use a new/zero
+					// value, as that would lose existing data.
+					subv = reflect.New(et).Elem()
+					subv.Set(existing)
+				}
+			}
+			if !subv.IsValid() {
+				// We couldn't reuse an existing value.
+				subv = reflect.New(et).Elem()
+			}
 		} else {
 			var f *field
 			if i, ok := fields.nameIndex[string(key)]; ok {
@@ -790,43 +838,8 @@
 
 		// Write value back to map;
 		// if using struct, subv points into struct already.
-		if v.Kind() == reflect.Map {
-			kt := t.Key()
-			var kv reflect.Value
-			switch {
-			case reflect.PtrTo(kt).Implements(textUnmarshalerType):
-				kv = reflect.New(kt)
-				if err := d.literalStore(item, kv, true); err != nil {
-					return err
-				}
-				kv = kv.Elem()
-			case kt.Kind() == reflect.String:
-				kv = reflect.ValueOf(key).Convert(kt)
-			default:
-				switch kt.Kind() {
-				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-					s := string(key)
-					n, err := strconv.ParseInt(s, 10, 64)
-					if err != nil || reflect.Zero(kt).OverflowInt(n) {
-						d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
-						break
-					}
-					kv = reflect.ValueOf(n).Convert(kt)
-				case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-					s := string(key)
-					n, err := strconv.ParseUint(s, 10, 64)
-					if err != nil || reflect.Zero(kt).OverflowUint(n) {
-						d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
-						break
-					}
-					kv = reflect.ValueOf(n).Convert(kt)
-				default:
-					panic("json: Unexpected key type") // should never occur
-				}
-			}
-			if kv.IsValid() {
-				v.SetMapIndex(kv, subv)
-			}
+		if v.Kind() == reflect.Map && kv.IsValid() {
+			v.SetMapIndex(kv, subv)
 		}
 
 		// Next token must be , or }.
diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go
index 5ac1022..a62488d 100644
--- a/src/encoding/json/decode_test.go
+++ b/src/encoding/json/decode_test.go
@@ -2569,3 +2569,57 @@
 		}
 	}
 }
+
+func TestUnmarshalMapPointerElem(t *testing.T) {
+	type S struct{ Unchanged, Changed int }
+	input := []byte(`{"S":{"Changed":5}}`)
+	want := S{1, 5}
+
+	// First, a map with struct pointer elements. The key-value pair exists,
+	// so reuse the existing value.
+	s := &S{1, 2}
+	ptrMap := map[string]*S{"S": s}
+	if err := Unmarshal(input, &ptrMap); err != nil {
+		t.Fatal(err)
+	}
+	if s != ptrMap["S"] {
+		t.Fatal("struct pointer element in map was completely replaced")
+	}
+	if got := *s; got != want {
+		t.Fatalf("want %#v, got %#v", want, got)
+	}
+
+	// Second, a map with struct elements. The key-value pair exists, but
+	// the value isn't addresable, so make a copy and use that.
+	s = &S{1, 2}
+	strMap := map[string]S{"S": *s}
+	if err := Unmarshal(input, &strMap); err != nil {
+		t.Fatal(err)
+	}
+	if *s == strMap["S"] {
+		t.Fatal("struct element in map wasn't copied")
+	}
+	if got := strMap["S"]; got != want {
+		t.Fatalf("want %#v, got %#v", want, got)
+	}
+
+	// Finally, check the cases where the key-value pair exists, but the
+	// value is zero.
+	want = S{0, 5}
+
+	ptrMap = map[string]*S{"S": nil}
+	if err := Unmarshal(input, &ptrMap); err != nil {
+		t.Fatal(err)
+	}
+	if got := *ptrMap["S"]; got != want {
+		t.Fatalf("want %#v, got %#v", want, got)
+	}
+
+	strMap = map[string]S{"S": {}}
+	if err := Unmarshal(input, &strMap); err != nil {
+		t.Fatal(err)
+	}
+	if got := strMap["S"]; got != want {
+		t.Fatalf("want %#v, got %#v", want, got)
+	}
+}
diff --git a/src/image/png/reader.go b/src/image/png/reader.go
index 5521b39..910520b 100644
--- a/src/image/png/reader.go
+++ b/src/image/png/reader.go
@@ -862,8 +862,7 @@
 
 func (d *decoder) parseChunk() error {
 	// Read the length and chunk type.
-	n, err := io.ReadFull(d.r, d.tmp[:8])
-	if err != nil {
+	if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
 		return err
 	}
 	length := binary.BigEndian.Uint32(d.tmp[:4])
@@ -920,7 +919,7 @@
 	// Ignore this chunk (of a known length).
 	var ignored [4096]byte
 	for length > 0 {
-		n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
+		n, err := io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
 		if err != nil {
 			return err
 		}
diff --git a/src/internal/poll/copy_file_range_linux.go b/src/internal/poll/copy_file_range_linux.go
index 98210cc..604607f 100644
--- a/src/internal/poll/copy_file_range_linux.go
+++ b/src/internal/poll/copy_file_range_linux.go
@@ -88,6 +88,12 @@
 		return 0, err
 	}
 	defer src.readUnlock()
-	n, err := unix.CopyFileRange(src.Sysfd, nil, dst.Sysfd, nil, max, 0)
+	var n int
+	for {
+		n, err = unix.CopyFileRange(src.Sysfd, nil, dst.Sysfd, nil, max, 0)
+		if err != syscall.EINTR {
+			break
+		}
+	}
 	return int64(n), err
 }
diff --git a/src/internal/poll/fd_unix.go b/src/internal/poll/fd_unix.go
index 4716d58..85c79bb 100644
--- a/src/internal/poll/fd_unix.go
+++ b/src/internal/poll/fd_unix.go
@@ -8,7 +8,6 @@
 
 import (
 	"io"
-	"runtime"
 	"sync/atomic"
 	"syscall"
 )
@@ -153,7 +152,7 @@
 		p = p[:maxRW]
 	}
 	for {
-		n, err := syscall.Read(fd.Sysfd, p)
+		n, err := ignoringEINTR(syscall.Read, fd.Sysfd, p)
 		if err != nil {
 			n = 0
 			if err == syscall.EAGAIN && fd.pd.pollable() {
@@ -161,12 +160,6 @@
 					continue
 				}
 			}
-
-			// On MacOS we can see EINTR here if the user
-			// pressed ^Z.  See issue #22838.
-			if runtime.GOOS == "darwin" && err == syscall.EINTR {
-				continue
-			}
 		}
 		err = fd.eofError(n, err)
 		return n, err
@@ -184,7 +177,16 @@
 	if fd.IsStream && len(p) > maxRW {
 		p = p[:maxRW]
 	}
-	n, err := syscall.Pread(fd.Sysfd, p, off)
+	var (
+		n   int
+		err error
+	)
+	for {
+		n, err = syscall.Pread(fd.Sysfd, p, off)
+		if err != syscall.EINTR {
+			break
+		}
+	}
 	if err != nil {
 		n = 0
 	}
@@ -205,6 +207,9 @@
 	for {
 		n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
 		if err != nil {
+			if err == syscall.EINTR {
+				continue
+			}
 			n = 0
 			if err == syscall.EAGAIN && fd.pd.pollable() {
 				if err = fd.pd.waitRead(fd.isFile); err == nil {
@@ -229,6 +234,9 @@
 	for {
 		n, oobn, flags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, 0)
 		if err != nil {
+			if err == syscall.EINTR {
+				continue
+			}
 			// TODO(dfc) should n and oobn be set to 0
 			if err == syscall.EAGAIN && fd.pd.pollable() {
 				if err = fd.pd.waitRead(fd.isFile); err == nil {
@@ -256,7 +264,7 @@
 		if fd.IsStream && max-nn > maxRW {
 			max = nn + maxRW
 		}
-		n, err := syscall.Write(fd.Sysfd, p[nn:max])
+		n, err := ignoringEINTR(syscall.Write, fd.Sysfd, p[nn:max])
 		if n > 0 {
 			nn += n
 		}
@@ -293,6 +301,9 @@
 			max = nn + maxRW
 		}
 		n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
+		if err == syscall.EINTR {
+			continue
+		}
 		if n > 0 {
 			nn += n
 		}
@@ -319,6 +330,9 @@
 	}
 	for {
 		err := syscall.Sendto(fd.Sysfd, p, 0, sa)
+		if err == syscall.EINTR {
+			continue
+		}
 		if err == syscall.EAGAIN && fd.pd.pollable() {
 			if err = fd.pd.waitWrite(fd.isFile); err == nil {
 				continue
@@ -342,6 +356,9 @@
 	}
 	for {
 		n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
+		if err == syscall.EINTR {
+			continue
+		}
 		if err == syscall.EAGAIN && fd.pd.pollable() {
 			if err = fd.pd.waitWrite(fd.isFile); err == nil {
 				continue
@@ -370,6 +387,8 @@
 			return s, rsa, "", err
 		}
 		switch err {
+		case syscall.EINTR:
+			continue
 		case syscall.EAGAIN:
 			if fd.pd.pollable() {
 				if err = fd.pd.waitRead(fd.isFile); err == nil {
@@ -404,7 +423,7 @@
 	}
 	defer fd.decref()
 	for {
-		n, err := syscall.ReadDirent(fd.Sysfd, buf)
+		n, err := ignoringEINTR(syscall.ReadDirent, fd.Sysfd, buf)
 		if err != nil {
 			n = 0
 			if err == syscall.EAGAIN && fd.pd.pollable() {
@@ -495,7 +514,7 @@
 		return 0, err
 	}
 	defer fd.writeUnlock()
-	return syscall.Write(fd.Sysfd, p)
+	return ignoringEINTR(syscall.Write, fd.Sysfd, p)
 }
 
 // RawRead invokes the user-defined function f for a read operation.
@@ -535,3 +554,19 @@
 		}
 	}
 }
+
+// ignoringEINTR makes a function call and repeats it if it returns
+// an EINTR error. This appears to be required even though we install
+// all signal handlers with SA_RESTART: see #22838, #38033, #38836.
+// Also #20400 and #36644 are issues in which a signal handler is
+// installed without setting SA_RESTART. None of these are the common case,
+// but there are enough of them that it seems that we can't avoid
+// an EINTR loop.
+func ignoringEINTR(fn func(fd int, p []byte) (int, error), fd int, p []byte) (int, error) {
+	for {
+		n, err := fn(fd, p)
+		if err != syscall.EINTR {
+			return n, err
+		}
+	}
+}
diff --git a/src/internal/poll/fd_writev_unix.go b/src/internal/poll/fd_writev_unix.go
index 86af795..daeec96c 100644
--- a/src/internal/poll/fd_writev_unix.go
+++ b/src/internal/poll/fd_writev_unix.go
@@ -12,9 +12,18 @@
 )
 
 func writev(fd int, iovecs []syscall.Iovec) (uintptr, error) {
-	r, _, e := syscall.Syscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs)))
+	var (
+		r uintptr
+		e syscall.Errno
+	)
+	for {
+		r, _, e = syscall.Syscall(syscall.SYS_WRITEV, uintptr(fd), uintptr(unsafe.Pointer(&iovecs[0])), uintptr(len(iovecs)))
+		if e != syscall.EINTR {
+			break
+		}
+	}
 	if e != 0 {
-		return r, syscall.Errno(e)
+		return r, e
 	}
 	return r, nil
 }
diff --git a/src/internal/poll/sendfile_bsd.go b/src/internal/poll/sendfile_bsd.go
index 40ae346..a24e41d 100644
--- a/src/internal/poll/sendfile_bsd.go
+++ b/src/internal/poll/sendfile_bsd.go
@@ -35,6 +35,9 @@
 		} else if n == 0 && err1 == nil {
 			break
 		}
+		if err1 == syscall.EINTR {
+			continue
+		}
 		if err1 == syscall.EAGAIN {
 			if err1 = dstFD.pd.waitWrite(dstFD.isFile); err1 == nil {
 				continue
diff --git a/src/internal/poll/sendfile_linux.go b/src/internal/poll/sendfile_linux.go
index 8e93806..d642830 100644
--- a/src/internal/poll/sendfile_linux.go
+++ b/src/internal/poll/sendfile_linux.go
@@ -32,6 +32,9 @@
 		} else if n == 0 && err1 == nil {
 			break
 		}
+		if err1 == syscall.EINTR {
+			continue
+		}
 		if err1 == syscall.EAGAIN {
 			if err1 = dstFD.pd.waitWrite(dstFD.isFile); err1 == nil {
 				continue
diff --git a/src/internal/poll/splice_linux.go b/src/internal/poll/splice_linux.go
index 5b17ae85..01baf14 100644
--- a/src/internal/poll/splice_linux.go
+++ b/src/internal/poll/splice_linux.go
@@ -87,6 +87,9 @@
 	}
 	for {
 		n, err := splice(pipefd, sock.Sysfd, max, spliceNonblock)
+		if err == syscall.EINTR {
+			continue
+		}
 		if err != syscall.EAGAIN {
 			return n, err
 		}
diff --git a/src/internal/poll/writev.go b/src/internal/poll/writev.go
index 6050d1f..305e2fd 100644
--- a/src/internal/poll/writev.go
+++ b/src/internal/poll/writev.go
@@ -68,7 +68,10 @@
 			iovecs[i] = syscall.Iovec{}
 		}
 		if err != nil {
-			if err.(syscall.Errno) == syscall.EAGAIN {
+			if err == syscall.EINTR {
+				continue
+			}
+			if err == syscall.EAGAIN {
 				if err = fd.pd.waitWrite(fd.isFile); err == nil {
 					continue
 				}
diff --git a/src/internal/trace/writer.go b/src/internal/trace/writer.go
index af5fec8..dd0b9f1 100644
--- a/src/internal/trace/writer.go
+++ b/src/internal/trace/writer.go
@@ -1,3 +1,7 @@
+// Copyright 2017 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 trace
 
 import "bytes"
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
index 4fd19eb..81df044 100644
--- a/src/net/http/pprof/pprof.go
+++ b/src/net/http/pprof/pprof.go
@@ -36,15 +36,17 @@
 //
 //	go tool pprof http://localhost:6060/debug/pprof/block
 //
-// Or to collect a 5-second execution trace:
-//
-//	wget http://localhost:6060/debug/pprof/trace?seconds=5
-//
 // Or to look at the holders of contended mutexes, after calling
 // runtime.SetMutexProfileFraction in your program:
 //
 //	go tool pprof http://localhost:6060/debug/pprof/mutex
 //
+// The package also exports a handler that serves execution trace data
+// for the "go tool trace" command. To collect a 5-second execution trace:
+//
+//	wget -O trace.out http://localhost:6060/debug/pprof/trace?seconds=5
+//	go tool trace trace.out
+//
 // To view all available profiles, open http://localhost:6060/debug/pprof/
 // in your browser.
 //
diff --git a/src/net/sockopt_aix.go b/src/net/sockopt_aix.go
index b49c4d5..7729a44 100644
--- a/src/net/sockopt_aix.go
+++ b/src/net/sockopt_aix.go
@@ -16,8 +16,11 @@
 		// never admit this option.
 		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
 	}
-	// Allow broadcast.
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX {
+		// Allow broadcast.
+		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	}
+	return nil
 }
 
 func setDefaultListenerSockopts(s int) error {
diff --git a/src/net/sockopt_bsd.go b/src/net/sockopt_bsd.go
index 4ecc8cb..8fd1e88 100644
--- a/src/net/sockopt_bsd.go
+++ b/src/net/sockopt_bsd.go
@@ -31,8 +31,11 @@
 		// never admit this option.
 		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
 	}
-	// Allow broadcast.
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX {
+		// Allow broadcast.
+		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	}
+	return nil
 }
 
 func setDefaultListenerSockopts(s int) error {
diff --git a/src/net/sockopt_linux.go b/src/net/sockopt_linux.go
index 0f70b12..3d54429 100644
--- a/src/net/sockopt_linux.go
+++ b/src/net/sockopt_linux.go
@@ -16,8 +16,11 @@
 		// never admit this option.
 		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
 	}
-	// Allow broadcast.
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX {
+		// Allow broadcast.
+		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	}
+	return nil
 }
 
 func setDefaultListenerSockopts(s int) error {
diff --git a/src/net/sockopt_solaris.go b/src/net/sockopt_solaris.go
index 0f70b12..3d54429 100644
--- a/src/net/sockopt_solaris.go
+++ b/src/net/sockopt_solaris.go
@@ -16,8 +16,11 @@
 		// never admit this option.
 		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
 	}
-	// Allow broadcast.
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX {
+		// Allow broadcast.
+		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	}
+	return nil
 }
 
 func setDefaultListenerSockopts(s int) error {
diff --git a/src/net/sockopt_windows.go b/src/net/sockopt_windows.go
index 8017426..8afaf34 100644
--- a/src/net/sockopt_windows.go
+++ b/src/net/sockopt_windows.go
@@ -16,8 +16,10 @@
 		// never admit this option.
 		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
 	}
-	// Allow broadcast.
-	syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
+	if (sotype == syscall.SOCK_DGRAM || sotype == syscall.SOCK_RAW) && family != syscall.AF_UNIX && family != syscall.AF_INET6 {
+		// Allow broadcast.
+		return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+	}
 	return nil
 }
 
diff --git a/src/os/exec_unix.go b/src/os/exec_unix.go
index 6e4ffe8..7759a2d 100644
--- a/src/os/exec_unix.go
+++ b/src/os/exec_unix.go
@@ -33,9 +33,18 @@
 		p.sigMu.Unlock()
 	}
 
-	var status syscall.WaitStatus
-	var rusage syscall.Rusage
-	pid1, e := syscall.Wait4(p.Pid, &status, 0, &rusage)
+	var (
+		status syscall.WaitStatus
+		rusage syscall.Rusage
+		pid1   int
+		e      error
+	)
+	for {
+		pid1, e = syscall.Wait4(p.Pid, &status, 0, &rusage)
+		if e != syscall.EINTR {
+			break
+		}
+	}
 	if e != nil {
 		return nil, NewSyscallError("wait", e)
 	}
diff --git a/src/os/wait_wait6.go b/src/os/wait_wait6.go
index 45bf6490..5420b2d 100644
--- a/src/os/wait_wait6.go
+++ b/src/os/wait_wait6.go
@@ -18,15 +18,20 @@
 // It does not actually call p.Wait.
 func (p *Process) blockUntilWaitable() (bool, error) {
 	var errno syscall.Errno
-	// The arguments on 32-bit FreeBSD look like the following:
-	// - freebsd32_wait6_args{ idtype, id1, id2, status, options, wrusage, info } or
-	// - freebsd32_wait6_args{ idtype, pad, id1, id2, status, options, wrusage, info } when PAD64_REQUIRED=1 on ARM, MIPS or PowerPC
-	if runtime.GOARCH == "386" {
-		_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0, 0)
-	} else if runtime.GOARCH == "arm" {
-		_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, 0, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0)
-	} else {
-		_, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0)
+	for {
+		// The arguments on 32-bit FreeBSD look like the following:
+		// - freebsd32_wait6_args{ idtype, id1, id2, status, options, wrusage, info } or
+		// - freebsd32_wait6_args{ idtype, pad, id1, id2, status, options, wrusage, info } when PAD64_REQUIRED=1 on ARM, MIPS or PowerPC
+		if runtime.GOARCH == "386" {
+			_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0, 0)
+		} else if runtime.GOARCH == "arm" {
+			_, _, errno = syscall.Syscall9(syscall.SYS_WAIT6, _P_PID, 0, uintptr(p.Pid), 0, 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0, 0)
+		} else {
+			_, _, errno = syscall.Syscall6(syscall.SYS_WAIT6, _P_PID, uintptr(p.Pid), 0, syscall.WEXITED|syscall.WNOWAIT, 0, 0)
+		}
+		if errno != syscall.EINTR {
+			break
+		}
 	}
 	runtime.KeepAlive(p)
 	if errno != 0 {
diff --git a/src/os/wait_waitid.go b/src/os/wait_waitid.go
index 6c904e5..9c56eb2 100644
--- a/src/os/wait_waitid.go
+++ b/src/os/wait_waitid.go
@@ -27,7 +27,13 @@
 	// We don't care about the values it returns.
 	var siginfo [16]uint64
 	psig := &siginfo[0]
-	_, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
+	var e syscall.Errno
+	for {
+		_, _, e = syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
+		if e != syscall.EINTR {
+			break
+		}
+	}
 	runtime.KeepAlive(p)
 	if e != 0 {
 		// waitid has been available since Linux 2.6.9, but
diff --git a/src/runtime/cgo/gcc_android.c b/src/runtime/cgo/gcc_android.c
index 321a515..7ea2135 100644
--- a/src/runtime/cgo/gcc_android.c
+++ b/src/runtime/cgo/gcc_android.c
@@ -35,7 +35,7 @@
 // Truncated to a different magic value on 32-bit; that's ok.
 #define magic1 (0x23581321345589ULL)
 
-// From https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/private/bionic_asm_tls.h#69.
+// From https://android.googlesource.com/platform/bionic/+/refs/heads/android10-tests-release/libc/private/bionic_asm_tls.h#69.
 #define TLS_SLOT_APP 2
 
 // inittls allocates a thread-local storage slot for g.
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index a4d0ebf..4872189 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -573,3 +573,30 @@
 		})
 	}
 }
+
+// TestEINTR tests that we handle EINTR correctly.
+// See issue #20400 and friends.
+func TestEINTR(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("no EINTR on %s", runtime.GOOS)
+	case "linux":
+		if runtime.GOARCH == "386" {
+			// On linux-386 the Go signal handler sets
+			// a restorer function that is not preserved
+			// by the C sigaction call in the test,
+			// causing the signal handler to crash when
+			// returning the normal code. The test is not
+			// architecture-specific, so just skip on 386
+			// rather than doing a complicated workaround.
+			t.Skip("skipping on linux-386; C sigaction does not preserve Go restorer")
+		}
+	}
+
+	t.Parallel()
+	output := runTestProg(t, "testprogcgo", "EINTR")
+	want := "OK\n"
+	if output != want {
+		t.Fatalf("want %s, got %s\n", want, output)
+	}
+}
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 37271e4..5ab03f3 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -876,13 +876,9 @@
 // 64 bit and 32 bit platforms, allowing the tests to share code
 // between the two.
 //
-// On AIX, the arenaBaseOffset is 0x0a00000000000000. However, this
-// constant can't be used here because it is negative and will cause
-// a constant overflow.
-//
 // This should not be higher than 0x100*pallocChunkBytes to support
 // mips and mipsle, which only have 31-bit address spaces.
-var BaseChunkIdx = ChunkIdx(chunkIndex(((0xc000*pageAlloc64Bit + 0x100*pageAlloc32Bit) * pallocChunkBytes) + 0x0a00000000000000*sys.GoosAix))
+var BaseChunkIdx = ChunkIdx(chunkIndex(((0xc000*pageAlloc64Bit + 0x100*pageAlloc32Bit) * pallocChunkBytes) + arenaBaseOffset*sys.GoosAix))
 
 // PageBase returns an address given a chunk index and a page index
 // relative to that chunk.
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 0fbf45f..77a5a38 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -302,7 +302,7 @@
 	//
 	// On other platforms, the user address space is contiguous
 	// and starts at 0, so no offset is necessary.
-	arenaBaseOffset = sys.GoarchAmd64*(1<<47) + (^0x0a00000000000000+1)&uintptrMask*sys.GoosAix
+	arenaBaseOffset = 0xffff800000000000*sys.GoarchAmd64 + 0x0a00000000000000*sys.GoosAix
 
 	// Max number of threads to run garbage collection.
 	// 2, 3, and 4 are all plausible maximums depending
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index 3f57b0b..6f7dc6e 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -576,13 +576,13 @@
 //
 //go:nosplit
 func arenaIndex(p uintptr) arenaIdx {
-	return arenaIdx((p + arenaBaseOffset) / heapArenaBytes)
+	return arenaIdx((p - arenaBaseOffset) / heapArenaBytes)
 }
 
 // arenaBase returns the low address of the region covered by heap
 // arena i.
 func arenaBase(i arenaIdx) uintptr {
-	return uintptr(i)*heapArenaBytes - arenaBaseOffset
+	return uintptr(i)*heapArenaBytes + arenaBaseOffset
 }
 
 type arenaIdx uint
diff --git a/src/runtime/mpagealloc.go b/src/runtime/mpagealloc.go
index a28dd26..60f7f9f 100644
--- a/src/runtime/mpagealloc.go
+++ b/src/runtime/mpagealloc.go
@@ -99,12 +99,12 @@
 // chunkIndex returns the global index of the palloc chunk containing the
 // pointer p.
 func chunkIndex(p uintptr) chunkIdx {
-	return chunkIdx((p + arenaBaseOffset) / pallocChunkBytes)
+	return chunkIdx((p - arenaBaseOffset) / pallocChunkBytes)
 }
 
 // chunkIndex returns the base address of the palloc chunk at index ci.
 func chunkBase(ci chunkIdx) uintptr {
-	return uintptr(ci)*pallocChunkBytes - arenaBaseOffset
+	return uintptr(ci)*pallocChunkBytes + arenaBaseOffset
 }
 
 // chunkPageIndex computes the index of the page that contains p,
@@ -136,13 +136,13 @@
 // offAddrToLevelIndex converts an address in the offset address space
 // to the index into summary[level] containing addr.
 func offAddrToLevelIndex(level int, addr offAddr) int {
-	return int((addr.a + arenaBaseOffset) >> levelShift[level])
+	return int((addr.a - arenaBaseOffset) >> levelShift[level])
 }
 
 // levelIndexToOffAddr converts an index into summary[level] into
 // the corresponding address in the offset address space.
 func levelIndexToOffAddr(level, idx int) offAddr {
-	return offAddr{(uintptr(idx) << levelShift[level]) - arenaBaseOffset}
+	return offAddr{(uintptr(idx) << levelShift[level]) + arenaBaseOffset}
 }
 
 // addrsToSummaryRange converts base and limit pointers into a range
@@ -159,8 +159,8 @@
 	// of a summary's max page count boundary for this level
 	// (1 << levelLogPages[level]). So, make limit an inclusive upper bound
 	// then shift, then add 1, so we get an exclusive upper bound at the end.
-	lo = int((base + arenaBaseOffset) >> levelShift[level])
-	hi = int(((limit-1)+arenaBaseOffset)>>levelShift[level]) + 1
+	lo = int((base - arenaBaseOffset) >> levelShift[level])
+	hi = int(((limit-1)-arenaBaseOffset)>>levelShift[level]) + 1
 	return
 }
 
diff --git a/src/runtime/mranges.go b/src/runtime/mranges.go
index e574c2f..c2b8e71 100644
--- a/src/runtime/mranges.go
+++ b/src/runtime/mranges.go
@@ -31,7 +31,7 @@
 // Throws if the base and limit are not in the same memory segment.
 func makeAddrRange(base, limit uintptr) addrRange {
 	r := addrRange{offAddr{base}, offAddr{limit}}
-	if (base+arenaBaseOffset >= arenaBaseOffset) != (limit+arenaBaseOffset >= arenaBaseOffset) {
+	if (base-arenaBaseOffset >= base) != (limit-arenaBaseOffset >= limit) {
 		throw("addr range base and limit are not in the same memory segment")
 	}
 	return r
@@ -71,33 +71,21 @@
 
 var (
 	// minOffAddr is the minimum address in the offset space, and
-	// it corresponds to the virtual address -arenaBaseOffset.
-	//
-	// We don't initialize this with offAddrFromRaw because allocation
-	// may happen during bootstrapping, and we rely on this value
-	// being initialized.
-	//
-	// As a result, creating this value in Go is tricky because of
-	// overflow not being allowed in constants. In order to get
-	// the value we want, we take arenaBaseOffset and do a manual
-	// two's complement negation, then mask that into what can fit
-	// into a uintptr.
-	minOffAddr = offAddr{((^arenaBaseOffset) + 1) & uintptrMask}
+	// it corresponds to the virtual address arenaBaseOffset.
+	minOffAddr = offAddr{arenaBaseOffset}
 
 	// maxOffAddr is the maximum address in the offset address
-	// space, and it corresponds to the virtual address
-	// ^uintptr(0) - arenaBaseOffset.
-	//
-	// We don't initialize this with offAddrFromRaw because allocation
-	// may happen during bootstrapping, and we rely on this value
-	// being initialized.
-	maxOffAddr = offAddr{^uintptr(0) - arenaBaseOffset}
+	// space. It corresponds to the highest virtual address representable
+	// by the page alloc chunk and heap arena maps.
+	maxOffAddr = offAddr{(((1 << heapAddrBits) - 1) + arenaBaseOffset) & uintptrMask}
 )
 
 // offAddr represents an address in a contiguous view
 // of the address space on systems where the address space is
 // segmented. On other systems, it's just a normal address.
 type offAddr struct {
+	// a is just the virtual address, but should never be used
+	// directly. Call addr() to get this value instead.
 	a uintptr
 }
 
@@ -120,13 +108,13 @@
 // lessThan returns true if l1 is less than l2 in the offset
 // address space.
 func (l1 offAddr) lessThan(l2 offAddr) bool {
-	return (l1.a + arenaBaseOffset) < (l2.a + arenaBaseOffset)
+	return (l1.a - arenaBaseOffset) < (l2.a - arenaBaseOffset)
 }
 
 // lessEqual returns true if l1 is less than or equal to l2 in
 // the offset address space.
 func (l1 offAddr) lessEqual(l2 offAddr) bool {
-	return (l1.a + arenaBaseOffset) <= (l2.a + arenaBaseOffset)
+	return (l1.a - arenaBaseOffset) <= (l2.a - arenaBaseOffset)
 }
 
 // equal returns true if the two offAddr values are equal.
diff --git a/src/runtime/testdata/testprog/numcpu_freebsd.go b/src/runtime/testdata/testprog/numcpu_freebsd.go
index 42ee154..aff36ec 100644
--- a/src/runtime/testdata/testprog/numcpu_freebsd.go
+++ b/src/runtime/testdata/testprog/numcpu_freebsd.go
@@ -85,7 +85,13 @@
 	if err != nil {
 		return nil, fmt.Errorf("fail to execute '%s': %s", cmdline, err)
 	}
-	pos := bytes.IndexRune(output, ':')
+	pos := bytes.IndexRune(output, '\n')
+	if pos == -1 {
+		return nil, fmt.Errorf("invalid output from '%s', '\\n' not found: %s", cmdline, output)
+	}
+	output = output[0:pos]
+
+	pos = bytes.IndexRune(output, ':')
 	if pos == -1 {
 		return nil, fmt.Errorf("invalid output from '%s', ':' not found: %s", cmdline, output)
 	}
diff --git a/src/runtime/testdata/testprogcgo/eintr.go b/src/runtime/testdata/testprogcgo/eintr.go
new file mode 100644
index 0000000..58f0dd2
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/eintr.go
@@ -0,0 +1,240 @@
+// 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.
+
+// +build !plan9,!windows
+
+package main
+
+/*
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+
+static int clearRestart(int sig) {
+	struct sigaction sa;
+
+	memset(&sa, 0, sizeof sa);
+	if (sigaction(sig, NULL, &sa) < 0) {
+		return errno;
+	}
+	sa.sa_flags &=~ SA_RESTART;
+	if (sigaction(sig, &sa, NULL) < 0) {
+		return errno;
+	}
+	return 0;
+}
+*/
+import "C"
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"os"
+	"os/exec"
+	"os/signal"
+	"sync"
+	"syscall"
+	"time"
+)
+
+func init() {
+	register("EINTR", EINTR)
+	register("Block", Block)
+}
+
+// Test various operations when a signal handler is installed without
+// the SA_RESTART flag. This tests that the os and net APIs handle EINTR.
+func EINTR() {
+	if errno := C.clearRestart(C.int(syscall.SIGURG)); errno != 0 {
+		log.Fatal(syscall.Errno(errno))
+	}
+	if errno := C.clearRestart(C.int(syscall.SIGWINCH)); errno != 0 {
+		log.Fatal(syscall.Errno(errno))
+	}
+	if errno := C.clearRestart(C.int(syscall.SIGCHLD)); errno != 0 {
+		log.Fatal(syscall.Errno(errno))
+	}
+
+	var wg sync.WaitGroup
+	testPipe(&wg)
+	testNet(&wg)
+	testExec(&wg)
+	wg.Wait()
+	fmt.Println("OK")
+}
+
+// spin does CPU bound spinning and allocating for a millisecond,
+// to get a SIGURG.
+//go:noinline
+func spin() (float64, [][]byte) {
+	stop := time.Now().Add(time.Millisecond)
+	r1 := 0.0
+	var r2 [][]byte
+	for time.Now().Before(stop) {
+		for i := 1; i < 1e6; i++ {
+			r1 += r1 / float64(i)
+			r2 = append(r2, bytes.Repeat([]byte{byte(i)}, 100))
+		}
+	}
+	return r1, r2
+}
+
+// winch sends a few SIGWINCH signals to the process.
+func winch() {
+	ticker := time.NewTicker(100 * time.Microsecond)
+	defer ticker.Stop()
+	for n := 10; n > 0; n-- {
+		syscall.Kill(0, syscall.SIGWINCH)
+		<-ticker.C
+	}
+}
+
+// sendSomeSignals triggers a few SIGURG and SIGWINCH signals.
+func sendSomeSignals() {
+	spin()
+	winch()
+}
+
+// testPipe tests pipe operations.
+func testPipe(wg *sync.WaitGroup) {
+	r, w, err := os.Pipe()
+	if err != nil {
+		log.Fatal(err)
+	}
+	if err := syscall.SetNonblock(int(r.Fd()), false); err != nil {
+		log.Fatal(err)
+	}
+	if err := syscall.SetNonblock(int(w.Fd()), false); err != nil {
+		log.Fatal(err)
+	}
+	wg.Add(2)
+	go func() {
+		defer wg.Done()
+		defer w.Close()
+		// Spin before calling Write so that the first ReadFull
+		// in the other goroutine will likely be interrupted
+		// by a signal.
+		sendSomeSignals()
+		// This Write will likely be interrupted by a signal
+		// as the other goroutine spins in the middle of reading.
+		// We write enough data that we should always fill the
+		// pipe buffer and need multiple write system calls.
+		if _, err := w.Write(bytes.Repeat([]byte{0}, 2<<20)); err != nil {
+			log.Fatal(err)
+		}
+	}()
+	go func() {
+		defer wg.Done()
+		defer r.Close()
+		b := make([]byte, 1<<20)
+		// This ReadFull will likely be interrupted by a signal,
+		// as the other goroutine spins before writing anything.
+		if _, err := io.ReadFull(r, b); err != nil {
+			log.Fatal(err)
+		}
+		// Spin after reading half the data so that the Write
+		// in the other goroutine will likely be interrupted
+		// before it completes.
+		sendSomeSignals()
+		if _, err := io.ReadFull(r, b); err != nil {
+			log.Fatal(err)
+		}
+	}()
+}
+
+// testNet tests network operations.
+func testNet(wg *sync.WaitGroup) {
+	ln, err := net.Listen("tcp4", "127.0.0.1:0")
+	if err != nil {
+		if errors.Is(err, syscall.EAFNOSUPPORT) || errors.Is(err, syscall.EPROTONOSUPPORT) {
+			return
+		}
+		log.Fatal(err)
+	}
+	wg.Add(2)
+	go func() {
+		defer wg.Done()
+		defer ln.Close()
+		c, err := ln.Accept()
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer c.Close()
+		cf, err := c.(*net.TCPConn).File()
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer cf.Close()
+		if err := syscall.SetNonblock(int(cf.Fd()), false); err != nil {
+			log.Fatal(err)
+		}
+		// See comments in testPipe.
+		sendSomeSignals()
+		if _, err := cf.Write(bytes.Repeat([]byte{0}, 2<<20)); err != nil {
+			log.Fatal(err)
+		}
+	}()
+	go func() {
+		defer wg.Done()
+		sendSomeSignals()
+		c, err := net.Dial("tcp", ln.Addr().String())
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer c.Close()
+		cf, err := c.(*net.TCPConn).File()
+		if err != nil {
+			log.Fatal(err)
+		}
+		defer cf.Close()
+		if err := syscall.SetNonblock(int(cf.Fd()), false); err != nil {
+			log.Fatal(err)
+		}
+		// See comments in testPipe.
+		b := make([]byte, 1<<20)
+		if _, err := io.ReadFull(cf, b); err != nil {
+			log.Fatal(err)
+		}
+		sendSomeSignals()
+		if _, err := io.ReadFull(cf, b); err != nil {
+			log.Fatal(err)
+		}
+	}()
+}
+
+func testExec(wg *sync.WaitGroup) {
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		cmd := exec.Command(os.Args[0], "Block")
+		cmd.Stderr = new(bytes.Buffer)
+		cmd.Stdout = cmd.Stderr
+		if err := cmd.Start(); err != nil {
+			log.Fatal(err)
+		}
+
+		go func() {
+			sendSomeSignals()
+			if err := cmd.Process.Signal(os.Interrupt); err != nil {
+				panic(err)
+			}
+		}()
+
+		if err := cmd.Wait(); err != nil {
+			log.Fatalf("%v:\n%s", err, cmd.Stdout)
+		}
+	}()
+}
+
+// Block blocks until the process receives os.Interrupt.
+func Block() {
+	c := make(chan os.Signal, 1)
+	signal.Notify(c, os.Interrupt)
+	defer signal.Stop(c)
+	<-c
+}
diff --git a/src/runtime/trace/trace_stack_test.go b/src/runtime/trace/trace_stack_test.go
index e3608c6..cfc0419 100644
--- a/src/runtime/trace/trace_stack_test.go
+++ b/src/runtime/trace/trace_stack_test.go
@@ -252,6 +252,7 @@
 			{trace.EvGoSysCall, []frame{
 				{"syscall.read", 0},
 				{"syscall.Read", 0},
+				{"internal/poll.ignoringEINTR", 0},
 				{"internal/poll.(*FD).Read", 0},
 				{"os.(*File).read", 0},
 				{"os.(*File).Read", 0},
diff --git a/src/strconv/atoc_test.go b/src/strconv/atoc_test.go
index 5c817a2..3aa421d 100644
--- a/src/strconv/atoc_test.go
+++ b/src/strconv/atoc_test.go
@@ -17,6 +17,7 @@
 	infm0 = complex(math.Inf(-1), 0)
 	inf0p = complex(0, math.Inf(+1))
 	inf0m = complex(0, math.Inf(-1))
+
 	infpp = complex(math.Inf(+1), math.Inf(+1))
 	infpm = complex(math.Inf(+1), math.Inf(-1))
 	infmp = complex(math.Inf(-1), math.Inf(+1))
@@ -30,7 +31,6 @@
 }
 
 func TestParseComplex(t *testing.T) {
-
 	tests := []atocTest{
 		// Clearly invalid
 		{"", 0, ErrSyntax},
@@ -45,6 +45,7 @@
 		{"3+", 0, ErrSyntax},
 		{"3+5", 0, ErrSyntax},
 		{"3+5+5i", 0, ErrSyntax},
+
 		// Parentheses
 		{"()", 0, ErrSyntax},
 		{"(i)", 0, ErrSyntax},
@@ -54,6 +55,7 @@
 		{"(1)+1i", 0, ErrSyntax},
 		{"(3.0+5.5i", 0, ErrSyntax},
 		{"3.0+5.5i)", 0, ErrSyntax},
+
 		// NaNs
 		{"NaN", complex(math.NaN(), 0), nil},
 		{"NANi", complex(0, math.NaN()), nil},
@@ -61,6 +63,7 @@
 		{"+NaN", 0, ErrSyntax},
 		{"-NaN", 0, ErrSyntax},
 		{"NaN-NaNi", 0, ErrSyntax},
+
 		// Infs
 		{"Inf", infp0, nil},
 		{"+inf", infp0, nil},
@@ -74,6 +77,7 @@
 		{"+Inf-Infi", infpm, nil},
 		{"-Infinity+Infi", infmp, nil},
 		{"inf-inf", 0, ErrSyntax},
+
 		// Zeros
 		{"0", 0, nil},
 		{"0i", 0, nil},
@@ -88,6 +92,7 @@
 		{"+0e-0+0e-0i", 0, nil},
 		{"0e+0+0e+0i", 0, nil},
 		{"-0e+0-0e+0i", 0, nil},
+
 		// Regular non-zeroes
 		{"0.1", 0.1, nil},
 		{"0.1i", 0 + 0.1i, nil},
@@ -104,14 +109,17 @@
 		{"+3e+3-3e+3i", 3e+3 - 3e+3i, nil},
 		{"+3e+3+3e+3i", 3e+3 + 3e+3i, nil},
 		{"+3e+3+3e+3i+", 0, ErrSyntax},
+
 		// Separators
 		{"0.1", 0.1, nil},
 		{"0.1i", 0 + 0.1i, nil},
 		{"0.1_2_3", 0.123, nil},
 		{"+0x_3p3i", 0x3p3i, nil},
+		{"0_0+0x_0p0i", 0, nil},
 		{"0x_10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
-		{"+0x_1_0.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
-		{"0x10.3p+8-0x_3p3i", 0x10.3p+8 - 0x3p3i, nil},
+		{"+0x_1_0.3p-8+0x_3_0p3i", 0x10.3p-8 + 0x30p3i, nil},
+		{"0x1_0.3p+8-0x_3p3i", 0x10.3p+8 - 0x3p3i, nil},
+
 		// Hexadecimals
 		{"0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
 		{"+0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil},
@@ -125,6 +133,7 @@
 		{"0x1e2", 0, ErrSyntax},
 		{"1p2", 0, ErrSyntax},
 		{"0x1e2i", 0, ErrSyntax},
+
 		// ErrRange
 		// next float64 - too large
 		{"+0x1p1024", infp0, ErrRange},
@@ -177,19 +186,17 @@
 		{"1e+4294967296+1e+4294967296i", infpp, ErrRange},
 		{"1e+4294967296-1e+4294967296i", infpm, ErrRange},
 	}
-	for _, tt := range tests {
-		tt := tt // for capture in Run closures below
-		if tt.err != nil {
-			tt.err = &NumError{Func: "ParseComplex", Num: tt.in, Err: tt.err}
+	for i := range tests {
+		test := &tests[i]
+		if test.err != nil {
+			test.err = &NumError{Func: "ParseComplex", Num: test.in, Err: test.err}
 		}
-		t.Run(tt.in, func(t *testing.T) {
-			got, err := ParseComplex(tt.in, 128)
-			if !reflect.DeepEqual(err, tt.err) {
-				t.Fatalf("ParseComplex(%q, 128) = %v, %v want %v, %v", tt.in, got, err, tt.out, tt.err)
-			}
-			if !(cmplx.IsNaN(tt.out) && cmplx.IsNaN(got)) && got != tt.out {
-				t.Fatalf("ParseComplex(%q, 128) = %v, %v want %v, %v", tt.in, got, err, tt.out, tt.err)
-			}
-		})
+		got, err := ParseComplex(test.in, 128)
+		if !reflect.DeepEqual(err, test.err) {
+			t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
+		}
+		if !(cmplx.IsNaN(test.out) && cmplx.IsNaN(got)) && got != test.out {
+			t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err)
+		}
 	}
 }
diff --git a/src/strconv/atof.go b/src/strconv/atof.go
index f20ae4a..901f27a 100644
--- a/src/strconv/atof.go
+++ b/src/strconv/atof.go
@@ -300,7 +300,7 @@
 		exp = dp - ndMant
 	}
 
-	if underscores && !underscoreOK(s) {
+	if underscores && !underscoreOK(s[:i]) {
 		return
 	}
 
diff --git a/src/strconv/atof_test.go b/src/strconv/atof_test.go
index c30cb2e..545d989 100644
--- a/src/strconv/atof_test.go
+++ b/src/strconv/atof_test.go
@@ -480,7 +480,7 @@
 }
 
 func TestParseFloatPrefix(t *testing.T) {
-	for i := 0; i < len(atoftests); i++ {
+	for i := range atoftests {
 		test := &atoftests[i]
 		if test.err != nil {
 			continue
diff --git a/src/syscall/exec_linux_test.go b/src/syscall/exec_linux_test.go
index b7a8df2..b79dee7 100644
--- a/src/syscall/exec_linux_test.go
+++ b/src/syscall/exec_linux_test.go
@@ -355,7 +355,7 @@
 	}
 
 	cmd := exec.Command(os.Args[0], "-test.run=TestUnshareMountNameSpaceHelper", d)
-	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
+	cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
 	cmd.SysProcAttr = &syscall.SysProcAttr{Unshareflags: syscall.CLONE_NEWNS}
 
 	o, err := cmd.CombinedOutput()
@@ -406,7 +406,7 @@
 	}
 
 	cmd = exec.Command("/syscall.test", "-test.run=TestUnshareMountNameSpaceHelper", "/")
-	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
+	cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
 	cmd.SysProcAttr = &syscall.SysProcAttr{Chroot: d, Unshareflags: syscall.CLONE_NEWNS}
 
 	o, err := cmd.CombinedOutput()
@@ -621,7 +621,7 @@
 	}
 
 	cmd := exec.Command(f.Name(), "-test.run=TestAmbientCapsHelper")
-	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
+	cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1")
 	cmd.Stdout = os.Stdout
 	cmd.Stderr = os.Stderr
 	cmd.SysProcAttr = &syscall.SysProcAttr{
diff --git a/src/syscall/exec_unix.go b/src/syscall/exec_unix.go
index 0345af4..cb08b70 100644
--- a/src/syscall/exec_unix.go
+++ b/src/syscall/exec_unix.go
@@ -217,7 +217,12 @@
 
 	// Read child error status from pipe.
 	Close(p[1])
-	n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
+	for {
+		n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
+		if err != EINTR {
+			break
+		}
+	}
 	Close(p[0])
 	if err != nil || n != 0 {
 		if n == int(unsafe.Sizeof(err1)) {
diff --git a/src/syscall/js/js_test.go b/src/syscall/js/js_test.go
index fea4c13..5fc9107 100644
--- a/src/syscall/js/js_test.go
+++ b/src/syscall/js/js_test.go
@@ -591,3 +591,14 @@
 		document.Get("body").Call("removeChild", div)
 	}
 }
+
+func TestGlobal(t *testing.T) {
+	ident := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
+		return args[0]
+	})
+	defer ident.Release()
+
+	if got := ident.Invoke(js.Global()); !got.Equal(js.Global()) {
+		t.Errorf("got %#v, want %#v", got, js.Global())
+	}
+}
diff --git a/src/syscall/syscall_linux_test.go b/src/syscall/syscall_linux_test.go
index e30a10b..c5008f2 100644
--- a/src/syscall/syscall_linux_test.go
+++ b/src/syscall/syscall_linux_test.go
@@ -187,7 +187,7 @@
 	}
 
 	cmd := exec.Command(tmpBinary)
-	cmd.Env = []string{"GO_DEATHSIG_PARENT=1"}
+	cmd.Env = append(os.Environ(), "GO_DEATHSIG_PARENT=1")
 	chldStdin, err := cmd.StdinPipe()
 	if err != nil {
 		t.Fatalf("failed to create new stdin pipe: %v", err)
@@ -225,7 +225,10 @@
 
 func deathSignalParent() {
 	cmd := exec.Command(os.Args[0])
-	cmd.Env = []string{"GO_DEATHSIG_CHILD=1"}
+	cmd.Env = append(os.Environ(),
+		"GO_DEATHSIG_PARENT=",
+		"GO_DEATHSIG_CHILD=1",
+	)
 	cmd.Stdin = os.Stdin
 	cmd.Stdout = os.Stdout
 	attrs := syscall.SysProcAttr{
@@ -356,7 +359,7 @@
 	}
 
 	cmd := exec.Command(tmpBinary)
-	cmd.Env = []string{"GO_SYSCALL_NOERROR=1"}
+	cmd.Env = append(os.Environ(), "GO_SYSCALL_NOERROR=1")
 
 	out, err := cmd.CombinedOutput()
 	if err != nil {
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 90c15a2..216e46e 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -219,9 +219,12 @@
 // directly. TestMain runs in the main goroutine and can do whatever setup
 // and teardown is necessary around a call to m.Run. m.Run will return an exit
 // code that may be passed to os.Exit. If TestMain returns, the test wrapper
-// will pass the result of m.Run to os.Exit itself. When TestMain is called,
-// flag.Parse has not been run. If TestMain depends on command-line flags,
-// including those of the testing package, it should call flag.Parse explicitly.
+// will pass the result of m.Run to os.Exit itself.
+//
+// When TestMain is called, flag.Parse has not been run. If TestMain depends on
+// command-line flags, including those of the testing package, it should call
+// flag.Parse explicitly. Command line flags are always parsed by the time test
+// or benchmark functions run.
 //
 // A simple implementation of TestMain is:
 //
diff --git a/test/codegen/arithmetic.go b/test/codegen/arithmetic.go
index a076664..8f25974 100644
--- a/test/codegen/arithmetic.go
+++ b/test/codegen/arithmetic.go
@@ -451,3 +451,14 @@
 	c += 128
 	return a, b, c
 }
+
+
+// Divide -> shift rules usually require fixup for negative inputs.
+// If the input is non-negative, make sure the fixup is eliminated.
+func divInt(v int64) int64 {
+	if v < 0 {
+		return 0
+	}
+	// amd64:-`.*SARQ.*63,`, -".*SHRQ", ".*SARQ.*[$]9,"
+	return v / 512
+}
diff --git a/test/fixedbugs/issue25727.go b/test/fixedbugs/issue25727.go
index 9b7c804..da7c94c 100644
--- a/test/fixedbugs/issue25727.go
+++ b/test/fixedbugs/issue25727.go
@@ -9,13 +9,13 @@
 import "net/http"
 
 var s = http.Server{}
-var _ = s.doneChan // ERROR "s.doneChan undefined .cannot refer to unexported field or method doneChan.$"
-var _ = s.DoneChan // ERROR "s.DoneChan undefined .type http.Server has no field or method DoneChan.$"
+var _ = s.doneChan                  // ERROR "s.doneChan undefined .cannot refer to unexported field or method doneChan.$"
+var _ = s.DoneChan                  // ERROR "s.DoneChan undefined .type http.Server has no field or method DoneChan.$"
 var _ = http.Server{tlsConfig: nil} // ERROR "unknown field 'tlsConfig' in struct literal.+ .but does have TLSConfig.$"
-var _ = http.Server{DoneChan: nil} // ERROR "unknown field 'DoneChan' in struct literal of type http.Server$"
+var _ = http.Server{DoneChan: nil}  // ERROR "unknown field 'DoneChan' in struct literal of type http.Server$"
 
 type foo struct {
-    bar int
+	bar int
 }
 
 var _ = &foo{bAr: 10} // ERROR "unknown field 'bAr' in struct literal.+ .but does have bar.$"
diff --git a/test/fixedbugs/issue31053.dir/f1.go b/test/fixedbugs/issue31053.dir/f1.go
new file mode 100644
index 0000000..610f393
--- /dev/null
+++ b/test/fixedbugs/issue31053.dir/f1.go
@@ -0,0 +1,18 @@
+// Copyright 2019 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 f1
+
+type Foo struct {
+	doneChan chan bool
+	Name     string
+	fOO      int
+	hook     func()
+}
+
+func (f *Foo) Exported() {
+}
+
+func (f *Foo) unexported() {
+}
diff --git a/test/fixedbugs/issue31053.dir/main.go b/test/fixedbugs/issue31053.dir/main.go
new file mode 100644
index 0000000..895c262
--- /dev/null
+++ b/test/fixedbugs/issue31053.dir/main.go
@@ -0,0 +1,42 @@
+// errorcheck
+
+// Copyright 2019 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 p
+
+import "./f1"
+
+func main() {
+	f := f1.Foo{
+		doneChan:      nil, // ERROR "cannot refer to unexported field 'doneChan' in struct literal of type f1.Foo"
+		DoneChan:      nil, // ERROR "unknown field 'DoneChan' in struct literal of type f1.Foo"
+		Name:          "hey",
+		name:          "there",   // ERROR "unknown field 'name' in struct literal of type f1.Foo .but does have Name."
+		noSuchPrivate: true,      // ERROR "unknown field 'noSuchPrivate' in struct literal of type f1.Foo"
+		NoSuchPublic:  true,      // ERROR "unknown field 'NoSuchPublic' in struct literal of type f1.Foo"
+		foo:           true,      // ERROR "unknown field 'foo' in struct literal of type f1.Foo"
+		hook:          func() {}, // ERROR "cannot refer to unexported field 'hook' in struct literal of type f1.Foo"
+		unexported:    func() {}, // ERROR "unknown field 'unexported' in struct literal of type f1.Foo"
+		Exported:      func() {}, // ERROR "unknown field 'Exported' in struct literal of type f1.Foo"
+	}
+	f.doneChan = nil // ERROR "f.doneChan undefined .cannot refer to unexported field or method doneChan."
+	f.DoneChan = nil // ERROR "f.DoneChan undefined .type f1.Foo has no field or method DoneChan."
+	f.name = nil     // ERROR "f.name undefined .type f1.Foo has no field or method name, but does have Name."
+
+	_ = f.doneChan // ERROR "f.doneChan undefined .cannot refer to unexported field or method doneChan."
+	_ = f.DoneChan // ERROR "f.DoneChan undefined .type f1.Foo has no field or method DoneChan."
+	_ = f.Name
+	_ = f.name          // ERROR "f.name undefined .type f1.Foo has no field or method name, but does have Name."
+	_ = f.noSuchPrivate // ERROR "f.noSuchPrivate undefined .type f1.Foo has no field or method noSuchPrivate."
+	_ = f.NoSuchPublic  // ERROR "f.NoSuchPublic undefined .type f1.Foo has no field or method NoSuchPublic."
+	_ = f.foo           // ERROR "f.foo undefined .type f1.Foo has no field or method foo."
+	_ = f.Exported
+	_ = f.exported    // ERROR "f.exported undefined .type f1.Foo has no field or method exported, but does have Exported."
+	_ = f.Unexported  // ERROR "f.Unexported undefined .type f1.Foo has no field or method Unexported."
+	_ = f.unexported  // ERROR "f.unexported undefined .cannot refer to unexported field or method f1..\*Foo..unexported."
+	f.unexported = 10 // ERROR "f.unexported undefined .cannot refer to unexported field or method f1..\*Foo..unexported."
+	f.unexported()    // ERROR "f.unexported undefined .cannot refer to unexported field or method f1..\*Foo..unexported."
+	_ = f.hook        // ERROR "f.hook undefined .cannot refer to unexported field or method hook."
+}
diff --git a/test/fixedbugs/issue31053.go b/test/fixedbugs/issue31053.go
new file mode 100644
index 0000000..a33d3ff
--- /dev/null
+++ b/test/fixedbugs/issue31053.go
@@ -0,0 +1,7 @@
+// errorcheckdir
+
+// Copyright 2019 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 ignored
diff --git a/test/fixedbugs/issue36437.go b/test/fixedbugs/issue36437.go
new file mode 100644
index 0000000..f96544b
--- /dev/null
+++ b/test/fixedbugs/issue36437.go
@@ -0,0 +1,49 @@
+// run
+
+// +build !nacl,!js
+
+// 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.
+
+// Tests that when non-existent files are passed to the
+// compiler, such as in:
+//    go tool compile foo
+// we don't print the beginning position:
+//    foo:0: open foo: no such file or directory
+// but instead omit it and print out:
+//    open foo: no such file or directory
+
+package main
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"regexp"
+)
+
+func main() {
+	tmpDir, err := ioutil.TempDir("", "issue36437")
+	if err != nil {
+		panic(err)
+	}
+	defer os.RemoveAll(tmpDir)
+
+	msgOrErr := func(msg []byte, err error) string {
+		if len(msg) == 0 && err != nil {
+			return err.Error()
+		}
+		return string(msg)
+	}
+
+	filename := "non-existent.go"
+	output, err := exec.Command("go", "tool", "compile", filename).CombinedOutput()
+	got := msgOrErr(output, err)
+
+	regFilenamePos := regexp.MustCompile(filename + ":\\d+")
+	if regFilenamePos.MatchString(got) {
+		fmt.Printf("Error message must not contain filename:pos, but got:\n%q\n", got)
+	}
+}
diff --git a/test/fixedbugs/issue37246.go b/test/fixedbugs/issue37246.go
new file mode 100644
index 0000000..fe476da
--- /dev/null
+++ b/test/fixedbugs/issue37246.go
@@ -0,0 +1,23 @@
+// 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
+
+func main() {
+	var n, a, b int64
+	for i := int64(2); i < 10; i++ {
+		for j := i; j < 10; j++ {
+			if ((n % (i * j)) == 0) && (j > 1 && (n/(i*j)) == 1) {
+				a, b = i, 0
+				a = n / (i * j)
+			}
+		}
+	}
+
+	if a != b && a != n {
+		println("yes")
+	}
+}
diff --git a/test/fixedbugs/issue38916.go b/test/fixedbugs/issue38916.go
new file mode 100644
index 0000000..fb2ee34
--- /dev/null
+++ b/test/fixedbugs/issue38916.go
@@ -0,0 +1,14 @@
+// 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 p
+
+func f(b bool, c complex128) func(complex128) complex128 {
+	return func(p complex128) complex128 {
+		b = (p+1i == 0) && b
+		return (p + 2i) * (p + 3i - c)
+	}
+}
diff --git a/test/prove.go b/test/prove.go
index e5636a4..d37021d 100644
--- a/test/prove.go
+++ b/test/prove.go
@@ -956,6 +956,70 @@
 	useSlice(c)
 }
 
+// Check that prove is zeroing these right shifts of positive ints by bit-width - 1.
+// e.g (Rsh64x64 <t> n (Const64 <typ.UInt64> [63])) && ft.isNonNegative(n) -> 0
+func sh64(n int64) int64 {
+	if n < 0 {
+		return n
+	}
+	return n >> 63 // ERROR "Proved Rsh64x64 shifts to zero"
+}
+
+func sh32(n int32) int32 {
+	if n < 0 {
+		return n
+	}
+	return n >> 31 // ERROR "Proved Rsh32x64 shifts to zero"
+}
+
+func sh32x64(n int32) int32 {
+	if n < 0 {
+		return n
+	}
+	return n >> uint64(31) // ERROR "Proved Rsh32x64 shifts to zero"
+}
+
+func sh16(n int16) int16 {
+	if n < 0 {
+		return n
+	}
+	return n >> 15 // ERROR "Proved Rsh16x64 shifts to zero"
+}
+
+func sh64noopt(n int64) int64 {
+	return n >> 63 // not optimized; n could be negative
+}
+
+// These cases are division of a positive signed integer by a power of 2.
+// The opt pass doesnt have sufficient information to see that n is positive.
+// So, instead, opt rewrites the division with a less-than-optimal replacement.
+// Prove, which can see that n is nonnegative, cannot see the division because
+// opt, an earlier pass, has already replaced it.
+// The fix for this issue allows prove to zero a right shift that was added as
+// part of the less-than-optimal reqwrite. That change by prove then allows
+// lateopt to clean up all the unneccesary parts of the original division
+// replacement. See issue #36159.
+func divShiftClean(n int) int {
+	if n < 0 {
+		return n
+	}
+	return n / int(8) // ERROR "Proved Rsh64x64 shifts to zero"
+}
+
+func divShiftClean64(n int64) int64 {
+	if n < 0 {
+		return n
+	}
+	return n / int64(16) // ERROR "Proved Rsh64x64 shifts to zero"
+}
+
+func divShiftClean32(n int32) int32 {
+	if n < 0 {
+		return n
+	}
+	return n / int32(16) // ERROR "Proved Rsh32x64 shifts to zero"
+}
+
 //go:noinline
 func useInt(a int) {
 }