[PATCH] D60349: [COFF, ARM64] Fix ABI implementation of struct returns

2019-04-17 Thread Sanjin Sijaric via Phabricator via cfe-commits
ssijaric added inline comments.



Comment at: lib/CodeGen/MicrosoftCXXABI.cpp:1058
+
+  // 1. For return types <= 16 bytes, use the C return semantics.
+

richard.townsend.arm wrote:
> Microsoft have updated the spec since this was written, it now says to check 
> for aggregate-ness, trivial copy, and trivial destruct, instead of POD.  
This is only true for aggregates.  We can have non-aggregate return types that 
are less or equal to 16 bytes.  In this case, they are returned on the stack.



Comment at: lib/CodeGen/MicrosoftCXXABI.cpp:1075
+uint64_t RetTySize = getContext().getTypeSize(FI.getReturnType());
+if (RetTySize <= 16)
+  return false;

The size returned is in bits, not bytes.

As mentioned above, this applies to aggregates with trivial copy assignment 
operators and destructors.  I will provide a function to check for this.  At 
that point, the check can be removed from here, and the  check below can be 
replaced with something like:

bool isIndirectReturn = !canReturnInRegisters();


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60349/new/

https://reviews.llvm.org/D60349



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56463: [SEH] Pass the frame pointer from SEH finally to finally functions

2019-01-15 Thread Sanjin Sijaric via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC351302: [SEH] Pass the frame pointer from SEH finally to 
finally functions (authored by ssijaric, committed by ).

Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56463/new/

https://reviews.llvm.org/D56463

Files:
  lib/CodeGen/CGException.cpp
  test/CodeGen/exceptions-seh-nested-finally.c


Index: test/CodeGen/exceptions-seh-nested-finally.c
===
--- test/CodeGen/exceptions-seh-nested-finally.c
+++ test/CodeGen/exceptions-seh-nested-finally.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// Check that the first finally block passes the enclosing function's frame
+// pointer to the second finally block, instead of generating it via localaddr.
+
+// CHECK-LABEL: define internal void @"?fin$0@0@main@@"({{i8( zeroext)?}} 
%abnormal_termination, i8* %frame_pointer)
+// CHECK: call void @"?fin$1@0@main@@"({{i8( zeroext)?}} 0, i8* %frame_pointer)
+int
+main() {
+  int Check = 0;
+  __try {
+Check = 3;
+  } __finally {
+__try {
+  Check += 2;
+} __finally {
+  Check += 4;
+}
+  }
+  return Check;
+}
Index: lib/CodeGen/CGException.cpp
===
--- lib/CodeGen/CGException.cpp
+++ lib/CodeGen/CGException.cpp
@@ -1627,8 +1627,16 @@
 
 // Compute the two argument values.
 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
-llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
-llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
+llvm::Value *FP = nullptr;
+// If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
+if (CGF.IsOutlinedSEHHelper) {
+  FP = >arg_begin()[1];
+} else {
+  llvm::Value *LocalAddrFn =
+  CGM.getIntrinsic(llvm::Intrinsic::localaddress);
+  FP = CGF.Builder.CreateCall(LocalAddrFn);
+}
+
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
 Args.add(RValue::get(IsForEH), ArgTys[0]);


Index: test/CodeGen/exceptions-seh-nested-finally.c
===
--- test/CodeGen/exceptions-seh-nested-finally.c
+++ test/CodeGen/exceptions-seh-nested-finally.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// Check that the first finally block passes the enclosing function's frame
+// pointer to the second finally block, instead of generating it via localaddr.
+
+// CHECK-LABEL: define internal void @"?fin$0@0@main@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
+// CHECK: call void @"?fin$1@0@main@@"({{i8( zeroext)?}} 0, i8* %frame_pointer)
+int
+main() {
+  int Check = 0;
+  __try {
+Check = 3;
+  } __finally {
+__try {
+  Check += 2;
+} __finally {
+  Check += 4;
+}
+  }
+  return Check;
+}
Index: lib/CodeGen/CGException.cpp
===
--- lib/CodeGen/CGException.cpp
+++ lib/CodeGen/CGException.cpp
@@ -1627,8 +1627,16 @@
 
 // Compute the two argument values.
 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
-llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
-llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
+llvm::Value *FP = nullptr;
+// If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
+if (CGF.IsOutlinedSEHHelper) {
+  FP = >arg_begin()[1];
+} else {
+  llvm::Value *LocalAddrFn =
+  CGM.getIntrinsic(llvm::Intrinsic::localaddress);
+  FP = CGF.Builder.CreateCall(LocalAddrFn);
+}
+
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
 Args.add(RValue::get(IsForEH), ArgTys[0]);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56463: [SEH] Pass the frame pointer from SEH finally to finally functions

2019-01-11 Thread Sanjin Sijaric via Phabricator via cfe-commits
ssijaric updated this revision to Diff 181337.
ssijaric added a comment.

Address formatting comments.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56463/new/

https://reviews.llvm.org/D56463

Files:
  lib/CodeGen/CGException.cpp
  test/CodeGen/exceptions-seh-nested-finally.c


Index: test/CodeGen/exceptions-seh-nested-finally.c
===
--- /dev/null
+++ test/CodeGen/exceptions-seh-nested-finally.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// Check that the first finally block passes the enclosing function's frame
+// pointer to the second finally block, instead of generating it via localaddr.
+
+// CHECK-LABEL: define internal void @"?fin$0@0@main@@"({{i8( zeroext)?}} 
%abnormal_termination, i8* %frame_pointer)
+// CHECK: call void @"?fin$1@0@main@@"({{i8( zeroext)?}} 0, i8* %frame_pointer)
+int
+main() {
+  int Check = 0;
+  __try {
+Check = 3;
+  } __finally {
+__try {
+  Check += 2;
+} __finally {
+  Check += 4;
+}
+  }
+  return Check;
+}
Index: lib/CodeGen/CGException.cpp
===
--- lib/CodeGen/CGException.cpp
+++ lib/CodeGen/CGException.cpp
@@ -1627,8 +1627,16 @@
 
 // Compute the two argument values.
 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
-llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
-llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
+llvm::Value *FP = nullptr;
+// If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
+if (CGF.IsOutlinedSEHHelper) {
+  FP = >arg_begin()[1];
+} else {
+  llvm::Value *LocalAddrFn =
+  CGM.getIntrinsic(llvm::Intrinsic::localaddress);
+  FP = CGF.Builder.CreateCall(LocalAddrFn);
+}
+
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
 Args.add(RValue::get(IsForEH), ArgTys[0]);


Index: test/CodeGen/exceptions-seh-nested-finally.c
===
--- /dev/null
+++ test/CodeGen/exceptions-seh-nested-finally.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// Check that the first finally block passes the enclosing function's frame
+// pointer to the second finally block, instead of generating it via localaddr.
+
+// CHECK-LABEL: define internal void @"?fin$0@0@main@@"({{i8( zeroext)?}} %abnormal_termination, i8* %frame_pointer)
+// CHECK: call void @"?fin$1@0@main@@"({{i8( zeroext)?}} 0, i8* %frame_pointer)
+int
+main() {
+  int Check = 0;
+  __try {
+Check = 3;
+  } __finally {
+__try {
+  Check += 2;
+} __finally {
+  Check += 4;
+}
+  }
+  return Check;
+}
Index: lib/CodeGen/CGException.cpp
===
--- lib/CodeGen/CGException.cpp
+++ lib/CodeGen/CGException.cpp
@@ -1627,8 +1627,16 @@
 
 // Compute the two argument values.
 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
-llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
-llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
+llvm::Value *FP = nullptr;
+// If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
+if (CGF.IsOutlinedSEHHelper) {
+  FP = >arg_begin()[1];
+} else {
+  llvm::Value *LocalAddrFn =
+  CGM.getIntrinsic(llvm::Intrinsic::localaddress);
+  FP = CGF.Builder.CreateCall(LocalAddrFn);
+}
+
 llvm::Value *IsForEH =
 llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
 Args.add(RValue::get(IsForEH), ArgTys[0]);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56463: [SEH] Pass the frame pointer from SEH finally to finally functions

