[llvm] [clang] [X86] Support CFE flags for APX features (PR #74199)
Shengchen Kan via cfe-commits
cfe-commits at lists.llvm.org
Sun Dec 3 18:56:14 PST 2023
https://github.com/KanRobert updated https://github.com/llvm/llvm-project/pull/74199
>From 246d6e2bc3f6fb60623b5d4c3f07b53c628ed88a Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Sat, 2 Dec 2023 23:52:53 +0800
Subject: [PATCH 1/2] [X86] Support CFE flags for APX features
Positive options: -mapx-features=<comma-separated-features>
Negative options: -mno-apx-features=<comma-separated-features>
-m[no-]apx-features is designed to be able to control separate APX
features.
Besides, we also support the flag -m[no-]apxf, which can be used like an
alias of -m[no-]apx-features=< all APX features covered by CPUID APX_F>
Behaviour when positive and negative options are used together:
For boolean flags, the last one wins
-mapxf -mno-apxf -> -mno-apxf
-mno-apxf -mapxf -> -mapxf
For flags that take a set as arguments, it sets the mask by order of the
flags
-mapx-features=egpr,ndd -mno-apx-features=egpr -> -egpr,+ndd
-mapx-features=egpr -mno-apx-features=egpr,ndd -> -egpr,-ndd
-mno-apx-features=egpr -mapx-features=egpr,ndd -> +egpr,+ndd
-mno-apx-features=egpr,ndd -mapx-features=egpr -> -ndd,+egpr
The design is aligned with gcc
https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628905.html
---
clang/include/clang/Driver/Options.td | 6 ++++
clang/lib/Basic/Targets/X86.cpp | 34 +++++++++++++++++++
clang/lib/Basic/Targets/X86.h | 6 ++++
clang/lib/Driver/ToolChains/Arch/X86.cpp | 15 ++++++++
clang/test/Driver/apxf-target-features.c | 25 ++++++++++++++
.../llvm/TargetParser/X86TargetParser.def | 6 ++++
llvm/lib/Target/X86/X86.td | 6 ++++
llvm/lib/TargetParser/X86TargetParser.cpp | 8 +++++
8 files changed, 106 insertions(+)
create mode 100644 clang/test/Driver/apxf-target-features.c
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 19d04e82aed4d..631c5ad1c015d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5999,6 +5999,12 @@ def mno_gather : Flag<["-"], "mno-gather">, Group<m_Group>,
HelpText<"Disable generation of gather instructions in auto-vectorization(x86 only)">;
def mno_scatter : Flag<["-"], "mno-scatter">, Group<m_Group>,
HelpText<"Disable generation of scatter instructions in auto-vectorization(x86 only)">;
+def mapx_features_EQ : CommaJoined<["-"], "mapx-features=">, Group<m_x86_Features_Group>,
+ HelpText<"Enable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,cf">;
+def mno_apx_features_EQ : CommaJoined<["-"], "mno-apx-features=">, Group<m_x86_Features_Group>,
+ HelpText<"Disable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,cf">;
+def mapxf : Flag<["-"], "mapxf">, Alias<mapx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","cf"]>;
+def mno_apxf : Flag<["-"], "mno-apxf">, Alias<mno_apx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","cf"]>;
} // let Flags = [TargetSpecific]
// VE feature flags
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 85d0697ad63ca..9392211aa6fdf 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -428,6 +428,18 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasX87 = true;
} else if (Feature == "+fullbf16") {
HasFullBFloat16 = true;
+ } else if (Feature == "+egpr") {
+ HasEGPR = true;
+ } else if (Feature == "+push2pop2") {
+ HasPush2Pop2 = true;
+ } else if (Feature == "+ppx") {
+ HasPPX = true;
+ } else if (Feature == "+ndd") {
+ HasNDD = true;
+ } else if (Feature == "+ccmp") {
+ HasCCMP = true;
+ } else if (Feature == "+cf") {
+ HasCF = true;
}
X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
@@ -927,6 +939,16 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__USERMSR__");
if (HasCRC32)
Builder.defineMacro("__CRC32__");
+ if (HasEGPR)
+ Builder.defineMacro("__EGPR__");
+ if (HasPush2Pop2)
+ Builder.defineMacro("__PUSH2POP2__");
+ if (HasNDD)
+ Builder.defineMacro("__NDD__");
+ if (HasCCMP)
+ Builder.defineMacro("__CCMP__");
+ if (HasCF)
+ Builder.defineMacro("__CF__");
// Each case falls through to the previous one here.
switch (SSELevel) {
@@ -1122,6 +1144,12 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("xsavec", true)
.Case("xsaves", true)
.Case("xsaveopt", true)
+ .Case("egpr", true)
+ .Case("push2pop2", true)
+ .Case("ppx", true)
+ .Case("ndd", true)
+ .Case("ccmp", true)
+ .Case("cf", true)
.Default(false);
}
@@ -1238,6 +1266,12 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("xsaves", HasXSAVES)
.Case("xsaveopt", HasXSAVEOPT)
.Case("fullbf16", HasFullBFloat16)
+ .Case("egpr", HasEGPR)
+ .Case("push2pop2", HasPush2Pop2)
+ .Case("ppx", HasPPX)
+ .Case("ndd", HasNDD)
+ .Case("ccmp", HasCCMP)
+ .Case("cf", HasCF)
.Default(false);
}
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 99a64501d263c..0ab1c10833db2 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -168,6 +168,12 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasUINTR = false;
bool HasCRC32 = false;
bool HasX87 = false;
+ bool HasEGPR = false;
+ bool HasPush2Pop2 = false;
+ bool HasPPX = false;
+ bool HasNDD = false;
+ bool HasCCMP = false;
+ bool HasCF = false;
protected:
llvm::X86::CPUKind CPU = llvm::X86::CK_None;
diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp
index fbe665bdd5c8a..3e51b2b5ce864 100644
--- a/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp
@@ -270,6 +270,21 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
}
bool IsNegative = Name.startswith("no-");
+ if (A->getOption().matches(options::OPT_mapx_features_EQ) ||
+ A->getOption().matches(options::OPT_mno_apx_features_EQ)) {
+
+ for (StringRef Value : A->getValues()) {
+ if (Value == "egpr" || Value == "push2pop2" || Value == "ppx" ||
+ Value == "ndd" || Value == "ccmp" || Value == "cf") {
+ Features.push_back(
+ Args.MakeArgString((IsNegative ? "-" : "+") + Value));
+ continue;
+ }
+ D.Diag(clang::diag::err_drv_unsupported_option_argument)
+ << A->getSpelling() << Value;
+ }
+ continue;
+ }
if (IsNegative)
Name = Name.substr(3);
Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
diff --git a/clang/test/Driver/apxf-target-features.c b/clang/test/Driver/apxf-target-features.c
new file mode 100644
index 0000000000000..fa66b688f6220
--- /dev/null
+++ b/clang/test/Driver/apxf-target-features.c
@@ -0,0 +1,25 @@
+// RUN: %clang -target x86_64-unknown-linux-gnu -mapxf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=APXF %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mno-apxf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-APXF %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mno-apxf -mapxf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=APXF %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mapxf -mno-apxf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-APXF %s
+//
+// APXF: "-target-feature" "+egpr" "-target-feature" "+push2pop2" "-target-feature" "+ppx" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+cf"
+// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-push2pop2" "-target-feature" "-ppx" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-cf"
+
+// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=egpr,ndd %s -### -o %t.o 2>&1 | FileCheck -check-prefix=EGPR-NDD %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=egpr -mapx-features=ndd %s -### -o %t.o 2>&1 | FileCheck -check-prefix=EGPR-NDD %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mno-apx-features=egpr -mno-apx-features=ndd %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-EGPR-NO-NDD %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mno-apx-features=egpr -mapx-features=egpr,ndd %s -### -o %t.o 2>&1 | FileCheck -check-prefix=EGPR-NDD %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mno-apx-features=egpr,ndd -mapx-features=egpr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=EGPR-NO-NDD %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=egpr,ndd -mno-apx-features=egpr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-EGPR-NDD %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=egpr -mno-apx-features=egpr,ndd %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-EGPR-NO-NDD %s
+//
+// EGPR-NDD: "-target-feature" "+egpr" "-target-feature" "+ndd"
+// EGPR-NO-NDD: "-target-feature" "-ndd" "-target-feature" "+egpr"
+// NO-EGPR-NDD: "-target-feature" "+ndd" "-target-feature" "-egpr"
+// NO-EGPR-NO-NDD: "-target-feature" "-egpr" "-target-feature" "-ndd"
+
+// RUN: not %clang -target x86_64-unknown-linux-gnu -mapx-features=egpr,foo,bar %s -### -o %t.o 2>&1 | FileCheck -check-prefix=ERROR %s
+//
+// ERROR: unsupported argument 'foo' to option '-mapx-features='
+// ERROR: unsupported argument 'bar' to option '-mapx-features='
diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.def b/llvm/include/llvm/TargetParser/X86TargetParser.def
index 4204811a6a379..b58feafe4e8c2 100644
--- a/llvm/include/llvm/TargetParser/X86TargetParser.def
+++ b/llvm/include/llvm/TargetParser/X86TargetParser.def
@@ -246,6 +246,12 @@ X86_FEATURE (EVEX512, "evex512")
X86_FEATURE (AVX10_1, "avx10.1-256")
X86_FEATURE (AVX10_1_512, "avx10.1-512")
X86_FEATURE (USERMSR, "usermsr")
+X86_FEATURE (EGPR, "egpr")
+X86_FEATURE (Push2Pop2, "push2pop2")
+X86_FEATURE (PPX, "ppx")
+X86_FEATURE (NDD, "ndd")
+X86_FEATURE (CCMP, "ccmp")
+X86_FEATURE (CF, "cf")
// These features aren't really CPU features, but the frontend can set them.
X86_FEATURE (RETPOLINE_EXTERNAL_THUNK, "retpoline-external-thunk")
X86_FEATURE (RETPOLINE_INDIRECT_BRANCHES, "retpoline-indirect-branches")
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index 522d8513c9aff..5fd6828f43129 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -347,6 +347,12 @@ def FeaturePush2Pop2 : SubtargetFeature<"push2pop2", "HasPush2Pop2", "true",
"Support PUSH2/POP2 instructions">;
def FeaturePPX : SubtargetFeature<"ppx", "HasPPX", "true",
"Support Push-Pop Acceleration">;
+def FeatureNDD : SubtargetFeature<"ndd", "HasNDD", "true",
+ "Support non-destructive destination">;
+def FeatureCCMP : SubtargetFeature<"ccmp", "HasCCMP", "true",
+ "Support conditional cmp & test instructions">;
+def FeatureCF : SubtargetFeature<"cf", "HasCF", "true",
+ "Support conditional faulting">;
// Ivy Bridge and newer processors have enhanced REP MOVSB and STOSB (aka
// "string operations"). See "REP String Enhancement" in the Intel Software
diff --git a/llvm/lib/TargetParser/X86TargetParser.cpp b/llvm/lib/TargetParser/X86TargetParser.cpp
index cde36021ee958..085554f18b2b6 100644
--- a/llvm/lib/TargetParser/X86TargetParser.cpp
+++ b/llvm/lib/TargetParser/X86TargetParser.cpp
@@ -628,6 +628,14 @@ constexpr FeatureBitset ImpliedFeaturesAVX10_1 =
constexpr FeatureBitset ImpliedFeaturesAVX10_1_512 =
FeatureAVX10_1 | FeatureEVEX512;
+// APX Features
+constexpr FeatureBitset ImpliedFeaturesEGPR = {};
+constexpr FeatureBitset ImpliedFeaturesPush2Pop2 = {};
+constexpr FeatureBitset ImpliedFeaturesPPX = {};
+constexpr FeatureBitset ImpliedFeaturesNDD = {};
+constexpr FeatureBitset ImpliedFeaturesCCMP = {};
+constexpr FeatureBitset ImpliedFeaturesCF = {};
+
constexpr FeatureInfo FeatureInfos[X86::CPU_FEATURE_MAX] = {
#define X86_FEATURE(ENUM, STR) {{"+" STR}, ImpliedFeatures##ENUM},
#include "llvm/TargetParser/X86TargetParser.def"
>From 887f09124b3600347e87c80ca4d9a6136476c698 Mon Sep 17 00:00:00 2001
From: Shengchen Kan <shengchen.kan at intel.com>
Date: Mon, 4 Dec 2023 10:54:48 +0800
Subject: [PATCH 2/2] Update release notes for -mapxf
---
llvm/docs/ReleaseNotes.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 2c160f1707cbb..3c7a40ebd2953 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -156,6 +156,7 @@ Changes to the X86 Backend
* Support ISA of ``USER_MSR``.
* Support ISA of ``AVX10.1-256`` and ``AVX10.1-512``.
* ``-mcpu=pantherlake`` and ``-mcpu=clearwaterforest`` are now supported.
+* ``-mapxf`` is supported.
Changes to the OCaml bindings
-----------------------------
More information about the cfe-commits
mailing list