[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
@@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" + auto GetOpRes = [&](Value *FieldValue, unsigned Mask, unsigned Op, + unsigned Op_Value) -> Value * { +Value *Value1 = FieldValue; +if (Mask) + Value1 = Builder.CreateAnd(Value1, Mask); +assert((Op == OP_EQ) && "Only support equal comparision"); +return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue, + ConstantInt::get(Int32Ty, Op_Value)); + }; + + auto ConvBuiltinCpu = [&](unsigned SupportOP, unsigned FieldIdx, +unsigned Op_Mask, unsigned Op, +unsigned Op_Value) -> Value * { +if (SupportOP == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportOP == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportOP <= COMP_OP && "Invalid value for SupportOP."); +llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + +llvm::Constant *SysConf = +CGM.CreateRuntimeVariable(STy, "_system_configuration"); + +// Grab the appropriate field from _system_configuration. +llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + +llvm::Value *FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); +FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); + +return GetOpRes(FieldValue, Op_Mask, Op, Op_Value); + }; + switch (BuiltinID) { default: return nullptr; case Builtin::BI__builtin_cpu_is: { const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); StringRef CPUStr = cast(CPUExpr)->getString(); -unsigned NumCPUID = StringSwitch(CPUStr) +llvm::Triple Triple = getTarget().getTriple(); +if (Triple.isOSLinux()) { + unsigned NumCPUID = StringSwitch(CPUStr) #define PPC_LNX_CPU(Name, NumericID) .Case(Name, NumericID) #include "llvm/TargetParser/PPCTargetParser.def" -.Default(-1U); + .Default(-1U); assert(NumCPUID < -1U && "Invalid CPU name. Missed by SemaChecking?"); Value *Op0 = llvm::ConstantInt::get(Int32Ty, PPC_FAWORD_CPUID); llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_fixed_addr_ld); Value *TheCall = Builder.CreateCall(F, {Op0}, "cpu_is"); return Builder.CreateICmpEQ(TheCall, llvm::ConstantInt::get(Int32Ty, NumCPUID)); +} else if (Triple.isOSAIX()) { + unsigned IsCpuSupport, FieldIdx, CpuIdMask, CpuIdOp, CpuIdValue; + typedef std::tuple + CPUType; + std::tie(IsCpuSupport, FieldIdx, CpuIdMask, CpuIdOp, CpuIdValue) = + static_cast(StringSwitch(CPUStr) +#define PPC_AIX_CPU(NAME, SUPPORT, MASK, INDEX, OP, VALUE) \ + .Case(NAME, {SUPPORT, MASK, INDEX, OP, VALUE}) +#include "llvm/TargetParser/PPCTargetParser.def" + ); + return ConvBuiltinCpu(IsCpuSupport, FieldIdx, CpuIdMask, CpuIdOp, +CpuIdValue); +} +LLVM_FALLTHROUGH; diggerlin wrote: good catch. https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
@@ -0,0 +1,83 @@ +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc970\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefix=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc-cell-be\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefix=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"ppca2\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefix=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc405\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefix=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc440\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefix=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc464\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefix=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"ppc476\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefix=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"power4\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefixes=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"power5\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefixes=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"power5+\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefixes=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"power6\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefixes=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"power6x\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s \ +// RUN: --check-prefixes=CHECKBOOL + +// RUN: echo "int main() { return __builtin_cpu_is(\"power7\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=32768 \ +// RUN: --check-prefixes=CHECKOP + +// RUN: echo "int main() { return __builtin_cpu_is(\"power8\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=65536 \ +// RUN: --check-prefixes=CHECKOP + +// RUN: echo "int main() { return __builtin_cpu_is(\"power9\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=131072\ +// RUN: --check-prefixes=CHECKOP + +// RUN: echo "int main() { return __builtin_cpu_is(\"power10\");}" > %t.c +// RUN: %clang_cc1 -triple powerpc-ibm-aix7.2.0.0 -emit-llvm -o - %t.c | FileCheck %s -DVALUE=262144 \ +// RUN: --check-prefixes=CHECKOP + +// CHECKBOOL: define i32 @main() #0 { +// CHECKBOOL-NEXT: entry: +// CHECKBOOL-NEXT: %retval = alloca i32, align 4 +// CHECKBOOL-NEXT: store i32 0, ptr %retval, align 4 +// CHECKBOOL-NEXT: ret i32 0 +// CHECKBOOL-NEXT: } + +// CHECKOP: @_system_configuration = external global { i32, i32, i32 } +// CHECKOP: define i32 @main() #0 { +// CHECKOP-NEXT: entry: +// CHECKOP-NEXT: %retval = alloca i32, align 4 +// CHECKOP-NEXT: store i32 0, ptr %retval, align 4 +// CHECKOP-NEXT: %0 = load i32, ptr getelementptr inbounds ({ i32, i32, i32 }, ptr @_system_configuration, i32 0, i32 1), align 4 diggerlin wrote: yes. I think so, but the test case will be in the later patch. the mask is always 0 in the patch, I will delete the mask related code in the patch. https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
@@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" diggerlin wrote: I think the function is too short, It not worth to have a two separate static functions. and I reorganize the code in other way. https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
@@ -10347,6 +10347,8 @@ def err_x86_builtin_tile_arg_duplicate : Error< def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; +def err_builtin_aix_os_unsupported : Error< + "this builtin is available only in AIX 7.2 and later operating systems">; diggerlin wrote: we need to use this builtin here the error output will be lile __builtin_cpu_is("power8") ^^^ this builtin is available only in AIX 7.2 and later operating systems}} this indicates the function which in the compiler error message https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
@@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" + auto GetOpRes = [&](Value *FieldValue, unsigned Mask, unsigned Op, + unsigned Op_Value) -> Value * { +Value *Value1 = FieldValue; +if (Mask) + Value1 = Builder.CreateAnd(Value1, Mask); +assert((Op == OP_EQ) && "Only support equal comparision"); +return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue, + ConstantInt::get(Int32Ty, Op_Value)); + }; + + auto ConvBuiltinCpu = [&](unsigned SupportOP, unsigned FieldIdx, +unsigned Op_Mask, unsigned Op, +unsigned Op_Value) -> Value * { +if (SupportOP == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportOP == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportOP <= COMP_OP && "Invalid value for SupportOP."); diggerlin wrote: after I think it over, keeping the assert here is OK too. https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/80069 >From a82a60e3af041f50b833d241a284e09a883e849a Mon Sep 17 00:00:00 2001 From: zhijian Date: Tue, 30 Jan 2024 15:13:39 -0500 Subject: [PATCH 1/2] support builtin_cpu_is() for aix --- .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/lib/Basic/Targets/PPC.cpp | 13 ++- clang/lib/Basic/Targets/PPC.h | 12 ++- clang/lib/CodeGen/CGBuiltin.cpp | 57 - clang/lib/Sema/SemaChecking.cpp | 5 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 83 +++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 6 ++ .../llvm/TargetParser/PPCTargetParser.def | 53 8 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-is.c create mode 100644 clang/test/Sema/aix-builtin-cpu-unsupports.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1c0ebbe4e68343..139a90a3020684 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10347,6 +10347,8 @@ def err_x86_builtin_tile_arg_duplicate : Error< def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; +def err_builtin_aix_os_unsupported : Error< + "this builtin is available only in AIX 7.2 and later operating systems">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; def err_builtin_setjmp_unsupported : Error< diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 8c891ccdeb59d4..c9cf7435334402 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -904,8 +904,17 @@ bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { } bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSLinux()) { #define PPC_LNX_CPU(NAME, NUM) .Case(NAME, true) - return llvm::StringSwitch(CPUName) +return llvm::StringSwitch(CPUName) #include "llvm/TargetParser/PPCTargetParser.def" - .Default(false); +.Default(false); + } else if (Triple.isOSAIX()) { +#define PPC_AIX_CPU(NAME, SUPPORT, INDEX, MASK, OP, VALUE) .Case(NAME, true) +return llvm::StringSwitch(CPUName) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + return false; } diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index a91bdede53e40d..5f92c80d15c0fa 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -362,8 +362,18 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // We support __builtin_cpu_supports/__builtin_cpu_is on targets that // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. +#define MINIMUM_AIX_OS_MAJOR 7 +#define MINIMUM_AIX_OS_MINOR 2 bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } - bool supportsCpuIs() const override { return getTriple().isOSGlibc(); } + bool supportsCpuIs() const override { +llvm::Triple Tri = getTriple(); +// The AIX7.2 is mininum requirement to support __builtin_cpu_is(). +return Tri.isOSGlibc() || + (Tri.isOSAIX() && +!Tri.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } +#undef MINIMUM_AIX_OS_MAJOR +#undef MINIMUM_AIX_OS_MINOR bool validateCpuSupports(StringRef Feature) const override; bool validateCpuIs(StringRef Name) const override; }; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f3ab5ad7b08ec8..bab5b144275fd8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" + auto GetOpRes = [&](Value *FieldValue, unsigned Mask, unsigned Op, + unsigned Op_Value) -> Value * { +Value *Value1 = FieldValue; +if (Mask) + Value1 = Builder.CreateAnd(Value1, Mask); +assert((Op == OP_EQ) && "Only support equal comparision"); +return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue, + ConstantInt::get(Int32Ty, Op_Value)); + }; + + auto ConvBuiltinCpu = [&](unsigned SupportOP, unsigned FieldIdx, +unsigned Op_Mask, unsigned Op, +unsigned Op_Value) -> Value * { +if (SupportOP == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportOP == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportOP <= COMP_OP && "Invalid value for SupportOP."); +llvm::Type *STy =
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/80069 >From a82a60e3af041f50b833d241a284e09a883e849a Mon Sep 17 00:00:00 2001 From: zhijian Date: Tue, 30 Jan 2024 15:13:39 -0500 Subject: [PATCH 1/3] support builtin_cpu_is() for aix --- .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/lib/Basic/Targets/PPC.cpp | 13 ++- clang/lib/Basic/Targets/PPC.h | 12 ++- clang/lib/CodeGen/CGBuiltin.cpp | 57 - clang/lib/Sema/SemaChecking.cpp | 5 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 83 +++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 6 ++ .../llvm/TargetParser/PPCTargetParser.def | 53 8 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-is.c create mode 100644 clang/test/Sema/aix-builtin-cpu-unsupports.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1c0ebbe4e68343..139a90a3020684 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10347,6 +10347,8 @@ def err_x86_builtin_tile_arg_duplicate : Error< def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; +def err_builtin_aix_os_unsupported : Error< + "this builtin is available only in AIX 7.2 and later operating systems">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; def err_builtin_setjmp_unsupported : Error< diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 8c891ccdeb59d4..c9cf7435334402 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -904,8 +904,17 @@ bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { } bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSLinux()) { #define PPC_LNX_CPU(NAME, NUM) .Case(NAME, true) - return llvm::StringSwitch(CPUName) +return llvm::StringSwitch(CPUName) #include "llvm/TargetParser/PPCTargetParser.def" - .Default(false); +.Default(false); + } else if (Triple.isOSAIX()) { +#define PPC_AIX_CPU(NAME, SUPPORT, INDEX, MASK, OP, VALUE) .Case(NAME, true) +return llvm::StringSwitch(CPUName) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + return false; } diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index a91bdede53e40d..5f92c80d15c0fa 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -362,8 +362,18 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // We support __builtin_cpu_supports/__builtin_cpu_is on targets that // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. +#define MINIMUM_AIX_OS_MAJOR 7 +#define MINIMUM_AIX_OS_MINOR 2 bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } - bool supportsCpuIs() const override { return getTriple().isOSGlibc(); } + bool supportsCpuIs() const override { +llvm::Triple Tri = getTriple(); +// The AIX7.2 is mininum requirement to support __builtin_cpu_is(). +return Tri.isOSGlibc() || + (Tri.isOSAIX() && +!Tri.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } +#undef MINIMUM_AIX_OS_MAJOR +#undef MINIMUM_AIX_OS_MINOR bool validateCpuSupports(StringRef Feature) const override; bool validateCpuIs(StringRef Name) const override; }; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f3ab5ad7b08ec8..bab5b144275fd8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" + auto GetOpRes = [&](Value *FieldValue, unsigned Mask, unsigned Op, + unsigned Op_Value) -> Value * { +Value *Value1 = FieldValue; +if (Mask) + Value1 = Builder.CreateAnd(Value1, Mask); +assert((Op == OP_EQ) && "Only support equal comparision"); +return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue, + ConstantInt::get(Int32Ty, Op_Value)); + }; + + auto ConvBuiltinCpu = [&](unsigned SupportOP, unsigned FieldIdx, +unsigned Op_Mask, unsigned Op, +unsigned Op_Value) -> Value * { +if (SupportOP == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportOP == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportOP <= COMP_OP && "Invalid value for SupportOP."); +llvm::Type *STy =
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX][TOC] Add -mtocdata/-mno-tocdata options on AIX (PR #67999)
@@ -172,6 +172,30 @@ bool PPCSubtarget::enableSubRegLiveness() const { return UseSubRegLiveness; } +void PPCSubtarget::tocDataChecks(unsigned PointerSize, + const GlobalVariable *GV) const { + // TODO: These asserts should be updated as more support for the toc data + // transformation is added (struct support, etc.). + assert( + PointerSize >= GV->getAlign().valueOrOne().value() && + "GlobalVariables with an alignment requirement stricter than TOC entry " + "size not supported by the toc data transformation."); + + Type *GVType = GV->getValueType(); + assert(GVType->isSized() && "A GlobalVariable's size must be known to be " + "supported by the toc data transformation."); + if (GV->getParent()->getDataLayout().getTypeSizeInBits(GVType) > + PointerSize * 8) +report_fatal_error( +"A GlobalVariable with size larger than a TOC entry is not currently " +"supported by the toc data transformation."); + if (GV->hasLocalLinkage() || GV->hasPrivateLinkage()) +report_fatal_error("A GlobalVariable with private or local linkage is not " + "currently supported by the toc data transformation."); + assert(!GV->hasCommonLinkage() && + "Tentative definitions cannot have the mapping class XMC_TD."); +} diggerlin wrote: since the https://github.com/llvm/llvm-project/pull/79530/files merge , please remember to remove assert(!GV->hasCommonLinkage() && "Tentative definitions cannot have the mapping class XMC_TD."); https://github.com/llvm/llvm-project/pull/67999 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
@@ -16542,12 +16542,64 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; + // The lambda function converts builtin_cpu_is function into directly + // returning false or true, or it gets and checks the information from the + // kernel variable _system_configuration for AIX OS. + +#include "llvm/TargetParser/PPCTargetParser.def" + auto ConvBuiltinCpu = [&](unsigned SupportMagic, unsigned FieldIdx, +unsigned CompOp, unsigned OpValue) -> Value * { +if (SupportMagic == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportMagic == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportMagic <= SYS_CONF && "Invalid value for SupportMagic."); +llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + +llvm::Constant *SysConf = +CGM.CreateRuntimeVariable(STy, "_system_configuration"); + +// Grab the appropriate field from _system_configuration. +llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + +llvm::Value *FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); +FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); + +assert((CompOp == COMP_EQ) && "Only equal comparisons are supported!"); diggerlin wrote: I moved the assert up and check earlier https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
@@ -126,4 +126,53 @@ PPC_LNX_CPU("power10",47) #undef PPC_LNX_DEFINE_OFFSETS #undef PPC_LNX_FEATURE #undef PPC_LNX_CPU + +// Definition of the following values are found in the AIX header file: . +#ifndef AIX_POWERPC_SYS_CONF +#define AIX_POWERPC_SYS_CONF + #define AIX_SYSCON_IMPL_IDX 1 + #define AIX_PPC7_VALUE 0x8000 + #define AIX_PPC8_VALUE 0x0001 + #define AIX_PPC9_VALUE 0x0002 + #define AIX_PPC10_VALUE 0x0004 + + #define AIX_BUILTIN_PPC_TRUE 1 + #define AIX_BUILTIN_PPC_FALSE 0 + #define SYS_CONF 2 + + #define COMP_EQ 0 + +#endif + +// When the value of SUPPORT_MAGIC is SYS_CONF, the return value depends on the +// _system_configuration[INDEX] COMPARE_OP VALUE. +#ifndef PPC_AIX_CPU + #define PPC_AIX_CPU(NAME, SUPPORT_MAGIC, INDEX, COMPARE_OP, VALUE) diggerlin wrote: we will have API call in other patch later, I do not think change `INDEX` to `SYS_CFG_INDEX` and `VALUE` to `SYS_CFG_VALUE` is a good idea. https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
@@ -10347,6 +10347,8 @@ def err_x86_builtin_tile_arg_duplicate : Error< def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; +def err_builtin_aix_os_unsupported : Error< + "this builtin is available only on AIX 7.2 and later operating systems">; diggerlin wrote: I think with `this` grammar correct in the following compiler error output: (this indicates a certain functions __builtin_cpu_is("power8"); ) builtin.c:2:10: error: this builtin is available only on AIX 7.2 and later operating systems 2 | return __builtin_cpu_is("power8"); https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] support builtin_cpu_is() for aix (PR #80069)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/80069 >From a82a60e3af041f50b833d241a284e09a883e849a Mon Sep 17 00:00:00 2001 From: zhijian Date: Tue, 30 Jan 2024 15:13:39 -0500 Subject: [PATCH 1/4] support builtin_cpu_is() for aix --- .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/lib/Basic/Targets/PPC.cpp | 13 ++- clang/lib/Basic/Targets/PPC.h | 12 ++- clang/lib/CodeGen/CGBuiltin.cpp | 57 - clang/lib/Sema/SemaChecking.cpp | 5 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 83 +++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 6 ++ .../llvm/TargetParser/PPCTargetParser.def | 53 8 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-is.c create mode 100644 clang/test/Sema/aix-builtin-cpu-unsupports.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1c0ebbe4e68343..139a90a3020684 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10347,6 +10347,8 @@ def err_x86_builtin_tile_arg_duplicate : Error< def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; +def err_builtin_aix_os_unsupported : Error< + "this builtin is available only in AIX 7.2 and later operating systems">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; def err_builtin_setjmp_unsupported : Error< diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 8c891ccdeb59d4..c9cf7435334402 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -904,8 +904,17 @@ bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { } bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSLinux()) { #define PPC_LNX_CPU(NAME, NUM) .Case(NAME, true) - return llvm::StringSwitch(CPUName) +return llvm::StringSwitch(CPUName) #include "llvm/TargetParser/PPCTargetParser.def" - .Default(false); +.Default(false); + } else if (Triple.isOSAIX()) { +#define PPC_AIX_CPU(NAME, SUPPORT, INDEX, MASK, OP, VALUE) .Case(NAME, true) +return llvm::StringSwitch(CPUName) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + return false; } diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index a91bdede53e40d..5f92c80d15c0fa 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -362,8 +362,18 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // We support __builtin_cpu_supports/__builtin_cpu_is on targets that // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. +#define MINIMUM_AIX_OS_MAJOR 7 +#define MINIMUM_AIX_OS_MINOR 2 bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } - bool supportsCpuIs() const override { return getTriple().isOSGlibc(); } + bool supportsCpuIs() const override { +llvm::Triple Tri = getTriple(); +// The AIX7.2 is mininum requirement to support __builtin_cpu_is(). +return Tri.isOSGlibc() || + (Tri.isOSAIX() && +!Tri.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } +#undef MINIMUM_AIX_OS_MAJOR +#undef MINIMUM_AIX_OS_MINOR bool validateCpuSupports(StringRef Feature) const override; bool validateCpuIs(StringRef Name) const override; }; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f3ab5ad7b08ec8..bab5b144275fd8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" + auto GetOpRes = [&](Value *FieldValue, unsigned Mask, unsigned Op, + unsigned Op_Value) -> Value * { +Value *Value1 = FieldValue; +if (Mask) + Value1 = Builder.CreateAnd(Value1, Mask); +assert((Op == OP_EQ) && "Only support equal comparision"); +return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue, + ConstantInt::get(Int32Ty, Op_Value)); + }; + + auto ConvBuiltinCpu = [&](unsigned SupportOP, unsigned FieldIdx, +unsigned Op_Mask, unsigned Op, +unsigned Op_Value) -> Value * { +if (SupportOP == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportOP == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportOP <= COMP_OP && "Invalid value for SupportOP."); +llvm::Type *STy =
[clang] [llvm] [AIX] Lower intrinsic __builtin_cpu_is into AIX platform-specific code. (PR #80069)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] Lower intrinsic __builtin_cpu_is into AIX platform-specific code. (PR #80069)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] Lower intrinsic __builtin_cpu_is into AIX platform-specific code. (PR #80069)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] Lower intrinsic __builtin_cpu_is into AIX platform-specific code. (PR #80069)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/80069 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] Lower intrinsic __builtin_cpu_is into AIX platform-specific code. (PR #80069)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/80069 >From a82a60e3af041f50b833d241a284e09a883e849a Mon Sep 17 00:00:00 2001 From: zhijian Date: Tue, 30 Jan 2024 15:13:39 -0500 Subject: [PATCH 1/5] support builtin_cpu_is() for aix --- .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/lib/Basic/Targets/PPC.cpp | 13 ++- clang/lib/Basic/Targets/PPC.h | 12 ++- clang/lib/CodeGen/CGBuiltin.cpp | 57 - clang/lib/Sema/SemaChecking.cpp | 5 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 83 +++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 6 ++ .../llvm/TargetParser/PPCTargetParser.def | 53 8 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-is.c create mode 100644 clang/test/Sema/aix-builtin-cpu-unsupports.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1c0ebbe4e68343..139a90a3020684 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10347,6 +10347,8 @@ def err_x86_builtin_tile_arg_duplicate : Error< def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; +def err_builtin_aix_os_unsupported : Error< + "this builtin is available only in AIX 7.2 and later operating systems">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; def err_builtin_setjmp_unsupported : Error< diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 8c891ccdeb59d4..c9cf7435334402 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -904,8 +904,17 @@ bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { } bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSLinux()) { #define PPC_LNX_CPU(NAME, NUM) .Case(NAME, true) - return llvm::StringSwitch(CPUName) +return llvm::StringSwitch(CPUName) #include "llvm/TargetParser/PPCTargetParser.def" - .Default(false); +.Default(false); + } else if (Triple.isOSAIX()) { +#define PPC_AIX_CPU(NAME, SUPPORT, INDEX, MASK, OP, VALUE) .Case(NAME, true) +return llvm::StringSwitch(CPUName) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + return false; } diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index a91bdede53e40d..5f92c80d15c0fa 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -362,8 +362,18 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // We support __builtin_cpu_supports/__builtin_cpu_is on targets that // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. +#define MINIMUM_AIX_OS_MAJOR 7 +#define MINIMUM_AIX_OS_MINOR 2 bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } - bool supportsCpuIs() const override { return getTriple().isOSGlibc(); } + bool supportsCpuIs() const override { +llvm::Triple Tri = getTriple(); +// The AIX7.2 is mininum requirement to support __builtin_cpu_is(). +return Tri.isOSGlibc() || + (Tri.isOSAIX() && +!Tri.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } +#undef MINIMUM_AIX_OS_MAJOR +#undef MINIMUM_AIX_OS_MINOR bool validateCpuSupports(StringRef Feature) const override; bool validateCpuIs(StringRef Name) const override; }; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f3ab5ad7b08ec8..bab5b144275fd8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" + auto GetOpRes = [&](Value *FieldValue, unsigned Mask, unsigned Op, + unsigned Op_Value) -> Value * { +Value *Value1 = FieldValue; +if (Mask) + Value1 = Builder.CreateAnd(Value1, Mask); +assert((Op == OP_EQ) && "Only support equal comparision"); +return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue, + ConstantInt::get(Int32Ty, Op_Value)); + }; + + auto ConvBuiltinCpu = [&](unsigned SupportOP, unsigned FieldIdx, +unsigned Op_Mask, unsigned Op, +unsigned Op_Value) -> Value * { +if (SupportOP == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportOP == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportOP <= COMP_OP && "Invalid value for SupportOP."); +llvm::Type *STy =
[clang] [llvm] [AIX] Lower intrinsic __builtin_cpu_is into AIX platform-specific code. (PR #80069)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/80069 >From a82a60e3af041f50b833d241a284e09a883e849a Mon Sep 17 00:00:00 2001 From: zhijian Date: Tue, 30 Jan 2024 15:13:39 -0500 Subject: [PATCH 1/6] support builtin_cpu_is() for aix --- .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/lib/Basic/Targets/PPC.cpp | 13 ++- clang/lib/Basic/Targets/PPC.h | 12 ++- clang/lib/CodeGen/CGBuiltin.cpp | 57 - clang/lib/Sema/SemaChecking.cpp | 5 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 83 +++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 6 ++ .../llvm/TargetParser/PPCTargetParser.def | 53 8 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-is.c create mode 100644 clang/test/Sema/aix-builtin-cpu-unsupports.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1c0ebbe4e68343..139a90a3020684 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10347,6 +10347,8 @@ def err_x86_builtin_tile_arg_duplicate : Error< def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; +def err_builtin_aix_os_unsupported : Error< + "this builtin is available only in AIX 7.2 and later operating systems">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; def err_builtin_setjmp_unsupported : Error< diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 8c891ccdeb59d4..c9cf7435334402 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -904,8 +904,17 @@ bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { } bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSLinux()) { #define PPC_LNX_CPU(NAME, NUM) .Case(NAME, true) - return llvm::StringSwitch(CPUName) +return llvm::StringSwitch(CPUName) #include "llvm/TargetParser/PPCTargetParser.def" - .Default(false); +.Default(false); + } else if (Triple.isOSAIX()) { +#define PPC_AIX_CPU(NAME, SUPPORT, INDEX, MASK, OP, VALUE) .Case(NAME, true) +return llvm::StringSwitch(CPUName) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + return false; } diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index a91bdede53e40d..5f92c80d15c0fa 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -362,8 +362,18 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // We support __builtin_cpu_supports/__builtin_cpu_is on targets that // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. +#define MINIMUM_AIX_OS_MAJOR 7 +#define MINIMUM_AIX_OS_MINOR 2 bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } - bool supportsCpuIs() const override { return getTriple().isOSGlibc(); } + bool supportsCpuIs() const override { +llvm::Triple Tri = getTriple(); +// The AIX7.2 is mininum requirement to support __builtin_cpu_is(). +return Tri.isOSGlibc() || + (Tri.isOSAIX() && +!Tri.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } +#undef MINIMUM_AIX_OS_MAJOR +#undef MINIMUM_AIX_OS_MINOR bool validateCpuSupports(StringRef Feature) const override; bool validateCpuIs(StringRef Name) const override; }; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f3ab5ad7b08ec8..bab5b144275fd8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" + auto GetOpRes = [&](Value *FieldValue, unsigned Mask, unsigned Op, + unsigned Op_Value) -> Value * { +Value *Value1 = FieldValue; +if (Mask) + Value1 = Builder.CreateAnd(Value1, Mask); +assert((Op == OP_EQ) && "Only support equal comparision"); +return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue, + ConstantInt::get(Int32Ty, Op_Value)); + }; + + auto ConvBuiltinCpu = [&](unsigned SupportOP, unsigned FieldIdx, +unsigned Op_Mask, unsigned Op, +unsigned Op_Value) -> Value * { +if (SupportOP == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportOP == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportOP <= COMP_OP && "Invalid value for SupportOP."); +llvm::Type *STy =
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From 557e7163d744890aadfa703a81a0c4f2cd112517 Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/5] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 15 +- clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 104 +++--- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 135 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 +- .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 ++ .../llvm/TargetParser/PPCTargetParser.def | 73 +- 9 files changed, 356 insertions(+), 39 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..1d488dff825ede 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,19 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, COMP_OP, \ +VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" @@ -906,7 +919,7 @@ bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { llvm::Triple Triple = getTriple(); if (Triple.isOSAIX()) { -#define PPC_AIX_CPU(NAME, SUPPORT, INDEX, OP, VALUE) .Case(NAME, true) +#define PPC_AIX_CPU(NAME, SUPPORT_METHOD, INDEX, OP, VALUE) .Case(NAME, true) return llvm::StringSwitch(CPUName) #include "llvm/TargetParser/PPCTargetParser.def" .Default(false); diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 9ee51ca7142c77..1565e4103d9ef8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16570,7 +16570,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16578,24 +16578,64 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropria
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From 557e7163d744890aadfa703a81a0c4f2cd112517 Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/6] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 15 +- clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 104 +++--- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 135 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 +- .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 ++ .../llvm/TargetParser/PPCTargetParser.def | 73 +- 9 files changed, 356 insertions(+), 39 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..1d488dff825ede 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,19 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, COMP_OP, \ +VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" @@ -906,7 +919,7 @@ bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { llvm::Triple Triple = getTriple(); if (Triple.isOSAIX()) { -#define PPC_AIX_CPU(NAME, SUPPORT, INDEX, OP, VALUE) .Case(NAME, true) +#define PPC_AIX_CPU(NAME, SUPPORT_METHOD, INDEX, OP, VALUE) .Case(NAME, true) return llvm::StringSwitch(CPUName) #include "llvm/TargetParser/PPCTargetParser.def" .Default(false); diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 9ee51ca7142c77..1565e4103d9ef8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16570,7 +16570,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16578,24 +16578,64 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropria
[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 &TypeSize) 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 &ArgGPRsLeft) const { + assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (IsComplexInRegABI && Ty->isAnyComplexType() && + TypeSize <= RegLen * ArgGPRsLeft) { +assert(Ty->isAnyComplexType() && "Ty must be Complex type."); +ArgGPRsLeft -= TypeSize / RegLen; +return handleComplex(TypeSize); + } + + if (ArgGPRsLeft) { +// Records with non-trivial destructors/copy-constructors should not be +// passed by value. +if (isAggregateTypeForABI(Ty)) + ArgGPRsLeft -= 1; +else if (!Ty->isFloatingType()) { + // For other premitive types. + if (TypeSize > RegLen && TypeSize <= 2 * RegLen) +ArgGPRsLeft -= TypeSize / RegLen; diggerlin wrote: for a test case `foo(_Complex long double foo4(int x1, long long y1, int x2, _Complex double z,)` `int x1` will have r3, `long long y1` will have r5,r6 (skip r4 since re is even.) `int x2` will have r7, ` _Complex double z` need to occupy 4 registers, there is no enough register , it can not pass `_Complex double z` in r8,r9,r10 , you have to pass ` _Complex double z` in by pointer (you can not call `handleComplex()`). but in your code, ArgGPRsLeft is 7 after int x1, ArgGPRsLeft is 5 after int y1 ArgGPRsLeft is 4 after int x2 there is still have 4 registers left for ` _Complex double z`, you can call `handleComplex()`, you can pass ` _Complex double z by value https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -420,6 +496,10 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { return ABIArgInfo::getDirect(CoerceTy); } } + if (IsComplexInRegABI && RetTy->isAnyComplexType()) { +assert(RetTy->isAnyComplexType() && "RetTy must be Complex type."); diggerlin wrote: you already has `if (IsComplexInRegABI && RetTy->isAnyComplexType())` as condition, is there any reason to keep the `assert(RetTy->isAnyComplexType() && "RetTy must be Complex type.");` https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -330,22 +330,33 @@ namespace { class PPC32_SVR4_ABIInfo : public DefaultABIInfo { bool IsSoftFloatABI; bool IsRetSmallStructInRegABI; + bool IsComplexInRegABI; diggerlin wrote: do we need a new data member `IsComplexInRegABI` here ? (there are several place code be modified because we add the new data member `IsComplexInRegABI` ) we can add ``` bool IsComplexInRegABI = getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR ; ``` in the function `classifyArgumentType` and `classifyReturnType()` https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -337,12 +347,58 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t &TypeSize) 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 &ArgGPRsLeft) const { + assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (IsComplexInRegABI && Ty->isAnyComplexType() && + TypeSize <= RegLen * ArgGPRsLeft) { +assert(Ty->isAnyComplexType() && "Ty must be Complex type."); diggerlin wrote: do we need the assert here since there is `if (Ty->isAnyComplexType() && TypeSize <= RegLen * ArgGPRsLeft)` https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -396,12 +407,77 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t &TypeSize) 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 &ArgGPRsLeft) const { + assert(ArgGPRsLeft >= 0 && "Arg GPR must be large or equal than zero"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (Ty->isAnyComplexType() && TypeSize <= RegLen * ArgGPRsLeft) { +assert(Ty->isAnyComplexType() && "Ty must be Complex type."); +if (IsComplexInRegABI) { + ArgGPRsLeft -= TypeSize / RegLen; + return handleComplex(TypeSize); +} else + ArgGPRsLeft--; diggerlin wrote: I do not think you care about the value of ArgGPRsLeft when IsComplexInRegABI is false. is it correct ? we can add following code in front of the function. ``` if (!IsComplexInRegABI ) return DefaultABIInfo::classifyArgumentType(Ty); ``` https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [AIX] Lower intrinsic __builtin_cpu_is into AIX platform-specific code. (PR #80069)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/80069 >From a82a60e3af041f50b833d241a284e09a883e849a Mon Sep 17 00:00:00 2001 From: zhijian Date: Tue, 30 Jan 2024 15:13:39 -0500 Subject: [PATCH 1/7] support builtin_cpu_is() for aix --- .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/lib/Basic/Targets/PPC.cpp | 13 ++- clang/lib/Basic/Targets/PPC.h | 12 ++- clang/lib/CodeGen/CGBuiltin.cpp | 57 - clang/lib/Sema/SemaChecking.cpp | 5 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 83 +++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 6 ++ .../llvm/TargetParser/PPCTargetParser.def | 53 8 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-is.c create mode 100644 clang/test/Sema/aix-builtin-cpu-unsupports.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1c0ebbe4e68343..139a90a3020684 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10347,6 +10347,8 @@ def err_x86_builtin_tile_arg_duplicate : Error< def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; +def err_builtin_aix_os_unsupported : Error< + "this builtin is available only in AIX 7.2 and later operating systems">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; def err_builtin_setjmp_unsupported : Error< diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index 8c891ccdeb59d4..c9cf7435334402 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -904,8 +904,17 @@ bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { } bool PPCTargetInfo::validateCpuIs(StringRef CPUName) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSLinux()) { #define PPC_LNX_CPU(NAME, NUM) .Case(NAME, true) - return llvm::StringSwitch(CPUName) +return llvm::StringSwitch(CPUName) #include "llvm/TargetParser/PPCTargetParser.def" - .Default(false); +.Default(false); + } else if (Triple.isOSAIX()) { +#define PPC_AIX_CPU(NAME, SUPPORT, INDEX, MASK, OP, VALUE) .Case(NAME, true) +return llvm::StringSwitch(CPUName) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + return false; } diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index a91bdede53e40d..5f92c80d15c0fa 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -362,8 +362,18 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // We support __builtin_cpu_supports/__builtin_cpu_is on targets that // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. +#define MINIMUM_AIX_OS_MAJOR 7 +#define MINIMUM_AIX_OS_MINOR 2 bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } - bool supportsCpuIs() const override { return getTriple().isOSGlibc(); } + bool supportsCpuIs() const override { +llvm::Triple Tri = getTriple(); +// The AIX7.2 is mininum requirement to support __builtin_cpu_is(). +return Tri.isOSGlibc() || + (Tri.isOSAIX() && +!Tri.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } +#undef MINIMUM_AIX_OS_MAJOR +#undef MINIMUM_AIX_OS_MINOR bool validateCpuSupports(StringRef Feature) const override; bool validateCpuIs(StringRef Name) const override; }; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index f3ab5ad7b08ec8..bab5b144275fd8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16542,22 +16542,75 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, Intrinsic::ID ID = Intrinsic::not_intrinsic; +#include "llvm/TargetParser/PPCTargetParser.def" + auto GetOpRes = [&](Value *FieldValue, unsigned Mask, unsigned Op, + unsigned Op_Value) -> Value * { +Value *Value1 = FieldValue; +if (Mask) + Value1 = Builder.CreateAnd(Value1, Mask); +assert((Op == OP_EQ) && "Only support equal comparision"); +return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue, + ConstantInt::get(Int32Ty, Op_Value)); + }; + + auto ConvBuiltinCpu = [&](unsigned SupportOP, unsigned FieldIdx, +unsigned Op_Mask, unsigned Op, +unsigned Op_Value) -> Value * { +if (SupportOP == AIX_BUILTIN_PPC_FALSE) + return llvm::ConstantInt::getFalse(ConvertType(E->getType())); + +if (SupportOP == AIX_BUILTIN_PPC_TRUE) + return llvm::ConstantInt::getTrue(ConvertType(E->getType())); + +assert(SupportOP <= COMP_OP && "Invalid value for SupportOP."); +llvm::Type *STy =
[clang] [llvm] [AIX] Lower intrinsic __builtin_cpu_is into AIX platform-specific code. (PR #80069)
https://github.com/diggerlin closed https://github.com/llvm/llvm-project/pull/80069 ___ 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 &TypeSize) const { + diggerlin wrote: it look the TypeSize only has 32bit and 64bit. can you change the `uint64_t &TypeSize` to `bool is64BitTypeSize` and change following code as ``` llvm::Type *ElemTy =is64BitTypeSize? llvm::Type::getInt64Ty(getVMContext()): llvm::Type::getInt32Ty(getVMContext()); unsigned SizeRegs = is64BitTypeSize ? 1:2; ``` 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)
@@ -184,11 +184,13 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { bool IsSoftFloat = CodeGenOpts.FloatABI == "soft" || Target.hasFeature("spe"); -return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat); +unsigned RLen = Target.getPointerWidth(LangAS::Default); +return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat, RLen); } case llvm::Triple::ppcle: { bool IsSoftFloat = CodeGenOpts.FloatABI == "soft"; -return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat); +unsigned RLen = Target.getPointerWidth(LangAS::Default); +return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat, RLen); diggerlin wrote: the variable is used only once , do not need to introduce a new variable. 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)
@@ -184,11 +184,13 @@ createTargetCodeGenInfo(CodeGenModule &CGM) { bool IsSoftFloat = CodeGenOpts.FloatABI == "soft" || Target.hasFeature("spe"); -return createPPC32TargetCodeGenInfo(CGM, IsSoftFloat); +unsigned RLen = Target.getPointerWidth(LangAS::Default); diggerlin wrote: the variable is used only once , do not need to introduce a new variable. 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,33 @@ namespace { class PPC32_SVR4_ABIInfo : public DefaultABIInfo { bool IsSoftFloatABI; bool IsRetSmallStructInRegABI; + bool isComplexInRegABI; + // Size of GPR in bits + unsigned RLen; diggerlin wrote: `RLen` is too short to understand what `R` means , suggest to change to `RegLen` and `RegisterLen`. and Do we need to add `RLen` ? since the class is PPC32_SVR4_ABIInfo, Should the Register Len be default to 32 bit ? 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/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -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 &TypeSize) const { + + assert(Ty->isAnyComplexType()); + llvm::Type *ElemTy; + unsigned SizeRegs; + + if (TypeSize == 64) { +ElemTy = llvm::Type::getInt64Ty(getVMContext()); +SizeRegs = 1; + } else { +ElemTy = llvm::Type::getInt32Ty(getVMContext()); diggerlin wrote: I am curiously , why not get ElemTy = llvm::Type::getInt128Ty(getVMContext()); instead of ElemTy = llvm::Type::getInt32Ty(getVMContext()); 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 &TypeSize) const { + + assert(Ty->isAnyComplexType()); diggerlin wrote: it looks the Ty pass in the function is only used for assert ? 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 &TypeSize) const { + + assert(Ty->isAnyComplexType()); + llvm::Type *ElemTy; + unsigned SizeRegs; diggerlin wrote: I can not understand what the SizeRegs stand for ? can you explain it ? do it indicate how many Registers will be used by the parameter which has TypeSize length. 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/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -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 &TypeSize) const { + + assert(Ty->isAnyComplexType()); + llvm::Type *ElemTy; + unsigned SizeRegs; + + if (TypeSize == 64) { +ElemTy = llvm::Type::getInt64Ty(getVMContext()); +SizeRegs = 1; + } else { +ElemTy = llvm::Type::getInt32Ty(getVMContext()); +SizeRegs = (TypeSize + 31) / 32; + } + return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, SizeRegs)); +} + +ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty, +int &ArgGPRsLeft) const { + + assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (isComplexInRegABI && Ty->isAnyComplexType() && + TypeSize <= RLen * ArgGPRsLeft) { +ArgGPRsLeft -= TypeSize / RLen; +return handleComplex(Ty, TypeSize); + } + + if (isAggregateTypeForABI(Ty)) { +if (ArgGPRsLeft) + ArgGPRsLeft -= 1; +// Records with non-trivial destructors/copy-constructors should not be +// passed by value. +if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { + return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); +} +return getNaturalAlignIndirect(Ty); + } + + if (!Ty->isFloatingType()) { +if (TypeSize > RLen && TypeSize <= 2 * RLen) + ArgGPRsLeft -= 2; +else + ArgGPRsLeft--; diggerlin wrote: There is a bug here, you decrease the ArgGPRsLeft no mater whether ArgGPRsLeft >0; I think you can put after `Ty = useFirstFieldIfTransparentUnion(Ty);` ``` Ty = useFirstFieldIfTransparentUnion(Ty); if(Ty->isFloatingType()) return; ``` and change the code here as ``` if(TypeSize <= RLen * ArgGPRsLeft) ArgGPRsLeft -= TypeSize / RLen; ``` 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/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin created https://github.com/llvm/llvm-project/pull/82809 The features which __builtin_cpu_support() supports are descripted in https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/PowerPC-Built-in-Functions.html#:~:text=The%20__builtin_cpu_supports%20function%20requires,in%20function%20is%20fully%20supported. the PR implements a subset of features of function __builtin_cpu_support() for AIX OS based on the information which AIX kernel runtime variable _system_configuration.version of /usr/include/sys/systemcfg.h and getsystemcfg() can provide. >From cef79b36bcb3f4b7452d01aafdf111ff0e50605d Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 12 ++ clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 99 --- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 154 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 - .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 + .../llvm/TargetParser/PPCTargetParser.def | 73 - 9 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..17b462c73bfc6a 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,18 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, OP, VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..cf4ddc52ff362a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16560,7 +16560,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16568,24 +16568,61 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(In
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From cef79b36bcb3f4b7452d01aafdf111ff0e50605d Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/2] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 12 ++ clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 99 --- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 154 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 - .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 + .../llvm/TargetParser/PPCTargetParser.def | 73 - 9 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..17b462c73bfc6a 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,18 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, OP, VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..cf4ddc52ff362a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16560,7 +16560,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16568,24 +16568,61 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + + FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); + FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); +} else if (SupportMethod == SYS_CALL) { + llvm::FunctionType *FTy = + llvm::FunctionType::get(Int64Ty, Int32Ty, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunc
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From cef79b36bcb3f4b7452d01aafdf111ff0e50605d Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/3] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 12 ++ clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 99 --- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 154 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 - .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 + .../llvm/TargetParser/PPCTargetParser.def | 73 - 9 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..17b462c73bfc6a 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,18 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, OP, VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..cf4ddc52ff362a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16560,7 +16560,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16568,24 +16568,61 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + + FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); + FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); +} else if (SupportMethod == SYS_CALL) { + llvm::FunctionType *FTy = + llvm::FunctionType::get(Int64Ty, Int32Ty, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunc
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/82809 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/82809 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From cef79b36bcb3f4b7452d01aafdf111ff0e50605d Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/4] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 12 ++ clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 99 --- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 154 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 - .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 + .../llvm/TargetParser/PPCTargetParser.def | 73 - 9 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..17b462c73bfc6a 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,18 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, OP, VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..cf4ddc52ff362a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16560,7 +16560,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16568,24 +16568,61 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + + FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); + FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); +} else if (SupportMethod == SYS_CALL) { + llvm::FunctionType *FTy = + llvm::FunctionType::get(Int64Ty, Int32Ty, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunc
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -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 &TypeSize) const { + + assert(Ty->isAnyComplexType()); diggerlin wrote: if use only for the assert, suggest putting assert outside the function, 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,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 &TypeSize) const; public: PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, 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 &ArgGPRsLeft) const; void computeInfo(CGFunctionInfo &FI) const override { + +int ArgGPRsLeft = NumArgGPRs; + if (!getCXXABI().classifyReturnType(FI)) FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); for (auto &I : FI.arguments()) - I.info = classifyArgumentType(I.type); + I.info = classifyArgumentType(I.type, ArgGPRsLeft); diggerlin wrote: why do you need introduce a new variable `ArgGPRsLeft` since you do not use the new variable after the call . 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/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -372,11 +453,12 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList, if (getTarget().getTriple().isOSDarwin()) { auto TI = getContext().getTypeInfoInChars(Ty); TI.Align = getParamTypeAlignment(Ty); +int ArgGPRs = NumArgGPRs; CharUnits SlotSize = CharUnits::fromQuantity(4); return emitVoidPtrVAArg(CGF, VAList, Ty, -classifyArgumentType(Ty).isIndirect(), TI, SlotSize, -/*AllowHigherAlign=*/true); +classifyArgumentType(Ty, ArgGPRs).isIndirect(), TI, diggerlin wrote: I am sure purpose the calculation the variable `ArgGPRs`, it be calculated in the function `classifyArgumentType` , but never use it. https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -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 &TypeSize) const { + + assert(Ty->isAnyComplexType()); + llvm::Type *ElemTy; + unsigned SizeRegs; + + if (TypeSize == 64) { +ElemTy = llvm::Type::getInt64Ty(getVMContext()); +SizeRegs = 1; + } else { +ElemTy = llvm::Type::getInt32Ty(getVMContext()); +SizeRegs = (TypeSize + 31) / 32; + } + return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, SizeRegs)); +} + +ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty, +int &ArgGPRsLeft) const { + + assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (isComplexInRegABI && Ty->isAnyComplexType() && + TypeSize <= RLen * ArgGPRsLeft) { +ArgGPRsLeft -= TypeSize / RLen; +return handleComplex(Ty, TypeSize); + } + + if (isAggregateTypeForABI(Ty)) { +if (ArgGPRsLeft) + ArgGPRsLeft -= 1; +// Records with non-trivial destructors/copy-constructors should not be +// passed by value. +if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { + return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); +} +return getNaturalAlignIndirect(Ty); + } + + if (!Ty->isFloatingType()) { +if (TypeSize > RLen && TypeSize <= 2 * RLen) + ArgGPRsLeft -= 2; +else + ArgGPRsLeft--; + } + + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs()) +Ty = EnumTy->getDecl()->getIntegerType(); + + if (const auto *EIT = Ty->getAs()) +if (EIT->getNumBits() > +Context.getTypeSize(Context.getTargetInfo().hasInt128Type() +? Context.Int128Ty +: Context.LongLongTy)) + return getNaturalAlignIndirect(Ty); + + return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) diggerlin wrote: since most of the code is same as `DefaultABIInfo::classifyArgumentType(QualType Ty)` , I suggest rewrite the function `PPC32_SVR4_ABIInfo::classifyArgumentType` as ``` ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty, int &ArgGPRsLeft) const { special functionality code of the function here . DefaultABIInfo::classifyArgumentType(Ty) } ``` duplication code is not a good idea. https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin deleted https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin deleted https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -78,6 +78,13 @@ class CodeGenOptions : public CodeGenOptionsBase { SRCK_InRegs// Small structs in registers (-freg-struct-return). }; + enum ComplexArgumentConventionKind { +CMPLX_Default, +CMPLX_OnStack, diggerlin wrote: it looks you define the `CMPLX_Default` and ` CMPLX_OnStack` , but never use them. https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -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 &TypeSize) const; public: PPC32_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, 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 &ArgGPRsLeft) const; void computeInfo(CGFunctionInfo &FI) const override { + +int ArgGPRsLeft = NumArgGPRs; diggerlin wrote: nit: move the definition to the closest first be used. https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin deleted https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -0,0 +1,132 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 + +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -target-cpu pwr8 \ +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-DEF +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -target-cpu pwr8 -fcomplex-ppc-gnu-abi \ diggerlin wrote: ditto https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -0,0 +1,132 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 + +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -target-cpu pwr8 \ diggerlin wrote: do you really need `-target-cpu pwr8` since the test case only check generated IR? https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -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 &TypeSize) const { + + assert(Ty->isAnyComplexType()); + llvm::Type *ElemTy; + unsigned SizeRegs; + + if (TypeSize == 64) { +ElemTy = llvm::Type::getInt64Ty(getVMContext()); +SizeRegs = 1; + } else { +ElemTy = llvm::Type::getInt32Ty(getVMContext()); +SizeRegs = (TypeSize + 31) / 32; + } + return ABIArgInfo::getDirect(llvm::ArrayType::get(ElemTy, SizeRegs)); +} + +ABIArgInfo PPC32_SVR4_ABIInfo::classifyArgumentType(QualType Ty, +int &ArgGPRsLeft) const { + + assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (isComplexInRegABI && Ty->isAnyComplexType() && + TypeSize <= RLen * ArgGPRsLeft) { +ArgGPRsLeft -= TypeSize / RLen; +return handleComplex(Ty, TypeSize); + } + + if (isAggregateTypeForABI(Ty)) { diggerlin wrote: it look, you only has Complex as parameter in your test case .for example `_Complex float foo1(_Complex float x)` I think you need more test case with other parameters to test the functionality of function `classifyArgumentType()` https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/82809 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/82809 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From cef79b36bcb3f4b7452d01aafdf111ff0e50605d Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/5] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 12 ++ clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 99 --- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 154 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 - .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 + .../llvm/TargetParser/PPCTargetParser.def | 73 - 9 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..17b462c73bfc6a 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,18 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, OP, VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..cf4ddc52ff362a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16560,7 +16560,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16568,24 +16568,61 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + + FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); + FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); +} else if (SupportMethod == SYS_CALL) { + llvm::FunctionType *FTy = + llvm::FunctionType::get(Int64Ty, Int32Ty, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunc
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
@@ -16560,32 +16560,69 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + + FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); + FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); +} else if (SupportMethod == SYS_CALL) { + llvm::FunctionType *FTy = + llvm::FunctionType::get(Int64Ty, Int32Ty, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunction(FTy, "getsystemcfg"); + + FieldValue = + Builder.CreateCall(Func, {ConstantInt::get(Int32Ty, FieldIdx)}); +} + +if (Mask) + FieldValue = Builder.CreateAnd(FieldValue, Mask); -llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); -llvm::Constant *SysConf = -CGM.CreateRuntimeVariable(STy, "_system_configuration"); +CmpInst::Predicate PreOp; +switch (CompOp) { +case COMP_EQ: + PreOp = ICmpInst::ICMP_EQ; + break; +case COMP_GT: + PreOp = ICmpInst::ICMP_UGT; + break; +case COMP_GE: + PreOp = ICmpInst::ICMP_UGE; + break; +case COMP_NE: + PreOp = ICmpInst::ICMP_NE; + break; +default: + llvm_unreachable("Compare type is not correct in PPCTargetParser.def."); +} -// Grab the appropriate field from _system_configuration. -llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), - ConstantInt::get(Int32Ty, FieldIdx)}; +llvm::Type *ValueType = FieldValue->getType(); diggerlin wrote: I will add assert. thanks https://github.com/llvm/llvm-project/pull/82809 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From cef79b36bcb3f4b7452d01aafdf111ff0e50605d Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/6] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 12 ++ clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 99 --- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 154 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 - .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 + .../llvm/TargetParser/PPCTargetParser.def | 73 - 9 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..17b462c73bfc6a 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,18 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, OP, VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..cf4ddc52ff362a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16560,7 +16560,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16568,24 +16568,61 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + + FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); + FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); +} else if (SupportMethod == SYS_CALL) { + llvm::FunctionType *FTy = + llvm::FunctionType::get(Int64Ty, Int32Ty, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunc
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From cef79b36bcb3f4b7452d01aafdf111ff0e50605d Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/7] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 12 ++ clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 99 --- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 154 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 - .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 + .../llvm/TargetParser/PPCTargetParser.def | 73 - 9 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..17b462c73bfc6a 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,18 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, OP, VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..cf4ddc52ff362a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16560,7 +16560,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16568,24 +16568,61 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + + FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); + FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); +} else if (SupportMethod == SYS_CALL) { + llvm::FunctionType *FTy = + llvm::FunctionType::get(Int64Ty, Int32Ty, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunc
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
@@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { diggerlin wrote: > Does this need to be a separate function if it is the same as > `supportsCpuIs()`? Can they be combined? yes, we can combined them , but it need another NFC to do it. since not only PPC.h has the two function but also X86.h https://github.com/llvm/llvm-project/pull/82809 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Implement a subset of builtin_cpu_supports() features (PR #82809)
https://github.com/diggerlin updated https://github.com/llvm/llvm-project/pull/82809 >From cef79b36bcb3f4b7452d01aafdf111ff0e50605d Mon Sep 17 00:00:00 2001 From: zhijian Date: Fri, 23 Feb 2024 13:23:18 -0500 Subject: [PATCH 1/8] Implement a subset of builtin_cpu_supports() features --- clang/lib/Basic/Targets/PPC.cpp | 12 ++ clang/lib/Basic/Targets/PPC.h | 9 +- clang/lib/CodeGen/CGBuiltin.cpp | 99 --- clang/lib/Sema/SemaChecking.cpp | 6 +- clang/test/CodeGen/aix-builtin-cpu-is.c | 4 +- clang/test/CodeGen/aix-builtin-cpu-supports.c | 154 ++ clang/test/Sema/aix-builtin-cpu-unsupports.c | 40 - .../test/Sema/builtin-cpu-unsupports-AIX-Os.c | 9 + .../llvm/TargetParser/PPCTargetParser.def | 73 - 9 files changed, 369 insertions(+), 37 deletions(-) create mode 100644 clang/test/CodeGen/aix-builtin-cpu-supports.c create mode 100644 clang/test/Sema/builtin-cpu-unsupports-AIX-Os.c diff --git a/clang/lib/Basic/Targets/PPC.cpp b/clang/lib/Basic/Targets/PPC.cpp index aebe51bfa4daad..17b462c73bfc6a 100644 --- a/clang/lib/Basic/Targets/PPC.cpp +++ b/clang/lib/Basic/Targets/PPC.cpp @@ -897,6 +897,18 @@ ArrayRef PPCTargetInfo::getTargetBuiltins() const { } bool PPCTargetInfo::validateCpuSupports(StringRef FeatureStr) const { + llvm::Triple Triple = getTriple(); + if (Triple.isOSAIX()) { +#define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, OP, VALUE) \ + .Case(NAME, true) +return llvm::StringSwitch(FeatureStr) +#include "llvm/TargetParser/PPCTargetParser.def" +.Default(false); + } + + assert(Triple.isOSLinux() && + "__builtin_cpu_supports() is only supported for AIX and Linux."); + #define PPC_LNX_FEATURE(NAME, DESC, ENUMNAME, ENUMVAL, HWCAPN) .Case(NAME, true) return llvm::StringSwitch(FeatureStr) #include "llvm/TargetParser/PPCTargetParser.def" diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 70683916a8b04f..39b52d362f36b8 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -364,7 +364,14 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo { // have Glibc since it is Glibc that provides the HWCAP[2] in the auxv. static constexpr int MINIMUM_AIX_OS_MAJOR = 7; static constexpr int MINIMUM_AIX_OS_MINOR = 2; - bool supportsCpuSupports() const override { return getTriple().isOSGlibc(); } + bool supportsCpuSupports() const override { +llvm::Triple Triple = getTriple(); +// AIX 7.2 is the minimum requirement to support __builtin_cpu_supports(). +return Triple.isOSGlibc() || + (Triple.isOSAIX() && +!Triple.isOSVersionLT(MINIMUM_AIX_OS_MAJOR, MINIMUM_AIX_OS_MINOR)); + } + bool supportsCpuIs() const override { llvm::Triple Triple = getTriple(); // AIX 7.2 is the minimum requirement to support __builtin_cpu_is(). diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..cf4ddc52ff362a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -16560,7 +16560,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, #include "llvm/TargetParser/PPCTargetParser.def" auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx, - unsigned CompOp, + unsigned Mask, unsigned CompOp, unsigned OpValue) -> Value * { if (SupportMethod == AIX_BUILTIN_PPC_FALSE) return llvm::ConstantInt::getFalse(ConvertType(E->getType())); @@ -16568,24 +16568,61 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, if (SupportMethod == AIX_BUILTIN_PPC_TRUE) return llvm::ConstantInt::getTrue(ConvertType(E->getType())); -assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod."); -assert((CompOp == COMP_EQ) && "Only equal comparisons are supported."); +assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod."); + +llvm::Value *FieldValue = nullptr; +if (SupportMethod == USE_SYS_CONF) { + llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE); + llvm::Constant *SysConf = + CGM.CreateRuntimeVariable(STy, "_system_configuration"); + + // Grab the appropriate field from _system_configuration. + llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), + ConstantInt::get(Int32Ty, FieldIdx)}; + + FieldValue = Builder.CreateGEP(STy, SysConf, Idxs); + FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue, + CharUnits::fromQuantity(4)); +} else if (SupportMethod == SYS_CALL) { + llvm::FunctionType *FTy = + llvm::FunctionType::get(Int64Ty, Int32Ty, false); + llvm::FunctionCallee Func = + CGM.CreateRuntimeFunc
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin deleted https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin deleted https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -337,12 +347,58 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t &TypeSize) 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 &ArgGPRsLeft) const { + assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (IsComplexInRegABI && Ty->isAnyComplexType() && + TypeSize <= RegLen * ArgGPRsLeft) { +assert(Ty->isAnyComplexType() && "Ty must be Complex type."); +ArgGPRsLeft -= TypeSize / RegLen; +return handleComplex(TypeSize); + } + + if (ArgGPRsLeft) { +// Records with non-trivial destructors/copy-constructors should not be +// passed by value. +if (isAggregateTypeForABI(Ty)) + ArgGPRsLeft -= 1; +else if (!Ty->isFloatingType()) { + // For other premitive types. + if (TypeSize > RegLen && TypeSize <= 2 * RegLen) +ArgGPRsLeft -= TypeSize / RegLen; diggerlin wrote: for a test case `foo6(_Complex long double foo4(int x1, long long y1, int x2, _Complex double z,)` `int x1` will have r3, `long long y1` will have r5,r6 (skip r4 since it is even, for 64bit integer need to start start odd register.) `int x2` will have r7, ` _Complex double z` need to occupy 4 registers, there is no enough register , it can not pass `_Complex double z` in r8,r9,r10 , you have to pass ` _Complex double z` in by pointer (you can not call `handleComplex()`). but in your code, ArgGPRsLeft is 7 after int x1, ArgGPRsLeft is 5 after long long y1 ArgGPRsLeft is 4 after int x2 there is still have 4 registers left for ` _Complex double z`, you can call `handleComplex()`, you will pass ` _Complex double z` by value can you check how gcc deal with this case `foo6(_Complex long double foo4(int x1, long long y1, int x2, _Complex double z,)` ? https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -337,12 +347,58 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t &TypeSize) 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 &ArgGPRsLeft) const { + assert(ArgGPRsLeft <= NumArgGPRs && "Arg GPR tracking underflow"); + Ty = useFirstFieldIfTransparentUnion(Ty); + + ASTContext &Context = getContext(); + + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (IsComplexInRegABI && Ty->isAnyComplexType() && + TypeSize <= RegLen * ArgGPRsLeft) { +assert(Ty->isAnyComplexType() && "Ty must be Complex type."); +ArgGPRsLeft -= TypeSize / RegLen; +return handleComplex(TypeSize); + } + + if (ArgGPRsLeft) { +// Records with non-trivial destructors/copy-constructors should not be +// passed by value. +if (isAggregateTypeForABI(Ty)) + ArgGPRsLeft -= 1; +else if (!Ty->isFloatingType()) { + // For other premitive types. + if (TypeSize > RegLen && TypeSize <= 2 * RegLen) +ArgGPRsLeft -= TypeSize / RegLen; diggerlin wrote: for a test case `foo6(_Complex long double foo4(int x1, long long y1, int x2, _Complex double z,)` `int x1` will have r3, `long long y1` will have r5,r6 (skip r4 since it is even, for 64bit integer need to start start odd register.) `int x2` will have r7, ` _Complex double z` need to occupy 4 registers, there is no enough register , it can not pass `_Complex double z` in r8,r9,r10 , you have to pass ` _Complex double z` in by pointer (you can not call `handleComplex()`). but in your code, ArgGPRsLeft is 7 after int x1, ArgGPRsLeft is 5 after long long y1 ArgGPRsLeft is 4 after int x2 there is still have 4 registers left for ` _Complex double z`, you can call `handleComplex()`, you will pass ` _Complex double z` by value can you check how gcc deal with this case `foo6(_Complex long double foo4(int x1, long long y1, int x2, _Complex double z,)` ? https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -421,6 +503,11 @@ ABIArgInfo PPC32_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { } } + bool IsComplexInRegABI = + getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR; + if (IsComplexInRegABI && RetTy->isAnyComplexType()) diggerlin wrote: you do not need to introduce a new variable `IsComplexInRegABI` here since it only be used once. change to `if ((getCodeGenOpts().getComplexInRegABI() == CodeGenOptions::CMPLX_InGPR) && RetTy->isAnyComplexType())` https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -0,0 +1,306 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 + +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu \ +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-DEF +// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fcomplex-ppc-gnu-abi \ +// RUN: -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK-GNU + +// CHECK-DEF-LABEL: define dso_local void @foo1 +// CHECK-DEF-SAME: (ptr dead_on_unwind noalias writable sret({ float, float }) align 4 [[AGG_RESULT:%.*]], ptr noundef byval({ float, float }) align 4 [[X:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-DEF-NEXT: entry: +// CHECK-DEF-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[X]], i32 0, i32 0 +// CHECK-DEF-NEXT:[[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4 +// CHECK-DEF-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[X]], i32 0, i32 1 +// CHECK-DEF-NEXT:[[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4 +// CHECK-DEF-NEXT:[[AGG_RESULT_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-DEF-NEXT:store float [[X_REAL]], ptr [[AGG_RESULT_REALP]], align 4 +// CHECK-DEF-NEXT:store float [[X_IMAG]], ptr [[AGG_RESULT_IMAGP]], align 4 +// CHECK-DEF-NEXT:[[AGG_RESULT_REALP1:%.*]] = getelementptr inbounds { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-DEF-NEXT:[[AGG_RESULT_REAL:%.*]] = load float, ptr [[AGG_RESULT_REALP1]], align 4 +// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP2:%.*]] = getelementptr inbounds { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-DEF-NEXT:[[AGG_RESULT_IMAG:%.*]] = load float, ptr [[AGG_RESULT_IMAGP2]], align 4 +// CHECK-DEF-NEXT:[[AGG_RESULT_REALP3:%.*]] = getelementptr inbounds { float, float }, ptr [[AGG_RESULT]], i32 0, i32 0 +// CHECK-DEF-NEXT:[[AGG_RESULT_IMAGP4:%.*]] = getelementptr inbounds { float, float }, ptr [[AGG_RESULT]], i32 0, i32 1 +// CHECK-DEF-NEXT:store float [[AGG_RESULT_REAL]], ptr [[AGG_RESULT_REALP3]], align 4 +// CHECK-DEF-NEXT:store float [[AGG_RESULT_IMAG]], ptr [[AGG_RESULT_IMAGP4]], align 4 +// CHECK-DEF-NEXT:ret void +// +// CHECK-GNU-LABEL: define dso_local [1 x i64] @foo1 +// CHECK-GNU-SAME: ([1 x i64] noundef [[X_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-GNU-NEXT: entry: +// CHECK-GNU-NEXT:[[RETVAL:%.*]] = alloca { float, float }, align 4 +// CHECK-GNU-NEXT:[[X:%.*]] = alloca { float, float }, align 4 +// CHECK-GNU-NEXT:store [1 x i64] [[X_COERCE]], ptr [[X]], align 4 +// CHECK-GNU-NEXT:[[X_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[X]], i32 0, i32 0 +// CHECK-GNU-NEXT:[[X_REAL:%.*]] = load float, ptr [[X_REALP]], align 4 +// CHECK-GNU-NEXT:[[X_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[X]], i32 0, i32 1 +// CHECK-GNU-NEXT:[[X_IMAG:%.*]] = load float, ptr [[X_IMAGP]], align 4 +// CHECK-GNU-NEXT:[[RETVAL_REALP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 0 +// CHECK-GNU-NEXT:[[RETVAL_IMAGP:%.*]] = getelementptr inbounds { float, float }, ptr [[RETVAL]], i32 0, i32 1 +// CHECK-GNU-NEXT:store float [[X_REAL]], ptr [[RETVAL_REALP]], align 4 +// CHECK-GNU-NEXT:store float [[X_IMAG]], ptr [[RETVAL_IMAGP]], align 4 +// CHECK-GNU-NEXT:[[TMP0:%.*]] = load [1 x i64], ptr [[RETVAL]], align 4 +// CHECK-GNU-NEXT:ret [1 x i64] [[TMP0]] +// +_Complex float foo1(_Complex float x) { diggerlin wrote: general question for all test scenario: can you add a caller function to call the function to check whether organize the call parameter and pass the parameter as called function need ? https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
@@ -396,12 +405,85 @@ CharUnits PPC32_SVR4_ABIInfo::getParamTypeAlignment(QualType Ty) const { return CharUnits::fromQuantity(4); } +ABIArgInfo PPC32_SVR4_ABIInfo::handleComplex(uint64_t &TypeSize) 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 &ArgGPRsLeft) 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 &Context = getContext(); + uint64_t TypeSize = Context.getTypeSize(Ty); + + if (Ty->isAnyComplexType()) { +// If gr is even set gr = gr + 1 for TypeSize=64. +if (TypeSize == 64 && ArgGPRsLeft % 2 == 1) + --ArgGPRsLeft; + +if (TypeSize <= RegLen * ArgGPRsLeft) { + ArgGPRsLeft -= TypeSize / RegLen; + return handleComplex(TypeSize); +} + } + + // Records with non-trivial destructors/copy-constructors should not be + // passed by value. + if (isAggregateTypeForABI(Ty)) +--ArgGPRsLeft; + else if (!Ty->isFloatingType()) { +// For other primitive types. +if (TypeSize == 64) { + // If gr is even set gr = gr + 1 for TypeSize=64. + if (ArgGPRsLeft % 2 == 1) +--ArgGPRsLeft; + if (TypeSize <= ArgGPRsLeft * RegLen) { +ArgGPRsLeft -= TypeSize / RegLen; + } +} else + --ArgGPRsLeft; diggerlin wrote: it look that if TypeSize=128, you only do `--ArgGPRsLeft`, it pass by pointer ? https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][PowerPC] Add flag to enable compatibility with GNU for complex arguments (PR #77732)
https://github.com/diggerlin edited https://github.com/llvm/llvm-project/pull/77732 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits