func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
        call := n.Call
 
-       var callX ir.Node      // thing being called
-       var callArgs []ir.Node // call arguments
+       var callX ir.Node        // thing being called
+       var callArgs []ir.Node   // call arguments
+       var keepAlive []*ir.Name // KeepAlive list from call, if present
 
        // A helper to recreate the call within the closure.
        var mkNewCall func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node
        case *ir.CallExpr:
                callX = x.X
                callArgs = x.Args
+               keepAlive = x.KeepAlive
                mkNewCall = func(pos src.XPos, op ir.Op, fun ir.Node, args []ir.Node) ir.Node {
                        newcall := ir.NewCallExpr(pos, op, fun, args)
                        newcall.IsDDD = x.IsDDD
                return argCopy
        }
 
-       unsafeArgs := make([]*ir.Name, len(callArgs))
-       origArgs := callArgs
+       // getUnsafeArg looks for an unsafe.Pointer arg that has been
+       // previously captured into the call's keepalive list, returning
+       // the name node for it if found.
+       getUnsafeArg := func(arg ir.Node) *ir.Name {
+               // Look for uintptr(unsafe.Pointer(name))
+               if arg.Op() != ir.OCONVNOP {
+                       return nil
+               }
+               if !arg.Type().IsUintptr() {
+                       return nil
+               }
+               if !arg.(*ir.ConvExpr).X.Type().IsUnsafePtr() {
+                       return nil
+               }
+               arg = arg.(*ir.ConvExpr).X
+               argname, ok := arg.(*ir.Name)
+               if !ok {
+                       return nil
+               }
+               for i := range keepAlive {
+                       if argname == keepAlive[i] {
+                               return argname
+                       }
+               }
+               return nil
+       }
 
        // Copy the arguments to the function into temps.
-       pos := n.Pos()
-       outerfn := ir.CurFunc
+       //
+       // For calls with uintptr(unsafe.Pointer(...)) args that are being
+       // kept alive (see code in (*orderState).call that does this), use
+       // the existing arg copy instead of creating a new copy.
+       unsafeArgs := make([]*ir.Name, len(callArgs))
+       origArgs := callArgs
        var newNames []*ir.Name
        for i := range callArgs {
                arg := callArgs[i]
                var argname *ir.Name
-               if arg.Op() == ir.OCONVNOP && arg.Type().IsUintptr() && arg.(*ir.ConvExpr).X.Type().IsUnsafePtr() {
-                       // No need for copy here; orderState.call() above has already inserted one.
-                       arg = arg.(*ir.ConvExpr).X
-                       argname = arg.(*ir.Name)
-                       unsafeArgs[i] = argname
+               unsafeArgName := getUnsafeArg(arg)
+               if unsafeArgName != nil {
+                       // arg has been copied already, use keepalive copy
+                       argname = unsafeArgName
+                       unsafeArgs[i] = unsafeArgName
                } else {
                        argname = mkArgCopy(arg)
                }
        var noFuncArgs []*ir.Field
        noargst := ir.NewFuncType(base.Pos, nil, noFuncArgs, nil)
        wrapGoDefer_prgen++
+       outerfn := ir.CurFunc
        wrapname := fmt.Sprintf("%v·dwrap·%d", outerfn, wrapGoDefer_prgen)
        sym := types.LocalPkg.Lookup(wrapname)
        fn := typecheck.DeclFunc(sym, noargst)
        if methSelectorExpr != nil {
                methSelectorExpr.X = capName(callX.Pos(), fn, methSelectorExpr.X.(*ir.Name))
        }
-       ir.FinishCaptureNames(pos, outerfn, fn)
+       ir.FinishCaptureNames(n.Pos(), outerfn, fn)
 
        // This flags a builtin as opposed to a regular call.
        irregular := (call.Op() != ir.OCALLFUNC &&
        typecheck.Target.Decls = append(typecheck.Target.Decls, fn)
 
        // Create closure expr
-       clo := ir.NewClosureExpr(pos, fn)
+       clo := ir.NewClosureExpr(n.Pos(), fn)
        fn.OClosure = clo
        clo.SetType(fn.Type())
 
        }
 
        // Create new top level call to closure over argless function.
-       topcall := ir.NewCallExpr(pos, ir.OCALL, clo, []ir.Node{})
+       topcall := ir.NewCallExpr(n.Pos(), ir.OCALL, clo, []ir.Node{})
        typecheck.Call(topcall)
 
        // Tag the call to insure that directClosureCall doesn't undo our work.