diff --git a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp index 80b4aeeda1e00..739a29283b41c 100644 --- a/llvm/lib/Target/X86/X86ISelLoweringCall.cpp +++ b/llvm/lib/Target/X86/X86ISelLoweringCall.cpp @@ -2034,11 +2034,17 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, X86MachineFunctionInfo *X86Info = MF.getInfo(); bool HasNCSR = (CB && isa(CB) && CB->hasFnAttr("no_caller_saved_registers")); - bool HasNoCfCheck = (CB && CB->doesNoCfCheck()); bool IsIndirectCall = (CB && isa(CB) && CB->isIndirectCall()); bool IsCFICall = IsIndirectCall && CLI.CFIType; const Module *M = MF.getFunction().getParent(); - Metadata *IsCFProtectionSupported = M->getModuleFlag("cf-protection-branch"); + + // If the indirect call target has the nocf_check attribute, the call needs + // the NOTRACK prefix. For simplicity just disable tail calls as there are + // so many variants. + bool IsNoTrackIndirectCall = IsIndirectCall && CB->doesNoCfCheck() && + M->getModuleFlag("cf-protection-branch"); + if (IsNoTrackIndirectCall) + isTailCall = false; MachineFunction::CallSiteInfo CSInfo; if (CallConv == CallingConv::X86_INTR) @@ -2549,7 +2555,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, // Returns a chain & a glue for retval copy to use. SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); - if (HasNoCfCheck && IsCFProtectionSupported && IsIndirectCall) { + if (IsNoTrackIndirectCall) { Chain = DAG.getNode(X86ISD::NT_CALL, dl, NodeTys, Ops); } else if (CLI.CB && objcarc::hasAttachedCallOpBundle(CLI.CB)) { // Calls with a "clang.arc.attachedcall" bundle are special. They should be diff --git a/llvm/test/CodeGen/X86/nocf_check.ll b/llvm/test/CodeGen/X86/nocf_check.ll index d6c6edea55e14..7b184edf8c0b0 100644 --- a/llvm/test/CodeGen/X86/nocf_check.ll +++ b/llvm/test/CodeGen/X86/nocf_check.ll @@ -43,6 +43,29 @@ entry: ret void } +;; NOTRACK tail call is not implemented, so nocf_check just disables tail call. +define void @NoCfCheckTail(ptr %p) #1 { +; CHECK-LABEL: NoCfCheckTail: +; CHECK: notrack callq *%rax + %f = load ptr, ptr %p, align 4 + tail call void %f() #2 + ret void +} + +define void @NoCfCheckTailCond(ptr %f, i1 %x) #1 { +; CHECK-LABEL: NoCfCheckTailCond: +; CHECK: notrack callq *%rdi +; CHECK: notrack callq *%rdi +entry: + br i1 %x, label %bb1, label %bb2 +bb1: + tail call void %f() #2 + ret void +bb2: + tail call void %f() #2 + ret void +} + attributes #0 = { nocf_check noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #2 = { nocf_check }