diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 856ef34a2ad2..1c596b8c42ee 100644 --- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -740,10 +740,16 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, unsigned NumDefs = II.getNumDefs(); const uint16_t *ScratchRegs = NULL; - // Handle PATCHPOINT specially and then use the generic code. - if (Opc == TargetOpcode::PATCHPOINT) { - unsigned CC = Node->getConstantOperandVal(PatchPointOpers::CCPos); - NumDefs = NumResults; + // Handle STACKMAP and PATCHPOINT specially and then use the generic code. + if (Opc == TargetOpcode::STACKMAP || Opc == TargetOpcode::PATCHPOINT) { + // Stackmaps do not have arguments and do not preserve their calling + // convention. However, to simplify runtime support, they clobber the same + // scratch registers as AnyRegCC. + unsigned CC = CallingConv::AnyReg; + if (Opc == TargetOpcode::PATCHPOINT) { + CC = Node->getConstantOperandVal(PatchPointOpers::CCPos); + NumDefs = NumResults; + } ScratchRegs = TLI->getScratchRegisters((CallingConv::ID) CC); } diff --git a/llvm/test/CodeGen/X86/stackmap.ll b/llvm/test/CodeGen/X86/stackmap.ll index 2b7bb183007c..cfd0c6e88451 100644 --- a/llvm/test/CodeGen/X86/stackmap.ll +++ b/llvm/test/CodeGen/X86/stackmap.ll @@ -6,7 +6,7 @@ ; CHECK-NEXT: __LLVM_StackMaps: ; CHECK-NEXT: .long 0 ; Num Functions -; CHECK-NEXT: .long 14 +; CHECK-NEXT: .long 15 ; CHECK-NEXT: .long _constantargs ; CHECK-NEXT: .long 8 ; CHECK-NEXT: .long _osrinline @@ -35,13 +35,15 @@ ; CHECK-NEXT: .long 56 ; CHECK-NEXT: .long _longid ; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long _clobberScratch +; CHECK-NEXT: .long 56 ; Num LargeConstants ; CHECK-NEXT: .long 3 ; CHECK-NEXT: .quad 2147483648 ; CHECK-NEXT: .quad 4294967295 ; CHECK-NEXT: .quad 4294967296 ; Num Callsites -; CHECK-NEXT: .long 18 +; CHECK-NEXT: .long 19 ; Constant arguments ; @@ -436,6 +438,24 @@ entry: ret void } +; Map a value when R11 is the only free register. +; The scratch register should not be used for a live stackmap value. +; +; CHECK-LABEL: .long L{{.*}}-_clobberScratch +; CHECK-NEXT: .short 0 +; 1 location +; CHECK-NEXT: .short 1 +; Loc 0: Indirect fp - offset +; CHECK-NEXT: .byte 3 +; CHECK-NEXT: .byte 4 +; CHECK-NEXT: .short 6 +; CHECK-NEXT: .long -{{[0-9]+}} +define void @clobberScratch(i32 %a) { + tail call void asm sideeffect "nop", "~{ax},~{bx},~{cx},~{dx},~{bp},~{si},~{di},~{r8},~{r9},~{r10},~{r12},~{r13},~{r14},~{r15}"() nounwind + tail call void (i64, i32, ...)* @llvm.experimental.stackmap(i64 16, i32 8, i32 %a) + ret void +} + declare void @llvm.experimental.stackmap(i64, i32, ...) declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) declare i64 @llvm.experimental.patchpoint.i64(i64, i32, i8*, i32, ...)