diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -2942,13 +2942,26 @@ bool X86InstrInfo::canMakeTailCallConditional( SmallVectorImpl &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; diff --git a/llvm/test/CodeGen/X86/jcc-indirect-thunk-kernel.ll b/llvm/test/CodeGen/X86/jcc-indirect-thunk-kernel.ll new file mode 100644 --- /dev/null +++ b/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 }