[X86] Fix callee side of receiving byval args on the stack
authorHans Wennborg <hans@chromium.org>
Thu, 15 Jun 2023 13:01:36 +0000 (15:01 +0200)
committerHans Wennborg <hans@chromium.org>
Fri, 16 Jun 2023 12:11:21 +0000 (14:11 +0200)
See the discussion in
https://discourse.llvm.org/t/generic-llvm-ir-windows-x64-argument-passing-issue-in-llvm-11-0-0-and-later/71350

D51842 implemented byval lowering for Win64. D83175 made the call
lowering honor the "from now on treat this as a regular pointer" comment
also when the argument gets passed on the stack. However, it didn't
update the callee side.

Differential revision: https://reviews.llvm.org/D153020

llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/win64-byval.ll

index 7197fc3..14ca38d 100644 (file)
@@ -4316,9 +4316,11 @@ SDValue X86TargetLowering::LowerFormalArguments(
     }
 
     // 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);
   }
index bb6be14..676e811 100644 (file)
@@ -87,3 +87,13 @@ define void @test() {
   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
+}