[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-09 Thread Kishan Parmar via cfe-commits

Long5hot wrote:

ping!! @nemanjai

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-07 Thread zhijian lin via cfe-commits

https://github.com/diggerlin approved this pull request.


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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-07 Thread zhijian lin via cfe-commits

diggerlin wrote:

> @diggerlin ,
> 
> > > can we implement -fcomplex-ppc-gnu-abi as "-msoft-float" ? what is your 
> > > opinion ?
> > > that was  not the intent here and we need to consultant ABI reference 
> > > regrading the same ,before we decide on implementation .

I think I do not express comment clearly, My comment is that "can we implement 
` -fcomplex-ppc-gnu-abi` in llc  ? ,  as  `-msoft-float` which was implemented 
in the llc .

I went through the code  which implement of the `-msoft-float` today , I am OK 
to implement   ` -fcomplex-ppc-gnu-abi` as it is.


I do not have comment on the PR, I approved it, but please wait other several 
days to see whether there is other comment from other reviewer before you merge.


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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-07 Thread via cfe-commits

UmeshKalappa0 wrote:

@diggerlin  ,
>>can we implement -fcomplex-ppc-gnu-abi as "-msoft-float" ? what is your 
>>opinion ?
that was  not the intent here and we need to consultant ABI reference regrading 
the same ,before we decide on implementation .

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-06 Thread zhijian lin via cfe-commits

diggerlin wrote:

I do not further comment on the PR, 

but I have worry about that , the PR have different mechanism with 
"-msoft-float" , the -msoft-float pass "use-soft-float"="true" in the IR, the 
llc will l put float parameter in the GPR, but the PR implement 
`-fcomplex-ppc-gnu-abi` in the frontend  , can we implement  
`-fcomplex-ppc-gnu-abi`  as  "-msoft-float"   ?

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-06 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From cc5fe4a6aa4762040077ab39edb6677f42638673 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Sun, 28 Apr 2024 14:18:42 +0530
Subject: [PATCH 1/2] [clang][PowerPC] Add flag to enable compatibility with
 GNU for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.

Following up with this patch : https://reviews.llvm.org/D146942
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp |  87 +++-
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 394 ++
 .../ppc32-complex-soft-float-gnu-abi.c| 286 +
 .../test/Driver/ppc32-fcomplex-ppc-gnu-abi.c  |  15 +
 9 files changed, 805 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c
 create mode 100644 
clang/test/CodeGen/PowerPC/ppc32-complex-soft-float-gnu-abi.c
 create mode 100644 clang/test/Driver/ppc32-fcomplex-ppc-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 086aedefc11878..e35ac8ea36d727 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2601,6 +2601,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlaghttps://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+  bool IsComplex = Ty->isAnyComplexType();
+
+  if ((getCodeGenOpts().getComplexInRegABI() != CodeGenOptions::CMPLX_InGPR) ||
+  !ArgGPRsLeft || (!IsComplex && Ty->isFloatingType() && !IsSoftFloatABI))
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  // For complex type or any other primitive types.
+  if (IsComplex || !isAggregateTypeForABI(Ty)) {
+// If gr is even set gr = gr + 1 for 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-06 Thread Kishan Parmar via cfe-commits


@@ -0,0 +1,286 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-DEF-SAME: (float noundef [[F:%.*]], [8 x i32] noundef 
[[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, 
align 16
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK-GNU-DEF-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// CHECK-GNU-DEF-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 
16
+// CHECK-GNU-DEF-NEXT:ret [8 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-SOFT-FLOAT-SAME: (float noundef [[F:%.*]], ptr noundef byval({ 
ppc_fp128, ppc_fp128 }) align 16 [[X:%.*]]) #[[ATTR0:[0-9]+]] {

Long5hot wrote:

Below assembly's generated with -fcomplex-ppc-gnu-abi -O1 --target=ppc32 -S  
-msoft-float

"use-soft-float"="true" get's passed in IR in attributes

```
_Complex double testComplexDouble(float w, _Complex float x, _Complex double z)
{
  return z;
}

testComplexDouble:  # @testComplexDouble
.Lfunc_begin2:
.cfi_startproc
# %bb.0:
mr  6, 10
mr  5, 9
mr  4, 8
mr  3, 7
blr
.Lfunc_end2:
.size   testComplexDouble, .Lfunc_end2-.Lfunc_begin2
.cfi_endproc
# -- End function
```

```
_Complex double checkComplexDoubleOnStack(float x1, _Complex float cf, float 
x2, _Complex double cd)
{
  return testComplexDouble(x2, cf, cd);
}

.globl  checkComplexDoubleOnStack   # -- Begin function 
checkComplexDoubleOnStack
.p2align2
.type   checkComplexDoubleOnStack,@function
checkComplexDoubleOnStack:  # @checkComplexDoubleOnStack
.Lfunc_begin3:
.cfi_startproc
# %bb.0:
lwz 3, 0(8)
lwz 4, 4(8)
lwz 5, 8(8)
lwz 6, 12(8)
blr
```

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-06 Thread Kishan Parmar via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-06 Thread Kishan Parmar via cfe-commits


@@ -0,0 +1,286 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-DEF-SAME: (float noundef [[F:%.*]], [8 x i32] noundef 
[[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, 
align 16
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK-GNU-DEF-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// CHECK-GNU-DEF-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 
16
+// CHECK-GNU-DEF-NEXT:ret [8 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-SOFT-FLOAT-SAME: (float noundef [[F:%.*]], ptr noundef byval({ 
ppc_fp128, ppc_fp128 }) align 16 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, 
ppc_fp128 }, align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr 
[[X_REALP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr 
[[X_IMAGP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:store ppc_fp128 [[X_REAL]], ptr 
[[RETVAL_REALP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:store ppc_fp128 [[X_IMAG]], ptr 
[[RETVAL_IMAGP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr 
[[RETVAL]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:ret [8 x i32] [[TMP0]]
+//
+_Complex long double _cldouble(float f, _Complex long double x) {
+  return x;
+}
+
+// CHECK-GNU-DEF-LABEL: define dso_local [4 x i32] @testComplexDouble
+// CHECK-GNU-DEF-SAME: (float noundef [[W:%.*]], [1 x i64] noundef 
[[X_COERCE:%.*]], [4 x i32] noundef [[Z_COERCE:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-DEF-NEXT:[[Z:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[W_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [1 x i64] [[X_COERCE]], ptr [[X]], align 4
+// CHECK-GNU-DEF-NEXT:store [4 x i32] [[Z_COERCE]], ptr [[Z]], align 8
+// CHECK-GNU-DEF-NEXT:store float [[W]], ptr [[W_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[Z_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[Z]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[Z_REAL:%.*]] = load double, ptr [[Z_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[Z_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[Z]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[Z_IMAG:%.*]] = load double, ptr [[Z_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-04 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits

diggerlin wrote:

please do not merge the commit if possible, merging the commit make the review 
difficult,  We want to compare what change between the two commit when we 
review. otherwise we have review the patch from scratch.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits


@@ -0,0 +1,15 @@
+// RUN: not %clang %s --target=x86_64 -fcomplex-ppc-gnu-abi 2>&1 \
+// RUN: | FileCheck %s -check-prefix=X86_64
+// X86_64: error: unsupported option '-fcomplex-ppc-gnu-abi' for target 
'x86_64'
+
+// RUN: not %clang %s --target=ppc64 -fcomplex-ppc-gnu-abi 2>&1 \

diggerlin wrote:

I think two test scenarios is enough , 

`if (!TC.getTriple().isPPC32() || !TC.getTriple().isOSBinFormatELF()) {`

one for `!TC.getTriple().isPPC32()` , other for 
`!TC.getTriple().isOSBinFormatELF()`

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits


@@ -0,0 +1,286 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-DEF-SAME: (float noundef [[F:%.*]], [8 x i32] noundef 
[[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, 
align 16
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK-GNU-DEF-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// CHECK-GNU-DEF-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 
16
+// CHECK-GNU-DEF-NEXT:ret [8 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-SOFT-FLOAT-SAME: (float noundef [[F:%.*]], ptr noundef byval({ 
ppc_fp128, ppc_fp128 }) align 16 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, 
ppc_fp128 }, align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr 
[[X_REALP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr 
[[X_IMAGP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:store ppc_fp128 [[X_REAL]], ptr 
[[RETVAL_REALP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:store ppc_fp128 [[X_IMAG]], ptr 
[[RETVAL_IMAGP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr 
[[RETVAL]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:ret [8 x i32] [[TMP0]]
+//
+_Complex long double _cldouble(float f, _Complex long double x) {
+  return x;
+}
+
+// CHECK-GNU-DEF-LABEL: define dso_local [4 x i32] @testComplexDouble
+// CHECK-GNU-DEF-SAME: (float noundef [[W:%.*]], [1 x i64] noundef 
[[X_COERCE:%.*]], [4 x i32] noundef [[Z_COERCE:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-DEF-NEXT:[[Z:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[W_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [1 x i64] [[X_COERCE]], ptr [[X]], align 4
+// CHECK-GNU-DEF-NEXT:store [4 x i32] [[Z_COERCE]], ptr [[Z]], align 8
+// CHECK-GNU-DEF-NEXT:store float [[W]], ptr [[W_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[Z_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[Z]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[Z_REAL:%.*]] = load double, ptr [[Z_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[Z_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[Z]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[Z_IMAG:%.*]] = load double, ptr [[Z_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits


@@ -0,0 +1,286 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-DEF-SAME: (float noundef [[F:%.*]], [8 x i32] noundef 
[[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, 
align 16
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK-GNU-DEF-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// CHECK-GNU-DEF-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 
16
+// CHECK-GNU-DEF-NEXT:ret [8 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-SOFT-FLOAT-SAME: (float noundef [[F:%.*]], ptr noundef byval({ 
ppc_fp128, ppc_fp128 }) align 16 [[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, 
ppc_fp128 }, align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr 
[[X_REALP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr 
[[X_IMAGP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:store ppc_fp128 [[X_REAL]], ptr 
[[RETVAL_REALP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:store ppc_fp128 [[X_IMAG]], ptr 
[[RETVAL_IMAGP]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr 
[[RETVAL]], align 16
+// CHECK-GNU-SOFT-FLOAT-NEXT:ret [8 x i32] [[TMP0]]
+//
+_Complex long double _cldouble(float f, _Complex long double x) {
+  return x;
+}
+
+// CHECK-GNU-DEF-LABEL: define dso_local [4 x i32] @testComplexDouble
+// CHECK-GNU-DEF-SAME: (float noundef [[W:%.*]], [1 x i64] noundef 
[[X_COERCE:%.*]], [4 x i32] noundef [[Z_COERCE:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-DEF-NEXT:[[Z:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[W_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [1 x i64] [[X_COERCE]], ptr [[X]], align 4
+// CHECK-GNU-DEF-NEXT:store [4 x i32] [[Z_COERCE]], ptr [[Z]], align 8
+// CHECK-GNU-DEF-NEXT:store float [[W]], ptr [[W_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[Z_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[Z]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[Z_REAL:%.*]] = load double, ptr [[Z_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[Z_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[Z]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[Z_IMAG:%.*]] = load double, ptr [[Z_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits


@@ -0,0 +1,286 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-DEF-SAME: (float noundef [[F:%.*]], [8 x i32] noundef 
[[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, 
align 16
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK-GNU-DEF-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// CHECK-GNU-DEF-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 
16
+// CHECK-GNU-DEF-NEXT:ret [8 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-SOFT-FLOAT-SAME: (float noundef [[F:%.*]], ptr noundef byval({ 
ppc_fp128, ppc_fp128 }) align 16 [[X:%.*]]) #[[ATTR0:[0-9]+]] {

diggerlin wrote:

I am curiously that option `-msoft-float` do not change the `float noundef 
[[F:%.*]]` to `i32 noundef [[F:%.*]]` , I do not read the code implement of the 
option `-msoft-float` 

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-05-03 Thread zhijian lin via cfe-commits


@@ -330,8 +330,12 @@ namespace {
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
   bool IsRetSmallStructInRegABI;
+  // Size of GPR in bits.
+  static const unsigned RegLen = 32;

diggerlin wrote:

suggest change RegLen to GPRBits  as 

https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/Targets/PPC.cpp#L615
 

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-28 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From cc5fe4a6aa4762040077ab39edb6677f42638673 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Sun, 28 Apr 2024 14:18:42 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.

Following up with this patch : https://reviews.llvm.org/D146942
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp |  87 +++-
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 394 ++
 .../ppc32-complex-soft-float-gnu-abi.c| 286 +
 .../test/Driver/ppc32-fcomplex-ppc-gnu-abi.c  |  15 +
 9 files changed, 805 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c
 create mode 100644 
clang/test/CodeGen/PowerPC/ppc32-complex-soft-float-gnu-abi.c
 create mode 100644 clang/test/Driver/ppc32-fcomplex-ppc-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 086aedefc11878..e35ac8ea36d727 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2601,6 +2601,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlaghttps://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+  bool IsComplex = Ty->isAnyComplexType();
+
+  if ((getCodeGenOpts().getComplexInRegABI() != CodeGenOptions::CMPLX_InGPR) ||
+  !ArgGPRsLeft || (!IsComplex && Ty->isFloatingType() && !IsSoftFloatABI))
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  // For complex type or any other primitive types.
+  if (IsComplex || !isAggregateTypeForABI(Ty)) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+ 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-24 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From 4cdfaf0a576d44a65484c61f5a572bed73ab0ce4 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Wed, 24 Apr 2024 19:06:23 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.

Following up with this patch : https://reviews.llvm.org/D146942
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp |  87 +++-
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 415 ++
 .../ppc32-complex-soft-float-gnu-abi.c| 310 +
 .../test/Driver/ppc32-fcomplex-ppc-gnu-abi.c  |  15 +
 9 files changed, 850 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c
 create mode 100644 
clang/test/CodeGen/PowerPC/ppc32-complex-soft-float-gnu-abi.c
 create mode 100644 clang/test/Driver/ppc32-fcomplex-ppc-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 922bda721dc780..605440ed1c596d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2601,6 +2601,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlaghttps://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+  bool IsComplex = Ty->isAnyComplexType();
+
+  if ((getCodeGenOpts().getComplexInRegABI() != CodeGenOptions::CMPLX_InGPR) ||
+  !ArgGPRsLeft || (!IsComplex && Ty->isFloatingType() && !IsSoftFloatABI))
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  // For complex type or any other primitive types.
+  if (IsComplex || !isAggregateTypeForABI(Ty)) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+ 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-24 Thread Kishan Parmar via cfe-commits


@@ -0,0 +1,350 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [4 x i32] @_cdouble
+// CHECK-GNU-DEF-SAME: ([4 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:store [4 x i32] [[X_COERCE]], ptr [[X]], align 8
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load double, ptr [[X_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load double, ptr [[X_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store double [[X_REAL]], ptr [[RETVAL_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:store double [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 
8
+// CHECK-GNU-DEF-NEXT:ret [4 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [4 x i32] @_cdouble
+// CHECK-GNU-SOFT-FLOAT-SAME: ([4 x i32] noundef [[X_COERCE:%.*]]) 
#[[ATTR0:[0-9]+]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL:%.*]] = alloca { double, double }, 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:store [4 x i32] [[X_COERCE]], ptr [[X]], 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REAL:%.*]] = load double, ptr 
[[X_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAG:%.*]] = load double, ptr 
[[X_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:store double [[X_REAL]], ptr 
[[RETVAL_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:store double [[X_IMAG]], ptr 
[[RETVAL_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[TMP0:%.*]] = load [4 x i32], ptr 
[[RETVAL]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:ret [4 x i32] [[TMP0]]
+//
+_Complex double _cdouble(_Complex double x) {
+  return x;
+}
+
+// CHECK-GNU-DEF-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-DEF-SAME: (float noundef [[F:%.*]], [8 x i32] noundef 
[[X_COERCE:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, 
align 16
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK-GNU-DEF-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// CHECK-GNU-DEF-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 
16
+// CHECK-GNU-DEF-NEXT:ret [8 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [8 x i32] @_cldouble
+// 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-24 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From b5746d24130b9595762d85f4da7169d7b7a801f0 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Wed, 24 Apr 2024 18:01:23 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.

Following up with this patch : https://reviews.llvm.org/D146942
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp |  87 +++-
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 415 ++
 .../ppc32-complex-soft-float-gnu-abi.c| 310 +
 .../test/Driver/ppc32-fcomplex-ppc-gnu-abi.c  |  15 +
 9 files changed, 850 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c
 create mode 100644 
clang/test/CodeGen/PowerPC/ppc32-complex-soft-float-gnu-abi.c
 create mode 100644 clang/test/Driver/ppc32-fcomplex-ppc-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 922bda721dc780..605440ed1c596d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2601,6 +2601,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlaghttps://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if ((getCodeGenOpts().getComplexInRegABI() != CodeGenOptions::CMPLX_InGPR) ||
+  !ArgGPRsLeft ||
+  (!Ty->isAnyComplexType() && Ty->isFloatingType() && !IsSoftFloatABI))
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  // For complex type or any other primitive types.
+  if (bool IsComplex = Ty->isAnyComplexType() || !isAggregateTypeForABI(Ty)) {
+// If gr is even set gr = gr + 1 for 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-05 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-05 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-05 Thread zhijian lin via cfe-commits


@@ -0,0 +1,350 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [4 x i32] @_cdouble
+// CHECK-GNU-DEF-SAME: ([4 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:store [4 x i32] [[X_COERCE]], ptr [[X]], align 8
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load double, ptr [[X_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load double, ptr [[X_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store double [[X_REAL]], ptr [[RETVAL_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:store double [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 
8
+// CHECK-GNU-DEF-NEXT:ret [4 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [4 x i32] @_cdouble
+// CHECK-GNU-SOFT-FLOAT-SAME: ([4 x i32] noundef [[X_COERCE:%.*]]) 
#[[ATTR0:[0-9]+]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL:%.*]] = alloca { double, double }, 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:store [4 x i32] [[X_COERCE]], ptr [[X]], 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REAL:%.*]] = load double, ptr 
[[X_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAG:%.*]] = load double, ptr 
[[X_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:store double [[X_REAL]], ptr 
[[RETVAL_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:store double [[X_IMAG]], ptr 
[[RETVAL_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[TMP0:%.*]] = load [4 x i32], ptr 
[[RETVAL]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:ret [4 x i32] [[TMP0]]
+//
+_Complex double _cdouble(_Complex double x) {
+  return x;
+}
+
+// CHECK-GNU-DEF-LABEL: define dso_local [8 x i32] @_cldouble
+// CHECK-GNU-DEF-SAME: (float noundef [[F:%.*]], [8 x i32] noundef 
[[X_COERCE:%.*]]) #[[ATTR0]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { ppc_fp128, ppc_fp128 }, 
align 16
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { ppc_fp128, ppc_fp128 }, align 16
+// CHECK-GNU-DEF-NEXT:[[F_ADDR:%.*]] = alloca float, align 4
+// CHECK-GNU-DEF-NEXT:store [8 x i32] [[X_COERCE]], ptr [[X]], align 16
+// CHECK-GNU-DEF-NEXT:store float [[F]], ptr [[F_ADDR]], align 4
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load ppc_fp128, ptr [[X_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load ppc_fp128, ptr [[X_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
ppc_fp128, ppc_fp128 }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_REAL]], ptr [[RETVAL_REALP]], 
align 16
+// CHECK-GNU-DEF-NEXT:store ppc_fp128 [[X_IMAG]], ptr [[RETVAL_IMAGP]], 
align 16
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [8 x i32], ptr [[RETVAL]], align 
16
+// CHECK-GNU-DEF-NEXT:ret [8 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [8 x i32] @_cldouble
+// 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-05 Thread zhijian lin via cfe-commits


@@ -5585,6 +5585,15 @@ void Clang::ConstructJob(Compilation , const JobAction 
,
 }
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_fcomplex_ppc_gnu_abi)) {
+if (!TC.getTriple().isPPC32() || !TC.getTriple().isOSBinFormatELF()) {
+  D.Diag(diag::err_drv_unsupported_opt_for_target)

diggerlin wrote:

I think we need a test case for this.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-05 Thread zhijian lin via cfe-commits


@@ -396,12 +405,80 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  // Choice of using llvm::Type::getInt64Ty(getVMContext()) for complex
+  // single-precision floats is based on the ABI ATR-PASS-COMPLEX-IN-GPRS
+  // specification. According to the specification:
+  // - For complex single-precision floats: If the register (gr) is even, it's
+  // incremented by one, and the lower-addressed word of the argument is loaded
+  // into gr, while the higher-addressed word is loaded into gr + 1. Then, gr 
is
+  // incremented by 2.
+  // - For complex double-precision floats: The words of the argument are 
loaded
+  // in memory-address order into gr, gr + 1, gr + 2, and gr + 3, with gr being
+  // incremented by 4. Thus, to maintain even alignment and adhere to the ABI
+  // specification, llvm::Type::getInt64Ty(getVMContext()) is used when 
TypeSize
+  // is 64. Powerpc backend handles this alignment requirement. Specifically,
+  // you can refer to the CC_PPC32_SVR4_Custom_AlignArgRegs method from
+  // PPCCallingconvention.cpp. For more context, refer to the previous
+  // discussion: https://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)

diggerlin wrote:

` if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
|| !ArgGPRsLeft)`
 
 -->
`  if (getCodeGenOpts().getComplexInRegABI() != CodeGenOptions::CMPLX_InGPR ||  
!ArgGPRsLeft)`

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-05 Thread zhijian lin via cfe-commits


@@ -0,0 +1,350 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-DEF
+// RUN: %clang_cc1 -msoft-float  -mfloat-abi soft -triple 
powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU-SOFT-FLOAT
+
+// CHECK-GNU-DEF-LABEL: define dso_local [4 x i32] @_cdouble
+// CHECK-GNU-DEF-SAME: ([4 x i32] noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-DEF-NEXT:  entry:
+// CHECK-GNU-DEF-NEXT:[[RETVAL:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:[[X:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-DEF-NEXT:store [4 x i32] [[X_COERCE]], ptr [[X]], align 8
+// CHECK-GNU-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[X_REAL:%.*]] = load double, ptr [[X_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:[[X_IMAG:%.*]] = load double, ptr [[X_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-DEF-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-DEF-NEXT:store double [[X_REAL]], ptr [[RETVAL_REALP]], align 
8
+// CHECK-GNU-DEF-NEXT:store double [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 
8
+// CHECK-GNU-DEF-NEXT:[[TMP0:%.*]] = load [4 x i32], ptr [[RETVAL]], align 
8
+// CHECK-GNU-DEF-NEXT:ret [4 x i32] [[TMP0]]
+//
+// CHECK-GNU-SOFT-FLOAT-LABEL: define dso_local [4 x i32] @_cdouble
+// CHECK-GNU-SOFT-FLOAT-SAME: ([4 x i32] noundef [[X_COERCE:%.*]]) 
#[[ATTR0:[0-9]+]] {
+// CHECK-GNU-SOFT-FLOAT-NEXT:  entry:
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL:%.*]] = alloca { double, double }, 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X:%.*]] = alloca { double, double }, align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:store [4 x i32] [[X_COERCE]], ptr [[X]], 
align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_REAL:%.*]] = load double, ptr 
[[X_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[X_IMAG:%.*]] = load double, ptr 
[[X_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds 
{ double, double }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-SOFT-FLOAT-NEXT:store double [[X_REAL]], ptr 
[[RETVAL_REALP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:store double [[X_IMAG]], ptr 
[[RETVAL_IMAGP]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:[[TMP0:%.*]] = load [4 x i32], ptr 
[[RETVAL]], align 8
+// CHECK-GNU-SOFT-FLOAT-NEXT:ret [4 x i32] [[TMP0]]
+//
+_Complex double _cdouble(_Complex double x) {

diggerlin wrote:

there is not float or double as parameter in the test case , I think we have 
tested the  scenario in the ppc32-complex-gnu-abi.c 
, do we still need it ?


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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-04-05 Thread zhijian lin via cfe-commits


@@ -396,12 +405,80 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  // Choice of using llvm::Type::getInt64Ty(getVMContext()) for complex
+  // single-precision floats is based on the ABI ATR-PASS-COMPLEX-IN-GPRS
+  // specification. According to the specification:
+  // - For complex single-precision floats: If the register (gr) is even, it's
+  // incremented by one, and the lower-addressed word of the argument is loaded
+  // into gr, while the higher-addressed word is loaded into gr + 1. Then, gr 
is
+  // incremented by 2.
+  // - For complex double-precision floats: The words of the argument are 
loaded
+  // in memory-address order into gr, gr + 1, gr + 2, and gr + 3, with gr being
+  // incremented by 4. Thus, to maintain even alignment and adhere to the ABI
+  // specification, llvm::Type::getInt64Ty(getVMContext()) is used when 
TypeSize
+  // is 64. Powerpc backend handles this alignment requirement. Specifically,
+  // you can refer to the CC_PPC32_SVR4_Custom_AlignArgRegs method from
+  // PPCCallingconvention.cpp. For more context, refer to the previous
+  // discussion: https://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType()) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft;
+
+if (TypeSize <= RegLen * ArgGPRsLeft) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+}
+  }
+
+  // Records with non-trivial destructors/copy-constructors should not be
+  // passed by value.
+  if (isAggregateTypeForABI(Ty))
+--ArgGPRsLeft;
+  else if (!Ty->isFloatingType() || (Ty->isFloatingType() && IsSoftFloatABI)) {
+// For other primitive types.
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft; // If gr is even set gr = gr + 1 for TypeSize=64.
+if (TypeSize <= ArgGPRsLeft * RegLen)
+  ArgGPRsLeft -= TypeSize / RegLen;
+  }

diggerlin wrote:

the code line 467-472 is duplicated with the code 452-458 ,you rewrite the 
function as 
```

ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
int ) const {
  Ty = useFirstFieldIfTransparentUnion(Ty);
  if ( getCodeGenOpts().getComplexInRegABI() != CodeGenOptions::CMPLX_InGPR ||
  !ArgGPRsLeft || (Ty->isFloatingType() && !IsSoftFloatABI)
return DefaultABIInfo::classifyArgumentType(Ty);

  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
  // Records with non-trivial destructors/copy-constructors should not be
  // passed by value.
  if (isAggregateTypeForABI(Ty))
--ArgGPRsLeft;

  ASTContext  = getContext();
  uint64_t TypeSize = Context.getTypeSize(Ty);

// If gr is even set gr = gr + 1 for TypeSize=64.
if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
  --ArgGPRsLeft;

if (TypeSize <= RegLen * ArgGPRsLeft) {
  ArgGPRsLeft -= TypeSize / RegLen;
  return handleComplex(TypeSize);
}
  return DefaultABIInfo::classifyArgumentType(Ty);
}
```

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-28 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From 3c5fcb03ee7871a93d3163beb51133c836f58ca6 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Thu, 28 Mar 2024 17:26:48 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp |  94 -
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 394 ++
 .../ppc32-complex-soft-float-gnu-abi.c| 350 
 8 files changed, 861 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c
 create mode 100644 
clang/test/CodeGen/PowerPC/ppc32-complex-soft-float-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 29066ea14280c2..4a5cfc988b8c18 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2577,6 +2577,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlaghttps://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType()) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft;
+
+if (TypeSize <= RegLen * ArgGPRsLeft) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+}
+  }
+
+  // Records with non-trivial destructors/copy-constructors should not be
+  // passed by value.
+  if (isAggregateTypeForABI(Ty))
+

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-27 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-27 Thread zhijian lin via cfe-commits


@@ -396,12 +405,85 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  // Choice of using llvm::Type::getInt64Ty(getVMContext()) for complex
+  // single-precision floats is based on the ABI ATR-PASS-COMPLEX-IN-GPRS
+  // specification. According to the specification:
+  // - For complex single-precision floats: If the register (gr) is even, it's
+  // incremented by one, and the lower-addressed word of the argument is loaded
+  // into gr, while the higher-addressed word is loaded into gr + 1. Then, gr 
is
+  // incremented by 2.
+  // - For complex double-precision floats: The words of the argument are 
loaded
+  // in memory-address order into gr, gr + 1, gr + 2, and gr + 3, with gr being
+  // incremented by 4. Thus, to maintain even alignment and adhere to the ABI
+  // specification, llvm::Type::getInt64Ty(getVMContext()) is used when 
TypeSize
+  // is 64. Powerpc backend handles this alignment requirement. Specifically,
+  // you can refer to the CC_PPC32_SVR4_Custom_AlignArgRegs method from
+  // PPCCallingconvention.cpp. For more context, refer to the previous
+  // discussion: https://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType()) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft;
+
+if (TypeSize <= RegLen * ArgGPRsLeft) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+}
+  }
+
+  // Records with non-trivial destructors/copy-constructors should not be
+  // passed by value.
+  if (isAggregateTypeForABI(Ty))
+--ArgGPRsLeft;
+  else if (!Ty->isFloatingType()) {
+// For other primitive types.
+if (TypeSize == 64) {
+  // If gr is even set gr = gr + 1 for TypeSize=64.
+  if (ArgGPRsLeft % 2 == 1)
+--ArgGPRsLeft;
+  if (TypeSize <= ArgGPRsLeft * RegLen) {
+ArgGPRsLeft -= TypeSize / RegLen;
+  }
+} else
+  --ArgGPRsLeft;

diggerlin wrote:

it is nice to have.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-27 Thread Kishan Parmar via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-27 Thread Kishan Parmar via cfe-commits


@@ -396,12 +405,85 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  // Choice of using llvm::Type::getInt64Ty(getVMContext()) for complex
+  // single-precision floats is based on the ABI ATR-PASS-COMPLEX-IN-GPRS
+  // specification. According to the specification:
+  // - For complex single-precision floats: If the register (gr) is even, it's
+  // incremented by one, and the lower-addressed word of the argument is loaded
+  // into gr, while the higher-addressed word is loaded into gr + 1. Then, gr 
is
+  // incremented by 2.
+  // - For complex double-precision floats: The words of the argument are 
loaded
+  // in memory-address order into gr, gr + 1, gr + 2, and gr + 3, with gr being
+  // incremented by 4. Thus, to maintain even alignment and adhere to the ABI
+  // specification, llvm::Type::getInt64Ty(getVMContext()) is used when 
TypeSize
+  // is 64. Powerpc backend handles this alignment requirement. Specifically,
+  // you can refer to the CC_PPC32_SVR4_Custom_AlignArgRegs method from
+  // PPCCallingconvention.cpp. For more context, refer to the previous
+  // discussion: https://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType()) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft;
+
+if (TypeSize <= RegLen * ArgGPRsLeft) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+}
+  }
+
+  // Records with non-trivial destructors/copy-constructors should not be
+  // passed by value.
+  if (isAggregateTypeForABI(Ty))
+--ArgGPRsLeft;
+  else if (!Ty->isFloatingType()) {
+// For other primitive types.
+if (TypeSize == 64) {
+  // If gr is even set gr = gr + 1 for TypeSize=64.
+  if (ArgGPRsLeft % 2 == 1)
+--ArgGPRsLeft;
+  if (TypeSize <= ArgGPRsLeft * RegLen) {
+ArgGPRsLeft -= TypeSize / RegLen;
+  }
+} else
+  --ArgGPRsLeft;

Long5hot wrote:

I missed the part for soft-float, for soft-float we pass long-double(128) in 
GPRs, Below change works.

```
else if (!Ty->isFloatingType() || (Ty->isFloatingType() && IsSoftFloatABI)) { 
if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
 --ArgGPRsLeft; // If gr is even set gr = gr + 1 for TypeSize=64.
if (TypeSize <= ArgGPRsLeft * RegLen)
 ArgGPRsLeft -= TypeSize / RegLen;
   }
```

I will update the review as your comments. Do i need to add the tests for 
soft-floats as well??

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread zhijian lin via cfe-commits


@@ -396,12 +405,85 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  // Choice of using llvm::Type::getInt64Ty(getVMContext()) for complex
+  // single-precision floats is based on the ABI ATR-PASS-COMPLEX-IN-GPRS
+  // specification. According to the specification:
+  // - For complex single-precision floats: If the register (gr) is even, it's
+  // incremented by one, and the lower-addressed word of the argument is loaded
+  // into gr, while the higher-addressed word is loaded into gr + 1. Then, gr 
is
+  // incremented by 2.
+  // - For complex double-precision floats: The words of the argument are 
loaded
+  // in memory-address order into gr, gr + 1, gr + 2, and gr + 3, with gr being
+  // incremented by 4. Thus, to maintain even alignment and adhere to the ABI
+  // specification, llvm::Type::getInt64Ty(getVMContext()) is used when 
TypeSize
+  // is 64. Powerpc backend handles this alignment requirement. Specifically,
+  // you can refer to the CC_PPC32_SVR4_Custom_AlignArgRegs method from
+  // PPCCallingconvention.cpp. For more context, refer to the previous
+  // discussion: https://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType()) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft;
+
+if (TypeSize <= RegLen * ArgGPRsLeft) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+}
+  }
+
+  // Records with non-trivial destructors/copy-constructors should not be
+  // passed by value.
+  if (isAggregateTypeForABI(Ty))
+--ArgGPRsLeft;
+  else if (!Ty->isFloatingType()) {
+// For other primitive types.
+if (TypeSize == 64) {
+  // If gr is even set gr = gr + 1 for TypeSize=64.
+  if (ArgGPRsLeft % 2 == 1)
+--ArgGPRsLeft;
+  if (TypeSize <= ArgGPRsLeft * RegLen) {
+ArgGPRsLeft -= TypeSize / RegLen;
+  }
+} else
+  --ArgGPRsLeft;

diggerlin wrote:

it look that if TypeSize=128, you only do `--ArgGPRsLeft`,  it pass by pointer ?

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread zhijian lin via cfe-commits


@@ -421,6 +503,11 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType 
RetTy) const {
 }
   }
 
+  bool IsComplexInRegABI =
+  getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR;
+  if (IsComplexInRegABI && RetTy->isAnyComplexType())

diggerlin wrote:

you do not need to introduce a new variable `IsComplexInRegABI` here since it 
only be used once.

change to 
`if ((getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) && 
RetTy->isAnyComplexType())`



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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread zhijian lin via cfe-commits


@@ -0,0 +1,306 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-DEF
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU
+
+// CHECK-DEF-LABEL: define dso_local void @foo1
+// CHECK-DEF-SAME: (ptr dead_on_unwind noalias writable sret({ float, float }) 
align 4 [[AGG_RESULT:%.*]], ptr noundef byval({ float, float }) align 4 
[[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-DEF-NEXT:  entry:
+// CHECK-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { float, float 
}, ptr [[X]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4
+// CHECK-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { float, float 
}, ptr [[X]], i32 0, i32 1
+// CHECK-DEF-NEXT:[[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4
+// CHECK-DEF-NEXT:[[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// CHECK-DEF-NEXT:store float [[X_REAL]], ptr [[AGG_RESULT_REALP]], align 4
+// CHECK-DEF-NEXT:store float [[X_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 4
+// CHECK-DEF-NEXT:[[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[AGG_RESULT_REAL:%.*]] = load float, ptr 
[[AGG_RESULT_REALP1]], align 4
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAG:%.*]] = load float, ptr 
[[AGG_RESULT_IMAGP2]], align 4
+// CHECK-DEF-NEXT:[[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// CHECK-DEF-NEXT:store float [[AGG_RESULT_REAL]], ptr 
[[AGG_RESULT_REALP3]], align 4
+// CHECK-DEF-NEXT:store float [[AGG_RESULT_IMAG]], ptr 
[[AGG_RESULT_IMAGP4]], align 4
+// CHECK-DEF-NEXT:ret void
+//
+// CHECK-GNU-LABEL: define dso_local [1 x i64] @foo1
+// CHECK-GNU-SAME: ([1 x i64] noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-NEXT:  entry:
+// CHECK-GNU-NEXT:[[RETVAL:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-NEXT:[[X:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-NEXT:store [1 x i64] [[X_COERCE]], ptr [[X]], align 4
+// CHECK-GNU-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { float, float 
}, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-NEXT:[[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4
+// CHECK-GNU-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { float, float 
}, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-NEXT:[[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4
+// CHECK-GNU-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { float, 
float }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, 
float }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-NEXT:store float [[X_REAL]], ptr [[RETVAL_REALP]], align 4
+// CHECK-GNU-NEXT:store float [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 4
+// CHECK-GNU-NEXT:[[TMP0:%.*]] = load [1 x i64], ptr [[RETVAL]], align 4
+// CHECK-GNU-NEXT:ret [1 x i64] [[TMP0]]
+//
+_Complex float foo1(_Complex float x) {

diggerlin wrote:

general question for all test scenario: 

can you add a caller function to call the function to check whether organize 
the call parameter and pass the parameter as called function need ? 

   

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From 81d57b415738e4cea8fbbade990046271cb505a5 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Tue, 26 Mar 2024 17:08:25 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp | 100 +-
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 306 ++
 7 files changed, 429 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 29066ea14280c2..4a5cfc988b8c18 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2577,6 +2577,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlaghttps://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType()) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft;
+
+if (TypeSize <= RegLen * ArgGPRsLeft) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+}
+  }
+
+  // Records with non-trivial destructors/copy-constructors should not be
+  // passed by value.
+  if (isAggregateTypeForABI(Ty))
+--ArgGPRsLeft;
+  else if (!Ty->isFloatingType()) {
+// For other primitive types.
+if (TypeSize == 64) {
+  // If gr is even set gr = gr + 1 for 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread Kishan Parmar via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+ArgGPRsLeft -= TypeSize / RegLen;
+return handleComplex(TypeSize);
+  }
+
+  if (ArgGPRsLeft) {
+// Records with non-trivial destructors/copy-constructors should not be
+// passed by value.
+if (isAggregateTypeForABI(Ty))
+  ArgGPRsLeft -= 1;
+else if (!Ty->isFloatingType()) {
+  // For other premitive types.
+  if (TypeSize > RegLen && TypeSize <= 2 * RegLen)
+ArgGPRsLeft -= TypeSize / RegLen;

Long5hot wrote:

Yes, gcc  passes the last arg in stack
https://godbolt.org/z/EbPMK4jad

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From 59bd85681c590a5b3e259bfa93d87a80e5362878 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Tue, 26 Mar 2024 16:40:32 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp | 104 +-
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 306 ++
 7 files changed, 431 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 29066ea14280c2..4a5cfc988b8c18 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2577,6 +2577,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlaghttps://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType()) {
+// If gr is even set gr = gr + 1 for TypeSize=64.
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft;
+
+if (TypeSize <= RegLen * ArgGPRsLeft) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+}
+  }
+
+  // Records with non-trivial destructors/copy-constructors should not be
+  // passed by value.
+  if (isAggregateTypeForABI(Ty))
+--ArgGPRsLeft;
+  else if (!Ty->isFloatingType()) {
+// For other primitive types.
+if (TypeSize == 64) {
+  // If gr is even set gr = gr + 1 for 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-26 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From 618762c79f5ec1ea9a945b81e182e3d8e1046baf Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Tue, 26 Mar 2024 16:21:10 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp | 103 +-
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 306 ++
 7 files changed, 430 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 29066ea14280c2..4a5cfc988b8c18 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2577,6 +2577,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlaghttps://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  if (!(getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) 
||
+  !ArgGPRsLeft)
+return DefaultABIInfo::classifyArgumentType(Ty);
+
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  ASTContext  = getContext();
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType()) {
+if (TypeSize == 64 && ArgGPRsLeft % 2 == 1)
+  --ArgGPRsLeft;
+
+if (TypeSize <= RegLen * ArgGPRsLeft) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+}
+  }
+
+  // Records with non-trivial destructors/copy-constructors should not be
+  // passed by value.
+  if (isAggregateTypeForABI(Ty))
+--ArgGPRsLeft;
+  else if (!Ty->isFloatingType()) {
+// For other primitive types.
+if (TypeSize == 64) {
+  if (ArgGPRsLeft % 2 == 1)
+--ArgGPRsLeft;
+  if (TypeSize <= ArgGPRsLeft * 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-22 Thread zhijian lin via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+ArgGPRsLeft -= TypeSize / RegLen;
+return handleComplex(TypeSize);
+  }
+
+  if (ArgGPRsLeft) {
+// Records with non-trivial destructors/copy-constructors should not be
+// passed by value.
+if (isAggregateTypeForABI(Ty))
+  ArgGPRsLeft -= 1;
+else if (!Ty->isFloatingType()) {
+  // For other premitive types.
+  if (TypeSize > RegLen && TypeSize <= 2 * RegLen)
+ArgGPRsLeft -= TypeSize / RegLen;

diggerlin wrote:

for a test case `foo6(_Complex long double foo4(int x1, long  long y1, int x2, 
_Complex double z,)`
 
 `int x1` will have r3, 
`long long y1` will have r5,r6 (skip r4 since it is even, for 64bit integer 
need to start start odd register.)
`int x2` will have r7, 
` _Complex double z`  need to occupy 4 registers, there is no enough register , 
it can not pass `_Complex double z` in r8,r9,r10 , you have to pass ` _Complex 
double z` in by pointer (you can not call `handleComplex()`). 

but in your code, 
ArgGPRsLeft is 7 after int x1,
ArgGPRsLeft is 5 after long long y1
ArgGPRsLeft is 4 after int x2

there is still have 4 registers left for ` _Complex double z`, you can call 
`handleComplex()`,  you will pass ` _Complex double z` by value 

can you check how gcc deal with this case   `foo6(_Complex long double foo4(int 
x1, long  long y1, int x2, _Complex double z,)`  ?

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-22 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-22 Thread zhijian lin via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+ArgGPRsLeft -= TypeSize / RegLen;
+return handleComplex(TypeSize);
+  }
+
+  if (ArgGPRsLeft) {
+// Records with non-trivial destructors/copy-constructors should not be
+// passed by value.
+if (isAggregateTypeForABI(Ty))
+  ArgGPRsLeft -= 1;
+else if (!Ty->isFloatingType()) {
+  // For other premitive types.
+  if (TypeSize > RegLen && TypeSize <= 2 * RegLen)
+ArgGPRsLeft -= TypeSize / RegLen;

diggerlin wrote:

for a test case `foo6(_Complex long double foo4(int x1, long  long y1, int x2, 
_Complex double z,)`
 
 `int x1` will have r3, 
`long long y1` will have r5,r6 (skip r4 since it is even, for 64bit integer 
need to start start odd register.)
`int x2` will have r7, 
` _Complex double z`  need to occupy 4 registers, there is no enough register , 
it can not pass `_Complex double z` in r8,r9,r10 , you have to pass ` _Complex 
double z` in by pointer (you can not call `handleComplex()`). 

but in your code, 
ArgGPRsLeft is 7 after int x1,
ArgGPRsLeft is 5 after long long y1
ArgGPRsLeft is 4 after int x2

there is still have 4 registers left for ` _Complex double z`, you can call 
`handleComplex()`,  you will pass ` _Complex double z` by value 

can you check how gcc deal with this case   `foo6(_Complex long double foo4(int 
x1, long  long y1, int x2, _Complex double z,)`  ?

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-22 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-22 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-21 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-21 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits


@@ -396,12 +407,77 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  // Choice of using llvm::Type::getInt64Ty(getVMContext()) for complex
+  // single-precision floats is based on the ABI ATR-PASS-COMPLEX-IN-GPRS
+  // specification. According to the specification:
+  // - For complex single-precision floats: If the register (gr) is even, it's
+  // incremented by one, and the lower-addressed word of the argument is loaded
+  // into gr, while the higher-addressed word is loaded into gr + 1. Then, gr 
is
+  // incremented by 2.
+  // - For complex double-precision floats: The words of the argument are 
loaded
+  // in memory-address order into gr, gr + 1, gr + 2, and gr + 3, with gr being
+  // incremented by 4. Thus, to maintain even alignment and adhere to the ABI
+  // specification, llvm::Type::getInt64Ty(getVMContext()) is used when 
TypeSize
+  // is 64. Powerpc backend handles this alignment requirement. Specifically,
+  // you can refer to the CC_PPC32_SVR4_Custom_AlignArgRegs method from
+  // PPCCallingconvention.cpp. For more context, refer to the previous
+  // discussion: https://reviews.llvm.org/D146942 and the related LLVM pull
+  // request: #77732
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = TypeSize >> 5;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (Ty->isAnyComplexType() && TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+if (IsComplexInRegABI) {
+  ArgGPRsLeft -= TypeSize / RegLen;
+  return handleComplex(TypeSize);
+} else
+  ArgGPRsLeft--;

diggerlin wrote:

I do not think  you care about the value of ArgGPRsLeft when IsComplexInRegABI 
is false. is it correct ?

we can add following code in front of the function.

```
if (!IsComplexInRegABI )
return DefaultABIInfo::classifyArgumentType(Ty);
```

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");

diggerlin wrote:

do we need the assert here since there is `if (Ty->isAnyComplexType() && 
TypeSize <= RegLen * ArgGPRsLeft)`

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits


@@ -330,22 +330,33 @@ namespace {
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
   bool IsRetSmallStructInRegABI;
+  bool IsComplexInRegABI;

diggerlin wrote:

do we need a new data member `IsComplexInRegABI` here ? (there are several 
place code be modified because we add the new data member `IsComplexInRegABI` )

we can add 

```
bool IsComplexInRegABI = getCodeGenOpts().getComplexInRegABI() ==
CodeGenOptions::CMPLX_InGPR ;
```

in the function  `classifyArgumentType` and `classifyReturnType()`

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits


@@ -420,6 +496,10 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType 
RetTy) const {
   return ABIArgInfo::getDirect(CoerceTy);
 }
   }
+  if (IsComplexInRegABI && RetTy->isAnyComplexType()) {
+assert(RetTy->isAnyComplexType() && "RetTy must be Complex type.");

diggerlin wrote:

you already has `if (IsComplexInRegABI && RetTy->isAnyComplexType())` as 
condition, is there any reason to keep the `assert(RetTy->isAnyComplexType() && 
"RetTy must be Complex type.");`

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-20 Thread zhijian lin via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+ArgGPRsLeft -= TypeSize / RegLen;
+return handleComplex(TypeSize);
+  }
+
+  if (ArgGPRsLeft) {
+// Records with non-trivial destructors/copy-constructors should not be
+// passed by value.
+if (isAggregateTypeForABI(Ty))
+  ArgGPRsLeft -= 1;
+else if (!Ty->isFloatingType()) {
+  // For other premitive types.
+  if (TypeSize > RegLen && TypeSize <= 2 * RegLen)
+ArgGPRsLeft -= TypeSize / RegLen;

diggerlin wrote:

for a test case `foo(_Complex long double foo4(int x1, long  long y1, int x2, 
_Complex double z,)`
 
 `int x1` will have r3, 
`long long y1` will have r5,r6 (skip r4 since re is even.)
`int x2` will have r7, 
` _Complex double z`  need to occupy 4 registers, there is no enough register , 
it can not pass `_Complex double z` in r8,r9,r10 , you have to pass ` _Complex 
double z` in by pointer (you can not call `handleComplex()`). 

but in your code, 
ArgGPRsLeft is 7 after int x1,
ArgGPRsLeft is 5 after int y1
ArgGPRsLeft is 4 after int x2

there is still have 4 registers left for ` _Complex double z`, you can call 
`handleComplex()`,  you can pass ` _Complex double z by value 


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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-15 Thread Kishan Parmar via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-15 Thread Kishan Parmar via cfe-commits


@@ -0,0 +1,177 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-DEF
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU
+
+// CHECK-DEF-LABEL: define dso_local void @foo1
+// CHECK-DEF-SAME: (ptr dead_on_unwind noalias writable sret({ float, float }) 
align 4 [[AGG_RESULT:%.*]], ptr noundef byval({ float, float }) align 4 
[[X:%.*]]) #[[ATTR0:[0-9]+]] {

Long5hot wrote:

I couldn't remove #[[ATTR0:[0-9]+]]1. Because testcase fails saying no missing 
attributes.
llvm-lit(clang) generates IR with # attributes, so looks like Filecheck expects 
#attribute fields to be present.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-15 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From ac3e5526189f5d9e2abe739a21394a63f75567b5 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Fri, 15 Mar 2024 15:29:41 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.

Following up with this patch : https://reviews.llvm.org/D146942
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp | 107 +++-
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 255 ++
 7 files changed, 379 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..f4845e9e424c67 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -225,6 +225,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 9469a424045bb0..1c9424f65623dd 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index a7e43b4d179a4d..2128b87abe8ea6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2578,6 +2578,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlag(
-CGT, SoftFloatABI, RetSmallStructInRegABI)) {}
+CGT, SoftFloatABI, RetSmallStructInRegABI, ComplexInRegABI)) {}
 
   static bool isStructReturnInRegABI(const llvm::Triple ,
  const CodeGenOptions );
@@ -396,12 +407,77 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  // Choice of using llvm::Type::getInt64Ty(getVMContext()) for complex
+  // single-precision floats is based on the ABI ATR-PASS-COMPLEX-IN-GPRS
+  // specification. According to the specification:
+  // - For complex single-precision floats: If the register (gr) is even, it's
+  // incremented by one, and the lower-addressed word of the argument is loaded
+  // into gr, while the higher-addressed word is loaded into gr + 1. Then, gr 
is
+  // incremented by 2.
+  // - For complex double-precision floats: The words of the argument are 
loaded
+  // in memory-address order into gr, gr + 1, gr + 2, and gr + 3, with gr being
+  // incremented by 4. Thus, to maintain even alignment and adhere to the ABI
+  // specification, llvm::Type::getInt64Ty(getVMContext()) is used when 
TypeSize
+  // is 64. Powerpc backend handles this 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-14 Thread Kishan Parmar via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-14 Thread Kishan Parmar via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");

Long5hot wrote:

I apologize because, There's a bug here. for if not IsComplexInRegABI we need 
to --ArgGPRsLeft;
Will test and update the review accordingly.
Thank you.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-14 Thread Kishan Parmar via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-14 Thread Kishan Parmar via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+ArgGPRsLeft -= TypeSize / RegLen;
+return handleComplex(TypeSize);
+  }
+
+  if (ArgGPRsLeft) {
+// Records with non-trivial destructors/copy-constructors should not be
+// passed by value.
+if (isAggregateTypeForABI(Ty))
+  ArgGPRsLeft -= 1;
+else if (!Ty->isFloatingType()) {
+  // For other premitive types.
+  if (TypeSize > RegLen && TypeSize <= 2 * RegLen)
+ArgGPRsLeft -= TypeSize / RegLen;

Long5hot wrote:

llvm powerpc backend takes care of that. 
refer CC_PPC32_SVR4_Custom_AlignArgRegs method from PPCCallingconvention.cpp 
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/PowerPC/PPCCallingConv.cpp#L80

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-13 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-13 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-12 Thread zhijian lin via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+ArgGPRsLeft -= TypeSize / RegLen;
+return handleComplex(TypeSize);
+  }
+
+  if (ArgGPRsLeft) {
+// Records with non-trivial destructors/copy-constructors should not be
+// passed by value.
+if (isAggregateTypeForABI(Ty))
+  ArgGPRsLeft -= 1;
+else if (!Ty->isFloatingType()) {
+  // For other premitive types.
+  if (TypeSize > RegLen && TypeSize <= 2 * RegLen)
+ArgGPRsLeft -= TypeSize / RegLen;

diggerlin wrote:

and If I understand correct, the single precision floating point complex . and 
64 bit integer (long long unsigned)  also need a  even alignment .

`If gr > 9, go to OTHER. If gr is even, set gr = gr + 1. Load the 
lower-addressed word of the
argument into gr and the higher-addressed word into gr + 1, set gr = gr + 2,` 

it looks  the logic not express in your code when you calculate the 
`ArgGPRsLeft` ?


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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-12 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits


@@ -0,0 +1,177 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-DEF
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU
+
+// CHECK-DEF-LABEL: define dso_local void @foo1
+// CHECK-DEF-SAME: (ptr dead_on_unwind noalias writable sret({ float, float }) 
align 4 [[AGG_RESULT:%.*]], ptr noundef byval({ float, float }) align 4 
[[X:%.*]]) #[[ATTR0:[0-9]+]] {

diggerlin wrote:

nit, we can delete  `#[[ATTR0:[0-9]+]]1` , and please delete other place as 
well.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");

diggerlin wrote:

and add assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero"); 
?

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;

diggerlin wrote:

do we need to add `+31` here , can we change to 
`RegsNeeded = TypeSize >> 5;  ` ? and 

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits


@@ -271,22 +271,32 @@ namespace {
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
   bool IsRetSmallStructInRegABI;
+  bool IsComplexInRegABI;
+  // Size of GPR in bits.
+  static const unsigned RegLen = 32;
+  static const int NumArgGPRs = 8;

diggerlin wrote:

change to `ArgGPRsNum` ?

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits


@@ -337,12 +350,77 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(QualType Ty,
+ uint64_t ) const {
+
+  assert(Ty->isAnyComplexType());
+  llvm::Type *ElemTy;
+  unsigned SizeRegs;
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+SizeRegs = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());

diggerlin wrote:

got it, thanks for explain. can you add your explain as comment ? 

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-11 Thread zhijian lin via cfe-commits


@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+ArgGPRsLeft -= TypeSize / RegLen;
+return handleComplex(TypeSize);
+  }
+
+  if (ArgGPRsLeft) {
+// Records with non-trivial destructors/copy-constructors should not be
+// passed by value.
+if (isAggregateTypeForABI(Ty))
+  ArgGPRsLeft -= 1;
+else if (!Ty->isFloatingType()) {
+  // For other premitive types.
+  if (TypeSize > RegLen && TypeSize <= 2 * RegLen)
+ArgGPRsLeft -= TypeSize / RegLen;

diggerlin wrote:

can we change 
```
if (TypeSize > RegLen && TypeSize <= 2 * RegLen)
ArgGPRsLeft -= TypeSize / RegLen;
```

and what if ArgGPRsLeft =1 and  TypeSize == 2 * RegLen. after above code , the 
ArgGPRsLeft  will be -1. is it correct ? it hit assert `assert(ArgGPRsLeft <= 
NumArgGPRs && "Arg GPR tracking underflow");` when the `classifyArgumentType` 
is called next time.

suggest change to 
 ```
 if (TypeSize > RegLen &&  && TypeSize <= RLen * ArgGPRsLeft)
ArgGPRsLeft -= TypeSize / RegLen;
```

and add a test case which can make ArgGPRsLeft  to zero; 


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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-07 Thread zhijian lin via cfe-commits


@@ -271,22 +271,33 @@ namespace {
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
   bool IsRetSmallStructInRegABI;
+  bool isComplexInRegABI;
+  // Size of GPR in bits
+  unsigned RLen;
+  static const int NumArgGPRs = 8;
 
   CharUnits getParamTypeAlignment(QualType Ty) const;
+  ABIArgInfo handleComplex(QualType Ty, uint64_t ) const;
 
 public:
   PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes , bool SoftFloatABI,
- bool RetSmallStructInRegABI)
+ bool RetSmallStructInRegABI, unsigned RLen,
+ bool ComplexInRegABI)
   : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
-IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
+IsRetSmallStructInRegABI(RetSmallStructInRegABI),
+isComplexInRegABI(ComplexInRegABI), RLen(RLen) {}
 
   ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType Ty, int ) const;
 
   void computeInfo(CGFunctionInfo ) const override {
+
+int ArgGPRsLeft = NumArgGPRs;

diggerlin wrote:

put `int ArgGPRsLeft = NumArgGPRs;` in front of 

 `   for (auto  : FI.arguments())
  I.info = classifyArgumentType(I.type, ArgGPRsLeft);`

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-04 Thread Kishan Parmar via cfe-commits


@@ -271,22 +271,32 @@ namespace {
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
   bool IsRetSmallStructInRegABI;
+  bool IsComplexInRegABI;
+  // Size of GPR in bits.
+  static const unsigned RegLen = 32;
+  static const int NumArgGPRs = 8;

Long5hot wrote:

The purpose of NumArgGPRs or ArgGPRsLeft is limited to complex types.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-04 Thread Kishan Parmar via cfe-commits


@@ -78,6 +78,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_Default,
+CMPLX_OnStack,

Long5hot wrote:

This was for future reference, if any arch wants to use this.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-04 Thread Kishan Parmar via cfe-commits


@@ -337,12 +350,77 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(QualType Ty,
+ uint64_t ) const {
+
+  assert(Ty->isAnyComplexType());
+  llvm::Type *ElemTy;
+  unsigned SizeRegs;
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+SizeRegs = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());

Long5hot wrote:

> llvm::Type *ElemTy = llvm::Type::getInt64Ty(getVMContext());
> unsigned SizeRegs = TypeSize/64;


Since Typesize will be 64, in if is it necessary to replace 1 to TypeSize/64?

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-04 Thread Kishan Parmar via cfe-commits


@@ -337,12 +350,77 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(QualType Ty,
+ uint64_t ) const {
+
+  assert(Ty->isAnyComplexType());
+  llvm::Type *ElemTy;
+  unsigned SizeRegs;
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+SizeRegs = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());

Long5hot wrote:

Reason for using llvm::Type::getInt64Ty(getVMContext()) for floats here was to 
follow ABI ATR-PASS-COMPLEX-IN-GPRS

> complex single-precision float : If gr is even, set gr = gr + 1. Load the 
> lower-addressed word of the
> argument into gr and the higher-addressed word into gr + 1, set gr = gr + 2.
> 
> complex double-precision float: Load the words of the argument, in 
> memory-address order, into gr, gr + 1,
> gr + 2 and gr + 3, set gr = gr + 4.

You can check the previous discussion here. : https://reviews.llvm.org/D146942

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-04 Thread Kishan Parmar via cfe-commits


@@ -0,0 +1,177 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-DEF
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU
+
+// CHECK-DEF-LABEL: define dso_local void @foo1
+// CHECK-DEF-SAME: (ptr dead_on_unwind noalias writable sret({ float, float }) 
align 4 [[AGG_RESULT:%.*]], ptr noundef byval({ float, float }) align 4 
[[X:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-DEF-NEXT:  entry:
+// CHECK-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { float, float 
}, ptr [[X]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4
+// CHECK-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { float, float 
}, ptr [[X]], i32 0, i32 1
+// CHECK-DEF-NEXT:[[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4
+// CHECK-DEF-NEXT:[[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// CHECK-DEF-NEXT:store float [[X_REAL]], ptr [[AGG_RESULT_REALP]], align 4
+// CHECK-DEF-NEXT:store float [[X_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 4
+// CHECK-DEF-NEXT:[[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[AGG_RESULT_REAL:%.*]] = load float, ptr 
[[AGG_RESULT_REALP1]], align 4
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAG:%.*]] = load float, ptr 
[[AGG_RESULT_IMAGP2]], align 4
+// CHECK-DEF-NEXT:[[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { 
float, float }, ptr [[AGG_RESULT]], i32 0, i32 1
+// CHECK-DEF-NEXT:store float [[AGG_RESULT_REAL]], ptr 
[[AGG_RESULT_REALP3]], align 4
+// CHECK-DEF-NEXT:store float [[AGG_RESULT_IMAG]], ptr 
[[AGG_RESULT_IMAGP4]], align 4
+// CHECK-DEF-NEXT:ret void
+//
+// CHECK-GNU-LABEL: define dso_local [1 x i64] @foo1
+// CHECK-GNU-SAME: ([1 x i64] noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-GNU-NEXT:  entry:
+// CHECK-GNU-NEXT:[[RETVAL:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-NEXT:[[X:%.*]] = alloca { float, float }, align 4
+// CHECK-GNU-NEXT:store [1 x i64] [[X_COERCE]], ptr [[X]], align 4
+// CHECK-GNU-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { float, float 
}, ptr [[X]], i32 0, i32 0
+// CHECK-GNU-NEXT:[[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4
+// CHECK-GNU-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { float, float 
}, ptr [[X]], i32 0, i32 1
+// CHECK-GNU-NEXT:[[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4
+// CHECK-GNU-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { float, 
float }, ptr [[RETVAL]], i32 0, i32 0
+// CHECK-GNU-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, 
float }, ptr [[RETVAL]], i32 0, i32 1
+// CHECK-GNU-NEXT:store float [[X_REAL]], ptr [[RETVAL_REALP]], align 4
+// CHECK-GNU-NEXT:store float [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 4
+// CHECK-GNU-NEXT:[[TMP0:%.*]] = load [1 x i64], ptr [[RETVAL]], align 4
+// CHECK-GNU-NEXT:ret [1 x i64] [[TMP0]]
+//
+_Complex float foo1(_Complex float x) {
+  return x;
+}
+
+// CHECK-DEF-LABEL: define dso_local void @foo2
+// CHECK-DEF-SAME: (ptr dead_on_unwind noalias writable sret({ double, double 
}) align 8 [[AGG_RESULT:%.*]], ptr noundef byval({ double, double }) align 8 
[[X:%.*]]) #[[ATTR0]] {
+// CHECK-DEF-NEXT:  entry:
+// CHECK-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[X]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[X_REAL:%.*]] = load double, ptr [[X_REALP]], align 8
+// CHECK-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { double, 
double }, ptr [[X]], i32 0, i32 1
+// CHECK-DEF-NEXT:[[X_IMAG:%.*]] = load double, ptr [[X_IMAGP]], align 8
+// CHECK-DEF-NEXT:[[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { 
double, double }, ptr [[AGG_RESULT]], i32 0, i32 1
+// CHECK-DEF-NEXT:store double [[X_REAL]], ptr [[AGG_RESULT_REALP]], align 
8
+// CHECK-DEF-NEXT:store double [[X_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 
8
+// CHECK-DEF-NEXT:[[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { 
double, double }, ptr [[AGG_RESULT]], i32 0, i32 0
+// CHECK-DEF-NEXT:[[AGG_RESULT_REAL:%.*]] = load double, ptr 
[[AGG_RESULT_REALP1]], align 8
+// CHECK-DEF-NEXT:

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-04 Thread Kishan Parmar via cfe-commits


@@ -271,22 +271,33 @@ namespace {
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
   bool IsRetSmallStructInRegABI;
+  bool isComplexInRegABI;
+  // Size of GPR in bits
+  unsigned RLen;
+  static const int NumArgGPRs = 8;
 
   CharUnits getParamTypeAlignment(QualType Ty) const;
+  ABIArgInfo handleComplex(QualType Ty, uint64_t ) const;
 
 public:
   PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes , bool SoftFloatABI,
- bool RetSmallStructInRegABI)
+ bool RetSmallStructInRegABI, unsigned RLen,
+ bool ComplexInRegABI)
   : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
-IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
+IsRetSmallStructInRegABI(RetSmallStructInRegABI),
+isComplexInRegABI(ComplexInRegABI), RLen(RLen) {}
 
   ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType Ty, int ) const;
 
   void computeInfo(CGFunctionInfo ) const override {
+
+int ArgGPRsLeft = NumArgGPRs;

Long5hot wrote:

Couldn't understand what you mean here..

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-03-04 Thread Kishan Parmar via cfe-commits

https://github.com/Long5hot updated 
https://github.com/llvm/llvm-project/pull/77732

>From a89cd20615f3649e2a625eb8da851f9cbdd2d863 Mon Sep 17 00:00:00 2001
From: Kishan Parmar 
Date: Mon, 4 Mar 2024 18:04:20 +0530
Subject: [PATCH] [clang][PowerPC] Add flag to enable compatibility with GNU
 for complex arguments

Fixes : https://github.com/llvm/llvm-project/issues/56023

https://godbolt.org/z/1bsW1sKMs

newFlag : -fcomplex-ppc-gnu-abi

GNU uses GPRs for complex parameters and return values storing for 
PowerPC-32bit,
which can be enabled which above flag.
Intent of this patch is to make clang compatible with GNU libraries of complex.
---
 clang/include/clang/Basic/CodeGenOptions.def  |   2 +
 clang/include/clang/Basic/CodeGenOptions.h|   6 +
 clang/include/clang/Driver/Options.td |   4 +
 clang/lib/CodeGen/Targets/PPC.cpp |  87 +++--
 clang/lib/Driver/ToolChains/Clang.cpp |   9 +
 clang/lib/Frontend/CompilerInvocation.cpp |   8 +
 .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c   | 177 ++
 7 files changed, 281 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/CodeGen/PowerPC/ppc32-complex-gnu-abi.c

diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 6ad05031962562..64f938dd01 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -224,6 +224,8 @@ CODEGENOPT(MCDCCoverage , 1, 0) ///< Enable MC/DC code 
coverage criteria.
 
   /// If -fpcc-struct-return or -freg-struct-return is specified.
 ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, 
SRCK_Default)
+  /// If -fcomplex-ppc-gnu-abi is specified on ppc32.
+ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, 
CMPLX_OnStack)
 
 CODEGENOPT(RelaxAll  , 1, 0) ///< Relax all machine code instructions.
 CODEGENOPT(RelaxedAliasing   , 1, 0) ///< Set when -fno-strict-aliasing is 
enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index 3f8fe385fef3df..af22bc00797655 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -78,6 +78,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_OnStack,
+CMPLX_InGPR, // If -fcomplex-ppc-gnu-abi is specified on ppc32
+CMPLX_InFPR
+  };
+
   enum ProfileInstrKind {
 ProfileNone,   // Profile instrumentation is turned off.
 ProfileClangInstr, // Clang instrumentation to generate execution counts
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 3e857f4e6faf87..82d8ab087fe6a5 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2574,6 +2574,10 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, 
Group,
   HelpText<"Form fused FP ops (e.g. FMAs)">,
   Values<"fast,on,off,fast-honor-pragmas">;
 
+def fcomplex_ppc_gnu_abi : Flag<["-"], "fcomplex-ppc-gnu-abi">, 
Group, Visibility<[ClangOption, CC1Option]>,
+  DocBrief<"Follow the GNU ABI, pass Complex values in GPRs instead of the 
stack for PowerPC-32">,
+  HelpText<"Pass Complex values in GPR instead of stack for PowerPC-32">;
+
 defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow",
   CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue,
   NegFlag(
-CGT, SoftFloatABI, RetSmallStructInRegABI)) {}
+CGT, SoftFloatABI, RetSmallStructInRegABI, ComplexInRegABI)) {}
 
   static bool isStructReturnInRegABI(const llvm::Triple ,
  const CodeGenOptions );
@@ -337,12 +347,58 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t ) const {
+  llvm::Type *ElemTy;
+  unsigned RegsNeeded; // Registers Needed for Complex.
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+RegsNeeded = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+RegsNeeded = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, RegsNeeded));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (IsComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RegLen * ArgGPRsLeft) {
+assert(Ty->isAnyComplexType() && "Ty must be Complex type.");
+ArgGPRsLeft -= TypeSize / RegLen;
+return handleComplex(TypeSize);
+  }
+
+  if (ArgGPRsLeft) {
+// 

[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-27 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-27 Thread zhijian lin via cfe-commits


@@ -337,12 +350,77 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(QualType Ty,
+ uint64_t ) const {
+
+  assert(Ty->isAnyComplexType());
+  llvm::Type *ElemTy;
+  unsigned SizeRegs;
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+SizeRegs = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+SizeRegs = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, SizeRegs));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (isComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RLen * ArgGPRsLeft) {
+ArgGPRsLeft -= TypeSize / RLen;
+return handleComplex(Ty, TypeSize);
+  }
+
+  if (isAggregateTypeForABI(Ty)) {

diggerlin wrote:

it look, you only has Complex as parameter in your test case .for example 
`_Complex float foo1(_Complex float x)`

I think you need more test case with other parameters to test the functionality 
of function `classifyArgumentType()`

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits


@@ -0,0 +1,132 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -target-cpu pwr8 \

diggerlin wrote:

do you really need `-target-cpu pwr8` since the test case only check generated 
IR?

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits


@@ -0,0 +1,132 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 2
+
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -target-cpu pwr8 \
+// RUN:   -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-DEF
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -target-cpu pwr8 
-fcomplex-ppc-gnu-abi \

diggerlin wrote:

ditto

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits


@@ -271,22 +271,33 @@ namespace {
 class PPC32_SVR4_ABIInfo : public DefaultABIInfo {
   bool IsSoftFloatABI;
   bool IsRetSmallStructInRegABI;
+  bool isComplexInRegABI;
+  // Size of GPR in bits
+  unsigned RLen;
+  static const int NumArgGPRs = 8;
 
   CharUnits getParamTypeAlignment(QualType Ty) const;
+  ABIArgInfo handleComplex(QualType Ty, uint64_t ) const;
 
 public:
   PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes , bool SoftFloatABI,
- bool RetSmallStructInRegABI)
+ bool RetSmallStructInRegABI, unsigned RLen,
+ bool ComplexInRegABI)
   : DefaultABIInfo(CGT), IsSoftFloatABI(SoftFloatABI),
-IsRetSmallStructInRegABI(RetSmallStructInRegABI) {}
+IsRetSmallStructInRegABI(RetSmallStructInRegABI),
+isComplexInRegABI(ComplexInRegABI), RLen(RLen) {}
 
   ABIArgInfo classifyReturnType(QualType RetTy) const;
+  ABIArgInfo classifyArgumentType(QualType Ty, int ) const;
 
   void computeInfo(CGFunctionInfo ) const override {
+
+int ArgGPRsLeft = NumArgGPRs;

diggerlin wrote:

nit: move the definition to the closest first be used.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits


@@ -78,6 +78,13 @@ class CodeGenOptions : public CodeGenOptionsBase {
 SRCK_InRegs// Small structs in registers (-freg-struct-return).
   };
 
+  enum ComplexArgumentConventionKind {
+CMPLX_Default,
+CMPLX_OnStack,

diggerlin wrote:

it looks you define the `CMPLX_Default` and   ` CMPLX_OnStack` , but never use 
them.

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits

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


[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)

2024-02-26 Thread zhijian lin via cfe-commits


@@ -337,12 +350,77 @@ CharUnits 
PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const {
   return CharUnits::fromQuantity(4);
 }
 
+ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(QualType Ty,
+ uint64_t ) const {
+
+  assert(Ty->isAnyComplexType());
+  llvm::Type *ElemTy;
+  unsigned SizeRegs;
+
+  if (TypeSize == 64) {
+ElemTy = llvm::Type::getInt64Ty(getVMContext());
+SizeRegs = 1;
+  } else {
+ElemTy = llvm::Type::getInt32Ty(getVMContext());
+SizeRegs = (TypeSize + 31) / 32;
+  }
+  return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, SizeRegs));
+}
+
+ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
+int ) const {
+
+  assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow");
+  Ty = useFirstFieldIfTransparentUnion(Ty);
+
+  ASTContext  = getContext();
+
+  uint64_t TypeSize = Context.getTypeSize(Ty);
+
+  if (isComplexInRegABI && Ty->isAnyComplexType() &&
+  TypeSize <= RLen * ArgGPRsLeft) {
+ArgGPRsLeft -= TypeSize / RLen;
+return handleComplex(Ty, TypeSize);
+  }
+
+  if (isAggregateTypeForABI(Ty)) {
+if (ArgGPRsLeft)
+  ArgGPRsLeft -= 1;
+// Records with non-trivial destructors/copy-constructors should not be
+// passed by value.
+if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
+  return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
+}
+return getNaturalAlignIndirect(Ty);
+  }
+
+  if (!Ty->isFloatingType()) {
+if (TypeSize > RLen && TypeSize <= 2 * RLen)
+  ArgGPRsLeft -= 2;
+else
+  ArgGPRsLeft--;
+  }
+
+  // Treat an enum type as its underlying type.
+  if (const EnumType *EnumTy = Ty->getAs())
+Ty = EnumTy->getDecl()->getIntegerType();
+
+  if (const auto *EIT = Ty->getAs())
+if (EIT->getNumBits() >
+Context.getTypeSize(Context.getTargetInfo().hasInt128Type()
+? Context.Int128Ty
+: Context.LongLongTy))
+  return getNaturalAlignIndirect(Ty);
+
+  return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)

diggerlin wrote:

since most of the code is same as 
`DefaultABIInfo::classifyArgumentType(QualType Ty)` , I suggest rewrite the 
function `PPC32_SVR4_ABIInfo::classifyArgumentType` as 

```
ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty,
int ) const { 
   
   special functionality code of the function here
   .
   
DefaultABIInfo::classifyArgumentType(Ty)   
   }
```
duplication code is not a good idea.

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


  1   2   >