Skip to content

Commit a7348ae

Browse files
wesleywisercuviper
authored andcommitted
[Mangler] Calculate the argument list byte count suffix correctly when returning large values
`__stdcall`, `__fastcall` and `__vectorcall` return large values via a hidden pointer argument. However, the size of that argument should not be included in the argument list byte count suffix added to the function's decorated name. This patch fixes that issue so that LLVM generates the same decorated name as MSVC does. MSVC example: https://godbolt.org/z/nc35MKPhr Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D110719
1 parent 86509ec commit a7348ae

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

llvm/lib/IR/Mangler.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ static void addByteCountSuffix(raw_ostream &OS, const Function *F,
9999
const unsigned PtrSize = DL.getPointerSize();
100100

101101
for (const Argument &A : F->args()) {
102+
// For the purposes of the byte count suffix, structs returned by pointer
103+
// do not count as function arguments.
104+
if (A.hasStructRetAttr())
105+
continue;
106+
102107
// 'Dereference' type in case of byval or inalloca parameter attribute.
103108
uint64_t AllocSize = A.hasPassPointeeByValueCopyAttr() ?
104109
A.getPassPointeeByValueCopySize(DL) :

llvm/test/CodeGen/X86/stdcall.ll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,21 @@ entry:
1818
ret i32 %a
1919
}
2020

21+
%struct.large_type = type { i64, i64, i64 }
22+
23+
define x86_stdcallcc void @ReturnLargeType(%struct.large_type* noalias nocapture sret(%struct.large_type) align 8 %agg.result) {
24+
; CHECK: ReturnLargeType@0:
25+
; CHECK: retl
26+
entry:
27+
%a = getelementptr inbounds %struct.large_type, %struct.large_type* %agg.result, i32 0, i32 0
28+
store i64 123, i64* %a, align 8
29+
%b = getelementptr inbounds %struct.large_type, %struct.large_type* %agg.result, i32 0, i32 1
30+
store i64 456, i64* %b, align 8
31+
%c = getelementptr inbounds %struct.large_type, %struct.large_type* %agg.result, i32 0, i32 2
32+
store i64 789, i64* %c, align 8
33+
ret void
34+
}
35+
2136
@B = global %0 { void (...)* bitcast (void ()* @MyFunc to void (...)*) }, align 4
2237
; CHECK: _B:
2338
; CHECK: .long _MyFunc@0

llvm/test/CodeGen/X86/vectorcall.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@ declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture r
172172
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i1)
173173

174174
define x86_vectorcallcc void @test_mixed_7(%struct.HVA5* noalias sret(%struct.HVA5) %agg.result) {
175-
; X86-LABEL: test_mixed_7@@4
176-
; X64-LABEL: test_mixed_7@@8
175+
; CHECK-LABEL: test_mixed_7@@0
177176
; X64: mov{{[ql]}} %rcx, %rax
178177
; CHECK: movaps %xmm{{[0-9]}}, 64(%{{rcx|eax}})
179178
; CHECK: movaps %xmm{{[0-9]}}, 48(%{{rcx|eax}})

0 commit comments

Comments
 (0)