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

Reply via email to