2019-01-08 Thread Sanjin Sijaric via Phabricator via cfe-commits
ssijaric created this revision.
ssijaric added reviewers: rnk, efriedma, mstorsjo, TomTan.

The following test case, compiled with -OO -target=x86_64-windows-win32, 
returns an incorrect value.  It returns 5, when it should return 9.  The 
problem is that the frame pointer that the first finally block receives is not 
passed onto the second finally block, but is regenerated using the localaddr 
intrinsic.

The test case is:

  int
  main() {
int Check = 0;
__try {
  Check = 3;
} __finally {
  __try {
Check += 2;
  } __finally {
Check += 4; 
  }
}
return Check;
  }

The code generated with "-O0 --target=x86_64-windows-win32" is:

  main:   # @main
  .seh_proc main
  # %bb.0:# %entry
subq$40, %rsp
.seh_stackalloc 40
.seh_endprologue
xorl%ecx, %ecx
  .set .Lmain$frame_escape_0, 32  < Check is at %rsp of main + 32
movl$0, 36(%rsp)
movl$0, 32(%rsp)
movl$3, 32(%rsp)
movq%rsp, %rax
movq%rax, %rdx  < main's %rsp is passed to fin$0
callq   "?fin$0@0@main@@"
movl32(%rsp), %eax
addq$40, %rsp
retq
  
  ?fin$0@0@main@@:
  subq$56, %rsp
leaq.Lmain$frame_escape_0(%rdx), %r8
movq%rdx, 48(%rsp)
movb%cl, 47(%rsp)
movl(%r8), %r9d   < Check is at %rsp of main + 32
addl$2, %r9d
movq%rsp, %rdx<  %rsp of fin$0 is passed to fin$1, should 
be %rsp of main 
movl%eax, %ecx
  callq "?fin$1@0@main@@"
  
  
  "?fin$1@0@main@@":  # @"?fin$1@0@main@@"
  # %bb.0:# %entry
subq$16, %rsp
.seh_stackalloc 16
.seh_endprologue
leaq.Lmain$frame_escape_0(%rdx), %rax
movq%rdx, 8(%rsp)
movb%cl, 7(%rsp)
movl(%rax), %r8d
addl$4, %r8d
movl%r8d, (%rax)
addq$16, %rsp
retq
.seh_handlerdata
.text

With this change, we get the following:

  "?fin$0@0@main@@":  # @"?fin$0@0@main@@"
  .seh_proc "?fin$0@0@main@@"
  # %bb.0:# %entry
subq$56, %rsp
.seh_stackalloc 56
.seh_endprologue
xorl%eax, %eax
leaq.Lmain$frame_escape_0(%rdx), %r8
movq%rdx, 48(%rsp)
movb%cl, 47(%rsp)
movl(%r8), %r9d
addl$2, %r9d
movl%r9d, (%r8)
movl%eax, %ecx
callq   "?fin$1@0@main@@"  < %rsp of main is passed in %rdx onto 
fin$1
nop
addq$56, %rsp
retq

The change assumes that no compiler generated filter function can directly 
invoke a compiler generated finally function.  I haven't been able to come up 
with a test case where this occurs.  Otherwise, the check for 
IsOutlinedSEHHelper is insufficient.   All SEH finally functions have two 
parameters, the second being the frame pointer.   This is not the case for 
filter functions, as they differ on x86 vs x86_64.


Repository:
  rC Clang

https://reviews.llvm.org/D56463

Files:
  lib/CodeGen/CGException.cpp
  test/CodeGen/exceptions-seh-nested-finally.c


