pengfei updated this revision to Diff 449275.
pengfei marked an inline comment as done.
pengfei added a comment.

Add CC1 option test.

> When a module with "`indirect_branch_cs_prefix`" and another without the 
> module flag are merged, what the result should be? If 0, we should use `Min` 
> instead of `Override`.

I think `Override` is correct. This option is used for Linux Kernel build. When 
merged, all should be set to 1.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130754/new/

https://reviews.llvm.org/D130754

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/test/CodeGen/X86/indirect-branch-cs-prefix.c
  clang/test/Driver/x86_features.c
  llvm/lib/Target/X86/X86MCInstLower.cpp
  llvm/lib/Target/X86/X86ReturnThunks.cpp
  llvm/test/CodeGen/X86/attr-function-return.ll
  llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll

Index: llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll
===================================================================
--- llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll
+++ llvm/test/CodeGen/X86/lvi-hardening-indirectbr.ll
@@ -22,18 +22,22 @@
 ; X64:       callq bar
 ; X64-DAG:   movl %[[x]], %edi
 ; X64-DAG:   movq %[[fp]], %r11
-; X64:       callq __llvm_lvi_thunk_r11
+; X64:       cs
+; X64-NEXT:  callq __llvm_lvi_thunk_r11
 ; X64:       movl %[[x]], %edi
 ; X64:       callq bar
 ; X64-DAG:   movl %[[x]], %edi
 ; X64-DAG:   movq %[[fp]], %r11
-; X64:       jmp __llvm_lvi_thunk_r11 # TAILCALL
+; X64:       cs
+; X64-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL
 
 ; X64FAST-LABEL: icall_reg:
 ; X64FAST:       callq bar
-; X64FAST:       callq __llvm_lvi_thunk_r11
+; X64FAST:       cs
+; X64FAST-NEXT:  callq __llvm_lvi_thunk_r11
 ; X64FAST:       callq bar
-; X64FAST:       jmp __llvm_lvi_thunk_r11 # TAILCALL
+; X64FAST:       cs
+; X64FAST-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL
 
 
 @global_fp = external dso_local global ptr
@@ -50,16 +54,20 @@
 ; X64-LABEL: icall_global_fp:
 ; X64-DAG:   movl %edi, %[[x:[^ ]*]]
 ; X64-DAG:   movq global_fp(%rip), %r11
-; X64:       callq __llvm_lvi_thunk_r11
+; X64:       cs
+; X64-NEXT:  callq __llvm_lvi_thunk_r11
 ; X64-DAG:   movl %[[x]], %edi
 ; X64-DAG:   movq global_fp(%rip), %r11
-; X64:       jmp __llvm_lvi_thunk_r11 # TAILCALL
+; X64:       cs
+; X64-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL
 
 ; X64FAST-LABEL: icall_global_fp:
 ; X64FAST:       movq global_fp(%rip), %r11
-; X64FAST:       callq __llvm_lvi_thunk_r11
+; X64FAST:       cs
+; X64FAST-NEXT:  callq __llvm_lvi_thunk_r11
 ; X64FAST:       movq global_fp(%rip), %r11
-; X64FAST:       jmp __llvm_lvi_thunk_r11 # TAILCALL
+; X64FAST:       cs
+; X64FAST-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL
 
 
 %struct.Foo = type { ptr }
@@ -79,14 +87,18 @@
 ; X64:       movq (%rdi), %[[vptr:[^ ]*]]
 ; X64:       movq 8(%[[vptr]]), %[[fp:[^ ]*]]
 ; X64:       movq %[[fp]], %r11
-; X64:       callq __llvm_lvi_thunk_r11
+; X64:       cs
+; X64-NEXT:  callq __llvm_lvi_thunk_r11
 ; X64-DAG:   movq %[[obj]], %rdi
 ; X64-DAG:   movq %[[fp]], %r11
-; X64:       jmp __llvm_lvi_thunk_r11 # TAILCALL
+; X64:       cs
+; X64-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL
 
 ; X64FAST-LABEL: vcall:
-; X64FAST:       callq __llvm_lvi_thunk_r11
-; X64FAST:       jmp __llvm_lvi_thunk_r11 # TAILCALL
+; X64FAST:       cs
+; X64FAST-NEXT:  callq __llvm_lvi_thunk_r11
+; X64FAST:       cs
+; X64FAST-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL
 
 
 declare dso_local void @direct_callee()
