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. + const MachineOperand &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,32 @@ +; RUN: llc < %s -O2 --code-model=kernel | FileCheck %s +; The intent of the test is that we do not generate conditional +; tail calls to the thunk. + +target triple = "x86_64-unknown-linux-gnu" + +define dso_local void @foo(ptr %something) #0 { +; CHECK-LABEL: foo: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: movq (%rdi), %r11 +; CHECK-NEXT: testq %r11, %r11 +; Make sure that a JNE was not generated instead of a JE + JMP sequence +; CHECK-NOT: jne +; CHECK-NEXT: je .LBB0_1 +; CHECK-NEXT: bb.2: # %if.then +; CHECK-NEXT: jmp __x86_indirect_thunk_r11 +; CHECK-NEXT: LBB0_1: +; CHECK-NEXT: retq +entry: + %0 = load ptr, ptr %something, align 8 + %tobool.not = icmp eq ptr %0, null + br i1 %tobool.not, label %if.end, label %if.then + +if.then: + tail call void %0() + br label %if.end + +if.end: + ret void +} + +attributes #0 = { optsize "target-features"="+retpoline-external-thunk" }