Index: test/CodeGen/exceptions-seh-nested-finally.c
===
--- /dev/null
+++ test/CodeGen/exceptions-seh-nested-finally.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+// RUN: %clang_cc1 %s -triple aarch64-windows -fms-extensions -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+// Check that the first finally block passes the enclosing function's frame
+// pointer to the second finally block, instead of generating it via localaddr.
+
+// CHECK-LABEL: define internal void @"?fin$0@0@main@@"({{i8( zeroext)?}} 
%abnormal_termination, i8* %frame_pointer)
+// CHECK: call void @"?fin$1@0@main@@"({{i8( zeroext)?}} 0, i8* %frame_pointer)
+int
+main() {
+  int Check = 0;
+  __try {
+Check = 3;
+  } __finally {
+__try {
+  Check += 2;
+} __finally {
+  Check += 4;
+}
+  }
+  return Check;
+}
Index: lib/CodeGen/CGException.cpp
===
--- lib/CodeGen/CGException.cpp
+++ lib/CodeGen/CGException.cpp
@@ -1627,8 +1627,15 @@
 
 // Compute the two argument values.
 QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
-llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
-llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
+llvm::Value *FP = nullptr;
+// If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.
+if 

[PATCH] D49770: [ARM64] [Windows] Follow MS X86_64 C++ ABI when passing structs

2018-07-26 Thread Sanjin Sijaric via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC338076: [ARM64] [Windows] Follow MS X86_64 C++ ABI when 
passing structs (authored by ssijaric, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D49770

Files:
  include/clang/Basic/TargetInfo.h
  lib/Basic/Targets/AArch64.cpp
  lib/Basic/Targets/AArch64.h
  lib/Basic/Targets/X86.h
  lib/CodeGen/MicrosoftCXXABI.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp

Index: include/clang/Basic/TargetInfo.h
===
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -1223,7 +1223,7 @@
   enum CallingConvKind {
 CCK_Default,
 CCK_ClangABI4OrPS4,
-CCK_MicrosoftX86_64
+CCK_MicrosoftWin64
   };
 
   virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;
Index: test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
===
--- test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -2,6 +2,7 @@
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=thumb-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA %s
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=aarch64-windows-msvc -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA64 %s
 
 struct Empty {};
 
@@ -163,6 +164,9 @@
 // WIN64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %s.coerce) {{.*}} {
 // WIN64:   call void @"??1SmallWithDtor@@QEAA@XZ"
 // WIN64: }
+// WOA64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i64 %s.coerce) {{.*}} {
+// WOA64:   call void @"??1SmallWithDtor@@QEAA@XZ"
+// WOA64: }
 
 // FIXME: MSVC incompatible!
 // WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(%struct.SmallWithDtor* %s) {{.*}} {
@@ -227,12 +231,14 @@
 // LINUX-LABEL: define void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s)
 // WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca)
 // WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
+// WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
 
 void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
 // LINUX-LABEL: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s)
 // WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca)
 // WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
 // WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
+// WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
 
 void big_arg(Big s) {}
 // LINUX-LABEL: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s)
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -827,6 +827,7 @@
 return RAA_Default;
 
   case llvm::Triple::x86_64:
+  case llvm::Triple::aarch64:
 return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
   }
 
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -5831,7 +5831,7 @@
 return !D->hasNonTrivialDestructorForCall() &&
!D->hasNonTrivialCopyConstructorForCall();
 
-  if (CCK == TargetInfo::CCK_MicrosoftX86_64) {
+  if (CCK == TargetInfo::CCK_MicrosoftWin64) {
 bool CopyCtorIsTrivial = false, CopyCtorIsTrivialForCall = false;
 bool DtorIsTrivialForCall = false;
 
Index: lib/Basic/Targets/AArch64.h
===
--- lib/Basic/Targets/AArch64.h
+++ lib/Basic/Targets/AArch64.h
@@ -126,6 +126,8 @@
   MacroBuilder ) const;
   void getTargetDefines(const LangOptions ,
 MacroBuilder ) const override;
+  TargetInfo::CallingConvKind
+  getCallingConvKind(bool ClangABICompat4) const override;
 };
 
 // ARM64 MinGW target
