https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/179404
Backport 2f3935bcee6eaf7df8c85a21b7c0fbef967316b5 Requested by: @phoebewang >From 5548317f206002c9b6f90ba83eefda4e7d2e381c Mon Sep 17 00:00:00 2001 From: Phoebe Wang <[email protected]> Date: Mon, 2 Feb 2026 18:01:44 +0800 Subject: [PATCH] [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 2f3935bcee6eaf7df8c85a21b7c0fbef967316b5) --- clang/include/clang/Options/Options.td | 8 ++--- clang/lib/Basic/Targets/X86.cpp | 10 +++++-- clang/lib/Driver/ToolChains/Arch/X86.cpp | 30 +++++++++++++++---- clang/test/Driver/cl-x86-flags.c | 11 +++---- clang/test/Driver/x86-target-features.c | 11 +++---- llvm/lib/Target/X86/X86Subtarget.cpp | 3 ++ llvm/lib/TargetParser/Host.cpp | 4 +++ .../CodeGen/X86/apx/push2-pop2-cfi-seh.ll | 2 ++ 8 files changed, 56 insertions(+), 23 deletions(-) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index d48ca15864060..b2b8dc5d44a55 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -7017,12 +7017,8 @@ def mapx_features_EQ : CommaJoined<["-"], "mapx-features=">, Group<m_x86_Feature HelpText<"Enable features of APX">, Values<"egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu">, Visibility<[ClangOption, CLOption, FlangOption]>; 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,nf,cf,zu">, Visibility<[ClangOption, CLOption, FlangOption]>; -def mapxf : Flag<["-"], "mapxf">, Alias<mapx_features_EQ>, - AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf","zu"]>, - Group<m_x86_Features_Group>; -def mno_apxf : Flag<["-"], "mno-apxf">, Alias<mno_apx_features_EQ>, - AliasArgs<["egpr","push2pop2","ppx","ndd","ccmp","nf","zu"]>, - Group<m_x86_Features_Group>; +def mapxf : Flag<["-"], "mapxf">, Group<m_x86_Features_Group>; +def mno_apxf : Flag<["-"], "mno-apxf">, Group<m_x86_Features_Group>; def mapx_inline_asm_use_gpr32 : Flag<["-"], "mapx-inline-asm-use-gpr32">, Group<m_Group>, HelpText<"Enable use of GPR32 in inline assembly for APX">; } // let Flags = [TargetSpecific] diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index f00d435937b92..896a27a2c4458 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -164,6 +164,11 @@ bool X86TargetInfo::initFeatureMap( for (auto &F : CPUFeatures) setFeatureEnabled(Features, F, true); + if (Features.lookup("egpr") && getTriple().isOSWindows()) { + setFeatureEnabled(Features, "push2pop2", false); + setFeatureEnabled(Features, "ppx", false); + } + std::vector<std::string> UpdatedFeaturesVec; for (const auto &Feature : FeaturesVec) { // Expand general-regs-only to -x86, -mmx and -sse @@ -967,8 +972,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__CF__"); if (HasZU) Builder.defineMacro("__ZU__"); - if (HasEGPR && HasPush2Pop2 && HasPPX && HasNDD && HasCCMP && HasNF && HasZU) - Builder.defineMacro("__APX_F__"); + if (HasEGPR && HasNDD && HasCCMP && HasNF && HasZU) + if (getTriple().isOSWindows() || (HasPush2Pop2 && HasPPX)) + Builder.defineMacro("__APX_F__"); if (HasEGPR && HasInlineAsmUseGPR32) Builder.defineMacro("__APX_INLINE_ASM_USE_GPR32__"); diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index d6e6657c521f0..4fcb744db120d 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -252,13 +252,35 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getSpelling() << Triple.getTriple(); - if (A->getOption().matches(options::OPT_mapx_features_EQ) || + if (IsNegative) + Name = Name.substr(3); + if (A->getOption().matches(options::OPT_mapxf) || + A->getOption().matches(options::OPT_mno_apxf) || + A->getOption().matches(options::OPT_mapx_features_EQ) || A->getOption().matches(options::OPT_mno_apx_features_EQ)) { + if (Name == "apxf") { + if (IsNegative) { + Features.insert(Features.end(), + {"-egpr", "-ndd", "-ccmp", "-nf", "-zu"}); + if (!Triple.isOSWindows()) + Features.insert(Features.end(), {"-push2pop2", "-ppx"}); + } else { + Features.insert(Features.end(), + {"+egpr", "+ndd", "+ccmp", "+nf", "+zu"}); + if (!Triple.isOSWindows()) + Features.insert(Features.end(), {"+push2pop2", "+ppx"}); + + if (Not64Bit) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << StringRef("-mapxf") << Triple.getTriple(); + } + continue; + } + if (Not64Bit && !IsNegative) D.Diag(diag::err_drv_unsupported_opt_for_target) - << StringRef(A->getSpelling().str() + "|-mapxf") - << Triple.getTriple(); + << StringRef("-mapx-features=") << Triple.getTriple(); for (StringRef Value : A->getValues()) { if (Value != "egpr" && Value != "push2pop2" && Value != "ppx" && @@ -272,8 +294,6 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, } continue; } - if (IsNegative) - Name = Name.substr(3); Features.push_back(Args.MakeArgString((IsNegative ? "-" : "+") + Name)); } diff --git a/clang/test/Driver/cl-x86-flags.c b/clang/test/Driver/cl-x86-flags.c index 84270aae35f7a..5b32f17774e27 100644 --- a/clang/test/Driver/cl-x86-flags.c +++ b/clang/test/Driver/cl-x86-flags.c @@ -213,15 +213,16 @@ void f(void) { } -// RUN: not %clang_cl -### --target=i386-pc-windows -mapx-features=ndd -- 2>&1 %s | FileCheck --check-prefix=NON-APX %s -// RUN: not %clang_cl -### --target=i386-pc-windows -mapxf -- 2>&1 %s | FileCheck --check-prefix=NON-APX %s +// RUN: not %clang_cl -### --target=i386-pc-windows -mapx-features=ndd -- 2>&1 %s | FileCheck --check-prefixes=NON-APX,NON-APXFS %s +// RUN: not %clang_cl -### --target=i386-pc-windows -mapxf -- 2>&1 %s | FileCheck --check-prefixes=NON-APX,NON-APXF %s // RUN: %clang_cl -### --target=i386-pc-windows -mno-apxf -- 2>&1 %s > /dev/null -// NON-APX: error: unsupported option '-mapx-features=|-mapxf' for target 'i386-pc-windows{{.*}}' +// NON-APXF: error: unsupported option '-mapxf' for target 'i386-pc-windows{{.*}}' +// NON-APXFS: error: unsupported option '-mapx-features=' for target 'i386-pc-windows{{.*}}' // NON-APX-NOT: error: {{.*}} -mapx-features= // RUN: %clang_cl --target=x86_64-pc-windows -mapxf -### -- 2>&1 %s | FileCheck -check-prefix=APXF %s // RUN: %clang_cl --target=x86_64-pc-windows -mapxf -mno-apxf -### -- 2>&1 %s | FileCheck -check-prefix=NO-APXF %s // 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 -// APXF: "-target-feature" "+egpr" "-target-feature" "+push2pop2" "-target-feature" "+ppx" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+zu" -// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-push2pop2" "-target-feature" "-ppx" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu" +// APXF: "-target-feature" "+egpr" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+zu" +// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu" // 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" diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index f1660b1afb518..99eef8e4da172 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -417,11 +417,12 @@ // RUN: not %clang -### --target=i386 -muintr %s 2>&1 | FileCheck --check-prefix=NON-UINTR %s // RUN: %clang -### --target=i386 -mno-uintr %s 2>&1 > /dev/null -// RUN: not %clang -### --target=i386 -mapx-features=ndd %s 2>&1 | FileCheck --check-prefix=NON-APX %s -// RUN: not %clang -### --target=i386 -mapxf %s 2>&1 | FileCheck --check-prefix=NON-APX %s +// RUN: not %clang -### --target=i386 -mapx-features=ndd %s 2>&1 | FileCheck --check-prefixes=NON-APX,NON-APXFS %s +// RUN: not %clang -### --target=i386 -mapxf %s 2>&1 | FileCheck --check-prefixes=NON-APX,NON-APXF %s // RUN: %clang -### --target=i386 -mno-apxf %s 2>&1 > /dev/null // NON-UINTR: error: unsupported option '-muintr' for target 'i386' -// NON-APX: error: unsupported option '-mapx-features=|-mapxf' for target 'i386' +// NON-APXF: error: unsupported option '-mapxf' for target 'i386' +// NON-APXFS: error: unsupported option '-mapx-features=' for target 'i386' // NON-APX-NOT: error: {{.*}} -mapx-features= // 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 @@ // 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" "+nf" "-target-feature" "+zu" -// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-push2pop2" "-target-feature" "-ppx" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu" +// APXF: "-target-feature" "+egpr" "-target-feature" "+ndd" "-target-feature" "+ccmp" "-target-feature" "+nf" "-target-feature" "+zu" "-target-feature" "+push2pop2" "-target-feature" "+ppx" +// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-ndd" "-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu" "-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 diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 61f288ffb909b..4e2e98410f325 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -257,6 +257,9 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, StringRef TuneCPU, std::string FullFS = X86_MC::ParseX86Triple(TargetTriple); assert(!FullFS.empty() && "Failed to parse X86 triple"); + if (TargetTriple.isOSWindows()) + FullFS += ",-push2pop2,-ppx"; + if (!FS.empty()) FullFS = (Twine(FullFS) + "," + FS).str(); diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 5d4fa2c88153c..b01dca93dee0c 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2167,8 +2167,12 @@ StringMap<bool> sys::getHostCPUFeatures() { bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1); bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1) && HasAPXSave; Features["egpr"] = HasAPXF; +#ifndef _WIN32 + // TODO: We may need to check OS or MSVC version once unwinder opcodes + // support PUSH2/POP2/PPX. Features["push2pop2"] = HasAPXF; Features["ppx"] = HasAPXF; +#endif Features["ndd"] = HasAPXF; Features["ccmp"] = HasAPXF; Features["nf"] = HasAPXF; diff --git a/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll b/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll index d6d4db3509103..071b297b49dc1 100644 --- a/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll +++ b/llvm/test/CodeGen/X86/apx/push2-pop2-cfi-seh.ll @@ -2,7 +2,9 @@ ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=LIN-REF ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+push2pop2 | FileCheck %s --check-prefix=LIN ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mattr=+push2pop2,+ppx | FileCheck %s --check-prefix=LIN-PPX +; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=diamondrapids | FileCheck %s --check-prefix=LIN-PPX ; RUN: llc < %s -mtriple=x86_64-windows-msvc | FileCheck %s --check-prefix=WIN-REF +; RUN: llc < %s -mtriple=x86_64-windows-msvc -mcpu=diamondrapids | FileCheck %s --check-prefix=WIN-REF ; RUN: llc < %s -mtriple=x86_64-windows-msvc -mattr=+push2pop2 | FileCheck %s --check-prefix=WIN ; RUN: llc < %s -mtriple=x86_64-windows-msvc -mattr=+push2pop2,+ppx | FileCheck %s --check-prefix=WIN-PPX _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
