[PATCH] D43016: Fix for #31362 - ms_abi is implemented incorrectly for larger values (>=16 bytes).

2018-02-08 Thread Alexander Ivchenko via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC324594: Fix for #31362 - ms_abi is implemented incorrectly 
for values =16 bytes. (authored by aivchenk, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D43016?vs=133198=133395#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43016

Files:
  lib/CodeGen/TargetInfo.cpp
  test/CodeGen/ms_abi.c


Index: test/CodeGen/ms_abi.c
===
--- test/CodeGen/ms_abi.c
+++ test/CodeGen/ms_abi.c
@@ -146,3 +146,16 @@
   // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
   // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
 }
+
+// This test checks if structs are passed according to Win64 calling convention
+// when it's enforced by __attribute((ms_abi)).
+struct i128 {
+  unsigned long long a;
+  unsigned long long b;
+};
+
+__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
+  // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, 
%struct.i128* %a)
+  // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, 
%struct.i128* %a)
+  return a;
+}
Index: lib/CodeGen/TargetInfo.cpp
===
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -3529,7 +3529,17 @@
 
 void X86_64ABIInfo::computeInfo(CGFunctionInfo ) const {
 
-  bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall;
+  const unsigned CallingConv = FI.getCallingConvention();
+  // It is possible to force Win64 calling convention on any x86_64 target by
+  // using __attribute__((ms_abi)). In such case to correctly emit Win64
+  // compatible code delegate this call to WinX86_64ABIInfo::computeInfo.
+  if (CallingConv == llvm::CallingConv::Win64) {
+WinX86_64ABIInfo Win64ABIInfo(CGT);
+Win64ABIInfo.computeInfo(FI);
+return;
+  }
+
+  bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall;
 
   // Keep track of the number of assigned registers.
   unsigned FreeIntRegs = IsRegCall ? 11 : 6;


Index: test/CodeGen/ms_abi.c
===
--- test/CodeGen/ms_abi.c
+++ test/CodeGen/ms_abi.c
@@ -146,3 +146,16 @@
   // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
   // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
 }
+
+// This test checks if structs are passed according to Win64 calling convention
+// when it's enforced by __attribute((ms_abi)).
+struct i128 {
+  unsigned long long a;
+  unsigned long long b;
+};
+
+__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
+  // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
+  // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
+  return a;
+}
Index: lib/CodeGen/TargetInfo.cpp
===
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -3529,7 +3529,17 @@
 
 void X86_64ABIInfo::computeInfo(CGFunctionInfo ) const {
 
-  bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall;
+  const unsigned CallingConv = FI.getCallingConvention();
+  // It is possible to force Win64 calling convention on any x86_64 target by
+  // using __attribute__((ms_abi)). In such case to correctly emit Win64
+  // compatible code delegate this call to WinX86_64ABIInfo::computeInfo.
+  if (CallingConv == llvm::CallingConv::Win64) {
+WinX86_64ABIInfo Win64ABIInfo(CGT);
+Win64ABIInfo.computeInfo(FI);
+return;
+  }
+
+  bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall;
 
   // Keep track of the number of assigned registers.
   unsigned FreeIntRegs = IsRegCall ? 11 : 6;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43016: Fix for #31362 - ms_abi is implemented incorrectly for larger values (>=16 bytes).

2018-02-08 Thread Alexander Ivchenko via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL324594: Fix for #31362 - ms_abi is implemented incorrectly 
for values =16 bytes. (authored by aivchenk, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D43016

Files:
  cfe/trunk/lib/CodeGen/TargetInfo.cpp
  cfe/trunk/test/CodeGen/ms_abi.c


Index: cfe/trunk/test/CodeGen/ms_abi.c
===
--- cfe/trunk/test/CodeGen/ms_abi.c
+++ cfe/trunk/test/CodeGen/ms_abi.c
@@ -146,3 +146,16 @@
   // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
   // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
 }
+
+// This test checks if structs are passed according to Win64 calling convention
+// when it's enforced by __attribute((ms_abi)).
+struct i128 {
+  unsigned long long a;
+  unsigned long long b;
+};
+
+__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
+  // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, 
%struct.i128* %a)
+  // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, 
%struct.i128* %a)
+  return a;
+}
Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp
===
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp
@@ -3529,7 +3529,17 @@
 
 void X86_64ABIInfo::computeInfo(CGFunctionInfo ) const {
 
-  bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall;
+  const unsigned CallingConv = FI.getCallingConvention();
+  // It is possible to force Win64 calling convention on any x86_64 target by
+  // using __attribute__((ms_abi)). In such case to correctly emit Win64
+  // compatible code delegate this call to WinX86_64ABIInfo::computeInfo.
+  if (CallingConv == llvm::CallingConv::Win64) {
+WinX86_64ABIInfo Win64ABIInfo(CGT);
+Win64ABIInfo.computeInfo(FI);
+return;
+  }
+
+  bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall;
 
   // Keep track of the number of assigned registers.
   unsigned FreeIntRegs = IsRegCall ? 11 : 6;


Index: cfe/trunk/test/CodeGen/ms_abi.c
===
--- cfe/trunk/test/CodeGen/ms_abi.c
+++ cfe/trunk/test/CodeGen/ms_abi.c
@@ -146,3 +146,16 @@
   // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
   // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
 }