Index: lib/Basic/Targets/X86.h
===
--- lib/Basic/Targets/X86.h
+++ 

[PATCH] D49770: [ARM64] [Windows] Follow MS X86_64 C++ ABI when passing structs

2018-07-26 Thread Sanjin Sijaric via Phabricator via cfe-commits
ssijaric updated this revision to Diff 157559.
ssijaric added a comment.

Last change before committing to address Reid's point of using 
CCK_MicrosoftWin64 for Windows on both X86_64 and ARM64.


Repository:
  rC Clang

https://reviews.llvm.org/D49770

Files:
  include/clang/Basic/TargetInfo.h
  lib/Basic/Targets/AArch64.cpp
  lib/Basic/Targets/AArch64.h
  lib/Basic/Targets/X86.h
  lib/CodeGen/MicrosoftCXXABI.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp

Index: test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
===
--- test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -2,6 +2,7 @@
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=thumb-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA %s
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=aarch64-windows-msvc -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA64 %s
 
 struct Empty {};
 
@@ -163,6 +164,9 @@
 // WIN64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i32 %s.coerce) {{.*}} {
 // WIN64:   call void @"??1SmallWithDtor@@QEAA@XZ"
 // WIN64: }
+// WOA64: define dso_local void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(i64 %s.coerce) {{.*}} {
+// WOA64:   call void @"??1SmallWithDtor@@QEAA@XZ"
+// WOA64: }
 
 // FIXME: MSVC incompatible!
 // WOA: define dso_local arm_aapcs_vfpcc void @"?small_arg_with_dtor@@YAXUSmallWithDtor@@@Z"(%struct.SmallWithDtor* %s) {{.*}} {
@@ -227,12 +231,14 @@
 // LINUX-LABEL: define void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s)
 // WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca)
 // WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
+// WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
 
 void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
 // LINUX-LABEL: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s)
 // WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca)
 // WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
 // WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
+// WOA64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
 
 void big_arg(Big s) {}
 // LINUX-LABEL: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s)
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -5831,7 +5831,7 @@
 return !D->hasNonTrivialDestructorForCall() &&
!D->hasNonTrivialCopyConstructorForCall();
 
-  if (CCK == TargetInfo::CCK_MicrosoftX86_64) {
+  if (CCK == TargetInfo::CCK_MicrosoftWin64) {
 bool CopyCtorIsTrivial = false, CopyCtorIsTrivialForCall = false;
 bool DtorIsTrivialForCall = false;
 
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -827,6 +827,7 @@
 return RAA_Default;
 
   case llvm::Triple::x86_64:
+  case llvm::Triple::aarch64:
 return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
   }
 
Index: lib/Basic/Targets/X86.h
===
--- lib/Basic/Targets/X86.h
+++ lib/Basic/Targets/X86.h
@@ -752,7 +752,7 @@
 
   TargetInfo::CallingConvKind
   getCallingConvKind(bool ClangABICompat4) const override {
-return CCK_MicrosoftX86_64;
+return CCK_MicrosoftWin64;
   }
 };
 
Index: lib/Basic/Targets/AArch64.h
===
--- lib/Basic/Targets/AArch64.h
+++ lib/Basic/Targets/AArch64.h
@@ -126,6 +126,8 @@
   MacroBuilder ) const;
   void getTargetDefines(const LangOptions ,
 MacroBuilder ) const override;
+  TargetInfo::CallingConvKind
+  getCallingConvKind(bool ClangABICompat4) const override;
 };
 
 // ARM64 MinGW target
Index: lib/Basic/Targets/AArch64.cpp
===
--- lib/Basic/Targets/AArch64.cpp
+++ lib/Basic/Targets/AArch64.cpp
@@ -533,6 +533,11 @@
   

[PATCH] D49770: [ARM64] [Windows] Follow MS X86_64 C++ ABI when passing structs

2018-07-25 Thread Sanjin Sijaric via Phabricator via cfe-commits
ssijaric added a comment.

Yes, it looks like the comment for the thumb case is applicable here as well.   
VC++ on ARM64 passes small structs with a destructor and a default copy 
constructor in a register, while clang passes them on the stack.  I will 
probably address this in a separate patch.


Repository:
  rC Clang

https://reviews.llvm.org/D49770



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49770: [ARM64] [Windows] Follow MS X86_64 C++ ABI when passing structs

2018-07-24 Thread Sanjin Sijaric via Phabricator via cfe-commits
ssijaric created this revision.
ssijaric added reviewers: rnk, mstorsjo, TomTan, haripul.
Herald added a reviewer: javed.absar.
Herald added subscribers: cfe-commits, chrib, kristof.beyls.

Microsoft's C++ object model for ARM64 is the same as that for X86_64.  For 
example, small structs with non-trivial copy constructors or virtual function 
tables are passed indirectly.  Currently, they are passed in registers when 
compiled with clang.


Repository:
  rC Clang

https://reviews.llvm.org/D49770

Files:
  lib/CodeGen/MicrosoftCXXABI.cpp
  test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp


Index: test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
===
--- test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -2,6 +2,7 @@
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 
-mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=thumb-pc-win32 
-mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA %s
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 
-mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=aarch64-windows-msvc 
-mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA64 %s
 
 struct Empty {};
 
@@ -227,12 +228,14 @@
 // LINUX-LABEL: define void 
@_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s)
 // WIN32: define dso_local void 
@"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ 
%struct.SmallWithVftable }>* inalloca)
 // WIN64: define dso_local void 
@"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* 
%s)
+// WOA64: define dso_local void 
@"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* 
%s)
 
 void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
 // LINUX-LABEL: define void 
@_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* 
%s)
 // WIN32: define dso_local void 
@"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ 
%struct.MediumWithCopyCtor }>* inalloca)
 // WIN64: define dso_local void 
@"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor*
 %s)
 // WOA: define dso_local arm_aapcs_vfpcc void 
@"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor*
 %s)
+// WOA64: define dso_local void 
@"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor*
 %s)
 
 void big_arg(Big s) {}
 // LINUX-LABEL: define void @_Z7big_arg3Big(%struct.Big* byval align 4 %s)
Index: lib/CodeGen/MicrosoftCXXABI.cpp
===
--- lib/CodeGen/MicrosoftCXXABI.cpp
+++ lib/CodeGen/MicrosoftCXXABI.cpp
@@ -827,6 +827,7 @@
 return RAA_Default;
 
   case llvm::Triple::x86_64:
+  case llvm::Triple::aarch64:
 return !canCopyArgument(RD) ? RAA_Indirect : RAA_Default;
   }
 


Index: test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
===
--- test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
+++ test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp
@@ -2,6 +2,7 @@
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN32 %s
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=thumb-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA %s
 // RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-win32 -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WIN64 %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=aarch64-windows-msvc -mconstructor-aliases -fno-rtti | FileCheck -check-prefix WOA64 %s
 
 struct Empty {};
 
@@ -227,12 +228,14 @@
 // LINUX-LABEL: define void @_Z22small_arg_with_vftable16SmallWithVftable(%struct.SmallWithVftable* %s)
 // WIN32: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(<{ %struct.SmallWithVftable }>* inalloca)
 // WIN64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
+// WOA64: define dso_local void @"?small_arg_with_vftable@@YAXUSmallWithVftable@@@Z"(%struct.SmallWithVftable* %s)
 
 void medium_arg_with_copy_ctor(MediumWithCopyCtor s) {}
 // LINUX-LABEL: define void @_Z25medium_arg_with_copy_ctor18MediumWithCopyCtor(%struct.MediumWithCopyCtor* %s)
 // WIN32: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(<{ %struct.MediumWithCopyCtor }>* inalloca)
 // WIN64: define dso_local void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
 // WOA: define dso_local arm_aapcs_vfpcc void @"?medium_arg_with_copy_ctor@@YAXUMediumWithCopyCtor@@@Z"(%struct.MediumWithCopyCtor* %s)
+// WOA64: define