From ea85ff82c82687496453bc14c4ac60548a42d8f3 Mon Sep 17 00:00:00 2001 From: "Liu, Chen3" Date: Tue, 7 Jul 2020 21:22:27 +0800 Subject: [PATCH] [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 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 7 ++++--- llvm/lib/Target/X86/X86ISelLowering.h | 2 +- llvm/test/CodeGen/X86/win64-byval.ll | 28 ++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index d7a45f6..4821dd4 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -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)); } } diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index ad76c55..7f3dc90a 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -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. diff --git a/llvm/test/CodeGen/X86/win64-byval.ll b/llvm/test/CodeGen/X86/win64-byval.ll index 2fefa73..af2af4e 100644 --- a/llvm/test/CodeGen/X86/win64-byval.ll +++ b/llvm/test/CodeGen/X86/win64-byval.ll @@ -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 +} -- 2.7.4