Index: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp @@ -3011,7 +3011,11 @@ } // This is an argument in memory. We might be able to perform copy elision. - if (Flags.isCopyElisionCandidate()) { + // If the argument is passed directly in memory without any extension, then we + // can perform copy elision. Large vector types, for example, may be passed + // indirectly by pointer. + if (Flags.isCopyElisionCandidate() && + VA.getLocInfo() != CCValAssign::Indirect && !ExtendedInMem) { EVT ArgVT = Ins[i].ArgVT; SDValue PartAddr; if (Ins[i].PartOffset == 0) { Index: llvm/trunk/test/CodeGen/X86/arg-copy-elide-win64.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/arg-copy-elide-win64.ll +++ llvm/trunk/test/CodeGen/X86/arg-copy-elide-win64.ll @@ -13,12 +13,12 @@ ; CHECK-NEXT: vmovaps %xmm6, {{[-0-9]+}}(%r{{[sb]}}p) # 16-byte Spill ; CHECK-NEXT: andq $-128, %rsp ; CHECK-NEXT: movq 288(%rbp), %rax -; CHECK-NEXT: movq 320(%rbp), %r10 ; CHECK-NEXT: vmovaps (%rax), %ymm0 -; CHECK-NEXT: vmovaps (%r10), %ymm1 -; CHECK-NEXT: movq 352(%rbp), %rax +; CHECK-NEXT: movq 296(%rbp), %rax +; CHECK-NEXT: vmovaps (%rax), %ymm1 +; CHECK-NEXT: movq 304(%rbp), %rax ; CHECK-NEXT: vmovaps (%rax), %ymm2 -; CHECK-NEXT: movq 384(%rbp), %rax +; CHECK-NEXT: movq 312(%rbp), %rax ; CHECK-NEXT: vmovaps (%rax), %ymm3 ; CHECK-NEXT: vmovaps (%rcx), %ymm4 ; CHECK-NEXT: vmovaps (%rdx), %ymm5