forked from OSchip/llvm-project
[X86] Fix a bug that when lowering byval argument
When an argument has 'byval' attribute and should be passed on the stack according calling convention, a stack copy would be emitted twice. This will cause the real value will be put into stack where the pointer should be passed. Differential Revision: https://reviews.llvm.org/D83175
This commit is contained in:
parent
ed39becd27
commit
ea85ff82c8
|
@ -3763,12 +3763,13 @@ SDValue X86TargetLowering::LowerMemOpCallTo(SDValue Chain, SDValue StackPtr,
|
|||
SDValue Arg, const SDLoc &dl,
|
||||
SelectionDAG &DAG,
|
||||
const CCValAssign &VA,
|
||||
ISD::ArgFlagsTy Flags) const {
|
||||
ISD::ArgFlagsTy Flags,
|
||||
bool isByVal) const {
|
||||
unsigned LocMemOffset = VA.getLocMemOffset();
|
||||
SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset, dl);
|
||||
PtrOff = DAG.getNode(ISD::ADD, dl, getPointerTy(DAG.getDataLayout()),
|
||||
StackPtr, PtrOff);
|
||||
if (Flags.isByVal())
|
||||
if (isByVal)
|
||||
return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG, dl);
|
||||
|
||||
return DAG.getStore(
|
||||
|
@ -4080,7 +4081,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||
StackPtr = DAG.getCopyFromReg(Chain, dl, RegInfo->getStackRegister(),
|
||||
getPointerTy(DAG.getDataLayout()));
|
||||
MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg,
|
||||
dl, DAG, VA, Flags));
|
||||
dl, DAG, VA, Flags, isByVal));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1436,7 +1436,7 @@ namespace llvm {
|
|||
SDValue LowerMemOpCallTo(SDValue Chain, SDValue StackPtr, SDValue Arg,
|
||||
const SDLoc &dl, SelectionDAG &DAG,
|
||||
const CCValAssign &VA,
|
||||
ISD::ArgFlagsTy Flags) const;
|
||||
ISD::ArgFlagsTy Flags, bool isByval) const;
|
||||
|
||||
// Call lowering helpers.
|
||||
|
||||
|
|
|
@ -32,3 +32,31 @@ define void @baz({ float, double }* byval %arg)
|
|||
call void @foo({ float, double }* byval %arg)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @foo2({ float, double }* byval, { float, double }* byval, { float, double }* byval, { float, double }* byval, { float, double }* byval, i64 %f)
|
||||
@data = external constant { float, double }
|
||||
|
||||
define void @test() {
|
||||
; CHECK-LABEL: @test
|
||||
; CHECK: movq (%rax), %rcx
|
||||
; CHECK-NEXT: movq 8(%rax), %rax
|
||||
; CHECK-NEXT: movq %rax, 120(%rsp)
|
||||
; CHECK-NEXT: movq %rcx, 112(%rsp)
|
||||
; CHECK-NEXT: movq %rcx, 96(%rsp)
|
||||
; CHECK-NEXT: movq %rax, 104(%rsp)
|
||||
; CHECK-NEXT: movq %rcx, 80(%rsp)
|
||||
; CHECK-NEXT: movq %rax, 88(%rsp)
|
||||
; CHECK-NEXT: movq %rcx, 64(%rsp)
|
||||
; CHECK-NEXT: movq %rax, 72(%rsp)
|
||||
; CHECK-NEXT: movq %rax, 56(%rsp)
|
||||
; CHECK-NEXT: movq %rcx, 48(%rsp)
|
||||
; CHECK-NEXT: leaq 48(%rsp), %rax
|
||||
; CHECK-NEXT: movq %rax, 32(%rsp)
|
||||
; CHECK-NEXT: movq $10, 40(%rsp)
|
||||
; CHECK-NEXT: leaq 112(%rsp), %rcx
|
||||
; CHECK-NEXT: leaq 96(%rsp), %rdx
|
||||
; CHECK-NEXT: leaq 80(%rsp), %r8
|
||||
; CHECK-NEXT: leaq 64(%rsp), %r9
|
||||
call void @foo2({ float, double }* byval @G, { float, double }* byval @G, { float, double }* byval @G, { float, double }* byval @G, { float, double }* byval @G, i64 10)
|
||||
ret void
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue