Skip to content

Commit 4b20b3c

Browse files
author
Alexander Ivchenko
committedFeb 8, 2018
Fix for #31362 - ms_abi is implemented incorrectly for values >=16 bytes.
Summary: 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. Reviewed By: rnk (Reid Kleckner) Differential Revision: https://reviews.llvm.org/D43016 Author: belickim <mateusz.belicki@intel.com> llvm-svn: 324594
1 parent 1db3ca9 commit 4b20b3c

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed
 

‎clang/lib/CodeGen/TargetInfo.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -3529,7 +3529,17 @@ ABIArgInfo X86_64ABIInfo::classifyRegCallStructType(QualType Ty,
35293529

35303530
void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {
35313531

3532-
bool IsRegCall = FI.getCallingConvention() == llvm::CallingConv::X86_RegCall;
3532+
const unsigned CallingConv = FI.getCallingConvention();
3533+
// It is possible to force Win64 calling convention on any x86_64 target by
3534+
// using __attribute__((ms_abi)). In such case to correctly emit Win64
3535+
// compatible code delegate this call to WinX86_64ABIInfo::computeInfo.
3536+
if (CallingConv == llvm::CallingConv::Win64) {
3537+
WinX86_64ABIInfo Win64ABIInfo(CGT);
3538+
Win64ABIInfo.computeInfo(FI);
3539+
return;
3540+
}
3541+
3542+
bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall;
35333543

35343544
// Keep track of the number of assigned registers.
35353545
unsigned FreeIntRegs = IsRegCall ? 11 : 6;

‎clang/test/CodeGen/ms_abi.c

+13
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,16 @@ void __attribute__((sysv_abi)) f6(__builtin_ms_va_list ap) {
146146
// WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
147147
// WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
148148
}
149+
150+
// This test checks if structs are passed according to Win64 calling convention
151+
// when it's enforced by __attribute((ms_abi)).
152+
struct i128 {
153+
unsigned long long a;
154+
unsigned long long b;
155+
};
156+
157+
__attribute__((ms_abi)) struct i128 f7(struct i128 a) {
158+
// WIN64: define void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
159+
// FREEBSD: define win64cc void @f7(%struct.i128* noalias sret %agg.result, %struct.i128* %a)
160+
return a;
161+
}

0 commit comments

Comments
 (0)
Please sign in to comment.