https://github.com/phoebewang created 
https://github.com/llvm/llvm-project/pull/186402

None

>From 0b76fbc26aee9ff67b92a7e3f9969bf357d40e75 Mon Sep 17 00:00:00 2001
From: Phoebe Wang <[email protected]>
Date: Fri, 13 Mar 2026 21:13:23 +0800
Subject: [PATCH] [X86][APX] Combine MOVABS+JMP to JMPABS when in no-PIC large
 code model

---
 clang/include/clang/Options/Options.td            |  4 ++--
 clang/lib/Basic/Targets/X86.cpp                   |  8 +++++++-
 clang/lib/Basic/Targets/X86.h                     |  1 +
 clang/lib/Driver/ToolChains/Arch/X86.cpp          |  6 +++---
 clang/test/Driver/cl-x86-flags.c                  |  8 ++++----
 clang/test/Driver/x86-target-features.c           |  6 ++++--
 clang/test/Preprocessor/predefined-arch-macros.c  |  4 ++++
 clang/test/Preprocessor/x86_target_features.c     |  4 +++-
 .../include/llvm/TargetParser/X86TargetParser.def |  1 +
 llvm/lib/Target/X86/X86.td                        |  4 ++++
 llvm/lib/Target/X86/X86InstrCompiler.td           |  8 ++++++++
 llvm/lib/Target/X86/X86InstrPredicates.td         |  1 +
 llvm/lib/Target/X86/X86MCInstLower.cpp            | 14 +++++++++++---
 llvm/lib/Target/X86/X86Subtarget.cpp              |  5 +++--
 llvm/lib/TargetParser/Host.cpp                    |  1 +
 llvm/lib/TargetParser/X86TargetParser.cpp         |  9 +++++----
 llvm/test/CodeGen/X86/tailcc-largecode.ll         | 15 ++++++++++-----
 17 files changed, 72 insertions(+), 27 deletions(-)

diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 4bbdd9c8c0e58..2f780f4ac6163 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -7168,9 +7168,9 @@ def mno_gather : Flag<["-"], "mno-gather">, 
Group<m_Group>,
 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,nf,cf,zu">,  Visibility<[ClangOption, 
CLOption, FlangOption]>;
+    HelpText<"Enable features of APX">, 
Values<"egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu,jmpabs">,  
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]>;
+    HelpText<"Disable features of APX">, 
Values<"egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu,jmpabs">, Visibility<[ClangOption, 
CLOption, FlangOption]>;
 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>,
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 6f88a428b1230..cb941c94c84a7 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -451,6 +451,8 @@ bool 
X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
       HasCF = true;
     } else if (Feature == "+zu") {
       HasZU = true;
+    } else if (Feature == "+jmpabs") {
+      HasJMPABS = true;
     } else if (Feature == "+branch-hint") {
       HasBranchHint = true;
     }
@@ -975,7 +977,9 @@ void X86TargetInfo::getTargetDefines(const LangOptions 
&Opts,
     Builder.defineMacro("__CF__");
   if (HasZU)
     Builder.defineMacro("__ZU__");
-  if (HasEGPR && HasNDD && HasCCMP && HasNF && HasZU)
+  if (HasJMPABS)
+    Builder.defineMacro("__JMPABS__");
+  if (HasEGPR && HasNDD && HasCCMP && HasNF && HasZU && HasJMPABS)
     if (getTriple().isOSWindows() || (HasPush2Pop2 && HasPPX))
       Builder.defineMacro("__APX_F__");
   if (HasEGPR && HasInlineAsmUseGPR32)
@@ -1177,6 +1181,7 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) 
const {
       .Case("nf", true)
       .Case("cf", true)
       .Case("zu", true)
+      .Case("jmpabs", true)
       .Default(false);
 }
 
@@ -1300,6 +1305,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
       .Case("nf", HasNF)
       .Case("cf", HasCF)
       .Case("zu", HasZU)
+      .Case("jmpabs", HasJMPABS)
       .Case("branch-hint", HasBranchHint)
       .Default(false);
 }
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index f99bbf363458f..20090757c10c7 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -177,6 +177,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public 
TargetInfo {
   bool HasNF = false;
   bool HasCF = false;
   bool HasZU = false;
+  bool HasJMPABS = false;
   bool HasInlineAsmUseGPR32 = false;
   bool HasBranchHint = false;
 
diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp 
b/clang/lib/Driver/ToolChains/Arch/X86.cpp
index c113da6733370..5891b56999420 100644
--- a/clang/lib/Driver/ToolChains/Arch/X86.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp
@@ -265,13 +265,13 @@ void x86::getX86TargetFeatures(const Driver &D, const 
llvm::Triple &Triple,
       if (IsNegative) {
         EGPROpt = EGPRFeature::Disabled;
         Features.insert(Features.end(),
-                        {"-egpr", "-ndd", "-ccmp", "-nf", "-zu"});
+                        {"-egpr", "-ndd", "-ccmp", "-nf", "-zu", "-jmpabs"});
         if (!Triple.isOSWindows())
           Features.insert(Features.end(), {"-push2pop2", "-ppx"});
       } else {
         EGPROpt = EGPRFeature::Enabled;
         Features.insert(Features.end(),
-                        {"+egpr", "+ndd", "+ccmp", "+nf", "+zu"});
+                        {"+egpr", "+ndd", "+ccmp", "+nf", "+zu", "+jmpabs"});
         if (!Triple.isOSWindows())
           Features.insert(Features.end(), {"+push2pop2", "+ppx"});
 
@@ -291,7 +291,7 @@ void x86::getX86TargetFeatures(const Driver &D, const 
llvm::Triple &Triple,
       for (StringRef Value : A->getValues()) {
         if (Value != "egpr" && Value != "push2pop2" && Value != "ppx" &&
             Value != "ndd" && Value != "ccmp" && Value != "nf" &&
-            Value != "cf" && Value != "zu")
+            Value != "cf" && Value != "zu" && Value != "jmpabs")
           D.Diag(clang::diag::err_drv_unsupported_option_argument)
               << A->getSpelling() << Value;
 
diff --git a/clang/test/Driver/cl-x86-flags.c b/clang/test/Driver/cl-x86-flags.c
index 5b32f17774e27..05960dd07612b 100644
--- a/clang/test/Driver/cl-x86-flags.c
+++ b/clang/test/Driver/cl-x86-flags.c
@@ -222,7 +222,7 @@ 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" "+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"
+// RUN: %clang_cl --target=x86_64-pc-windows 
-mapx-features=egpr,push2pop2,ppx,ndd,ccmp,nf,cf,zu,jmpabs -### -- 2>&1 %s | 
FileCheck -check-prefix=APXALL %s
+// APXF: "-target-feature" "+egpr" "-target-feature" "+ndd" "-target-feature" 
"+ccmp" "-target-feature" "+nf" "-target-feature" "+zu" "-target-feature" 
"+jmpabs"
+// NO-APXF: "-target-feature" "-egpr" "-target-feature" "-ndd" 
"-target-feature" "-ccmp" "-target-feature" "-nf" "-target-feature" "-zu" 
"-target-feature" "-jmpabs"
+// 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" 
"-target-feature" "+jmpabs"
diff --git a/clang/test/Driver/x86-target-features.c 
b/clang/test/Driver/x86-target-features.c
index 99eef8e4da172..b6ca38c92003f 100644
--- a/clang/test/Driver/x86-target-features.c
+++ b/clang/test/Driver/x86-target-features.c
@@ -444,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" "+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"
+// APXF: "-target-feature" "+egpr" "-target-feature" "+ndd" "-target-feature" 
"+ccmp" "-target-feature" "+nf" "-target-feature" "+zu"  "-target-feature" 
"+jmpabs" "-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" "-jmpabs" "-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
@@ -455,6 +455,7 @@
 // RUN: %clang --target=x86_64-unknown-linux-gnu -mapx-features=nf %s -### -o 
%t.o 2>&1 | FileCheck -check-prefix=NF %s
 // RUN: %clang --target=x86_64-unknown-linux-gnu -mapx-features=cf %s -### -o 
%t.o 2>&1 | FileCheck -check-prefix=CF %s
 // RUN: %clang --target=x86_64-unknown-linux-gnu -mapx-features=zu %s -### -o 
%t.o 2>&1 | FileCheck -check-prefix=ZU %s
+// RUN: %clang --target=x86_64-unknown-linux-gnu -mapx-features=jmpabs %s -### 
-o %t.o 2>&1 | FileCheck -check-prefix=JMPABS %s
 // EGPR: "-target-feature" "+egpr"
 // PUSH2POP2: "-target-feature" "+push2pop2"
 // PPX: "-target-feature" "+ppx"
@@ -463,6 +464,7 @@
 // NF: "-target-feature" "+nf"
 // CF: "-target-feature" "+cf"
 // ZU: "-target-feature" "+zu"
+// JMPABS: "-target-feature" "+jmpabs"
 
 // 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
diff --git a/clang/test/Preprocessor/predefined-arch-macros.c 
b/clang/test/Preprocessor/predefined-arch-macros.c
index be94eb064cf91..8ca7a18d852d4 100644
--- a/clang/test/Preprocessor/predefined-arch-macros.c
+++ b/clang/test/Preprocessor/predefined-arch-macros.c
@@ -1876,6 +1876,7 @@
 // CHECK_GNR_M32: #define __FMA__ 1
 // CHECK_GNR_M32: #define __GFNI__ 1
 // CHECK_GNR_M32: #define __INVPCID__ 1
+// CHECK_DMR_M32: #define __JMPABS__ 1
 // CHECK_GNR_M32: #define __LZCNT__ 1
 // CHECK_GNR_M32: #define __MMX__ 1
 // CHECK_GNR_M32: #define __MOVBE__ 1
@@ -1981,6 +1982,7 @@
 // CHECK_GNR_M64: #define __FMA__ 1
 // CHECK_GNR_M64: #define __GFNI__ 1
 // CHECK_GNR_M64: #define __INVPCID__ 1
+// CHECK_DMR_M64: #define __JMPABS__ 1
 // CHECK_GNR_M64: #define __LZCNT__ 1
 // CHECK_GNR_M64: #define __MMX__ 1
 // CHECK_GNR_M64: #define __MOVBE__ 1
@@ -2576,6 +2578,7 @@
 // CHECK_ARL_M32: #define __GFNI__ 1
 // CHECK_ARL_M32: #define __HRESET__ 1
 // CHECK_ARL_M32: #define __INVPCID__ 1
+// CHECK_NVL_M32: #define __JMPABS__ 1
 // CHECK_KL_M32:  #define __KL__ 1
 // CHECK_NKL_M32-NOT: __KL__
 // CHECK_ARL_M32: #define __LZCNT__ 1
@@ -2709,6 +2712,7 @@
 // CHECK_ARL_M64: #define __GFNI__ 1
 // CHECK_ARL_M64: #define __HRESET__ 1
 // CHECK_ARL_M64: #define __INVPCID__ 1
+// CHECK_NVL_M64: #define __JMPABS__ 1
 // CHECK_KL_M64:  #define __KL__ 1
 // CHECK_NKL_M64-NOT: __KL__
 // CHECK_ARL_M64: #define __LZCNT__ 1
diff --git a/clang/test/Preprocessor/x86_target_features.c 
b/clang/test/Preprocessor/x86_target_features.c
index 78f8b19459c2f..daf81d71e41c0 100644
--- a/clang/test/Preprocessor/x86_target_features.c
+++ b/clang/test/Preprocessor/x86_target_features.c
@@ -738,11 +738,13 @@
 // RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapx-features=nf 
-x c -E -dM -o - %s | FileCheck --check-prefix=NF %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 -mapx-features=zu 
-x c -E -dM -o - %s | FileCheck --check-prefix=ZU %s
-// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapxf -x c -E -dM 
-o - %s | FileCheck --check-prefixes=EGPR,PUSH2POP2,PPX,NDD,CCMP,NF,ZU,APXF %s
+// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 
-mapx-features=jmpabs -x c -E -dM -o - %s | FileCheck --check-prefix=JMPABS %s
+// RUN: %clang -target x86_64-unknown-unknown -march=x86-64 -mapxf -x c -E -dM 
-o - %s | FileCheck 
--check-prefixes=EGPR,PUSH2POP2,PPX,NDD,CCMP,NF,ZU,JMPABS,APXF %s
 // APXF: #define __APX_F__ 1
 // CCMP: #define __CCMP__ 1
 // CF: #define __CF__ 1
 // EGPR: #define __EGPR__ 1
+// JMPABS: #define __JMPABS__ 1
 // NDD: #define __NDD__ 1
 // NF: #define __NF__ 1
 // PPX: #define __PPX__ 1
diff --git a/llvm/include/llvm/TargetParser/X86TargetParser.def 
b/llvm/include/llvm/TargetParser/X86TargetParser.def
index bc05452400458..db03fc855df5a 100644
--- a/llvm/include/llvm/TargetParser/X86TargetParser.def
+++ b/llvm/include/llvm/TargetParser/X86TargetParser.def
@@ -268,6 +268,7 @@ X86_FEATURE       (PPX,                "ppx")
 X86_FEATURE       (NDD,                "ndd")
 X86_FEATURE       (EGPR,               "egpr")
 X86_FEATURE       (ZU,                 "zu")
+X86_FEATURE       (JMPABS,             "jmpabs")
 
 // These features aren't really CPU features, but the frontend can set them.
 X86_FEATURE       (RETPOLINE_EXTERNAL_THUNK,    "retpoline-external-thunk")
diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td
index eca763735c315..cac10d3ca0847 100644
--- a/llvm/lib/Target/X86/X86.td
+++ b/llvm/lib/Target/X86/X86.td
@@ -371,6 +371,8 @@ def FeatureCF : SubtargetFeature<"cf", "HasCF", "true",
                                  "Support conditional faulting">;
 def FeatureZU : SubtargetFeature<"zu", "HasZU", "true",
                                  "Support zero-upper SETcc/IMUL">;
+def FeatureJMPABS : SubtargetFeature<"jmpabs", "HasJMPABS", "true",
+                                     "Support 64-bit absolute JMP">;
 def FeatureUseGPR32InInlineAsm
     : SubtargetFeature<"inline-asm-use-gpr32", "UseInlineAsmGPR32", "true",
                        "Enable use of GPR32 in inline assembly for APX">;
@@ -1188,6 +1190,7 @@ def ProcessorFeatures {
                                                   FeaturePPX,
                                                   FeatureNDD,
                                                   FeatureNF,
+                                                  FeatureJMPABS,
                                                   FeatureMOVRS,
                                                   FeatureAMXMOVRS,
                                                   FeatureAMXAVX512,
@@ -1361,6 +1364,7 @@ def ProcessorFeatures {
                                                   FeatureNF,
                                                   FeatureNDD,
                                                   FeatureZU,
+                                                  FeatureJMPABS,
                                                   FeatureCCMP,
                                                   FeaturePREFETCHI];
   list<SubtargetFeature> NVLFeatures =
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td 
b/llvm/lib/Target/X86/X86InstrCompiler.td
index 65188c0295f8c..04fb7ba01edf9 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1426,6 +1426,14 @@ def : Pat<(X86tcret (i64 texternalsym:$dst), timm:$off),
           (TCRETURNdi64 texternalsym:$dst, timm:$off)>,
           Requires<[IsLP64]>;
 
+def : Pat<(X86tcret (i64 (X86Wrapper tglobaladdr:$dst)), timm:$off),
+          (TCRETURNdi64 tglobaladdr:$dst, timm:$off)>,
+          Requires<[IsNotPIC, HasJMPABS]>;
+
+def : Pat<(X86tcret (i64 (X86Wrapper texternalsym:$dst)), timm:$off),
+          (TCRETURNdi64 texternalsym:$dst, timm:$off)>,
+          Requires<[IsNotPIC, HasJMPABS]>;
+
 // Normal calls, with various flavors of addresses.
 def : Pat<(X86call (i32 tglobaladdr:$dst)),
           (CALLpcrel32 tglobaladdr:$dst)>;
diff --git a/llvm/lib/Target/X86/X86InstrPredicates.td 
b/llvm/lib/Target/X86/X86InstrPredicates.td
index 21e6bacbacee2..caa5880532760 100644
--- a/llvm/lib/Target/X86/X86InstrPredicates.td
+++ b/llvm/lib/Target/X86/X86InstrPredicates.td
@@ -51,6 +51,7 @@ def PreferLegacySetCC  : Predicate<"!Subtarget->hasZU() || "
 def PreferNoLegacySetCC : Predicate<"Subtarget->hasZU() && "
                                     "!Subtarget->preferLegacySetCC()">;
 def HasCF        : Predicate<"Subtarget->hasCF()">;
+def HasJMPABS    : Predicate<"Subtarget->hasJMPABS()">;
 def HasCMOV      : Predicate<"Subtarget->canUseCMOV()">;
 def NoCMOV       : Predicate<"!Subtarget->canUseCMOV()">;
 def HasNOPL      : Predicate<"Subtarget->hasNOPL()">;
diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp 
b/llvm/lib/Target/X86/X86MCInstLower.cpp
index 0d4131632ff56..6740a3e38eb6c 100644
--- a/llvm/lib/Target/X86/X86MCInstLower.cpp
+++ b/llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -370,7 +370,7 @@ MCOperand X86MCInstLower::LowerMachineOperand(const 
MachineInstr *MI,
 
 // Replace TAILJMP opcodes with their equivalent opcodes that have encoding
 // information.
-static unsigned convertTailJumpOpcode(unsigned Opcode) {
+static unsigned convertTailJumpOpcode(unsigned Opcode, bool IsLarge = false) {
   switch (Opcode) {
   case X86::TAILJMPr:
     Opcode = X86::JMP32r;
@@ -392,7 +392,7 @@ static unsigned convertTailJumpOpcode(unsigned Opcode) {
     break;
   case X86::TAILJMPd:
   case X86::TAILJMPd64:
-    Opcode = X86::JMP_1;
+    Opcode = IsLarge ? X86::JMPABS64i : X86::JMP_1;
     break;
   case X86::TAILJMPd_CC:
   case X86::TAILJMPd64_CC:
@@ -485,10 +485,18 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst 
&OutMI) const {
   case X86::TAILJMPr64:
   case X86::TAILJMPr64_REX:
   case X86::TAILJMPd:
-  case X86::TAILJMPd64:
     assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands!");
     OutMI.setOpcode(convertTailJumpOpcode(OutMI.getOpcode()));
     break;
+  case X86::TAILJMPd64: {
+    assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands!");
+    bool IsLarge = TM.getCodeModel() == CodeModel::Large;
+    assert((!IsLarge || AsmPrinter.getSubtarget().hasJMPABS()) &&
+           "Unexpected TAILJMPd64 in large code model without JMPABS");
+    OutMI.setOpcode(convertTailJumpOpcode(
+        OutMI.getOpcode(), TM.getCodeModel() == CodeModel::Large));
+    break;
+  }
   case X86::TAILJMPd_CC:
   case X86::TAILJMPd64_CC:
     assert(OutMI.getNumOperands() == 2 && "Unexpected number of operands!");
diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp 
b/llvm/lib/Target/X86/X86Subtarget.cpp
index 4e2e98410f325..a36fd214e33f5 100644
--- a/llvm/lib/Target/X86/X86Subtarget.cpp
+++ b/llvm/lib/Target/X86/X86Subtarget.cpp
@@ -264,8 +264,9 @@ void X86Subtarget::initSubtargetFeatures(StringRef CPU, 
StringRef TuneCPU,
     FullFS = (Twine(FullFS) + "," + FS).str();
 
   // Disable 64-bit only features in non-64-bit mode.
-  StringRef FeaturesIn64BitOnly[] = {
-      "egpr", "push2pop2", "ppx", "ndd", "ccmp", "nf", "cf", "zu", "uintr"};
+  StringRef FeaturesIn64BitOnly[] = {"egpr",   "push2pop2", "ppx", "ndd",
+                                     "ccmp",   "nf",        "cf",  "zu",
+                                     "jmpabs", "uintr"};
   if (FullFS.find("-64bit-mode") != std::string::npos)
     for (StringRef F : FeaturesIn64BitOnly)
       FullFS += ",-" + F.str();
diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp
index e1bdfbe42d07f..dfe97f178bd46 100644
--- a/llvm/lib/TargetParser/Host.cpp
+++ b/llvm/lib/TargetParser/Host.cpp
@@ -2184,6 +2184,7 @@ StringMap<bool> sys::getHostCPUFeatures() {
   Features["nf"] = HasAPXF;
   Features["cf"] = HasAPXF;
   Features["zu"] = HasAPXF;
+  Features["jmpabs"] = HasAPXF;
 
   bool HasLeafD = MaxLevel >= 0xd &&
                   !getX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);
diff --git a/llvm/lib/TargetParser/X86TargetParser.cpp 
b/llvm/lib/TargetParser/X86TargetParser.cpp
index f848b1ac08607..b3859eb4ff2fd 100644
--- a/llvm/lib/TargetParser/X86TargetParser.cpp
+++ b/llvm/lib/TargetParser/X86TargetParser.cpp
@@ -142,8 +142,8 @@ constexpr FeatureBitset FeaturesDiamondRapids =
     FeatureCMPCCXADD | FeatureAVXIFMA | FeatureAVXNECONVERT |
     FeatureAVXVNNIINT8 | FeatureAVXVNNIINT16 | FeatureSHA512 | FeatureSM3 |
     FeatureSM4 | FeatureEGPR | FeatureZU | FeatureCCMP | FeaturePush2Pop2 |
-    FeaturePPX | FeatureNDD | FeatureNF | FeatureMOVRS | FeatureAMX_MOVRS |
-    FeatureAMX_AVX512 | FeatureAMX_FP8 | FeatureAMX_TF32;
+    FeaturePPX | FeatureNDD | FeatureNF | FeatureJMPABS | FeatureMOVRS |
+    FeatureAMX_MOVRS | FeatureAMX_AVX512 | FeatureAMX_FP8 | FeatureAMX_TF32;
 
 // Intel Atom processors.
 // Bonnell has feature parity with Core2 and adds MOVBE.
@@ -178,7 +178,7 @@ constexpr FeatureBitset FeaturesPantherlake =
 constexpr FeatureBitset FeaturesNovalake =
     FeaturesPantherlake | FeaturePREFETCHI | FeatureAVX10_2 | FeatureMOVRS |
     FeatureEGPR | FeatureZU | FeatureCCMP | FeaturePush2Pop2 | FeaturePPX |
-    FeatureNDD | FeatureNF;
+    FeatureNDD | FeatureNF | FeatureJMPABS;
 constexpr FeatureBitset FeaturesClearwaterforest =
     (FeaturesSierraforest ^ FeatureWIDEKL) | FeatureAVXVNNIINT16 |
     FeatureSHA512 | FeatureSM3 | FeatureSM4 | FeaturePREFETCHI | 
FeatureUSERMSR;
@@ -659,11 +659,12 @@ constexpr FeatureBitset ImpliedFeaturesCCMP = {};
 constexpr FeatureBitset ImpliedFeaturesNF = {};
 constexpr FeatureBitset ImpliedFeaturesCF = {};
 constexpr FeatureBitset ImpliedFeaturesZU = {};
+constexpr FeatureBitset ImpliedFeaturesJMPABS = {};
 
 constexpr FeatureBitset ImpliedFeaturesAPXF =
     ImpliedFeaturesEGPR | ImpliedFeaturesPush2Pop2 | ImpliedFeaturesPPX |
     ImpliedFeaturesNDD | ImpliedFeaturesCCMP | ImpliedFeaturesNF |
-    ImpliedFeaturesCF | ImpliedFeaturesZU;
+    ImpliedFeaturesCF | ImpliedFeaturesZU | ImpliedFeaturesJMPABS;
 
 constexpr FeatureBitset ImpliedFeaturesMOVRS = {};
 
diff --git a/llvm/test/CodeGen/X86/tailcc-largecode.ll 
b/llvm/test/CodeGen/X86/tailcc-largecode.ll
index ac32f67fce9e6..cdc39f01522a2 100644
--- a/llvm/test/CodeGen/X86/tailcc-largecode.ll
+++ b/llvm/test/CodeGen/X86/tailcc-largecode.ll
@@ -1,12 +1,15 @@
-; RUN: llc < %s -mtriple=x86_64-linux-gnu -code-model=large 
-enable-misched=false | FileCheck %s
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -code-model=large 
-enable-misched=false | FileCheck %s --check-prefixes=CHECK,JMP
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -code-model=large 
-enable-misched=false -mattr=jmpabs | FileCheck %s --check-prefixes=CHECK,JMPABS
 
 declare tailcc i32 @callee(i32 %arg)
 define tailcc i32 @directcall(i32 %arg) {
 entry:
 ; This is the large code model, so &callee may not fit into the jmp
 ; instruction.  Instead, stick it into a register.
-;  CHECK: movabsq $callee, [[REGISTER:%r[a-z0-9]+]]
-;  CHECK: jmpq    *[[REGISTER]]  # TAILCALL
+;  JMP: movabsq $callee, [[REGISTER:%r[a-z0-9]+]]
+;  JMP: jmpq    *[[REGISTER]]  # TAILCALL
+;  JMPABS-NOT: movabsq
+;  JMPABS:     jmpabs $callee  # TAILCALL
   %res = tail call tailcc i32 @callee(i32 %arg)
   ret i32 %res
 }
@@ -53,7 +56,8 @@ define tailcc i32 @direct_manyargs() {
 ; the jmp instruction.  Put it into a register which won't be clobbered
 ; while restoring callee-saved registers and won't be used for passing
 ; arguments.
-;  CHECK: movabsq $manyargs_callee, %rax
+;  JMP: movabsq $manyargs_callee, %rax
+;  JMPABS-NOT: movabsq
 ; Pass the register arguments, in the right registers.
 ;  CHECK: movl $1, %edi
 ;  CHECK: movl $2, %esi
@@ -64,7 +68,8 @@ define tailcc i32 @direct_manyargs() {
 ; Adjust the stack to "return".
 ;  CHECK: popq
 ; And tail-call to the target.
-;  CHECK: jmpq *%rax  # TAILCALL
+;  JMP: jmpq *%rax  # TAILCALL
+;  JMPABS: jmpabs $manyargs_callee  # TAILCALL
   %res = tail call tailcc i32 @manyargs_callee(i32 1, i32 2, i32 3, i32 4,
                                                i32 5, i32 6, i32 7)
   ret i32 %res

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to