Index: compiler-rt/lib/xray/xray_trampoline_x86_64.S =================================================================== --- compiler-rt/lib/xray/xray_trampoline_x86_64.S +++ compiler-rt/lib/xray/xray_trampoline_x86_64.S @@ -100,7 +100,7 @@ testq %rax, %rax je .Ltmp0 - // The patched function prolog puts its xray_instr_map index into %r10d. + // The patched function prologue puts its xray_instr_map index into %r10d. movl %r10d, %edi xor %esi,%esi ALIGNED_CALL_RAX @@ -220,15 +220,28 @@ SAVE_REGISTERS // We take two arguments to this trampoline, which should be in rdi and rsi - // already. We also make sure that we stash %rax because we use that register - // to call the logging handler. + // already. movq ASM_SYMBOL(_ZN6__xray22XRayPatchedCustomEventE)(%rip), %rax testq %rax,%rax je .LcustomEventCleanup + // Because calls to __xray_CustomEvent can occur in the middle of a function + // which may already be using scratch registers, we preserve more information + // in this trampoline than when we are handling entry/exit events. + subq $16, %rsp + CFI_ADJUST_CFA_OFFSET(16) + movq %r10, 8(%rsp) + movq %r11, 0(%rsp) + ALIGNED_CALL_RAX + movq 8(%rsp), %r10 + movq 0(%rsp), %r11 + addq $16, %rsp + CFI_ADJUST_CFA_OFFSET(-16) + .LcustomEventCleanup: + RESTORE_REGISTERS retq ASM_SIZE(__xray_CustomEvent) Index: llvm/include/llvm/CodeGen/TargetLowering.h =================================================================== --- llvm/include/llvm/CodeGen/TargetLowering.h +++ llvm/include/llvm/CodeGen/TargetLowering.h @@ -2515,6 +2515,13 @@ /// sequence of memory operands that is recognized by PrologEpilogInserter. MachineBasicBlock *emitPatchPoint(MachineInstr &MI, MachineBasicBlock *MBB) const; + + /// Replace/modify the XRay custom event operands to provide the correct + /// register mask (so that register allocation can deal with the fact that the + /// XRay custom event handlers may clobber all the registers). + MachineBasicBlock *emitXRayCustomEvent(MachineInstr &MI, + MachineBasicBlock *MBB, + const TargetRegisterInfo *TRI) const; }; /// This class defines information used to lower LLVM code to legal SelectionDAG Index: llvm/include/llvm/IR/Intrinsics.td =================================================================== --- llvm/include/llvm/IR/Intrinsics.td +++ llvm/include/llvm/IR/Intrinsics.td @@ -880,7 +880,7 @@ // Custom event logging for x-ray. // Takes a pointer to a string and the length of the string. def int_xray_customevent : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty], - [NoCapture<0>, ReadOnly<0>, IntrWriteMem]>; + [NoCapture<0>, ReadOnly<0>, IntrWriteMem, IntrHasSideEffects]>; //===----------------------------------------------------------------------===// //===------ Memory intrinsics with element-wise atomicity guarantees ------===// Index: llvm/lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -874,6 +874,13 @@ TII.get(TargetOpcode::PATCHABLE_EVENT_CALL)); for (auto &MO : Ops) MIB.add(MO); + + // We want to make sure that we mark all registers as clobbered for this + // function call. This is so that the codegen around the customevent call will + // treat this function call as something that will potentially use all the + // registers. + MIB.addRegMask(TRI.getNoPreservedMask()); + // Insert the Patchable Event Call instruction, that gets lowered properly. return true; } Index: llvm/lib/CodeGen/TargetLoweringBase.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringBase.cpp +++ llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -944,6 +944,25 @@ return MBB; } +MachineBasicBlock * +TargetLoweringBase::emitXRayCustomEvent(MachineInstr &MI, + MachineBasicBlock *MBB, + const TargetRegisterInfo *TRI) const { + assert(MI.getOpcode() == TargetOpcode::PATCHABLE_EVENT_CALL && + "Called emitXRayCustomEvent on the wrong MI!"); + auto &MF = *MI.getMF(); + auto MIB = BuildMI(MF, MI.getDebugLoc(), MI.getDesc()); + for (unsigned OpIdx = 0; OpIdx != MI.getNumOperands(); ++OpIdx) + MIB.add(MI.getOperand(OpIdx)); + + // We need to make sure that all registers are considered clobbered after this + // call. There will be *no* safe registers after this call. + MIB.addRegMask(TRI->getNoPreservedMask()); + MBB->insert(MachineBasicBlock::iterator(MI), MIB); + MI.eraseFromParent(); + return MBB; +} + /// findRepresentativeClass - Return the largest legal super-reg register class /// of the register class for the specified type and its associated "cost". // This function is in TargetLowering because it uses RegClassForVT which would Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ llvm/lib/Target/X86/X86ISelLowering.cpp @@ -27526,8 +27526,7 @@ return emitPatchPoint(MI, BB); case TargetOpcode::PATCHABLE_EVENT_CALL: - // Do nothing here, handle in xray instrumentation pass. - return BB; + return emitXRayCustomEvent(MI, BB, Subtarget.getRegisterInfo()); case X86::LCMPXCHG8B: { const X86RegisterInfo *TRI = Subtarget.getRegisterInfo();