diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1296,12 +1296,16 @@ // FIXME: Do we need to recurse here? void CodeGenFunction::EmitAggregateStore(llvm::Value *Val, Address Dest, bool DestIsVolatile) { - // Prefer scalar stores to first-class aggregate stores. if (llvm::StructType *STy = dyn_cast(Val->getType())) { - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - Address EltPtr = Builder.CreateStructGEP(Dest, i); - llvm::Value *Elt = Builder.CreateExtractValue(Val, i); - Builder.CreateStore(Elt, EltPtr, DestIsVolatile); + if (STy->containsScalableVectorType()) + Builder.CreateStore(Val, Dest, DestIsVolatile); + else { + // Prefer scalar stores to first-class aggregate stores. + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + Address EltPtr = Builder.CreateStructGEP(Dest, i); + llvm::Value *Elt = Builder.CreateExtractValue(Val, i); + Builder.CreateStore(Elt, EltPtr, DestIsVolatile); + } } } else { Builder.CreateStore(Val, Dest, DestIsVolatile); @@ -2857,11 +2861,21 @@ } assert(STy->getNumElements() == NumIRArgs); - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - auto AI = Fn->getArg(FirstIRArg + i); - AI->setName(Arg->getName() + ".coerce" + Twine(i)); - Address EltPtr = Builder.CreateStructGEP(AddrToStoreInto, i); - Builder.CreateStore(AI, EltPtr); + if (STy->containsScalableVectorType()) { + llvm::Value *Val = llvm::UndefValue::get(STy); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + auto AI = Fn->getArg(FirstIRArg + i); + AI->setName(Arg->getName() + ".coerce" + Twine(i)); + Val = Builder.CreateInsertValue(Val, AI, i); + } + Builder.CreateStore(Val, AddrToStoreInto); + } else { + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + auto AI = Fn->getArg(FirstIRArg + i); + AI->setName(Arg->getName() + ".coerce" + Twine(i)); + Address EltPtr = Builder.CreateStructGEP(AddrToStoreInto, i); + Builder.CreateStore(AI, EltPtr); + } } if (SrcSize > DstSize) { @@ -4920,10 +4934,18 @@ } assert(NumIRArgs == STy->getNumElements()); - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - Address EltPtr = Builder.CreateStructGEP(Src, i); - llvm::Value *LI = Builder.CreateLoad(EltPtr); - IRCallArgs[FirstIRArg + i] = LI; + if (STy->containsScalableVectorType()) { + llvm::Value *Val = Builder.CreateLoad(Src); + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + llvm::Value *LI = Builder.CreateExtractValue(Val, i); + IRCallArgs[FirstIRArg + i] = LI; + } + } else { + for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { + Address EltPtr = Builder.CreateStructGEP(Src, i); + llvm::Value *LI = Builder.CreateLoad(EltPtr); + IRCallArgs[FirstIRArg + i] = LI; + } } } else { // In the simple case, just pass the coerced loaded value.