#!/bin/sh

set -x

echo "This was applied to Morbo revision 115315: svn info llvmgcc42.morbo llvmCore.morbo | grep Revision == Revision: 115315"

echo "back out of Morbo: <rdar://problem/8156507> MINSSrm_Int is missing memoperand"
svn merge -c -113586 llvmCore.morbo llvmCore.morbo

echo "back out of Morbo: <rdar://problem/7734653> CPU codegen regression for byte interleaving 4 vectors"
svn merge -c -113368 llvmCore.morbo llvmCore.morbo

echo "back out of Morbo: <rdar://problem/8305081> llvm-gcc doesn't honor asm register variables"
echo "Note that we want this omitted from -2335, but we want it reapplied to the Morbo branch after -2335 has been tagged."
svn merge -c -114360 llvmCore.morbo llvmCore.morbo
svn merge -c -114359 llvmgcc42.morbo llvmgcc42.morbo

echo "back out of Morbo: <rdar://problem/8286101> SWB: clang-110 on Barolo11A231: Assertion failed: (*offset_ptr == end_prologue_offset)"
svn merge -c -114355 llvmCore.morbo llvmCore.morbo

echo "back out of Morbo: <rdar://problem/8251350> DejaGnu: gcc/testsuite/gcc.c-torture/execute/builtin-bitops-1.c assertion failure"
svn merge -c -114346 llvmgcc42.morbo llvmgcc42.morbo

echo "verify present in Morbo branch: <rdar://problem/8467536> 11A274: xnu-1699.9 fails to build with internal compiler error"
echo "Note this was r114723 on trunk, committed to Morbo in r114730.  Morbo revision number is not mentioned in the Radar."
svn diff -c 114730 llvmCore.morbo

echo "verify present in Morbo branch: <rdar://problem/8412415> gdb is lying even more than usual in 11A260 and 11A261"
svn diff -c 114590 llvmCore.morbo

llvm-svn: 115327
diff --git a/llvm-gcc-4.2/gcc/llvm-convert.cpp b/llvm-gcc-4.2/gcc/llvm-convert.cpp
index a94f2dc..48adcd5 100644
--- a/llvm-gcc-4.2/gcc/llvm-convert.cpp
+++ b/llvm-gcc-4.2/gcc/llvm-convert.cpp
@@ -2410,14 +2410,14 @@
 //                           ... Expressions ...
 //===----------------------------------------------------------------------===//
 
-static bool canEmitLocalRegisterVariable(tree exp) {
+static bool canEmitRegisterVariable(tree exp) {
   // Only variables can be marked as 'register'.
   if (TREE_CODE(exp) != VAR_DECL || !DECL_REGISTER(exp))
     return false;
 
-  // Global register variables are not accepted here.
+  // We can emit inline assembler for access to global register variables.
   if (TREE_STATIC(exp) || DECL_EXTERNAL(exp) || TREE_PUBLIC(exp))
-    return false;
+    return true;
 
   // Emit inline asm if this is local variable with assembler name on it.
   if (DECL_ASSEMBLER_NAME_SET_P(exp))
@@ -2427,19 +2427,6 @@
   return false;
 }
 
-static bool canEmitGlobalRegisterVariable(tree exp) {
-  // Only variables can be marked as 'register'.
-  if (TREE_CODE(exp) != VAR_DECL || !DECL_REGISTER(exp))
-    return false;
-
-  // Local register variables are not accepted here.
-  if (TREE_STATIC(exp) || DECL_EXTERNAL(exp) || TREE_PUBLIC(exp))
-    return true;
-
-  // Otherwise - it's normal automatic variable, or local register variable.
-  return false;
-}
-
 
 /// EmitLoadOfLValue - When an l-value expression is used in a context that
 /// requires an r-value, this method emits the lvalue computation, then loads
@@ -2457,10 +2444,10 @@
     DECL_GIMPLE_FORMAL_TEMP_P(exp) = 0;
     EmitAutomaticVariableDecl(exp);
     // Fall through.
-  } else if (canEmitGlobalRegisterVariable(exp)) {
-    // If this is a global register variable, EmitLV can't handle it (there is
-    // no l-value of a global register variable).  Emit an inline asm node that
-    // copies the value out of the specified register.
+  } else if (canEmitRegisterVariable(exp)) {
+    // If this is a register variable, EmitLV can't handle it (there is no
+    // l-value of a register variable).  Emit an inline asm node that copies the
+    // value out of the specified register.
     return EmitReadOfRegisterVariable(exp, DestLoc);
   }
 
@@ -2482,11 +2469,7 @@
       Value *Ptr = BitCastToType(LV.Ptr, Ty->getPointerTo());
       LoadInst *LI = Builder.CreateLoad(Ptr, isVolatile);
       LI->setAlignment(Alignment);
-      if (canEmitLocalRegisterVariable(exp)) {
-        // For register variable, move the loaded variable into the right reg.
-        return EmitMoveOfRegVariableToRightReg(LI, exp);
-      } else
-        return LI;
+      return LI;
     } else {
       EmitAggregateCopy(*DestLoc, MemRef(LV.Ptr, Alignment, isVolatile),
                         TREE_TYPE(exp));
@@ -3272,10 +3255,10 @@
     Builder.Insert(Cast);
     SET_DECL_LLVM(lhs, Cast);
     return Cast;
-  } else if (canEmitGlobalRegisterVariable(lhs)) {
-    // If this is a store to a global register variable, EmitLV can't handle the
-    // dest (there is no l-value of a global register variable).  Emit an inline
-    // asm node that copies the value into the specified register.
+  } else if (canEmitRegisterVariable(lhs)) {
+    // If this is a store to a register variable, EmitLV can't handle the dest
+    // (there is no l-value of a register variable).  Emit an inline asm node
+    // that copies the value into the specified register.
     Value *RHS = Emit(rhs, 0);
     RHS = CastToAnyType(RHS, RHSSigned, ConvertType(TREE_TYPE(lhs)), LHSSigned);
     EmitModifyOfRegisterVariable(lhs, RHS);
@@ -4204,8 +4187,8 @@
 #define LLVM_GET_REG_NAME(REG_NAME, REG_NUM) reg_names[REG_NUM]
 #endif
 
- /// Reads from global register variables are handled by emitting an inline
- /// asm node that copies the value out of the specified register.
+/// Reads from register variables are handled by emitting an inline asm node
+/// that copies the value out of the specified register.
 Value *TreeToLLVM::EmitReadOfRegisterVariable(tree decl,
                                               const MemRef *DestLoc) {
   const Type *Ty = ConvertType(TREE_TYPE(decl));
@@ -4230,43 +4213,8 @@
   return Call;
 }
 
-/// Reads from register variables are handled by emitting an inline asm node
-/// that copies the value out of the specified register.
-Value *TreeToLLVM::EmitMoveOfRegVariableToRightReg(Instruction *I, tree var) {
-  // Create a 'call void asm sideeffect "", "{reg}"(Ty %RHS)'.
-  const Type *Ty = I->getType();
-
-  // If there was an error, return something bogus.
-  if (ValidateRegisterVariable(var)) {
-    if (Ty->isSingleValueType())
-      return UndefValue::get(Ty);
-    return 0;   // Just don't copy something into DestLoc.
-  }
-
-  std::vector<const Type*> ArgTys;
-  ArgTys.push_back(Ty);
-  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), 
-                                        ArgTys, false);
-  const char *Name = extractRegisterName(var);
-  int RegNum = decode_reg_name(Name);
-  Name = LLVM_GET_REG_NAME(Name, RegNum);
-  InlineAsm *IA = InlineAsm::get(FTy, "", "{"+std::string(Name)+"}", 
-                                    true);
-  CallInst *Call = Builder.CreateCall(IA, I);
-  Call->setDoesNotThrow();
-  // Create another asm with the same reg, this time producing an output.
-  // Turn this into a 'tmp = call Ty asm "", "={reg}"()'.
-  FunctionType *FTy2 = FunctionType::get(Ty, std::vector<const Type*>(),
-                                        false);
-  InlineAsm *IA2 = InlineAsm::get(FTy2, "", "={"+std::string(Name)+"}",
-                                 true);
-  CallInst *Call2 = Builder.CreateCall(IA2);
-  Call2->setDoesNotThrow();
-  return Call2;
-}
-
-/// Stores to global register variables are handled by emitting an inline asm
-/// node that copies the value into the specified register.
+/// Stores to register variables are handled by emitting an inline asm node
+/// that copies the value into the specified register.
 void TreeToLLVM::EmitModifyOfRegisterVariable(tree decl, Value *RHS) {
   // If there was an error, bail out.
   if (ValidateRegisterVariable(decl))
@@ -5454,10 +5402,6 @@
     EmitBuiltinUnaryOp(Amt, Result, Intrinsic::ctpop);
     Result = Builder.CreateBinOp(Instruction::And, Result,
                                  ConstantInt::get(Result->getType(), 1));
-    const Type *DestTy = ConvertType(TREE_TYPE(exp));
-    Result = Builder.CreateIntCast(Result, DestTy,
-                                   !TYPE_UNSIGNED(TREE_TYPE(exp)),
-                                   "cast");
     return true;
   }
   case BUILT_IN_POPCOUNT:  // These GCC builtins always return int.
diff --git a/llvm-gcc-4.2/gcc/llvm-internal.h b/llvm-gcc-4.2/gcc/llvm-internal.h
index 1919e9c..483b5ef 100644
--- a/llvm-gcc-4.2/gcc/llvm-internal.h
+++ b/llvm-gcc-4.2/gcc/llvm-internal.h
@@ -526,7 +526,6 @@
   Value *EmitASM_EXPR(tree_node *exp);
   Value *EmitReadOfRegisterVariable(tree_node *vardecl, const MemRef *DestLoc);
   void EmitModifyOfRegisterVariable(tree_node *vardecl, Value *RHS);
-  Value *EmitMoveOfRegVariableToRightReg(Instruction *I, tree_node *decl);
 
   // Helpers for Builtin Function Expansion.
   void EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device);