Skip to content

Commit

Permalink
[X86] Support CFE flags for APX features (llvm#74199)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
KanRobert authored Dec 4, 2023
1 parent 853682c commit 6d6baef
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 0 deletions.
9 changes: 9 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -5999,6 +5999,15 @@ 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">;
// Features egpr, push2pop2 and ppx are validated with llvm-test-suite && cpu2017 on Intel SDE.
// For stability, we turn on these features only for -mapxf. After a feature pass the validation,
// we will add it to -mapxf.
def mapxf : Flag<["-"], "mapxf">, Alias<mapx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx"]>;
def mno_apxf : Flag<["-"], "mno-apxf">, Alias<mno_apx_features_EQ>, AliasArgs<["egpr","push2pop2","ppx"]>;
} // let Flags = [TargetSpecific]

// VE feature flags
Expand Down
36 changes: 36 additions & 0 deletions clang/lib/Basic/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -927,6 +939,18 @@ 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 (HasPPX)
Builder.defineMacro("__PPX__");
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) {
Expand Down Expand Up @@ -1122,6 +1146,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);
}

Expand Down Expand Up @@ -1238,6 +1268,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);
}

Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Basic/Targets/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 15 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
39 changes: 39 additions & 0 deletions clang/test/Driver/x86-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,3 +422,42 @@

// RUN: touch %t.o
// RUN: %clang -fdriver-only -Werror --target=x86_64-pc-linux-gnu -mharden-sls=all %t.o -o /dev/null 2>&1 | count 0

// 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"
// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-push2pop2" "-target-feature" "-ppx"

// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=egpr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=EGPR %s
// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=push2pop2 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=PUSH2POP2 %s
// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=ppx %s -### -o %t.o 2>&1 | FileCheck -check-prefix=PPX %s
// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=ndd %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NDD %s
// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=ccmp %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CCMP %s
// RUN: %clang -target x86_64-unknown-linux-gnu -mapx-features=cf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CF %s
// EGPR: "-target-feature" "+egpr"
// PUSH2POP2: "-target-feature" "+push2pop2"
// PPX: "-target-feature" "+ppx"
// NDD: "-target-feature" "+ndd"
// CCMP: "-target-feature" "+ccmp"
// CF: "-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='
14 changes: 14 additions & 0 deletions clang/test/Preprocessor/x86_target_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -796,3 +796,17 @@
// RUN: %clang -target i386-unknown-linux-gnu -march=i386 -mno-rdpru -x c -E -dM -o - %s | FileCheck -check-prefix=NORDPRU %s

// NORDPRU-NOT: #define __RDPRU__ 1

// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=egpr -x c -E -dM -o - %s | FileCheck --check-prefix=EGPR %s
// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=push2pop2 -x c -E -dM -o - %s | FileCheck --check-prefix=PUSH2POP2 %s
// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=ppx -x c -E -dM -o - %s | FileCheck --check-prefix=PPX %s
// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=ndd -x c -E -dM -o - %s | FileCheck --check-prefix=NDD %s
// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=ccmp -x c -E -dM -o - %s | FileCheck --check-prefix=CCMP %s
// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=cf -x c -E -dM -o - %s | FileCheck --check-prefix=CF %s
// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapxf -x c -E -dM -o - %s | FileCheck --check-prefixes=EGPR,PUSH2POP2,PPX %s
// EGPR: #define __EGPR__ 1
// PPX: #define __PPX__ 1
// PUSH2POP2: #define __PUSH2POP2__ 1
// NDD: #define __NDD__ 1
// CCMP: #define __CCMP__ 1
// CF: #define __CF__ 1
1 change: 1 addition & 0 deletions llvm/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
-----------------------------
Expand Down
6 changes: 6 additions & 0 deletions llvm/include/llvm/TargetParser/X86TargetParser.def
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/X86/X86.td
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/TargetParser/X86TargetParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 6d6baef

Please sign in to comment.