@@ -113,14 +125,18 @@
 ; X64-LABEL: nonlazybind_caller:
 ; X64:       movq nonlazybind_callee@GOTPCREL(%rip), %[[REG:.*]]
 ; X64:       movq %[[REG]], %r11
-; X64:       callq __llvm_lvi_thunk_r11
+; X64:       cs
+; X64-NEXT:  callq __llvm_lvi_thunk_r11
 ; X64:       movq %[[REG]], %r11
-; X64:       jmp __llvm_lvi_thunk_r11 # TAILCALL
+; X64:       cs
+; X64-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL
 ; X64FAST-LABEL: nonlazybind_caller:
 ; X64FAST:   movq nonlazybind_callee@GOTPCREL(%rip), %r11
-; X64FAST:   callq __llvm_lvi_thunk_r11
+; X64FAST:   cs
+; X64FAST-NEXT:  callq __llvm_lvi_thunk_r11
 ; X64FAST:   movq nonlazybind_callee@GOTPCREL(%rip), %r11
-; X64FAST:   jmp __llvm_lvi_thunk_r11 # TAILCALL
+; X64FAST:   cs
+; X64FAST-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL
 
 
 ; Check that a switch gets lowered using a jump table
@@ -278,3 +294,7 @@
 ; X64-NEXT:          jmpq     *%r11
 
 attributes #1 = { nonlazybind }
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 4, !"indirect_branch_cs_prefix", i32 1}
Index: llvm/test/CodeGen/X86/attr-function-return.ll
===================================================================
--- llvm/test/CodeGen/X86/attr-function-return.ll
+++ llvm/test/CodeGen/X86/attr-function-return.ll
@@ -6,6 +6,11 @@
 define void @x() fn_ret_thunk_extern {
 ; CHECK-LABEL: x:
 ; CHECK:       # %bb.0:
+; CHECK-NEXT:    cs
 ; CHECK-NEXT:    jmp __x86_return_thunk
   ret void
 }
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 4, !"indirect_branch_cs_prefix", i32 1}
Index: llvm/lib/Target/X86/X86ReturnThunks.cpp
===================================================================
--- llvm/lib/Target/X86/X86ReturnThunks.cpp
+++ llvm/lib/Target/X86/X86ReturnThunks.cpp
@@ -34,6 +34,7 @@
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/MC/MCInstrDesc.h"
 #include "llvm/Support/Debug.h"
 
@@ -73,9 +74,14 @@
       if (Term.getOpcode() == RetOpc)
         Rets.push_back(&Term);
 
+  bool IndCS =
+      MF.getMMI().getModule()->getModuleFlag("indirect_branch_cs_prefix");
+  const MCInstrDesc &CS = ST.getInstrInfo()->get(X86::CS_PREFIX);
   const MCInstrDesc &JMP = ST.getInstrInfo()->get(X86::TAILJMPd);
 
   for (MachineInstr *Ret : Rets) {
+    if (IndCS)
+      BuildMI(Ret->getParent(), Ret->getDebugLoc(), CS);
     BuildMI(Ret->getParent(), Ret->getDebugLoc(), JMP)
         .addExternalSymbol(ThunkName.data());
     Ret->eraseFromParent();
Index: llvm/lib/Target/X86/X86MCInstLower.cpp
===================================================================
--- llvm/lib/Target/X86/X86MCInstLower.cpp
+++ llvm/lib/Target/X86/X86MCInstLower.cpp
@@ -2441,6 +2441,9 @@
   if (OutStreamer->isVerboseAsm())
     addConstantComments(MI, *OutStreamer);
 
+  bool IndCS =
+      MF->getMMI().getModule()->getModuleFlag("indirect_branch_cs_prefix");
+
   switch (MI->getOpcode()) {
   case TargetOpcode::DBG_VALUE:
     llvm_unreachable("Should be handled target independently");
@@ -2489,13 +2492,16 @@
     break;
   }
 
+  case X86::TAILJMPd64:
+    if (IndCS && MI->hasRegisterImplicitUseOperand(X86::R11))
+      EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
+    LLVM_FALLTHROUGH;
   case X86::TAILJMPr:
   case X86::TAILJMPm:
   case X86::TAILJMPd:
   case X86::TAILJMPd_CC:
   case X86::TAILJMPr64:
   case X86::TAILJMPm64:
-  case X86::TAILJMPd64:
   case X86::TAILJMPd64_CC:
   case X86::TAILJMPr64_REX:
   case X86::TAILJMPm64_REX:
@@ -2669,6 +2675,10 @@
                                 .addImm(MI->getOperand(0).getImm())
                                 .addReg(X86::NoRegister));
     return;
