diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -4316,9 +4316,11 @@ } // If value is passed via pointer - do a load. - if (VA.getLocInfo() == CCValAssign::Indirect && !Ins[I].Flags.isByVal()) + if (VA.getLocInfo() == CCValAssign::Indirect && + !(Ins[I].Flags.isByVal() && VA.isRegLoc())) { ArgValue = DAG.getLoad(VA.getValVT(), dl, Chain, ArgValue, MachinePointerInfo()); + } InVals.push_back(ArgValue); } diff --git a/llvm/test/CodeGen/X86/win64-byval.ll b/llvm/test/CodeGen/X86/win64-byval.ll --- a/llvm/test/CodeGen/X86/win64-byval.ll +++ b/llvm/test/CodeGen/X86/win64-byval.ll @@ -87,3 +87,13 @@ call void @foo2(ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, ptr byval({ float, double }) @G, i64 10) ret void } + +define i64 @receive_byval_arg_via_stack_arg(i64* byval(i64), i64* byval(i64), i64* byval(i64), i64* byval(i64), i64* byval(i64) %x) { +; CHECK-LABEL: receive_byval_arg_via_stack_arg: +; CHECK: # %bb.0: +; CHECK-NEXT: movq {{[0-9]+}}(%rsp), %rax +; CHECK-NEXT: movq (%rax), %rax +; CHECK-NEXT: retq + %r = load i64, i64* %x + ret i64 %r +}