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&id=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 &FI) 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 &FI) 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