[PATCH] D134915: Do not emit JCC to __x86_indirect_thunk

Joao Moreira via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 29 15:22:08 PDT 2022


joaomoreira created this revision.
joaomoreira added reviewers: nickdesaulniers, nathanchance, samitolvanen, kees, pengfei, aaron.ballman, xiangzhangllvm, hjl.tools, gftg, gftg85, andrew.w.kaylor.
Herald added a subscriber: hiraditya.
Herald added a project: All.
joaomoreira requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Clang may optimize conditional tailcall blocks with the following layout:

cmp <condition>
je  tailcall_target
ret

When retpoline is in place, indirect calls are converted into direct calls to a retpoline thunk. When these indirect calls are tail calls, they may be subject to the above described optimization (there is no indirect JCC, but since now the jump is direct it can be made conditional). The above layout is non-ideal for the Linux kernel scenario because the branches into thunks may be patched back into indirect branches during runtime depending on the underlying CPU features, what would not be feasible if the binary is emitted with the optimized layout above.

Thus, prevent clang from emitting this it if CodeModel is Kernel.

Feature request from the respective kernel mailing list: https://lore.kernel.org/llvm/Yv3uI%2FMoJVctmBCh@worktop.programming.kicks-ass.net/


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134915

Files:
  llvm/lib/Target/X86/X86InstrInfo.cpp
  llvm/test/CodeGen/X86/jcc-indirect-thunk-kernel.ll


Index: llvm/test/CodeGen/X86/jcc-indirect-thunk-kernel.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/X86/jcc-indirect-thunk-kernel.ll
@@ -0,0 +1,25 @@
+; RUN: llc < %s -O2 -mtriple=x86_64-unknown-linux-gnu -x86-indirect-branch-tracking --code-model=kernel | FileCheck %s --check-prefix=CHECK-KERNEL-JCC-THUNK
+
+; CHECK-KERNEL-JCC-THUNK: foo:
+; CHECK-KERNEL-JCC-THUNK-NOT: jne
+; CHECK-KERNEL-JCC-THUNK: jmp
+
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: cold noredzone nounwind null_pointer_is_valid optsize sspstrong
+define dso_local void @foo(void()** %something) #0 {
+entry:
+  %0 = load void()*, void()** %something, align 8
+  %tobool.not = icmp eq void()* %0, null
+  br i1 %tobool.not, label %if.end, label %if.then
+
+if.then:
+  tail call void %0() #1
+  ret void
+
+if.end:
+  ret void
+}
+
+attributes #0 = { nounwind uwtable optsize "target-cpu"="x86-64" "target-features"="+retpoline-indirect-calls,+retpoline-external-thunk" }
+attributes #1 = { nounwind }
Index: llvm/lib/Target/X86/X86InstrInfo.cpp
===================================================================
--- llvm/lib/Target/X86/X86InstrInfo.cpp
+++ llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -2942,13 +2942,26 @@
 bool X86InstrInfo::canMakeTailCallConditional(
     SmallVectorImpl<MachineOperand> &BranchCond,
     const MachineInstr &TailCall) const {
+
+  const MachineFunction *MF = TailCall.getMF();
+
+  if (MF->getTarget().getCodeModel() == CodeModel::Kernel) {
+    // Kernel patches thunk calls in runtime, these should never be conditional.
+    auto Target = TailCall.getOperand(0);
+    if (Target.isSymbol()) {
+      StringRef Symbol(Target.getSymbolName());
+      // this is currently only relevant to r11/kernel indirect thunk.
+      if (Symbol.equals("__x86_indirect_thunk_r11"))
+        return false;
+    }
+  }
+
   if (TailCall.getOpcode() != X86::TCRETURNdi &&
       TailCall.getOpcode() != X86::TCRETURNdi64) {
     // Only direct calls can be done with a conditional branch.
     return false;
   }
 
-  const MachineFunction *MF = TailCall.getParent()->getParent();
   if (Subtarget.isTargetWin64() && MF->hasWinCFI()) {
     // Conditional tail calls confuse the Win64 unwinder.
     return false;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D134915.464032.patch
Type: text/x-patch
Size: 2289 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220929/693071af/attachment.bin>


More information about the llvm-commits mailing list