+
+// This test checks if structs are passed according to Win64 calling convention
+// when it's enforced by __attribute((ms_abi)).
+struct i128 {
+  unsigned long long a;
+  unsigned long long b;
+};
+
+__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
+  // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
+  // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
+  return a;
+}
Index: cfe/trunk/lib/CodeGen/TargetInfo.cpp
===
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp
@@ -3529,7 +3529,17 @@
 
 void X86_64ABIInfo::computeInfo(CGFunctionInfo ) const {
 
-  bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall;
+  const unsigned CallingConv = FI.getCallingConvention();
+  // It is possible to force Win64 calling convention on any x86_64 target by
+  // using __attribute__((ms_abi)). In such case to correctly emit Win64
+  // compatible code delegate this call to WinX86_64ABIInfo::computeInfo.
+  if (CallingConv == llvm::CallingConv::Win64) {
+WinX86_64ABIInfo Win64ABIInfo(CGT);
+Win64ABIInfo.computeInfo(FI);
+return;
+  }
+
+  bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall;
 
   // Keep track of the number of assigned registers.
   unsigned FreeIntRegs = IsRegCall ? 11 : 6;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43016: Fix for #31362 - ms_abi is implemented incorrectly for larger values (>=16 bytes).

2018-02-07 Thread Dimitry Andric via Phabricator via cfe-commits
dim added a comment.

FWIW, this allows me to build wine again for x86_64, without any crashes or 
assertions. So that looks good, in any case.


Repository:
  rC Clang

https://reviews.llvm.org/D43016



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


[PATCH] D43016: Fix for #31362 - ms_abi is implemented incorrectly for larger values (>=16 bytes).

2018-02-07 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

lgtm

These ABIInfo classes don't have any state, so just building one on the stack 
as needed is the way to go. Thanks for the fix!


Repository:
  rC Clang

https://reviews.llvm.org/D43016



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


[PATCH] D43016: Fix for #31362 - ms_abi is implemented incorrectly for larger values (>=16 bytes).

2018-02-07 Thread Mateusz Belicki via Phabricator via cfe-commits
belickim created this revision.
Herald added a subscriber: cfe-commits.

This patch is a fix for following issue: 
https://bugs.llvm.org/show_bug.cgi?id=31362
The problem was caused by front end lowering C calling conventions without 
taking into account calling conventions enforced by __attribute__. In this case 
win64cc was no correctly lowered on targets other than Windows.


Repository:
  rC Clang

https://reviews.llvm.org/D43016

Files:
  lib/CodeGen/TargetInfo.cpp
  test/CodeGen/ms_abi.c


Index: test/CodeGen/ms_abi.c
===
--- test/CodeGen/ms_abi.c
+++ test/CodeGen/ms_abi.c
@@ -146,3 +146,16 @@
   // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
   // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
 }
+
+// This test checks if structs are passed according to Win64 calling convention
+// when it's enforced by __attribute((ms_abi)).
+struct i128 {
+  unsigned long long a;
+  unsigned long long b;
+};
+
+__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
+  // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, 
%struct.i128* %a)
+  // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, 
%struct.i128* %a)
+  return a;
+}
Index: lib/CodeGen/TargetInfo.cpp
===
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -3536,7 +3536,17 @@
 
 void X86_64ABIInfo::computeInfo(CGFunctionInfo ) const {
 
-  bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall;
+  const unsigned CallingConv = FI.getCallingConvention();
+  // It is possible to force Win64 calling convention on any x86_64 target by
+  // using __attribute__((ms_abi)). In such case to correctly emit Win64
+  // compatible code delegate this call to WinX86_64ABIInfo::computeInfo.
+  if (CallingConv == llvm::CallingConv::Win64) {
+WinX86_64ABIInfo Win64ABIInfo(CGT);
+Win64ABIInfo.computeInfo(FI);
+return;
+  }
+
+  bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall;
 
   // Keep track of the number of assigned registers.
   unsigned FreeIntRegs = IsRegCall ? 11 : 6;


Index: test/CodeGen/ms_abi.c
===
--- test/CodeGen/ms_abi.c
+++ test/CodeGen/ms_abi.c
@@ -146,3 +146,16 @@
   // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
   // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
 }
+
+// This test checks if structs are passed according to Win64 calling convention
+// when it's enforced by __attribute((ms_abi)).
+struct i128 {
+  unsigned long long a;
+  unsigned long long b;
+};
+
+__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
+  // WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
+  // FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
+  return a;
+}
Index: lib/CodeGen/TargetInfo.cpp
===
--- lib/CodeGen/TargetInfo.cpp
+++ lib/CodeGen/TargetInfo.cpp
@@ -3536,7 +3536,17 @@
 
 void X86_64ABIInfo::computeInfo(CGFunctionInfo ) const {
 
-  bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall;
+  const unsigned CallingConv = FI.getCallingConvention();
+  // It is possible to force Win64 calling convention on any x86_64 target by
+  // using __attribute__((ms_abi)). In such case to correctly emit Win64
+  // compatible code delegate this call to WinX86_64ABIInfo::computeInfo.
+  if (CallingConv == llvm::CallingConv::Win64) {
+WinX86_64ABIInfo Win64ABIInfo(CGT);
+Win64ABIInfo.computeInfo(FI);
+return;
+  }
+
+  bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall;
 
   // Keep track of the number of assigned registers.
   unsigned FreeIntRegs = IsRegCall ? 11 : 6;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits