[clang] added regcall struct by reg support (PR #95257)

2024-06-27 Thread via cfe-commits

mahesh-attarde wrote:

Thanks aaron for clearing assumptions. Will work on it with separate PR.

https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-27 Thread via cfe-commits

https://github.com/mahesh-attarde closed 
https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-24 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> I don't have any context beyond what's written on 
> https://reviews.llvm.org/D25204 . And at this point, I'm not sure what 
> compiler we're trying to be compatible with. (I added @erichkeane in case he 
> remembers.)

The original feature was written for compatibility with ICC and the fixes are 
also for compatibility with ICC.

> Do you know why currently clang does not do that ? is there different version 
> of regcall spec it follows?

I suspect this was an oversight, but @erichkeane may recall more specific 
details (note, he's out on leave until Sept, so I don't expect to hear back 
from him any time soon). AFAIK, the spec you linked is the correct one for us 
to follow.

> Also if we add new regcall struct implementation, would that break binaries 
> across clang version?

It would be an ABI break because we'd start passing structures differently. 
However, we have ABI tags; we can implement the new functionality under an ABI 
tag so users can get the old ABI still if they need to (search for `AbiTagAttr` 
to see examples of how we do this elsewhere and how we test for it).

https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-18 Thread via cfe-commits

mahesh-attarde wrote:

@erichkeane 
Regcall spec has mentioned allocation strategy that is chunk based.
Do you know why currently clang does not do that ? is there different version 
of regcall spec it follows?
Also if we add new regcall struct implementation, would that break binaries 
across clang version?


https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-18 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

I don't have any context beyond what's written on 
https://reviews.llvm.org/D25204 .  And at this point, I'm not sure what 
compiler we're trying to be compatible with. (I added @erichkeane in case he 
remembers.)

https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-13 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

Right, the specification requires splitting the whole structure into chunks; if 
we add a special-case for 8-byte structs, we'll just have to throw it away when 
we implement the right algorithm.

Also, I'm not sure what the isBuiltinType() check is supposed to handle.  It 
seems to exclude values you'd want to handle, like pointers.

https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-13 Thread via cfe-commits

mahesh-attarde wrote:

> What you're implementing in this change doesn't seem like it brings us much 
> closer to what the document says. I mean, it handles the specific structs in 
> your testcase, but the algorithm you're using doesn't generalize.

Can you suggest case which  can be useful in generalizing?



https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-13 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

What you're implementing in this change doesn't seem like it brings us much 
closer to what the document says. I mean, it handles the specific structs in 
your testcase, but the algorithm you're using doesn't generalize.

https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-13 Thread via cfe-commits

mahesh-attarde wrote:

There are not failures on `buildkite/github-pull-requests/linux-linux-x64.`  
something else is off.


https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-12 Thread via cfe-commits

mahesh-attarde wrote:

Regcall ABI is described on  
https://cdrdv2-public.intel.com/679047/Intel-ABI-Vector-Function-v0.9.8.pdf 
Page No. 18

> 
![image](https://github.com/llvm/llvm-project/assets/145317060/5ff49ca5-0b4c-4c8f-9f00-5de65e4eaeda)


https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-12 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

Do you have a reference for the rules you're implementing?

https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-12 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: None (mahesh-attarde)


Changes

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.

 

---
Full diff: https://github.com/llvm/llvm-project/pull/95257.diff


2 Files Affected:

- (modified) clang/lib/CodeGen/Targets/X86.cpp (+20) 
- (added) clang/test/CodeGen/regcall3.c (+53) 


``diff
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 ) const;
+
   ABIArgInfo classifyArgumentType(QualType RetTy, CCState ,
   unsigned ArgIndex) const;
 
@@ -1306,6 +1307,8 @@ class X86_64ABIInfo : public ABIInfo {
unsigned ,
unsigned ) 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();
+  // 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 ,
  unsigned ,
@@ -2837,6 +2854,9 @@ X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, 
unsigned ,
   auto RT = Ty->getAs();
   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 0..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 
+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:movl12(%rsp), %eax
+// LINUX64:cvtsi2ssl   8(%rsp), %xmm0
+// LINUX64:movq16(%rsp), %rcx
+// LINUX64:callq   .L__regcall3__v31$local

``




https://github.com/llvm/llvm-project/pull/95257
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] added regcall struct by reg support (PR #95257)

2024-06-12 Thread via cfe-commits

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 
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 ) const;
+
   ABIArgInfo classifyArgumentType(QualType RetTy, CCState ,
   unsigned ArgIndex) const;
 
@@ -1306,6 +1307,8 @@ class X86_64ABIInfo : public ABIInfo {
unsigned ,
unsigned ) 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();
+  // 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 ,
  unsigned ,
@@ -2837,6 +2854,9 @@ X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, 
unsigned ,
   auto RT = Ty->getAs();
   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 0..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 
+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:movl12(%rsp), %eax
+// LINUX64:cvtsi2ssl   8(%rsp), %xmm0
+// LINUX64:movq16(%rsp), %rcx
+// LINUX64:callq   .L__regcall3__v31$local

___
cfe-commits mailing list