Index: test/Sema/altivec-init.c
===================================================================
--- test/Sema/altivec-init.c	(revision 119175)
+++ test/Sema/altivec-init.c	(working copy)
@@ -30,6 +30,6 @@
 
   f(vAltiVec);
   vGCC = vAltiVec;
-  vGCC = vGCC > vAltiVec;
+  int res = vGCC > vAltiVec;
   vAltiVec = 0 ? vGCC : vGCC;
 }
Index: test/Parser/cxx-altivec.cpp
===================================================================
--- test/Parser/cxx-altivec.cpp	(revision 119175)
+++ test/Parser/cxx-altivec.cpp	(working copy)
@@ -126,28 +126,18 @@
 vector int v4 = (vector int)(1, 2, 3, 4);
 vector float v5 = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
 vector char v6 = (vector char)((vector int)(1+2, -2, (int)(2.0 * 3), -(5-3)));
-
-#if 0 // Not ready yet.
-// bug 7553 - Problem with '==' and vectors
-void func() {
-  vector int v10i = (vector int)(1, 2, 3, 4);
-  vector int v11i = (vector int)(1, 2, 3, 4);
-  bool r10ieq = (v10i == v11i);
-  bool r10ine = (v10i != v11i);
-  bool r10igt = (v10i > v11i);
-  bool r10ige = (v10i >= v11i);
-  bool r10ilt = (v10i < v11i);
-  bool r10ile = (v10i <= v11i);
-  vector float v10f = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
-  vector float v11f = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
-  bool r10feq = (v10f == v11f);
-  bool r10fne = (v10f != v11f);
-  bool r10fgt = (v10f > v11f);
-  bool r10fge = (v10f >= v11f);
-  bool r10flt = (v10f < v11f);
-  bool r10fle = (v10f <= v11f);
+ 
+ // bug 7553 - Problem with '==' and vectors
+ void func() {
+  bool res_b;
+  res_b = (vv_sc == vv_sc);
+  res_b = (vv_uc != vv_uc);
+  res_b = (vv_s > vv_s);
+  res_b = (vv_us >= vv_us);
+  res_b = (vv_i < vv_i);
+  res_b = (vv_ui <= vv_ui);
+  res_b = (vv_f <= vv_f);
 }
-#endif
 
 // vecreturn attribute test
 struct Vector
@@ -169,7 +159,7 @@
 public:
   VectorClassNonPod() {}
   virtual ~VectorClassNonPod() {}
-} __attribute__((vecreturn));     // expected-error {{the vecreturn attribute can only be used on a POD (plain old data) class or structure (i.e. no virtual functions)}}
+} __attribute__((vecreturn));     // expected-error {{the vecreturn attribute can only be used on a class or structure with no virtual functions}}
 
 // vecreturn attribute test - should error because of virtual function.
 class VectorClassMultipleMembers
Index: test/Parser/altivec.c
===================================================================
--- test/Parser/altivec.c	(revision 119175)
+++ test/Parser/altivec.c	(working copy)
@@ -100,6 +100,16 @@
   __vector unsigned int tv = gccv;
   gccv = v;
   gccvector unsigned int tgv = v;
+
+  int res_i;
+  // bug 7553 - Problem with '==' and vectors
+  res_i = (vv_sc == vv_sc);
+  res_i = (vv_uc != vv_uc);
+  res_i = (vv_s > vv_s);
+  res_i = (vv_us >= vv_us);
+  res_i = (vv_i < vv_i);
+  res_i = (vv_ui <= vv_ui);
+  res_i = (vv_f <= vv_f);
 }
 
 // bug 6895 - Vectorl literal casting confusion.
@@ -109,3 +119,26 @@
 vector int v4 = (vector int)(1, 2, 3, 4);
 vector float v5 = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
 vector char v6 = (vector char)((vector int)(1+2, -2, (int)(2.0 * 3), -(5-3)));
+
+
+#if 0 // Not ready yet.
+// bug 7553 - Problem with '==' and vectors
+void func() {
+  vector int v10i = (vector int)(1, 2, 3, 4);
+  vector int v11i = (vector int)(1, 2, 3, 4);
+  int r10ieq = (v10i == v11i);
+  int r10ine = (v10i != v11i);
+  int r10igt = (v10i > v11i);
+  int r10ige = (v10i >= v11i);
+  int r10ilt = (v10i < v11i);
+  int r10ile = (v10i <= v11i);
+  vector float v10f = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
+  vector float v11f = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
+  int r10feq = (v10f == v11f);
+  int r10fne = (v10f != v11f);
+  int r10fgt = (v10f > v11f);
+  int r10fge = (v10f >= v11f);
+  int r10flt = (v10f < v11f);
+  int r10fle = (v10f <= v11f);
+}
+#endif
Index: test/CodeGen/builtins-ppc-altivec.c
===================================================================
--- test/CodeGen/builtins-ppc-altivec.c	(revision 119175)
+++ test/CodeGen/builtins-ppc-altivec.c	(working copy)
@@ -3052,3 +3052,64 @@
   /* vec_any_out */
   res_i = vec_any_out(vf, vf);                  // CHECK: @llvm.ppc.altivec.vcmpbfp.p
 }
