https://github.com/mahesh-attarde created https://github.com/llvm/llvm-project/pull/95257
In Context of __regcall, Whenever struct can fit in a register we must use single register to pass whole struct object. Without this patch, it uses separate registers for each field. With Patch, if Struct size is <= 64 we can use GPR. >From 6d6619f8f7a37906ac45791487a4d63b51a48ad1 Mon Sep 17 00:00:00 2001 From: mahesh-attarde <mahesh.atta...@intel.com> Date: Wed, 12 Jun 2024 06:15:51 -0700 Subject: [PATCH] added regcall strct by reg support --- clang/lib/CodeGen/Targets/X86.cpp | 20 ++++++++++++ clang/test/CodeGen/regcall3.c | 53 +++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 clang/test/CodeGen/regcall3.c diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp index 43dadf5e724ac..506d106ad65b0 100644 --- a/clang/lib/CodeGen/Targets/X86.cpp +++ b/clang/lib/CodeGen/Targets/X86.cpp @@ -148,6 +148,7 @@ class X86_32ABIInfo : public ABIInfo { Class classify(QualType Ty) const; ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const; + ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State, unsigned ArgIndex) const; @@ -1306,6 +1307,8 @@ class X86_64ABIInfo : public ABIInfo { unsigned &NeededSSE, unsigned &MaxVectorWidth) const; + bool DoesRegcallStructFitInReg(QualType Ty) const; + bool IsIllegalVectorType(QualType Ty) const; /// The 0.98 ABI revision clarified a lot of ambiguities, @@ -2830,6 +2833,20 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs, return ABIArgInfo::getDirect(ResType); } +bool X86_64ABIInfo::DoesRegcallStructFitInReg(QualType Ty) const { + auto RT = Ty->castAs<RecordType>(); + // For Integer class, Max GPR Size is 64 + if (getContext().getTypeSize(Ty) > 64) + return false; + // Struct At hand must not have other non Builtin types + for (const auto *FD : RT->getDecl()->fields()) { + QualType MTy = FD->getType(); + if (!MTy->isBuiltinType()) + return false; + } + return true; +} + ABIArgInfo X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt, unsigned &NeededSSE, @@ -2837,6 +2854,9 @@ X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt, auto RT = Ty->getAs<RecordType>(); assert(RT && "classifyRegCallStructType only valid with struct types"); + if (DoesRegcallStructFitInReg(Ty)) + return classifyArgumentType(Ty, UINT_MAX, NeededInt, NeededSSE, true, true); + if (RT->getDecl()->hasFlexibleArrayMember()) return getIndirectReturnResult(Ty); diff --git a/clang/test/CodeGen/regcall3.c b/clang/test/CodeGen/regcall3.c new file mode 100644 index 0000000000000..1c83407220861 --- /dev/null +++ b/clang/test/CodeGen/regcall3.c @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -S %s -o - -ffreestanding -triple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefixes=LINUX64 + +#include <xmmintrin.h> +struct struct1 { int x; int y; }; +void __regcall v6(int a, float b, struct struct1 c) {} + +void v6_caller(){ + struct struct1 c0; + c0.x = 0xa0a0; c0.y = 0xb0b0; + int x= 0xf0f0, y = 0x0f0f; + v6(x,y,c0); +} + +// LINUX64-LABEL: __regcall3__v6 +// LINUX64: movq %rcx, -8(%rsp) +// LINUX64: movl %eax, -12(%rsp) +// LINUX64: movss %xmm0, -16(%rsp) + +// LINUX64-LABEL: v6_caller +// LINUX64: movl $41120, 16(%rsp) # imm = 0xA0A0 +// LINUX64: movl $45232, 20(%rsp) # imm = 0xB0B0 +// LINUX64: movl $61680, 12(%rsp) # imm = 0xF0F0 +// LINUX64: movl $3855, 8(%rsp) # imm = 0xF0F +// LINUX64: movl 12(%rsp), %eax +// LINUX64: cvtsi2ssl 8(%rsp), %xmm0 +// LINUX64: movq 16(%rsp), %rcx +// LINUX64: callq .L__regcall3__v6$local + + +struct struct2 { int x; float y; }; +void __regcall v31(int a, float b, struct struct2 c) {} + +void v31_caller(){ + struct struct2 c0; + c0.x = 0xa0a0; c0.y = 0xb0b0; + int x= 0xf0f0, y = 0x0f0f; + v31(x,y,c0); +} + +// LINUX64: __regcall3__v31: # @__regcall3__v31 +// LINUX64: movq %rcx, -8(%rsp) +// LINUX64: movl %eax, -12(%rsp) +// LINUX64: movss %xmm0, -16(%rsp) +// LINUX64: v31_caller: # @v31_caller +// LINUX64: movl $41120, 16(%rsp) # imm = 0xA0A0 +// LINUX64: movss .LCPI3_0(%rip), %xmm0 # xmm0 = [4.5232E+4,0.0E+0,0.0E+0,0.0E+0] +// LINUX64: movss %xmm0, 20(%rsp) +// LINUX64: movl $61680, 12(%rsp) # imm = 0xF0F0 +// LINUX64: movl $3855, 8(%rsp) # imm = 0xF0F +// LINUX64: movl 12(%rsp), %eax +// LINUX64: cvtsi2ssl 8(%rsp), %xmm0 +// LINUX64: movq 16(%rsp), %rcx +// LINUX64: callq .L__regcall3__v31$local _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits