Index: lib/CodeGen/TargetInfo.cpp
==================================================================
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -404,12 +404,20 @@
                                        CodeGenFunction &CGF) const {
   return nullptr;
 }
 
 ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
-  if (isAggregateTypeForABI(Ty))
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (isAggregateTypeForABI(Ty)) {
+    // Records with non-trivial destructors/copy-constructors should not be
+    // passed by value.
+    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
+      return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory);
+
     return ABIArgInfo::getIndirect(0);
+  }
 
   // Treat an enum type as its underlying type.
   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
     Ty = EnumTy->getDecl()->getIntegerType();
 

ADDED   test/CodeGenCXX/powerpc-byval.cpp
Index: test/CodeGenCXX/powerpc-byval.cpp
==================================================================
--- test/CodeGenCXX/powerpc-byval.cpp
+++ test/CodeGenCXX/powerpc-byval.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=powerpc-unknown-linux | FileCheck -check-prefix CHECK-LL %s
+// RUN: %clang_cc1 -S -O1 %s -o - -triple=powerpc-unknown-linux -target-cpu 603e | FileCheck -check-prefix CHECK-S %s
+
+struct Shared {
+  Shared() : count(1) { }
+
+  void attach() { ++count; }
+  bool detach() { return (--count == 0); }
+  unsigned count;
+};
+
+struct A {
+  A() : obj(new Shared()) { }
+  ~A() {
+    if (obj->detach())
+      delete obj;
+  }
+
+  A(const A& other) : obj(other.obj) {
+    obj->attach();
+  }
+
+  A& operator=(const A& other) {
+    if (obj != other.obj) {
+      if (obj->detach())
+        delete obj;
+      (obj = other.obj)->attach();
+    }
+    return *this;
+  }
+
+  Shared* obj;
+};
+
+void byval(A one, A two) {
+  one = two;
+}
+
+void test() {
+  A one, two;
+  byval(one, two);
+}
+
+// CHECK-LL: define void @_Z5byval1AS_(%struct.A* %one, %struct.A* %two)
+
+
+// CHECK-S: _Z4testv:
+
+// CHECK-S:         mr 3, 29
+// CHECK-S:         bl _ZN1AC1Ev
+
+// CHECK-S:         mr 3, 28
+// CHECK-S:         bl _ZN1AC1Ev
+
+// CHECK-S:         mr 4, 29
+// CHECK-S:         mr 3, 27
+// CHECK-S:         bl _ZN1AC1ERKS_
+
+// CHECK-S:         mr 4, 28
+// CHECK-S:         mr 3, 26
+// CHECK-S:         bl _ZN1AC1ERKS_
+
+// CHECK-S-NOT:     lwz
+// CHECK-S-NOT:     stw
+// CHECK-S:         mr 3, 27
+// CHECK-S:         mr 4, 26
+// CHECK-S:         bl _Z5byval1AS_
+
+// CHECK-S:         mr 3, 26
+// CHECK-S:         bl _ZN1AD1Ev
+// CHECK-S:         mr 3, 27
+// CHECK-S:         bl _ZN1AD1Ev
+// CHECK-S:         mr 3, 28
+// CHECK-S:         bl _ZN1AD1Ev
+// CHECK-S:         mr 3, 29
+// CHECK-S:         bl _ZN1AD1Ev