+
+/* ------------------------------ Relational Operators------------------------------- */
+// CHECK: define void @test7
+void test7() {
+  vector signed char vsc1 = (vector signed char)(-1);
+  vector signed char vsc2 = (vector signed char)(-2);
+  res_i = (vsc1 == vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
+  res_i = (vsc1 != vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
+  res_i = (vsc1 <  vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+  res_i = (vsc1 >  vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 2
+  res_i = (vsc1 <= vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+  res_i = (vsc1 >= vsc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtsb.p(i32 0
+  vector unsigned char vuc1 = (vector unsigned char)(1);
+  vector unsigned char vuc2 = (vector unsigned char)(2);
+  res_i = (vuc1 == vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 2
+  res_i = (vuc1 != vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpequb.p(i32 0
+  res_i = (vuc1 <  vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+  res_i = (vuc1 >  vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 2
+  res_i = (vuc1 <= vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+  res_i = (vuc1 >= vuc2);                  // CHECK: @llvm.ppc.altivec.vcmpgtub.p(i32 0
+  vector short vs1 = (vector short)(-1);
+  vector short vs2 = (vector short)(-2);
+  res_i = (vs1 == vs2);                    // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
+  res_i = (vs1 != vs2);                    // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
+  res_i = (vs1 <  vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+  res_i = (vs1 >  vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 2
+  res_i = (vs1 <= vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+  res_i = (vs1 >= vs2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsh.p(i32 0
+  vector unsigned short vus1 = (vector unsigned short)(1);
+  vector unsigned short vus2 = (vector unsigned short)(2);
+  res_i = (vus1 == vus2);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 2
+  res_i = (vus1 != vus2);                  // CHECK: @llvm.ppc.altivec.vcmpequh.p(i32 0
+  res_i = (vus1 <  vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+  res_i = (vus1 >  vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 2
+  res_i = (vus1 <= vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+  res_i = (vus1 >= vus2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuh.p(i32 0
+  vector int vi1 = (vector int)(-1);
+  vector int vi2 = (vector int)(-2);
+  res_i = (vi1 == vi2);                    // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
+  res_i = (vi1 != vi2);                    // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
+  res_i = (vi1 <  vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+  res_i = (vi1 >  vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 2
+  res_i = (vi1 <= vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+  res_i = (vi1 >= vi2);                    // CHECK: @llvm.ppc.altivec.vcmpgtsw.p(i32 0
+  vector unsigned int vui1 = (vector unsigned int)(1);
+  vector unsigned int vui2 = (vector unsigned int)(2);
+  res_i = (vui1 == vui2);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 2
+  res_i = (vui1 != vui2);                  // CHECK: @llvm.ppc.altivec.vcmpequw.p(i32 0
+  res_i = (vui1 <  vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+  res_i = (vui1 >  vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 2
+  res_i = (vui1 <= vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+  res_i = (vui1 >= vui2);                  // CHECK: @llvm.ppc.altivec.vcmpgtuw.p(i32 0
+  vector float vf1 = (vector float)(1.0);
+  vector float vf2 = (vector float)(2.0);
+  res_i = (vf1 == vf2);                    // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 2
+  res_i = (vf1 != vf2);                    // CHECK: @llvm.ppc.altivec.vcmpeqfp.p(i32 0
+  res_i = (vf1 <  vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+  res_i = (vf1 >  vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgtfp.p(i32 2
+  res_i = (vf1 <= vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+  res_i = (vf1 >= vf2);                    // CHECK: @llvm.ppc.altivec.vcmpgefp.p(i32 2
+}
Index: test/SemaCXX/altivec.cpp
===================================================================
--- test/SemaCXX/altivec.cpp	(revision 119175)
+++ test/SemaCXX/altivec.cpp	(working copy)
@@ -13,6 +13,6 @@
 
   f(vAltiVec);
   vGCC = vAltiVec;
-  vGCC = vGCC > vAltiVec;
+  bool res = vGCC > vAltiVec;
   vAltiVec = 0 ? vGCC : vGCC;
 }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 119175)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -1002,8 +1002,8 @@
   " attribute ignored">;
 def err_attribute_vecreturn_only_vector_member : Error<
   "the vecreturn attribute can only be used on a class or structure with one member, which must be a vector">;
-def err_attribute_vecreturn_only_pod_record : Error<
-  "the vecreturn attribute can only be used on a POD (plain old data) class or structure (i.e. no virtual functions)">;
+def err_attribute_vecreturn_only_nonvirtual_record : Error<
+  "the vecreturn attribute can only be used on a class or structure with no virtual functions">;
 def err_cconv_change : Error<
   "function declared '%0' here was previously declared "
   "%select{'%2'|without calling convention}1">;
Index: www/get_started.html
===================================================================
--- www/get_started.html	(revision 119175)
+++ www/get_started.html	(working copy)
@@ -154,6 +154,10 @@
     <li><tt>cd ..</tt>  (Change directory back to the llvm top.)</li>
     <li>If you are using Visual Studio 2005:  <tt>cmake .</tt></li>
     <li>Or if you are using Visual Studio 2008:  <tt>cmake -G "Visual Studio 9 2008" .</tt></li>
+    <li>By default, cmake will target LLVM to X86.  If you want all targets
+        (needed if you want to run the LLVM tests), add the <tt>-DLLVM_TARGETS_TO_BUILD=all</tt> option to the
+        cmake command line.  Or specify a target from the LLVM_TARGETS_TO_BUILD
+        definition in CMakeLists.txt.</li>
     <li>The above, if successful, will have created an LLVM.sln file in the
        llvm directory.
   </ul>
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp	(revision 119175)
+++ lib/Sema/SemaDeclAttr.cpp	(working copy)
@@ -772,16 +772,13 @@
   RecordDecl *record = cast<RecordDecl>(d);
   int count = 0;
 
-  if (!isa<CXXRecordDecl>(record)) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
-    return;
+  if (isa<CXXRecordDecl>(record)) {
+    if (cast<CXXRecordDecl>(record)->isDynamicClass()) {
+		S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_nonvirtual_record);
+		return;
+    }
   }
 
-  if (!cast<CXXRecordDecl>(record)->isPOD()) {
-    S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
-    return;
-  }
-
   for (RecordDecl::field_iterator iter = record->field_begin(); iter != record->field_end(); iter++) {
     if ((count == 1) || !iter->getType()->isVectorType()) {
       S.Diag(Attr.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 119175)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -6389,6 +6389,11 @@
   if (vType.isNull())
     return vType;
 
+  // If AltiVec, the comparison results in a numeric type, i.e.
+  // bool for C++, int for C
+  if (getLangOptions().AltiVec)
+    return (getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy);
+
   QualType lType = lex->getType();
   QualType rType = rex->getType();
 
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp	(revision 119175)
+++ lib/CodeGen/CGExprScalar.cpp	(working copy)
@@ -1977,6 +1977,48 @@
   return Builder.CreateShl(Ops.LHS, RHS, "shl");
 }
 
+enum IntrinsicType { VCMPEQ, VCMPGT };
+// return corresponding comparison intrinsic for given vector type
+static llvm::Intrinsic::ID GetIntrinsic(IntrinsicType IT,
+                                        BuiltinType::Kind ElemKind) {
+  switch (ElemKind) {
+  default: assert(0 && "unexpected element type");
+  case BuiltinType::Char_U:
+  case BuiltinType::UChar:
+    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
+                            llvm::Intrinsic::ppc_altivec_vcmpgtub_p;
+    break;
+  case BuiltinType::Char_S:
+  case BuiltinType::SChar:
+    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequb_p :
+                            llvm::Intrinsic::ppc_altivec_vcmpgtsb_p;
+    break;
+  case BuiltinType::UShort:
+    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
+                            llvm::Intrinsic::ppc_altivec_vcmpgtuh_p;
+    break;
+  case BuiltinType::Short:
+    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequh_p :
+                            llvm::Intrinsic::ppc_altivec_vcmpgtsh_p;
+    break;
+  case BuiltinType::UInt:
+  case BuiltinType::ULong:
+    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
+                            llvm::Intrinsic::ppc_altivec_vcmpgtuw_p;
+    break;
+  case BuiltinType::Int:
+  case BuiltinType::Long:
+    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpequw_p :
+                            llvm::Intrinsic::ppc_altivec_vcmpgtsw_p;
+    break;
+  case BuiltinType::Float:
+    return (IT == VCMPEQ) ? llvm::Intrinsic::ppc_altivec_vcmpeqfp_p :
+                            llvm::Intrinsic::ppc_altivec_vcmpgtfp_p;
+    break;
+  }
+  return llvm::Intrinsic::not_intrinsic;
+}
+
 Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
   // LLVM requires the LHS and RHS to be the same type: promote or truncate the
   // RHS to the same size as the LHS.
@@ -2015,6 +2057,72 @@
     Value *LHS = Visit(E->getLHS());
     Value *RHS = Visit(E->getRHS());
 
+    // If AltiVec, the comparison results in a numeric type, so we use
+    // intrinsics comparing vectors and giving 0 or 1 as a result
+    if (LHSTy->isVectorType() && CGF.getContext().getLangOptions().AltiVec) {
+      // constants for mapping CR6 register bits to predicate result
+      enum { CR6_EQ=0, CR6_EQ_REV, CR6_LT, CR6_LT_REV } CR6;
+
+      llvm::Intrinsic::ID ID = llvm::Intrinsic::not_intrinsic;
+
+      // in several cases vector arguments order will be reversed
+      Value *FirstVecArg = LHS,
+            *SecondVecArg = RHS;
+
+      QualType ElTy = LHSTy->getAs<VectorType>()->getElementType();
+      Type *Ty = CGF.getContext().getCanonicalType(ElTy).getTypePtr();
+      const BuiltinType *BTy = dyn_cast<BuiltinType>(Ty);
+      BuiltinType::Kind ElementKind = BTy->getKind();
+
+      switch(E->getOpcode()) {
+      default: assert(0 && "is not a comparison operation");
+      case BO_EQ:
+        CR6 = CR6_LT;
+        ID = GetIntrinsic(VCMPEQ, ElementKind);
+        break;
+      case BO_NE:
+        CR6 = CR6_EQ;
+        ID = GetIntrinsic(VCMPEQ, ElementKind);
+        break;
+      case BO_LT:
+        CR6 = CR6_LT;
+        ID = GetIntrinsic(VCMPGT, ElementKind);
+        std::swap(FirstVecArg, SecondVecArg);
+        break;
+      case BO_GT:
+        CR6 = CR6_LT;
+        ID = GetIntrinsic(VCMPGT, ElementKind);
+        break;
+      case BO_LE:
+        if (ElementKind == BuiltinType::Float) {
+          CR6 = CR6_LT;
+          ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
+          std::swap(FirstVecArg, SecondVecArg);
+        }
+        else {
+          CR6 = CR6_EQ;
+          ID = GetIntrinsic(VCMPGT, ElementKind);
+        }
+        break;
+      case BO_GE:
+        if (ElementKind == BuiltinType::Float) {
+          CR6 = CR6_LT;
+          ID = llvm::Intrinsic::ppc_altivec_vcmpgefp_p;
+        }
+        else {
+          CR6 = CR6_EQ;
+          ID = GetIntrinsic(VCMPGT, ElementKind);
+          std::swap(FirstVecArg, SecondVecArg);
+        }
+        break;
+      }
+
+      Value *CR6Param = llvm::ConstantInt::get(CGF.Int32Ty, CR6);
+      llvm::Function *F = CGF.CGM.getIntrinsic(ID);
+      Result = Builder.CreateCall3(F, CR6Param, FirstVecArg, SecondVecArg, "");
+      return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType());
+    }
+
     if (LHS->getType()->isFPOrFPVectorTy()) {
       Result = Builder.CreateFCmp((llvm::CmpInst::Predicate)FCmpOpc,
                                   LHS, RHS, "cmp");
