From cf19ec8d705434ca6d989a72069dba1040c360ca Mon Sep 17 00:00:00 2001 From: Phoebe Wang Date: Sun, 7 Jul 2024 13:14:59 +0800 Subject: [PATCH 1/2] [X86][vectorcall] Do not consume register for indirect return value This is how MSVC handles it. https://godbolt.org/z/Eav3vx7cd --- clang/lib/CodeGen/Targets/X86.cpp | 2 +- clang/test/CodeGen/vectorcall.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 3146caba1c615..3c0947589ce3d 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -469,7 +469,7 @@ bool X86_32ABIInfo::canExpandIndirectArgument(QualType Ty) const { ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(QualType RetTy, CCState &State) const { // If the return value is indirect, then the hidden argument is consuming one // integer register. - if (State.FreeRegs) { + if (State.CC != llvm::CallingConv::X86_VectorCall && State.FreeRegs) { --State.FreeRegs; if (!IsMCUABI) return getNaturalAlignIndirectInReg(RetTy); diff --git a/clang/test/CodeGen/vectorcall.c b/clang/test/CodeGen/vectorcall.c index 71dc3b0b9585a..cab7fc0972d7b 100644 --- a/clang/test/CodeGen/vectorcall.c +++ b/clang/test/CodeGen/vectorcall.c @@ -90,7 +90,7 @@ struct HVA4 __vectorcall hva6(struct HVA4 a, struct HVA4 b) { return b;} // X64: define dso_local x86_vectorcallcc %struct.HVA4 @"\01hva6@@128"(%struct.HVA4 inreg %a.coerce, ptr noundef %b) struct HVA5 __vectorcall hva7(void) {struct HVA5 a = {}; return a;} -// X86: define dso_local x86_vectorcallcc void @"\01hva7@@0"(ptr dead_on_unwind inreg noalias writable sret(%struct.HVA5) align 16 %agg.result) +// X86: define dso_local x86_vectorcallcc void @"\01hva7@@0"(ptr dead_on_unwind noalias writable sret(%struct.HVA5) align 16 %agg.result) // X64: define dso_local x86_vectorcallcc void @"\01hva7@@0"(ptr dead_on_unwind noalias writable sret(%struct.HVA5) align 16 %agg.result) v4f32 __vectorcall hva8(v4f32 a, v4f32 b, v4f32 c, v4f32 d, int e, v4f32 f) {return f;} From 48ef23c72544bd9f7a862ab9dc17d46945de1a59 Mon Sep 17 00:00:00 2001 From: Phoebe Wang Date: Mon, 8 Jul 2024 10:01:00 +0800 Subject: [PATCH 2/2] Change for fastcall too --- clang/lib/CodeGen/Targets/X86.cpp | 3 ++- clang/test/CodeGen/stdcall-fastcall.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 3c0947589ce3d..1dc3172a6bdf9 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -469,7 +469,8 @@ bool X86_32ABIInfo::canExpandIndirectArgument(QualType Ty) const { ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(QualType RetTy, CCState &State) const { // If the return value is indirect, then the hidden argument is consuming one // integer register. - if (State.CC != llvm::CallingConv::X86_VectorCall && State.FreeRegs) { + if (State.CC != llvm::CallingConv::X86_FastCall && + State.CC != llvm::CallingConv::X86_VectorCall && State.FreeRegs) { --State.FreeRegs; if (!IsMCUABI) return getNaturalAlignIndirectInReg(RetTy); diff --git a/clang/test/CodeGen/stdcall-fastcall.c b/clang/test/CodeGen/stdcall-fastcall.c index f6d86d24463f3..5014b7d48e5b9 100644 --- a/clang/test/CodeGen/stdcall-fastcall.c +++ b/clang/test/CodeGen/stdcall-fastcall.c @@ -151,3 +151,9 @@ void bar13(long long a, int b, int c) { // CHECK: call x86_fastcallcc void @foo13(i64 noundef %{{.*}}, i32 inreg noundef %{{.*}}, i32 inreg noundef % foo13(a, b, c); } + +struct S2 __attribute__((fastcall)) foo14(int a) { + // CHECK-LABEL: define dso_local x86_fastcallcc void @foo14(ptr dead_on_unwind noalias writable sret(%struct.S2) align 4 %agg.result, i32 inreg noundef %a) + struct S2 r = {a}; + return r; +}