Skip to content

Commit 1655d51

Browse files
phoebewangc-rhodes
authored andcommitted
[X86][APX] Disable PP2/PPX generation on Windows (#178122)
The PUSH2/POP2/PPX instructions for APX require updates to the Microsoft Windows OS x64 calling convention documented at https://learn.microsoft.com/en-us/cpp/build/exception-handling-x64?view=msvc-170 due to lack of suitable unwinder opcodes that can support APX PUSH2/POP2/PPX. The PR request disables this support by default for code robustness; workloads that choose to explicitly enable this support can change the default behavior by explicitly specifying the flag options that enable this support e.g. for experimentation or code paths that do not need unwinder support. (cherry picked from commit 2f3935b)
1 parent 25b8d52 commit 1655d51

File tree

8 files changed

+56
-23
lines changed

8 files changed

+56
-23
lines changed

clang/include/clang/Options/Options.td

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7017,12 +7017,8 @@ def mapx_features_EQ : CommaJoined<["-"], "mapx-features=">, Group<m_x86_Feature
70177017
HelpText<"Enable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu">, Visibility<[ClangOption, CLOption, FlangOption]>;
70187018
def mno_apx_features_EQ : CommaJoined<["-"], "mno-apx-features=">, Group<m_x86_Features_Group>,
70197019
HelpText<"Disable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu">, Visibility<[ClangOption, CLOption, FlangOption]>;
7020-
def mapxf : Flag<["-"], "mapxf">, Alias<mapx_features_EQ>,
7021-
AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf","zu"]>,
7022-
Group<m_x86_Features_Group>;
7023-
def mno_apxf : Flag<["-"], "mno-apxf">, Alias<mno_apx_features_EQ>,
7024-
AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf","zu"]>,
7025-
Group<m_x86_Features_Group>;
7020+
def mapxf : Flag<["-"], "mapxf">, Group<m_x86_Features_Group>;
7021+
def mno_apxf : Flag<["-"], "mno-apxf">, Group<m_x86_Features_Group>;
70267022
def mapx_inline_asm_use_gpr32 : Flag<["-"], "mapx-inline-asm-use-gpr32">, Group<m_Group>,
70277023
HelpText<"Enable use of GPR32 in inline assembly for APX">;
70287024
} // let Flags = [TargetSpecific]

