[PATCH] D43016: Fix for #31362 - ms_abi is implemented incorrectly for larger values (>=16 bytes).
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).
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).
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).
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).
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