Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -10616,9 +10616,9 @@ DenseMap &ArgCopyElisionFrameIndexMap, SmallPtrSetImpl &ElidedArgCopyInstrs, ArgCopyElisionMapTy &ArgCopyElisionCandidates, const Argument &Arg, - SDValue ArgVal, bool &ArgHasUses) { + ArrayRef ArgVals, bool &ArgHasUses) { // Check if this is a load from a fixed stack object. - auto *LNode = dyn_cast(ArgVal); + auto *LNode = dyn_cast(ArgVals[0]); if (!LNode) return; auto *FINode = dyn_cast(LNode->getBasePtr().getNode()); @@ -10661,7 +10661,8 @@ MFI.setIsImmutableObjectIndex(FixedIndex, false); AllocaIndex = FixedIndex; ArgCopyElisionFrameIndexMap.insert({OldIndex, FixedIndex}); - Chains.push_back(ArgVal.getValue(1)); + for (SDValue ArgVal : ArgVals) + Chains.push_back(ArgVal.getValue(1)); // Avoid emitting code for the store implementing the copy. const StoreInst *SI = ArgCopyIter->second.second; @@ -10922,9 +10923,14 @@ // Elide the copying store if the target loaded this argument from a // suitable fixed stack object. if (Ins[i].Flags.isCopyElisionCandidate()) { + unsigned NumParts = 0; + for (EVT VT : ValueVTs) + NumParts += TLI->getNumRegistersForCallingConv(*CurDAG->getContext(), + F.getCallingConv(), VT); + tryToElideArgumentCopy(*FuncInfo, Chains, ArgCopyElisionFrameIndexMap, ElidedArgCopyInstrs, ArgCopyElisionCandidates, Arg, - InVals[i], ArgHasUses); + ArrayRef(&InVals[i], NumParts), ArgHasUses); } // If this argument is unused then remember its value. It is used to generate Index: llvm/test/CodeGen/X86/pr63430.ll =================================================================== --- llvm/test/CodeGen/X86/pr63430.ll +++ llvm/test/CodeGen/X86/pr63430.ll @@ -1,14 +1,14 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --no_x86_scrub_sp --version 2 ; RUN: llc -mtriple=x86_64-unknown-linux < %s | FileCheck %s -; TODO: This is a miscompile. +; Make sure the argument is read before the stack slot is over-written. define i1 @test(ptr %a0, ptr %a1, ptr %a2, ptr %a3, ptr %a4, ptr %a5, i128 %x) { ; CHECK-LABEL: test: ; CHECK: # %bb.0: ; CHECK-NEXT: movq 8(%rsp), %rax ; CHECK-NEXT: xorps %xmm0, %xmm0 -; CHECK-NEXT: movaps %xmm0, 8(%rsp) ; CHECK-NEXT: andq 16(%rsp), %rax +; CHECK-NEXT: movaps %xmm0, 8(%rsp) ; CHECK-NEXT: cmpq $-1, %rax ; CHECK-NEXT: sete %al ; CHECK-NEXT: retq