[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
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)
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)
@@ -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)
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)
@@ -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)
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)
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)
@@ -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)
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)
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)
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)
@@ -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)
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)
@@ -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)
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)
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)
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)
@@ -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)
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)
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)
@@ -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)
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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
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)
@@ -486,7 +486,8 @@ std::unique_ptr createAIXTargetCodeGenInfo(CodeGenModule , bool Is64Bit); std::unique_ptr -createPPC32TargetCodeGenInfo(CodeGenModule , bool SoftFloatABI); +createPPC32TargetCodeGenInfo(CodeGenModule , bool SoftFloatABI, + unsigned RLen); Long5hot wrote: I was not sure about hardcoding Register Width(RLen) **"32"** for RLen here.. https://github.com/llvm/llvm-project/pull/77732/files#diff-05339beb4a6cf7efdfc537984255dd372dcf1edd2d00eabed25831da4d1d0a9fR276 So i used similiar approach like, how RISC-V does to calculate Register Width here. PPC : https://github.com/llvm/llvm-project/pull/77732/files#diff-e724febedab9c1a2832bf2056d208ff02ddcb2e6f90b5a653afc9b19ac78a5d7R187 RISCV : https://github.com/llvm/llvm-project/pull/77732/files#diff-e724febedab9c1a2832bf2056d208ff02ddcb2e6f90b5a653afc9b19ac78a5d7L226 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)
Long5hot wrote: ping! @chmeeedalf @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)
https://github.com/Long5hot updated https://github.com/llvm/llvm-project/pull/77732 >From 6a209fb25b7923228a7f4e2a8e2accbc31988622 Mon Sep 17 00:00:00 2001 From: Kishan Parmar Date: Wed, 24 Jan 2024 13:14:03 +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| 7 + clang/include/clang/Driver/Options.td | 4 + clang/lib/CodeGen/CodeGenModule.cpp | 6 +- clang/lib/CodeGen/TargetInfo.h| 3 +- clang/lib/CodeGen/Targets/PPC.cpp | 110 +-- clang/lib/Driver/ToolChains/Clang.cpp | 9 ++ clang/lib/Frontend/CompilerInvocation.cpp | 8 ++ .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c | 132 ++ 9 files changed, 266 insertions(+), 15 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 2f2e45d5cf63dfa..5bafcab086bb409 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -223,6 +223,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 for ppc32 +ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, CMPLX_Default) 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 3f8fe385fef3dff..670b009e4138c1d 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -78,6 +78,13 @@ class CodeGenOptions : public CodeGenOptionsBase { SRCK_InRegs// Small structs in registers (-freg-struct-return). }; + enum ComplexArgumentConventionKind { +CMPLX_Default, +CMPLX_OnStack, +CMPLX_OnGPR, // if ppc32 -fcomplex-ppc-gnu-abi +CMPLX_OnFPR + }; + 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 7f4fa33748facaf..38e351e38037249 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2540,6 +2540,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, store Complex values in GPR instead of stack for PowerPC-32">, + HelpText<"Store Complex values in GPR instead of stack for PowerPC-32">; + defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow", CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue, NegFlag createAIXTargetCodeGenInfo(CodeGenModule , bool Is64Bit); std::unique_ptr -createPPC32TargetCodeGenInfo(CodeGenModule , bool SoftFloatABI); +createPPC32TargetCodeGenInfo(CodeGenModule , bool SoftFloatABI, + unsigned RLen); std::unique_ptr createPPC64TargetCodeGenInfo(CodeGenModule ); diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 40e508c1772..f514f2e25a48f92 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -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), +
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/Long5hot updated https://github.com/llvm/llvm-project/pull/77732 >From ec05087b89af829247879c2e860f9d93f548c7a1 Mon Sep 17 00:00:00 2001 From: Kishan Parmar Date: Wed, 17 Jan 2024 10:29:34 +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| 7 + clang/include/clang/Driver/Options.td | 4 + clang/lib/CodeGen/CodeGenModule.cpp | 6 +- clang/lib/CodeGen/TargetInfo.h| 3 +- clang/lib/CodeGen/Targets/PPC.cpp | 110 +-- clang/lib/Driver/ToolChains/Clang.cpp | 9 ++ clang/lib/Frontend/CompilerInvocation.cpp | 8 ++ .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c | 132 ++ 9 files changed, 266 insertions(+), 15 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 2c4fb6745bc172f..beeefae15c63f82 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -213,6 +213,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 for ppc32 +ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, CMPLX_Default) 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 6952b48e898a819..8abca0e3dda3343 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -78,6 +78,13 @@ class CodeGenOptions : public CodeGenOptionsBase { SRCK_InRegs// Small structs in registers (-freg-struct-return). }; + enum ComplexArgumentConventionKind { +CMPLX_Default, +CMPLX_OnStack, +CMPLX_OnGPR, // if ppc32 -fcomplex-ppc-gnu-abi +CMPLX_OnFPR + }; + 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 a4a988c71ec412c..10166757b1352ed 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2540,6 +2540,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, store Complex values in GPR instead of stack for PowerPC-32">, + HelpText<"Store Complex values in GPR instead of stack for PowerPC-32">; + defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow", CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue, NegFlag createAIXTargetCodeGenInfo(CodeGenModule , bool Is64Bit); std::unique_ptr -createPPC32TargetCodeGenInfo(CodeGenModule , bool SoftFloatABI); +createPPC32TargetCodeGenInfo(CodeGenModule , bool SoftFloatABI, + unsigned RLen); std::unique_ptr createPPC64TargetCodeGenInfo(CodeGenModule ); diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 40e508c1772..f514f2e25a48f92 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -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), +
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
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)
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)
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)
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)
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)
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)
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)
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)
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)
Long5hot wrote: Following up with this patch : 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)
https://github.com/Long5hot created https://github.com/llvm/llvm-project/pull/77732 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. >From e636286c6c817299ed7348fa8c40cc0fbc2e Mon Sep 17 00:00:00 2001 From: Kishan Parmar Date: Thu, 11 Jan 2024 11:54:50 +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| 7 + clang/include/clang/Driver/Options.td | 4 + clang/lib/CodeGen/CodeGenModule.cpp | 6 +- clang/lib/CodeGen/TargetInfo.h| 3 +- clang/lib/CodeGen/Targets/PPC.cpp | 110 +-- clang/lib/Driver/ToolChains/Clang.cpp | 9 ++ clang/lib/Frontend/CompilerInvocation.cpp | 8 ++ .../CodeGen/PowerPC/ppc32-complex-gnu-abi.c | 132 ++ 9 files changed, 266 insertions(+), 15 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 2c4fb6745bc172..beeefae15c63f8 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -213,6 +213,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 for ppc32 +ENUM_CODEGENOPT(ComplexInRegABI, ComplexArgumentConventionKind, 2, CMPLX_Default) 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 6952b48e898a81..8abca0e3dda334 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -78,6 +78,13 @@ class CodeGenOptions : public CodeGenOptionsBase { SRCK_InRegs// Small structs in registers (-freg-struct-return). }; + enum ComplexArgumentConventionKind { +CMPLX_Default, +CMPLX_OnStack, +CMPLX_OnGPR, // if ppc32 -fcomplex-ppc-gnu-abi +CMPLX_OnFPR + }; + 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 19becba4a5ad83..251bcb8c49782f 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2540,6 +2540,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, store Complex values in GPR instead of stack for PowerPC-32">, + HelpText<"Store Complex values in GPR instead of stack for PowerPC-32">; + defm strict_float_cast_overflow : BoolFOption<"strict-float-cast-overflow", CodeGenOpts<"StrictFloatCastOverflow">, DefaultTrue, NegFlag createAIXTargetCodeGenInfo(CodeGenModule , bool Is64Bit); std::unique_ptr -createPPC32TargetCodeGenInfo(CodeGenModule , bool SoftFloatABI); +createPPC32TargetCodeGenInfo(CodeGenModule , bool SoftFloatABI, + unsigned RLen); std::unique_ptr createPPC64TargetCodeGenInfo(CodeGenModule ); diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp index 40e508c177..f4885a927ab0ba 100644 --- a/clang/lib/CodeGen/Targets/PPC.cpp +++ b/clang/lib/CodeGen/Targets/PPC.cpp @@ -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, -
[clang] 2641d9b - Propagate the volatile qualifier of exp to store /load operations .
Author: Umesh Kalappa Date: 2023-09-23T19:40:24+05:30 New Revision: 2641d9b2807ded4b712f4dca809d63c138c91361 URL: https://github.com/llvm/llvm-project/commit/2641d9b2807ded4b712f4dca809d63c138c91361 DIFF: https://github.com/llvm/llvm-project/commit/2641d9b2807ded4b712f4dca809d63c138c91361.diff LOG: Propagate the volatile qualifier of exp to store /load operations . This changes to address the PR : 55207 We update the volatility on the LValue by looking at the LHS cast operation qualifier and propagate the RValue volatile-ness from the CGF data structure . Reviewed By: rjmccall Differential Revision: https://reviews.llvm.org/D157890 Added: clang/test/CodeGen/volatile.cpp Modified: clang/include/clang/AST/Expr.h clang/lib/CodeGen/CGExpr.cpp clang/lib/CodeGen/CGExprComplex.cpp clang/lib/CodeGen/CGExprScalar.cpp Removed: diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index fe20a84216d1f11..1c717b520dd87c6 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3608,6 +3608,19 @@ class CastExpr : public Expr { return FPOptionsOverride(); } + /// Return + // True : if this conversion changes the volatile-ness of a gl-value. + // Qualification conversions on gl-values currently use CK_NoOp, but + // it's important to recognize volatile-changing conversions in + // clients code generation that normally eagerly peephole loads. Note + // that the query is answering for this specific node; Sema may + // produce multiple cast nodes for any particular conversion sequence. + // False : Otherwise. + bool changesVolatileQualification() const { +return (isGLValue() && (getType().isVolatileQualified() != +getSubExpr()->getType().isVolatileQualified())); + } + static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType, QualType opType); static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD, diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 76bbeba468db643..86239d5e89fcc4d 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4802,6 +4802,9 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { // bound and change the IR type. // FIXME: Once pointee types are removed from IR, remove this. LValue LV = EmitLValue(E->getSubExpr()); +// Propagate the volatile qualifer to LValue, if exist in E. +if (E->changesVolatileQualification()) + LV.getQuals() = E->getType().getQualifiers(); if (LV.isSimple()) { Address V = LV.getAddress(*this); if (V.isValid()) { diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 2dd1a991ec97199..f3cbd1d0451ebe4 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -177,11 +177,15 @@ class ComplexExprEmitter ComplexPairTy VisitImplicitCastExpr(ImplicitCastExpr *E) { // Unlike for scalars, we don't have to worry about function->ptr demotion // here. +if (E->changesVolatileQualification()) + return EmitLoadOfLValue(E); return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); } ComplexPairTy VisitCastExpr(CastExpr *E) { if (const auto *ECE = dyn_cast(E)) CGF.CGM.EmitExplicitCastExprType(ECE, ); +if (E->changesVolatileQualification()) + return EmitLoadOfLValue(E); return EmitCast(E->getCastKind(), E->getSubExpr(), E->getType()); } ComplexPairTy VisitCallExpr(const CallExpr *E); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index a71b7057bb523a9..d76ce15b41ac570 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2225,7 +2225,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { return Visit(const_cast(E)); case CK_NoOp: { -llvm::Value *V = Visit(const_cast(E)); +llvm::Value *V = CE->changesVolatileQualification() + ? EmitLoadOfLValue(CE) + : Visit(const_cast(E)); if (V) { // CK_NoOp can model a pointer qualification conversion, which can remove // an array bound and change the IR type. diff --git a/clang/test/CodeGen/volatile.cpp b/clang/test/CodeGen/volatile.cpp new file mode 100644 index 000..38724659ad8a355 --- /dev/null +++ b/clang/test/CodeGen/volatile.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -O2 -triple=x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix CHECK +struct agg +{ +int a ; +int b ; +} t; +struct agg a; +int vt=10; +_Complex float cf; +int volatile vol =10; +void f0() { +const_cast(cf) = const_cast(cf) + 1; +// CHECK: %cf.real = load
[clang] 065da35 - clang driver throws error for -mabi=elfv2 or elfv2
Author: Kishan Parmar Date: 2023-07-29T16:10:51+05:30 New Revision: 065da3574b4fe9d4ee6283de2c82b8ce1c08af08 URL: https://github.com/llvm/llvm-project/commit/065da3574b4fe9d4ee6283de2c82b8ce1c08af08 DIFF: https://github.com/llvm/llvm-project/commit/065da3574b4fe9d4ee6283de2c82b8ce1c08af08.diff LOG: clang driver throws error for -mabi=elfv2 or elfv2 After clang release/16.x there is a regression that -mabi=elfv1 or -mabi=elfv2 are being unused and throws warning. But clang-trunk throws error for -mabi=elfv2 or elfv1. Intent of this patch to accept elfv1 or elfv2 for -mabi. Reviewed By : nemanjai Differential Revision: https://reviews.llvm.org/D156351 Added: Modified: clang/lib/Driver/ToolChains/Clang.cpp clang/test/Driver/ppc-abi.c Removed: diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0fc476fba53f34..170eedf0ac6222 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2068,6 +2068,12 @@ void Clang::AddPPCTargetArgs(const ArgList , } else if (V == "vec-extabi") { VecExtabi = true; A->claim(); +} else if (V == "elfv1") { + ABIName = "elfv1"; + A->claim(); +} else if (V == "elfv2") { + ABIName = "elfv2"; + A->claim(); } else if (V != "altivec") // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore // the option if given as we don't have backend support for any targets diff --git a/clang/test/Driver/ppc-abi.c b/clang/test/Driver/ppc-abi.c index cc07b084132f15..a433f4c0f5d8fc 100644 --- a/clang/test/Driver/ppc-abi.c +++ b/clang/test/Driver/ppc-abi.c @@ -15,6 +15,10 @@ // RUN: -mabi=elfv2 | FileCheck -check-prefix=CHECK-ELFv2 %s // RUN: %clang -target powerpc64le-unknown-linux-gnu %s -### -o %t.o 2>&1 \ // RUN: -mabi=altivec | FileCheck -check-prefix=CHECK-ELFv2 %s +// RUN: %clang --target=ppc64 -mabi=elfv1 %s -### -o %t.o 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-UNKNOWN-ELFv1 %s +// RUN: %clang --target=ppc64 -mabi=elfv2 %s -### -o %t.o 2>&1 \ +// RUN: | FileCheck -check-prefix=CHECK-UNKNOWN-ELFv2 %s // RUN: %clang -target powerpc64-unknown-freebsd11 %s -### 2>&1 | FileCheck --check-prefix=CHECK-ELFv1 %s // RUN: %clang -target powerpc64-unknown-freebsd12 %s -### 2>&1 | FileCheck --check-prefix=CHECK-ELFv1 %s @@ -31,6 +35,8 @@ // CHECK-ELFv2-BE: "-target-abi" "elfv2" // CHECK-ELFv2-BE-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" // CHECK-ELFv2-BE-PIE: "-target-abi" "elfv2" +// CHECK-UNKNOWN-ELFv1: "-target-abi" "elfv1" +// CHECK-UNKNOWN-ELFv2: "-target-abi" "elfv2" // RUN: %clang -fPIC -target powerpc64-unknown-linux-gnu %s -### -o %t.o 2>&1 \ // RUN: | FileCheck -check-prefix=CHECK-ELFv1-PIC %s ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits