const char* debug_escape_hash;
   int64_t nil_check_size_threshold;
   bool debug_optimization;
+  bool need_eqtype;
 };
 
 extern void go_create_gogo (const struct go_create_gogo_args*);
 
   args.debug_escape_hash = go_debug_escape_hash;
   args.nil_check_size_threshold = TARGET_AIX ? -1 : 4096;
   args.debug_optimization = go_debug_optimization;
+  args.need_eqtype = TARGET_AIX ? true : false;
   args.linemap = go_get_linemap();
   args.backend = go_get_backend();
   go_create_gogo (&args);
 
-307665073fce992ea8112f74b91954e770afcc70
+c512af85eb8c75a759b5e4fc6b72041fe09b75f1
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
 
 // assignment.
 
 Expression*
-Expression::convert_for_assignment(Gogo*, Type* lhs_type,
+Expression::convert_for_assignment(Gogo* gogo, Type* lhs_type,
                                   Expression* rhs, Location location)
 {
   Type* rhs_type = rhs->type();
                                                         location);
     }
   else if (!are_identical && rhs_type->interface_type() != NULL)
-    return Expression::convert_interface_to_type(lhs_type, rhs, location);
+    return Expression::convert_interface_to_type(gogo, lhs_type, rhs, location);
   else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
     {
       // Assigning nil to a slice.
 // non-interface type.
 
 Expression*
-Expression::convert_interface_to_type(Type *lhs_type, Expression* rhs,
+Expression::convert_interface_to_type(Gogo* gogo, Type *lhs_type, Expression* rhs,
                                       Location location)
 {
   // We are going to evaluate RHS multiple times.
   // Build an expression to check that the type is valid.  It will
   // panic with an appropriate runtime type error if the type is not
   // valid.
-  // (lhs_type != rhs_type ? panicdottype(lhs_type, rhs_type, inter_type) :
-  //    nil /*dummy*/)
+  // (lhs_type == rhs_type ? nil /*dummy*/ :
+  //    panicdottype(lhs_type, rhs_type, inter_type))
+  // For some Oses, we need to call runtime.eqtype instead of
+  // lhs_type == rhs_type, as we may have unmerged type descriptors
+  // from shared libraries.
   Expression* lhs_type_expr = Expression::make_type_descriptor(lhs_type,
                                                                 location);
   Expression* rhs_descriptor =
   Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type,
                                                                 location);
 
-  Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, lhs_type_expr,
-                                             rhs_descriptor, location);
+  Expression* cond;
+  if (gogo->need_eqtype()) {
+    cond = Runtime::make_call(Runtime::EQTYPE, location,
+                              2, lhs_type_expr,
+                              rhs_descriptor);
+  } else {
+    cond = Expression::make_binary(OPERATOR_EQEQ, lhs_type_expr,
+                                   rhs_descriptor, location);
+  }
+
   rhs_descriptor = Expression::get_interface_type_descriptor(rhs);
   Expression* panic = Runtime::make_call(Runtime::PANICDOTTYPE, location,
                                          3, lhs_type_expr->copy(),
                                          rhs_descriptor,
                                          rhs_inter_expr);
   Expression* nil = Expression::make_nil(location);
-  Expression* check = Expression::make_conditional(cond, panic, nil,
+  Expression* check = Expression::make_conditional(cond, nil, panic,
                                                    location);
 
   // If the conversion succeeds, pull out the value.
 
   }
 
   static Expression*
-  convert_interface_to_type(Type*, Expression*, Location);
+  convert_interface_to_type(Gogo*, Type*, Expression*, Location);
 
   static Expression*
   import_identifier(Import_function_body*, Location);
 
   ::gogo->set_nil_check_size_threshold(args->nil_check_size_threshold);
   if (args->debug_optimization)
     ::gogo->set_debug_optimization(args->debug_optimization);
+  if (args->need_eqtype)
+    ::gogo->set_need_eqtype(args->need_eqtype);
 }
 
 // Parse the input files.
 
     debug_escape_level_(0),
     debug_optimization_(false),
     nil_check_size_threshold_(4096),
+    need_eqtype_(false),
     verify_types_(),
     interface_types_(),
     specific_type_functions_(),
 
   set_nil_check_size_threshold(int64_t bytes)
   { this->nil_check_size_threshold_ = bytes; }
 
+  // Return whether runtime.eqtype calls are needed when comparing
+  // type descriptors.
+  bool
+  need_eqtype() const
+  { return this->need_eqtype_; }
+
+  // Set if calls to runtime.eqtype are needed.
+  void
+  set_need_eqtype(bool b)
+  { this->need_eqtype_ = b; }
+
   // Import a package.  FILENAME is the file name argument, LOCAL_NAME
   // is the local name to give to the package.  If LOCAL_NAME is empty
   // the declarations are added to the global scope.
   bool debug_optimization_;
   // Nil-check size threshhold.
   int64_t nil_check_size_threshold_;
+  // Whether runtime.eqtype calls are needed when comparing type
+  // descriptors.
+  bool need_eqtype_;
   // A list of types to verify.
   std::vector<Type*> verify_types_;
   // A list of interface types defined while parsing.
 
 // Return whether we can convert a type to an interface type.
 DEF_GO_RUNTIME(IFACET2IP, "runtime.ifaceT2Ip", P2(TYPE, TYPE), R1(BOOL))
 
+// Compare two type descriptors for equality.
+DEF_GO_RUNTIME(EQTYPE, "runtime.eqtype", P2(TYPE, TYPE), R1(BOOL))
+
 // Compare two empty interface values.
 DEF_GO_RUNTIME(EFACEEQ, "runtime.efaceeq", P2(EFACE, EFACE), R1(BOOL))
 
 
 }
 func efaceeq(x, y eface) bool {
        t := x._type
-       if t != y._type {
+       if !eqtype(t, y._type) {
                return false
        }
        if t == nil {
                return false
        }
        t := *(**_type)(xtab)
-       if t != *(**_type)(y.tab) {
+       if !eqtype(t, *(**_type)(y.tab)) {
                return false
        }
        eq := t.equal
                return false
        }
        xt := *(**_type)(x.tab)
-       if xt != t {
+       if !eqtype(xt, t) {
                return false
        }
        eq := t.equal
                return false
        }
        xt := *(**_type)(x.tab)
-       if xt != y._type {
+       if !eqtype(xt, y._type) {
                return false
        }
        eq := xt.equal
        if x._type == nil {
                return false
        }
-       if x._type != t {
+       if !eqtype(x._type, t) {
                return false
        }
        eq := t.equal
 
--- /dev/null
+// 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 !aix,gccgo
+
+package runtime
+
+import (
+       _ "unsafe"
+)
+
+// go:linkname is required as eqtype is a compiler-called
+// function on some OSes.
+//
+//go:linkname eqtype
+
+// Return whether two type descriptors are equal.
+func eqtype(t1, t2 *_type) bool {
+       return t1 == t2
+}
 
--- /dev/null
+// 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 aix,gccgo
+
+package runtime
+
+import (
+       _ "unsafe"
+)
+
+// eqtype is a compiler-called function.
+//
+//go:linkname eqtype
+
+// Return whether two type descriptors are equal.
+// This is gccgo-specific, as some linkers are not able
+// to merge identical type descriptors coming from
+// different object or shared object files.
+func eqtype(t1, t2 *_type) bool {
+       switch {
+       case t1 == t2:
+               return true
+       case t1 == nil || t2 == nil:
+               return false
+       case t1.kind != t2.kind || t1.hash != t2.hash:
+               return false
+       default:
+               return t1.string() == t2.string()
+       }
+}
 
                        ri++
                }
 
-               if lhsMethod.typ != rhsMethod.mtyp {
+               if !eqtype(lhsMethod.typ, rhsMethod.mtyp) {
                        m.methods[1] = nil
                        return *lhsMethod.name
                }
 
 // Convert an empty interface to a pointer non-interface type.
 func ifaceE2T2P(t *_type, e eface) (unsafe.Pointer, bool) {
-       if t != e._type {
+       if !eqtype(t, e._type) {
                return nil, false
        } else {
                return e.data, true
 
 // Convert a non-empty interface to a pointer non-interface type.
 func ifaceI2T2P(t *_type, i iface) (unsafe.Pointer, bool) {
-       if i.tab == nil || t != *(**_type)(i.tab) {
+       if i.tab == nil || !eqtype(t, *(**_type)(i.tab)) {
                return nil, false
        } else {
                return i.data, true
 
 // Convert an empty interface to a non-pointer non-interface type.
 func ifaceE2T2(t *_type, e eface, ret unsafe.Pointer) bool {
-       if t != e._type {
+       if !eqtype(t, e._type) {
                typedmemclr(t, ret)
                return false
        } else {
 
 // Convert a non-empty interface to a non-pointer non-interface type.
 func ifaceI2T2(t *_type, i iface, ret unsafe.Pointer) bool {
-       if i.tab == nil || t != *(**_type)(i.tab) {
+       if i.tab == nil || !eqtype(t, *(**_type)(i.tab)) {
                typedmemclr(t, ret)
                return false
        } else {
                        ri++
                }
 
-               if fromMethod.mtyp != toMethod.typ {
+               if !eqtype(fromMethod.mtyp, toMethod.typ) {
                        return false
                }