Kill off the 'coerce' ABI passing form.  Now 'direct' and 'extend' always
have a "coerce to" type which often matches the default lowering of Clang
type to LLVM IR type, but the coerce case can be handled by making them
not be the same.

This simplifies things and fixes issues where X86-64 abi lowering would 
return coerce after making preferred types exactly match up.  This caused
us to compile:

typedef float v4f32 __attribute__((__vector_size__(16)));
v4f32 foo(v4f32 X) {
  return X+X;
}

into this code at -O0:

define <4 x float> @foo(<4 x float> %X.coerce) nounwind {
entry:
  %retval = alloca <4 x float>, align 16          ; <<4 x float>*> [#uses=2]
  %coerce = alloca <4 x float>, align 16          ; <<4 x float>*> [#uses=2]
  %X.addr = alloca <4 x float>, align 16          ; <<4 x float>*> [#uses=3]
  store <4 x float> %X.coerce, <4 x float>* %coerce
  %X = load <4 x float>* %coerce                  ; <<4 x float>> [#uses=1]
  store <4 x float> %X, <4 x float>* %X.addr
  %tmp = load <4 x float>* %X.addr                ; <<4 x float>> [#uses=1]
  %tmp1 = load <4 x float>* %X.addr               ; <<4 x float>> [#uses=1]
  %add = fadd <4 x float> %tmp, %tmp1             ; <<4 x float>> [#uses=1]
  store <4 x float> %add, <4 x float>* %retval
  %0 = load <4 x float>* %retval                  ; <<4 x float>> [#uses=1]
  ret <4 x float> %0
}

Now we get:

define <4 x float> @foo(<4 x float> %X) nounwind {
entry:
  %X.addr = alloca <4 x float>, align 16          ; <<4 x float>*> [#uses=3]
  store <4 x float> %X, <4 x float>* %X.addr
  %tmp = load <4 x float>* %X.addr                ; <<4 x float>> [#uses=1]
  %tmp1 = load <4 x float>* %X.addr               ; <<4 x float>> [#uses=1]
  %add = fadd <4 x float> %tmp, %tmp1             ; <<4 x float>> [#uses=1]
  ret <4 x float> %add
}

This implements rdar://8248065



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109733 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 30f99c3..642fddb 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -38,17 +38,13 @@
   class ABIArgInfo {
   public:
     enum Kind {
-      Direct,    /// Pass the argument directly using the normal
-                 /// converted LLVM type. Complex and structure types
-                 /// are passed using first class aggregates.
+      Direct,    /// Pass the argument directly using the normal converted LLVM
+                 /// type, or by coercing to another specified type
+                 /// (stored in 'CoerceToType').
 
       Extend,    /// Valid only for integer argument types. Same as 'direct'
                  /// but also emit a zero/sign extension attribute.
 
-      Coerce,    /// Only valid for aggregate return types, the argument
-                 /// should be accessed by coercion to a provided type.
-      
-      
       Indirect,  /// Pass the argument indirectly via a hidden pointer
                  /// with the specified alignment (0 indicates default
                  /// alignment).
@@ -79,8 +75,8 @@
   public:
     ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
 
-    static ABIArgInfo getDirect() {
-      return ABIArgInfo(Direct);
+    static ABIArgInfo getDirect(const llvm::Type *T = 0) {
+      return ABIArgInfo(Direct, T);
     }
     static ABIArgInfo getExtend() {
       return ABIArgInfo(Extend);
@@ -88,9 +84,6 @@
     static ABIArgInfo getIgnore() {
       return ABIArgInfo(Ignore);
     }
-    static ABIArgInfo getCoerce(const llvm::Type *T) {
-      return ABIArgInfo(Coerce, T);
-    }
     static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
       return ABIArgInfo(Indirect, 0, Alignment, ByVal);
     }
@@ -102,16 +95,23 @@
     bool isDirect() const { return TheKind == Direct; }
     bool isExtend() const { return TheKind == Extend; }
     bool isIgnore() const { return TheKind == Ignore; }
-    bool isCoerce() const { return TheKind == Coerce; }
     bool isIndirect() const { return TheKind == Indirect; }
     bool isExpand() const { return TheKind == Expand; }
 
-    // Coerce accessors
+    bool canHaveCoerceToType() const {
+      return TheKind == Direct || TheKind == Extend;
+    }
+    
+    // Direct/Extend accessors
     const llvm::Type *getCoerceToType() const {
-      assert(TheKind == Coerce && "Invalid kind!");
+      assert(canHaveCoerceToType() && "Invalid kind!");
       return TypeData;
     }
-
+    
+    void setCoerceToType(const llvm::Type *T) {
+      assert(canHaveCoerceToType() && "Invalid kind!");
+      TypeData = T;
+    }
     // Indirect accessors
     unsigned getIndirectAlign() const {
       assert(TheKind == Indirect && "Invalid kind!");
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index f0e1079..94cfd98 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -245,6 +245,18 @@
 
   // Compute ABI information.
   getABIInfo().computeInfo(*FI);
+  
+  // Loop over all of the computed argument and return value info.  If any of
+  // them are direct or extend without a specified coerce type, specify the
+  // default now.
+  ABIArgInfo &RetInfo = FI->getReturnInfo();
+  if (RetInfo.canHaveCoerceToType() && RetInfo.getCoerceToType() == 0)
+    RetInfo.setCoerceToType(ConvertTypeRecursive(FI->getReturnType()));
+  
+  for (CGFunctionInfo::arg_iterator I = FI->arg_begin(), E = FI->arg_end();
+       I != E; ++I)
+    if (I->info.canHaveCoerceToType() && I->info.getCoerceToType() == 0)
+      I->info.setCoerceToType(ConvertTypeRecursive(I->type));
 
   // If this is a top-level call and ConvertTypeRecursive hit unresolved pointer
   // types, resolve them now.  These pointers may point to this function, which
@@ -592,7 +604,7 @@
 
   case ABIArgInfo::Extend:
   case ABIArgInfo::Direct:
-    ResultType = ConvertType(RetTy, IsRecursive);
+    ResultType = RetAI.getCoerceToType();
     break;
 
   case ABIArgInfo::Indirect: {
@@ -606,10 +618,6 @@
   case ABIArgInfo::Ignore:
     ResultType = llvm::Type::getVoidTy(getLLVMContext());
     break;
-
-  case ABIArgInfo::Coerce:
-    ResultType = RetAI.getCoerceToType();
-    break;
   }
 
   for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
@@ -620,7 +628,15 @@
     case ABIArgInfo::Ignore:
       break;
 
-    case ABIArgInfo::Coerce: {
+    case ABIArgInfo::Indirect: {
+      // indirect arguments are always on the stack, which is addr space #0.
+      const llvm::Type *LTy = ConvertTypeForMem(it->type, IsRecursive);
+      ArgTys.push_back(llvm::PointerType::getUnqual(LTy));
+      break;
+    }
+
+    case ABIArgInfo::Extend:
+    case ABIArgInfo::Direct:
       // If the coerce-to type is a first class aggregate, flatten it.  Either
       // way is semantically identical, but fast-isel and the optimizer
       // generally likes scalar values better than FCAs.
@@ -632,19 +648,6 @@
         ArgTys.push_back(ArgTy);
       }
       break;
-    }
-
-    case ABIArgInfo::Indirect: {
-      // indirect arguments are always on the stack, which is addr space #0.
-      const llvm::Type *LTy = ConvertTypeForMem(it->type, IsRecursive);
-      ArgTys.push_back(llvm::PointerType::getUnqual(LTy));
-      break;
-    }
-
-    case ABIArgInfo::Extend:
-    case ABIArgInfo::Direct:
-      ArgTys.push_back(ConvertType(it->type, IsRecursive));
-      break;
 
     case ABIArgInfo::Expand:
       GetExpandedTypes(it->type, ArgTys, IsRecursive);
@@ -713,8 +716,9 @@
      RetAttrs |= llvm::Attribute::SExt;
    else if (RetTy->hasUnsignedIntegerRepresentation())
      RetAttrs |= llvm::Attribute::ZExt;
-   // FALLTHROUGH
+    break;
   case ABIArgInfo::Direct:
+  case ABIArgInfo::Ignore:
     break;
 
   case ABIArgInfo::Indirect:
@@ -726,10 +730,6 @@
                    llvm::Attribute::ReadNone);
     break;
 
-  case ABIArgInfo::Ignore:
-  case ABIArgInfo::Coerce:
-    break;
-
   case ABIArgInfo::Expand:
     assert(0 && "Invalid ABI kind for return argument");
   }
@@ -752,15 +752,27 @@
     // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we
     // have the corresponding parameter variable.  It doesn't make
     // sense to do it here because parameters are so fucked up.
-
     switch (AI.getKind()) {
-    case ABIArgInfo::Coerce:
+    case ABIArgInfo::Extend:
+      if (ParamType->isSignedIntegerType())
+        Attributes |= llvm::Attribute::SExt;
+      else if (ParamType->isUnsignedIntegerType())
+        Attributes |= llvm::Attribute::ZExt;
+      // FALL THROUGH
+    case ABIArgInfo::Direct:
+      if (RegParm > 0 &&
+          (ParamType->isIntegerType() || ParamType->isPointerType())) {
+        RegParm -=
+        (Context.getTypeSize(ParamType) + PointerWidth - 1) / PointerWidth;
+        if (RegParm >= 0)
+          Attributes |= llvm::Attribute::InReg;
+      }
+      // FIXME: handle sseregparm someday...
+        
       if (const llvm::StructType *STy =
-          dyn_cast<llvm::StructType>(AI.getCoerceToType()))
-        Index += STy->getNumElements();
-      else
-        ++Index;
-      continue;  // Skip index increment.
+            dyn_cast<llvm::StructType>(AI.getCoerceToType()))
+        Index += STy->getNumElements()-1;  // 1 will be added below.
+      break;
 
     case ABIArgInfo::Indirect:
       if (AI.getIndirectByVal())
@@ -773,23 +785,6 @@
                      llvm::Attribute::ReadNone);
       break;
 
-    case ABIArgInfo::Extend:
-      if (ParamType->isSignedIntegerType())
-        Attributes |= llvm::Attribute::SExt;
-      else if (ParamType->isUnsignedIntegerType())
-        Attributes |= llvm::Attribute::ZExt;
-     // FALLS THROUGH
-    case ABIArgInfo::Direct:
-      if (RegParm > 0 &&
-          (ParamType->isIntegerType() || ParamType->isPointerType())) {
-        RegParm -=
-          (Context.getTypeSize(ParamType) + PointerWidth - 1) / PointerWidth;
-        if (RegParm >= 0)
-          Attributes |= llvm::Attribute::InReg;
-      }
-      // FIXME: handle sseregparm someday...
-      break;
-
     case ABIArgInfo::Ignore:
       // Skip increment, no matching LLVM parameter.
       continue;
@@ -871,15 +866,12 @@
 
     case ABIArgInfo::Extend:
     case ABIArgInfo::Direct: {
-      assert(AI != Fn->arg_end() && "Argument mismatch!");
-      llvm::Value *V = AI;
-      if (hasAggregateLLVMType(Ty)) {
-        // Create a temporary alloca to hold the argument; the rest of
-        // codegen expects to access aggregates & complex values by
-        // reference.
-        V = CreateMemTemp(Ty);
-        Builder.CreateStore(AI, V);
-      } else {
+      // If we have the trivial case, handle it with no muss and fuss.
+      if (!isa<llvm::StructType>(ArgI.getCoerceToType()) &&
+          ArgI.getCoerceToType() == ConvertType(Ty)) {
+        assert(AI != Fn->arg_end() && "Argument mismatch!");
+        llvm::Value *V = AI;
+        
         if (Arg->getType().isRestrictQualified())
           AI->addAttr(llvm::Attribute::NoAlias);
 
@@ -888,40 +880,10 @@
           // "void a(x) short x; {..."
           V = EmitScalarConversion(V, Ty, Arg->getType());
         }
-      }
-      EmitParmDecl(*Arg, V);
-      break;
-    }
-
-    case ABIArgInfo::Expand: {
-      // If this structure was expanded into multiple arguments then
-      // we need to create a temporary and reconstruct it from the
-      // arguments.
-      llvm::Value *Temp = CreateMemTemp(Ty, Arg->getName() + ".addr");
-      // FIXME: What are the right qualifiers here?
-      llvm::Function::arg_iterator End =
-        ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp, Qualifiers()), AI);
-      EmitParmDecl(*Arg, Temp);
-
-      // Name the arguments used in expansion and increment AI.
-      unsigned Index = 0;
-      for (; AI != End; ++AI, ++Index)
-        AI->setName(Arg->getName() + "." + llvm::Twine(Index));
-      continue;
-    }
-
-    case ABIArgInfo::Ignore:
-      // Initialize the local variable appropriately.
-      if (hasAggregateLLVMType(Ty)) {
-        EmitParmDecl(*Arg, CreateMemTemp(Ty));
-      } else {
-        EmitParmDecl(*Arg, llvm::UndefValue::get(ConvertType(Arg->getType())));
+        EmitParmDecl(*Arg, V);
+        break;
       }
 
-      // Skip increment, no matching LLVM parameter.
-      continue;
-
-    case ABIArgInfo::Coerce: {
       llvm::AllocaInst *Alloca = CreateMemTemp(Ty, "coerce");
       
       // The alignment we need to use is the max of the requested alignment for
@@ -968,6 +930,33 @@
       EmitParmDecl(*Arg, V);
       continue;  // Skip ++AI increment, already done.
     }
+
+    case ABIArgInfo::Expand: {
+      // If this structure was expanded into multiple arguments then
+      // we need to create a temporary and reconstruct it from the
+      // arguments.
+      llvm::Value *Temp = CreateMemTemp(Ty, Arg->getName() + ".addr");
+      // FIXME: What are the right qualifiers here?
+      llvm::Function::arg_iterator End =
+        ExpandTypeFromArgs(Ty, LValue::MakeAddr(Temp, Qualifiers()), AI);
+      EmitParmDecl(*Arg, Temp);
+
+      // Name the arguments used in expansion and increment AI.
+      unsigned Index = 0;
+      for (; AI != End; ++AI, ++Index)
+        AI->setName(Arg->getName() + "." + llvm::Twine(Index));
+      continue;
+    }
+
+    case ABIArgInfo::Ignore:
+      // Initialize the local variable appropriately.
+      if (hasAggregateLLVMType(Ty))
+        EmitParmDecl(*Arg, CreateMemTemp(Ty));
+      else
+        EmitParmDecl(*Arg, llvm::UndefValue::get(ConvertType(Arg->getType())));
+
+      // Skip increment, no matching LLVM parameter.
+      continue;
     }
 
     ++AI;
@@ -1001,38 +990,39 @@
     break;
 
   case ABIArgInfo::Extend:
-  case ABIArgInfo::Direct: {
-    // The internal return value temp always will have pointer-to-return-type
-    // type, just do a load.
-      
-    // If the instruction right before the insertion point is a store to the
-    // return value, we can elide the load, zap the store, and usually zap the
-    // alloca.
-    llvm::BasicBlock *InsertBB = Builder.GetInsertBlock();
-    llvm::StoreInst *SI = 0;
-    if (InsertBB->empty() || 
-        !(SI = dyn_cast<llvm::StoreInst>(&InsertBB->back())) ||
-        SI->getPointerOperand() != ReturnValue || SI->isVolatile()) {
-      RV = Builder.CreateLoad(ReturnValue);
-    } else {
-      // Get the stored value and nuke the now-dead store.
-      RetDbgLoc = SI->getDebugLoc();
-      RV = SI->getValueOperand();
-      SI->eraseFromParent();
-      
-      // If that was the only use of the return value, nuke it as well now.
-      if (ReturnValue->use_empty() && isa<llvm::AllocaInst>(ReturnValue)) {
-        cast<llvm::AllocaInst>(ReturnValue)->eraseFromParent();
-        ReturnValue = 0;
+  case ABIArgInfo::Direct:
+    
+    if (RetAI.getCoerceToType() == ConvertType(RetTy)) {
+      // The internal return value temp always will have pointer-to-return-type
+      // type, just do a load.
+        
+      // If the instruction right before the insertion point is a store to the
+      // return value, we can elide the load, zap the store, and usually zap the
+      // alloca.
+      llvm::BasicBlock *InsertBB = Builder.GetInsertBlock();
+      llvm::StoreInst *SI = 0;
+      if (InsertBB->empty() || 
+          !(SI = dyn_cast<llvm::StoreInst>(&InsertBB->back())) ||
+          SI->getPointerOperand() != ReturnValue || SI->isVolatile()) {
+        RV = Builder.CreateLoad(ReturnValue);
+      } else {
+        // Get the stored value and nuke the now-dead store.
+        RetDbgLoc = SI->getDebugLoc();
+        RV = SI->getValueOperand();
+        SI->eraseFromParent();
+        
+        // If that was the only use of the return value, nuke it as well now.
+        if (ReturnValue->use_empty() && isa<llvm::AllocaInst>(ReturnValue)) {
+          cast<llvm::AllocaInst>(ReturnValue)->eraseFromParent();
+          ReturnValue = 0;
+        }
       }
+    } else {
+      RV = CreateCoercedLoad(ReturnValue, RetAI.getCoerceToType(), *this);
     }
     break;
-  }
-  case ABIArgInfo::Ignore:
-    break;
 
-  case ABIArgInfo::Coerce:
-    RV = CreateCoercedLoad(ReturnValue, RetAI.getCoerceToType(), *this);
+  case ABIArgInfo::Ignore:
     break;
 
   case ABIArgInfo::Expand:
@@ -1145,24 +1135,20 @@
       }
       break;
 
-    case ABIArgInfo::Extend:
-    case ABIArgInfo::Direct:
-      if (RV.isScalar()) {
-        Args.push_back(RV.getScalarVal());
-      } else if (RV.isComplex()) {
-        llvm::Value *Tmp = llvm::UndefValue::get(ConvertType(I->second));
-        Tmp = Builder.CreateInsertValue(Tmp, RV.getComplexVal().first, 0);
-        Tmp = Builder.CreateInsertValue(Tmp, RV.getComplexVal().second, 1);
-        Args.push_back(Tmp);
-      } else {
-        Args.push_back(Builder.CreateLoad(RV.getAggregateAddr()));
-      }
-      break;
-
     case ABIArgInfo::Ignore:
       break;
+        
+    case ABIArgInfo::Extend:
+    case ABIArgInfo::Direct: {
+      if (!isa<llvm::StructType>(ArgInfo.getCoerceToType()) &&
+          ArgInfo.getCoerceToType() == ConvertType(info_it->type)) {
+        if (RV.isScalar())
+          Args.push_back(RV.getScalarVal());
+        else
+          Args.push_back(Builder.CreateLoad(RV.getAggregateAddr()));
+        break;
+      }
 
-    case ABIArgInfo::Coerce: {
       // FIXME: Avoid the conversion through memory if possible.
       llvm::Value *SrcPtr;
       if (RV.isScalar()) {
@@ -1286,32 +1272,33 @@
       return RValue::getAggregate(Args[0]);
     return RValue::get(EmitLoadOfScalar(Args[0], false, RetTy));
 
-  case ABIArgInfo::Extend:
-  case ABIArgInfo::Direct:
-    if (RetTy->isAnyComplexType()) {
-      llvm::Value *Real = Builder.CreateExtractValue(CI, 0);
-      llvm::Value *Imag = Builder.CreateExtractValue(CI, 1);
-      return RValue::getComplex(std::make_pair(Real, Imag));
-    }
-    if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
-      llvm::Value *DestPtr = ReturnValue.getValue();
-      bool DestIsVolatile = ReturnValue.isVolatile();
-
-      if (!DestPtr) {
-        DestPtr = CreateMemTemp(RetTy, "agg.tmp");
-        DestIsVolatile = false;
-      }
-      Builder.CreateStore(CI, DestPtr, DestIsVolatile);
-      return RValue::getAggregate(DestPtr);
-    }
-    return RValue::get(CI);
-
   case ABIArgInfo::Ignore:
     // If we are ignoring an argument that had a result, make sure to
     // construct the appropriate return value for our caller.
     return GetUndefRValue(RetTy);
+    
+  case ABIArgInfo::Extend:
+  case ABIArgInfo::Direct: {
+    if (RetAI.getCoerceToType() == ConvertType(RetTy)) {
+      if (RetTy->isAnyComplexType()) {
+        llvm::Value *Real = Builder.CreateExtractValue(CI, 0);
+        llvm::Value *Imag = Builder.CreateExtractValue(CI, 1);
+        return RValue::getComplex(std::make_pair(Real, Imag));
+      }
+      if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
+        llvm::Value *DestPtr = ReturnValue.getValue();
+        bool DestIsVolatile = ReturnValue.isVolatile();
 
-  case ABIArgInfo::Coerce: {
+        if (!DestPtr) {
+          DestPtr = CreateMemTemp(RetTy, "agg.tmp");
+          DestIsVolatile = false;
+        }
+        Builder.CreateStore(CI, DestPtr, DestIsVolatile);
+        return RValue::getAggregate(DestPtr);
+      }
+      return RValue::get(CI);
+    }
+      
     llvm::Value *DestPtr = ReturnValue.getValue();
     bool DestIsVolatile = ReturnValue.isVolatile();
     
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index c7f48e6..54019f9 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -14,13 +14,12 @@
 #ifndef CLANG_CODEGEN_CODEGENTYPES_H
 #define CLANG_CODEGEN_CODEGENTYPES_H
 
+#include "CGCall.h"
+#include "GlobalDecl.h"
 #include "llvm/Module.h"
 #include "llvm/ADT/DenseMap.h"
 #include <vector>
 
-#include "CGCall.h"
-#include "GlobalDecl.h"
-
 namespace llvm {
   class FunctionType;
   class Module;
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index e8e4c5c..0f0dc0f 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -56,7 +56,11 @@
   OS << "(ABIArgInfo Kind=";
   switch (TheKind) {
   case Direct:
-    OS << "Direct";
+    OS << "Direct Type=";
+    if (const llvm::Type *Ty = getCoerceToType())
+      Ty->print(OS);
+    else
+      OS << "null";
     break;
   case Extend:
     OS << "Extend";
@@ -64,10 +68,6 @@
   case Ignore:
     OS << "Ignore";
     break;
-  case Coerce:
-    OS << "Coerce Type=";
-    getCoerceToType()->print(OS);
-    break;
   case Indirect:
     OS << "Indirect Align=" << getIndirectAlign()
        << " Byal=" << getIndirectByVal();
@@ -451,14 +451,14 @@
       // registers and we need to make sure to pick a type the LLVM
       // backend will like.
       if (Size == 128)
-        return ABIArgInfo::getCoerce(llvm::VectorType::get(
+        return ABIArgInfo::getDirect(llvm::VectorType::get(
                   llvm::Type::getInt64Ty(getVMContext()), 2));
 
       // Always return in register if it fits in a general purpose
       // register, or if it is 64 bits and has a single element.
       if ((Size == 8 || Size == 16 || Size == 32) ||
           (Size == 64 && VT->getNumElements() == 1))
-        return ABIArgInfo::getCoerce(llvm::IntegerType::get(getVMContext(),
+        return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
                                                             Size));
 
       return ABIArgInfo::getIndirect(0);
@@ -491,7 +491,7 @@
           // bit-fields can adjust that to be larger than the single
           // element type.
           uint64_t Size = getContext().getTypeSize(RetTy);
-          return ABIArgInfo::getCoerce(
+          return ABIArgInfo::getDirect(
             llvm::IntegerType::get(getVMContext(), (unsigned)Size));
         }
         
@@ -499,20 +499,20 @@
           assert(getContext().getTypeSize(RetTy) ==
                  getContext().getTypeSize(SeltTy) &&
                  "Unexpect single element structure size!");
-          return ABIArgInfo::getCoerce(llvm::Type::getFloatTy(getVMContext()));
+          return ABIArgInfo::getDirect(llvm::Type::getFloatTy(getVMContext()));
         }
         
         if (BT->getKind() == BuiltinType::Double) {
           assert(getContext().getTypeSize(RetTy) ==
                  getContext().getTypeSize(SeltTy) &&
                  "Unexpect single element structure size!");
-          return ABIArgInfo::getCoerce(llvm::Type::getDoubleTy(getVMContext()));
+          return ABIArgInfo::getDirect(llvm::Type::getDoubleTy(getVMContext()));
         }
       } else if (SeltTy->isPointerType()) {
         // FIXME: It would be really nice if this could come out as the proper
         // pointer type.
         const llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(getVMContext());
-        return ABIArgInfo::getCoerce(PtrTy);
+        return ABIArgInfo::getDirect(PtrTy);
       } else if (SeltTy->isVectorType()) {
         // 64- and 128-bit vectors are never returned in a
         // register when inside a structure.
@@ -528,7 +528,7 @@
     // in a register.
     if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) {
       uint64_t Size = getContext().getTypeSize(RetTy);
-      return ABIArgInfo::getCoerce(llvm::IntegerType::get(getVMContext(),Size));
+      return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size));
     }
 
     return ABIArgInfo::getIndirect(0);
@@ -1139,7 +1139,7 @@
       CoerceTo = llvm::Type::getFloatTy(CoerceTo->getContext());
   }
 
-  return ABIArgInfo::getCoerce(CoerceTo);
+  return ABIArgInfo::getDirect(CoerceTo);
 }
 
 ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const {
@@ -1195,8 +1195,6 @@
     STy = dyn_cast<llvm::StructType>(IRType);
   }
   
-  
-  
   // If the preferred type is a 16-byte vector, prefer to pass it.
   if (const llvm::VectorType *VT = dyn_cast<llvm::VectorType>(IRType)){
     const llvm::Type *EltTy = VT->getElementType();
@@ -1622,7 +1620,7 @@
                            "reg_save_area");
   if (neededInt && neededSSE) {
     // FIXME: Cleanup.
-    assert(AI.isCoerce() && "Unexpected ABI info for mixed regs");
+    assert(AI.isDirect() && "Unexpected ABI info for mixed regs");
     const llvm::StructType *ST = cast<llvm::StructType>(AI.getCoerceToType());
     llvm::Value *Tmp = CGF.CreateTempAlloca(ST);
     assert(ST->getNumElements() == 2 && "Unexpected ABI info for mixed regs");
@@ -1948,7 +1946,7 @@
   LLVMFields.push_back(llvm::ArrayType::get(ElemTy, SizeRegs));
   const llvm::Type* STy = llvm::StructType::get(getVMContext(), LLVMFields,
                                                 true);
-  return ABIArgInfo::getCoerce(STy);
+  return ABIArgInfo::getDirect(STy);
 }
 
 static bool isIntegerLikeType(QualType Ty, ASTContext &Context,
@@ -2064,7 +2062,7 @@
     // FIXME: Consider using 2 x vector types if the back end handles them
     // correctly.
     if (RetTy->isAnyComplexType())
-      return ABIArgInfo::getCoerce(llvm::IntegerType::get(getVMContext(),
+      return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
                                               getContext().getTypeSize(RetTy)));
 
     // Integer like structures are returned in r0.
@@ -2072,10 +2070,10 @@
       // Return in the smallest viable integer type.
       uint64_t Size = getContext().getTypeSize(RetTy);
       if (Size <= 8)
-        return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(getVMContext()));
+        return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
       if (Size <= 16)
-        return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(getVMContext()));
-      return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(getVMContext()));
+        return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
+      return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
     }
 
     // Otherwise return in memory.
@@ -2093,10 +2091,10 @@
   if (Size <= 32) {
     // Return in the smallest viable integer type.
     if (Size <= 8)
-      return ABIArgInfo::getCoerce(llvm::Type::getInt8Ty(getVMContext()));
+      return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
     if (Size <= 16)
-      return ABIArgInfo::getCoerce(llvm::Type::getInt16Ty(getVMContext()));
-    return ABIArgInfo::getCoerce(llvm::Type::getInt32Ty(getVMContext()));
+      return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext()));
+    return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext()));
   }
 
   return ABIArgInfo::getIndirect(0);
diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c
index 04447c1..3bda887 100644
--- a/test/CodeGen/x86_64-arguments.c
+++ b/test/CodeGen/x86_64-arguments.c
@@ -152,10 +152,16 @@
   // CHECK: define %struct.f24s @f24(%struct.f23S* %X, %struct.f24s* %P2)
 }
 
+// rdar://8248065
 typedef float v4f32 __attribute__((__vector_size__(16)));
-
 v4f32 f25(v4f32 X) {
-  // CHECK: define <4 x float> @f25(<4 x float> %X.coerce)
+  // CHECK: define <4 x float> @f25(<4 x float> %X)
+  // CHECK-NOT: alloca
+  // CHECK: %X.addr = alloca <4 x float>
+  // CHECK-NOT: alloca
+  // CHECK: store <4 x float> %X, <4 x float>* %X.addr
+  // CHECK-NOT: store
+  // CHECK: ret <4 x float>
   return X+X;
 }
 
diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp
index df0c78a..6c42bb8 100644
--- a/test/CodeGenCXX/x86_64-arguments.cpp
+++ b/test/CodeGenCXX/x86_64-arguments.cpp
@@ -23,7 +23,7 @@
 struct s3_1 { struct s3_0 a; long b; };
 void f3(struct s3_1 x) {}
 
-// CHECK: define i64 @_Z4f4_0M2s4i(i64 %a.coerce)
+// CHECK: define i64 @_Z4f4_0M2s4i(i64 %a)
 // CHECK: define {{.*}} @_Z4f4_1M2s4FivE(i64 %a.coerce0, i64 %a.coerce1)
 struct s4 {};
 typedef int s4::* s4_mdp;