clang/lib/Basic/Targets/X86.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,11 @@ bool X86TargetInfo::initFeatureMap(
164164
for (auto &F : CPUFeatures)
165165
setFeatureEnabled(Features, F, true);
166166

167+
if (Features.lookup("egpr") && getTriple().isOSWindows()) {
168+
setFeatureEnabled(Features, "push2pop2", false);
169+
setFeatureEnabled(Features, "ppx", false);
170+
}
171+
167172
std::vector<std::string> UpdatedFeaturesVec;
168173
for (const auto &Feature : FeaturesVec) {
169174
// Expand general-regs-only to -x86, -mmx and -sse
@@ -967,8 +972,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
967972
Builder.defineMacro("__CF__");
968973
if (HasZU)
969974
Builder.defineMacro("__ZU__");
970-
if (HasEGPR && HasPush2Pop2 && HasPPX && HasNDD && HasCCMP && HasNF && HasZU)
971-
Builder.defineMacro("__APX_F__");
975+
if (HasEGPR && HasNDD && HasCCMP && HasNF && HasZU)
976+
if (getTriple().isOSWindows() || (HasPush2Pop2 && HasPPX))
977+
Builder.defineMacro("__APX_F__");
972978
if (HasEGPR && HasInlineAsmUseGPR32)
973979
Builder.defineMacro("__APX_INLINE_ASM_USE_GPR32__");
974980

clang/lib/Driver/ToolChains/Arch/X86.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,35 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
252252
D.Diag(diag::err_drv_unsupported_opt_for_target)
253253
<< A->getSpelling() << Triple.getTriple();
254254

255-
if (A->getOption().matches(options::OPT_mapx_features_EQ) ||
255+
if (IsNegative)
256+
Name = Name.substr(3);
257+
if (A->getOption().matches(options::OPT_mapxf) ||
258+
A->getOption().matches(options::OPT_mno_apxf) ||
259+
A->getOption().matches(options::OPT_mapx_features_EQ) ||
256260
A->getOption().matches(options::OPT_mno_apx_features_EQ)) {
257261

262+
if (Name == "apxf") {
263+
if (IsNegative) {
264+
Features.insert(Features.end(),
265+
{"-egpr", "-ndd", "-ccmp", "-nf", "-zu"});
266+
if (!Triple.isOSWindows())
267+
Features.insert(Features.end(), {"-push2pop2", "-ppx"});
268+
} else {
269+
Features.insert(Features.end(),
270+
{"+egpr", "+ndd", "+ccmp", "+nf", "+zu"});
271+
if (!Triple.isOSWindows())
272+
Features.insert(Features.end(), {"+push2pop2", "+ppx"});
273+
274+
if (Not64Bit)
275+
D.Diag(diag::err_drv_unsupported_opt_for_target)
276+
<< StringRef("-mapxf") << Triple.getTriple();
277+
}
278+
continue;
279+
}
280+
258281
if (Not64Bit && !IsNegative)
259282
D.Diag(diag::err_drv_unsupported_opt_for_target)
260-
<< StringRef(A->getSpelling().str() + "|-mapxf")
261-
<< Triple.getTriple();
283+
<< StringRef("-mapx-features=") << Triple.getTriple();
262284

263285
for (StringRef Value : A->getValues()) {
264286
if (Value != "egpr" && Value != "push2pop2" && Value != "ppx" &&
@@ -272,8 +294,6 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple,
272294
}
273295
continue;
274296
}
275-
if (IsNegative)
276-
Name = Name.substr(3);
277297
Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name));
278298
}
279299

clang/test/Driver/cl-x86-flags.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,15 +213,16 @@ void f(void) {
213213
}
214214

215215

216-
// RUN: not %clang_cl -### --target=i386-pc-windows -mapx-features=ndd -- 2>&1 %s | FileCheck --check-prefix=NON-APX %s
217-
// RUN: not %clang_cl -### --target=i386-pc-windows -mapxf -- 2>&1 %s | FileCheck --check-prefix=NON-APX %s
216+
// RUN: not %clang_cl -### --target=i386-pc-windows -mapx-features=ndd -- 2>&1 %s | FileCheck --check-prefixes=NON-APX,NON-APXFS %s
217+
// RUN: not %clang_cl -### --target=i386-pc-windows -mapxf -- 2>&1 %s | FileCheck --check-prefixes=NON-APX,NON-APXF %s
218218
// RUN: %clang_cl -### --target=i386-pc-windows -mno-apxf -- 2>&1 %s > /dev/null
219-
// NON-APX: error: unsupported option '-mapx-features=|-mapxf' for target 'i386-pc-windows{{.*}}'
219+
// NON-APXF: error: unsupported option '-mapxf' for target 'i386-pc-windows{{.*}}'
220+
// NON-APXFS: error: unsupported option '-mapx-features=' for target 'i386-pc-windows{{.*}}'
220221
// NON-APX-NOT: error: {{.*}} -mapx-features=
221222

222223
// RUN: %clang_cl --target=x86_64-pc-windows -mapxf -### -- 2>&1 %s | FileCheck -check-prefix=APXF %s
223224
// RUN: %clang_cl --target=x86_64-pc-windows -mapxf -mno-apxf -### -- 2>&1 %s | FileCheck -check-prefix=NO-APXF %s
224225
// RUN: %clang_cl --target=x86_64-pc-windows -mapx-features=egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu -### -- 2>&1 %s | FileCheck -check-prefix=APXALL %s
225-
// APXF: "-target-feature" "+egpr" "-target-feature" "+push2pop2" "-target-feature" "+ppx" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+zu"
226-
// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-push2pop2" "-target-feature" "-ppx" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu"
226+
// APXF: "-target-feature" "+egpr" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+zu"
227+
// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu"
227228
// APXALL: "-target-feature" "+egpr" "-target-feature" "+push2pop2" "-target-feature" "+ppx" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+cf" "-target-feature" "+zu"

clang/test/Driver/x86-target-features.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -417,11 +417,12 @@
417417

418418
// RUN: not %clang -### --target=i386 -muintr %s 2>&1 | FileCheck --check-prefix=NON-UINTR %s
419419
// RUN: %clang -### --target=i386 -mno-uintr %s 2>&1 > /dev/null
420-
// RUN: not %clang -### --target=i386 -mapx-features=ndd %s 2>&1 | FileCheck --check-prefix=NON-APX %s
421-
// RUN: not %clang -### --target=i386 -mapxf %s 2>&1 | FileCheck --check-prefix=NON-APX %s
420+
// RUN: not %clang -### --target=i386 -mapx-features=ndd %s 2>&1 | FileCheck --check-prefixes=NON-APX,NON-APXFS %s
421+
// RUN: not %clang -### --target=i386 -mapxf %s 2>&1 | FileCheck --check-prefixes=NON-APX,NON-APXF %s
422422
// RUN: %clang -### --target=i386 -mno-apxf %s 2>&1 > /dev/null
423423
// NON-UINTR: error: unsupported option '-muintr' for target 'i386'
424-
// NON-APX: error: unsupported option '-mapx-features=|-mapxf' for target 'i386'
424+
// NON-APXF: error: unsupported option '-mapxf' for target 'i386'
425+
// NON-APXFS: error: unsupported option '-mapx-features=' for target 'i386'
425426
// NON-APX-NOT: error: {{.*}} -mapx-features=
426427

427428
// RUN: %clang --target=i386 -march=i386 -mharden-sls=return %s -### -o %t.o 2>&1 | FileCheck -check-prefixes=SLS-RET,NO-SLS %s
@@ -443,8 +444,8 @@
443444
// RUN: %clang --target=x86_64-unknown-linux-gnu -mno-apxf -mapxf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=APXF %s
444445
// RUN: %clang --target=x86_64-unknown-linux-gnu -mapxf -mno-apxf %s -### -o %t.o 2>&1 | FileCheck -check-prefix=NO-APXF %s
445446
//
446-
// APXF: "-target-feature" "+egpr" "-target-feature" "+push2pop2" "-target-feature" "+ppx" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+zu"
447-
// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-push2pop2" "-target-feature" "-ppx" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu"
447+
// APXF: "-target-feature" "+egpr" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+zu" "-target-feature" "+push2pop2" "-target-feature" "+ppx"
448+
// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu" "-target-feature" "-push2pop2" "-target-feature" "-ppx"
448449

449450
// RUN: %clang --target=x86_64-unknown-linux-gnu -mapx-features=egpr %s -### -o %t.o 2>&1 | FileCheck -check-prefix=EGPR %s
450451
// RUN: %clang --target=x86_64-unknown-linux-gnu -mapx-features=push2pop2 %s -### -o %t.o 2>&1 | FileCheck -check-prefix=PUSH2POP2 %s

llvm/lib/Target/X86/X86Subtarget.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU,
257257
std::string FullFS = X86_MC::ParseX86Triple(TargetTriple);
258258
assert(!FullFS.empty() && "Failed to parse X86 triple");
259259

260+
if (TargetTriple.isOSWindows())
261+
FullFS += ",-push2pop2,-ppx";
262+
260263
if (!FS.empty())
261264
FullFS = (Twine(FullFS) + "," + FS).str();
262265

llvm/lib/TargetParser/Host.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,8 +2167,12 @@ StringMap<bool> sys::getHostCPUFeatures() {
21672167
bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1);
21682168
bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1) && HasAPXSave;
21692169
Features["egpr"] = HasAPXF;
2170+
#ifndef _WIN32
2171+
// TODO: We may need to check OS or MSVC version once unwinder opcodes
2172+
// support PUSH2/POP2/PPX.
21702173
Features["push2pop2"] = HasAPXF;
21712174
Features["ppx"] = HasAPXF;
2175+
#endif
21722176
Features["ndd"] = HasAPXF;
21732177
Features["ccmp"] = HasAPXF;
21742178
Features["nf"] = HasAPXF;

llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=LIN-REF
33
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+push2pop2 | FileCheck %s --check-prefix=LIN
44
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+push2pop2,+ppx | FileCheck %s --check-prefix=LIN-PPX
5+
; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=diamondrapids | FileCheck %s --check-prefix=LIN-PPX
56
; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefix=WIN-REF
7+
; RUN: llc < %s -mtriple=x86_64-windows-msvc -mcpu=diamondrapids | FileCheck %s --check-prefix=WIN-REF
68
; RUN: llc < %s -mtriple=x86_64-windows-msvc -mattr=+push2pop2 | FileCheck %s --check-prefix=WIN
79
; RUN: llc < %s -mtriple=x86_64-windows-msvc -mattr=+push2pop2,+ppx | FileCheck %s --check-prefix=WIN-PPX
810

0 commit comments

Comments
 (0)