+  case X86::CALL64pcrel32:
+    if (IndCS && MI->hasRegisterImplicitUseOperand(X86::R11))
+      EmitAndCountInstruction(MCInstBuilder(X86::CS_PREFIX));
+    break;
   }
 
   MCInst TmpInst;
Index: clang/test/Driver/x86_features.c
===================================================================
--- clang/test/Driver/x86_features.c
+++ clang/test/Driver/x86_features.c
@@ -11,3 +11,6 @@
 
 // RUN: %clang -target i386-unknown-unknown -### %s -mno-skip-rax-setup -S 2>&1 | FileCheck --check-prefix=NO-SRS %s
 // NO-SRS-NOT: "-mskip-rax-setup"
+
+// RUN: %clang -target i386-unknown-unknown -### %s -mindirect-branch-cs-prefix -S 2>&1 | FileCheck --check-prefix=IND-CS %s
+// IND-CS: "-mindirect-branch-cs-prefix"
Index: clang/test/CodeGen/X86/indirect-branch-cs-prefix.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/X86/indirect-branch-cs-prefix.c
@@ -0,0 +1,4 @@
+// RUN: %clang -target i386-unknown-unknown -o - -emit-llvm -S -mindirect-branch-cs-prefix %s | FileCheck %s
+
+// CHECK: !{i32 4, !"indirect_branch_cs_prefix", i32 1}
+void foo() {}
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -6347,6 +6347,9 @@
     CmdArgs.push_back(
         Args.MakeArgString(Twine("-mfunction-return=") + A->getValue()));
 
+  if (Args.hasArg(options::OPT_mindirect_branch_cs_prefix))
+    CmdArgs.push_back("-mindirect-branch-cs-prefix");
+
   // Forward -f options with positive and negative forms; we translate these by
   // hand.  Do not propagate PGO options to the GPU-side compilations as the
   // profile info is for the host-side compilation only.
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -775,6 +775,9 @@
   if (CodeGenOpts.FunctionReturnThunks)
     getModule().addModuleFlag(llvm::Module::Override, "function_return_thunk_extern", 1);
 
+  if (CodeGenOpts.IndirectBranchCSPrefix)
+    getModule().addModuleFlag(llvm::Module::Override, "indirect_branch_cs_prefix", 1);
+
   // Add module metadata for return address signing (ignoring
   // non-leaf/all) and stack tagging. These are actually turned on by function
   // attributes, but we use module metadata to emit build attributes. This is
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -2028,6 +2028,10 @@
   NormalizedValues<["Keep", "Extern"]>,
   NormalizedValuesScope<"llvm::FunctionReturnThunksKind">,
   MarshallingInfoEnum<CodeGenOpts<"FunctionReturnThunks">, "Keep">;
+def mindirect_branch_cs_prefix : Flag<["-"], "mindirect-branch-cs-prefix">,
+  Group<m_Group>, Flags<[CoreOption, CC1Option]>,
+  HelpText<"Add cs prefix to call and jmp to indirect thunk">,
+  MarshallingInfoFlag<CodeGenOpts<"IndirectBranchCSPrefix">>;
 
 defm xray_instrument : BoolFOption<"xray-instrument",
   LangOpts<"XRayInstrument">, DefaultFalse,
Index: clang/include/clang/Basic/CodeGenOptions.def
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.def
+++ clang/include/clang/Basic/CodeGenOptions.def
@@ -108,6 +108,8 @@
                                       ///< set to full or branch.
 CODEGENOPT(IBTSeal, 1, 0)             ///< set to optimize CFProtectionBranch.
 CODEGENOPT(FunctionReturnThunks, 1, 0) ///< -mfunction-return={keep|thunk-extern}
+CODEGENOPT(IndirectBranchCSPrefix, 1, 0) ///< if -mindirect-branch-cs-prefix
+                                         ///< is set.
 
 CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
                                            ///< enabled.
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -131,6 +131,8 @@
 X86 Support in Clang
 --------------------
 
+- Support ``-mindirect-branch-cs-prefix`` for call and jmp to indirect thunk.
+
 DWARF Support in Clang
 ----------------------
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to