https://github.com/phoebewang updated https://github.com/llvm/llvm-project/pull/178122
>From 41a6d1d6ea244cc405531b9c15f885db18a0f805 Mon Sep 17 00:00:00 2001 From: Phoebe Wang <[email protected]> Date: Tue, 27 Jan 2026 14:30:40 +0800 Subject: [PATCH 1/4] [X86][APX] Disable PP2/PPX generation on Windows 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. --- clang/include/clang/Options/Options.td | 8 ++---- clang/lib/Basic/Targets/X86.cpp | 7 +++++- clang/lib/Driver/ToolChains/Arch/X86.cpp | 25 ++++++++++++++++--- clang/test/Driver/cl-x86-flags.c | 4 +-- clang/test/Driver/x86-target-features.c | 4 +-- llvm/lib/Target/X86/X86Subtarget.cpp | 3 +++ llvm/lib/TargetParser/Host.cpp | 2 ++ .../CodeGen/X86/apx/push2-pop2-cfi-seh.ll | 2 ++ 8 files changed, 40 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 43727236ed5a4..1f67441fb389b 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -7043,12 +7043,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..f0a1874be8111 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,7 +972,7 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__CF__"); if (HasZU) Builder.defineMacro("__ZU__"); - if (HasEGPR && HasPush2Pop2 && HasPPX && HasNDD && HasCCMP && HasNF && HasZU) + if (HasEGPR && HasNDD && HasCCMP && HasNF && HasZU) 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..7a0dea030615d 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -252,14 +252,33 @@ 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 (Not64Bit && !IsNegative) D.Diag(diag::err_drv_unsupported_opt_for_target) - << StringRef(A->getSpelling().str() + "|-mapxf") + << StringRef("-mapx-features=|-mapxf") << Triple.getTriple(); + 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"}); + } + continue; + } + for (StringRef Value : A->getValues()) { if (Value != "egpr" && Value != "push2pop2" && Value != "ppx" && Value != "ndd" && Value != "ccmp" && Value != "nf" && @@ -272,8 +291,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..f85828b370d9e 100644 --- a/clang/test/Driver/cl-x86-flags.c +++ b/clang/test/Driver/cl-x86-flags.c @@ -222,6 +222,6 @@ void f(void) { // 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..c0f2340d0f9fe 100644 --- a/clang/test/Driver/x86-target-features.c +++ b/clang/test/Driver/x86-target-features.c @@ -443,8 +443,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..7b1af1779a24a 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2167,8 +2167,10 @@ StringMap<bool> sys::getHostCPUFeatures() { bool HasAVX10 = HasLeaf7Subleaf1 && ((EDX >> 19) & 1); bool HasAPXF = HasLeaf7Subleaf1 && ((EDX >> 21) & 1) && HasAPXSave; Features["egpr"] = HasAPXF; +#ifndef _WIN32 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 >From 3b9f8fde90815523b1a501a852f9b1620c22b500 Mon Sep 17 00:00:00 2001 From: Phoebe Wang <[email protected]> Date: Tue, 27 Jan 2026 14:40:48 +0800 Subject: [PATCH 2/4] clang-format --- clang/lib/Driver/ToolChains/Arch/X86.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp index 7a0dea030615d..ce400ab0c86f8 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -261,8 +261,7 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, if (Not64Bit && !IsNegative) D.Diag(diag::err_drv_unsupported_opt_for_target) - << StringRef("-mapx-features=|-mapxf") - << Triple.getTriple(); + << StringRef("-mapx-features=|-mapxf") << Triple.getTriple(); if (Name == "apxf") { if (IsNegative) { >From 6cffdf883235d5a7a1e70a4c7e23cdeeabf616dd Mon Sep 17 00:00:00 2001 From: Phoebe Wang <[email protected]> Date: Tue, 27 Jan 2026 20:52:28 +0800 Subject: [PATCH 3/4] Add comment for host features --- llvm/lib/TargetParser/Host.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 7b1af1779a24a..b01dca93dee0c 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2168,6 +2168,8 @@ StringMap<bool> sys::getHostCPUFeatures() { 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 >From f7063f5cf6af53addb1edec63583dedf11a4e8f0 Mon Sep 17 00:00:00 2001 From: Phoebe Wang <[email protected]> Date: Thu, 29 Jan 2026 13:03:39 +0800 Subject: [PATCH 4/4] Address review comments --- clang/lib/Basic/Targets/X86.cpp | 3 ++- clang/lib/Driver/ToolChains/Arch/X86.cpp | 12 ++++++++---- clang/test/Driver/cl-x86-flags.c | 7 ++++--- clang/test/Driver/x86-target-features.c | 7 ++++--- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp index f0a1874be8111..896a27a2c4458 100644 --- a/clang/lib/Basic/Targets/X86.cpp +++ b/clang/lib/Basic/Targets/X86.cpp @@ -973,7 +973,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasZU) Builder.defineMacro("__ZU__"); if (HasEGPR && HasNDD && HasCCMP && HasNF && HasZU) - Builder.defineMacro("__APX_F__"); + 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 ce400ab0c86f8..4fcb744db120d 100644 --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -259,10 +259,6 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, A->getOption().matches(options::OPT_mapx_features_EQ) || A->getOption().matches(options::OPT_mno_apx_features_EQ)) { - if (Not64Bit && !IsNegative) - D.Diag(diag::err_drv_unsupported_opt_for_target) - << StringRef("-mapx-features=|-mapxf") << Triple.getTriple(); - if (Name == "apxf") { if (IsNegative) { Features.insert(Features.end(), @@ -274,10 +270,18 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, {"+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("-mapx-features=") << Triple.getTriple(); + for (StringRef Value : A->getValues()) { if (Value != "egpr" && Value != "push2pop2" && Value != "ppx" && Value != "ndd" && Value != "ccmp" && Value != "nf" && diff --git a/clang/test/Driver/cl-x86-flags.c b/clang/test/Driver/cl-x86-flags.c index f85828b370d9e..5b32f17774e27 100644 --- a/clang/test/Driver/cl-x86-flags.c +++ b/clang/test/Driver/cl-x86-flags.c @@ -213,10 +213,11 @@ 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 diff --git a/clang/test/Driver/x86-target-features.c b/clang/test/Driver/x86-target-features.c index c0f2340d0f9fe..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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
